// Sets up the service, ForkExecuteRedirect helper actually execs code void ForkExecuteRedirect_service(void) { int i, c, rc; int count = 0; bool forever = true; char input [INPUT_SIZE_MAX] = ""; int numArguments = 0; pid_t childPID; char** arguments = NULL; int input_index = 0; /* will not use the server socket */ Socket_close(welcome_socket); while (forever) /* actually, until EOF on connect socket */ { /* get a null-terminated string from the client on the data * transfer socket up to the maximim input line size. Continue * getting strings from the client until EOF on the socket. */ for (i = 0; i < MAX_LINE; i++) { c = Socket_getc(connect_socket); if (c == EOF) { printf("Socket_getc EOF or error\n"); return; /* assume socket EOF ends service for this client */ } else { if (c == '\n'){ // command entered input[input_index] = ' '; input[input_index + 1] = '\0'; // null-terminates string //printf("input: [%s]\n", input); arguments = getArgs(input, &numArguments); ForkExecuteRedirect_helper(numArguments, arguments); } else{ // command not entered, just continue filling input buffer if (input_index <= INPUT_SIZE_MAX){ input[input_index] = c; input[input_index + 1] = '\0'; input_index++; } else // if input size too large printf("max input size reached, no more input will be processed\n"); } } } } /* end while loop of the service process */ return; }
void read_line(char *line) { int i, c; /* Read from the socket */ for (i = 0; i < MAX_LINE; ++i) { c = Socket_getc(connect_socket); //Assume get c worked if (c == EOF) //EOF is found on read exit { remove(filename); //Delete the tmp file exit(-1); } line[i] = c; //Put the character into the line if (c == '\0') //Every line is null terminated so this is how we break out of loop { return; } } }
int main(int argc, char* argv[]) { int i, c, rc, fc; int count = 0; char line_data[MAX_LINE]; /* variable to hold socket descriptor */ Socket connect_socket; if (argc < 3) { printf("No host and port\n"); return (-1); } /* connect to the server at the specified host and port; * blocks the process until the connection is accepted * by the server; creates a new data transfer socket. */ connect_socket = Socket_new(argv[1], atoi(argv[2])); if (connect_socket < 0) { printf("Failed to connect to server\n"); return (-1); } printf("%% "); // print initial prompt /* get a string from stdin up to and including * a newline or to the maximim input line size. * Continue getting strings from stdin until EOF. */ while ((fgets(line_data, sizeof(line_data), stdin) != NULL)) { count = strlen(line_data) + 1; /* count includes '\0' */ /* send the characters of the input line to the server * using the data transfer socket. */ for (i = 0; i < count; i++) { c = line_data[i]; rc = Socket_putc(c, connect_socket); // if (rc == EOF) // { // printf("Socket_putc EOF or error\n"); // Socket_close(connect_socket); // exit (-1); /* assume socket problem is fatal, end client */ // } } /* receive the converted characters for the string from * the server using the data transfer socket. */ printf("boutta receive\n"); while (1) { fc = Socket_getc(connect_socket); printf("%c", fc); if (fc == '\0') { break; } } printf("%% "); // print prompt for next command } /* end of while loop; at EOF */ Socket_close(connect_socket); exit(0); }
void shell_service(void){ int i = 0, c, character, rc, no_error; //MAX_LINE is the longest the stdin buffer can be, so we won't overflow it char line_data[MAX_LINE]; pid_t cpid, term_pid; /* pid_t is typedef for Linux process ID */ int chld_status; unsigned char new_line[MAX_LINE]; unsigned char tmp_name[MAX_TMP]; unsigned char id_str[MAX_TMP]; char response[MAX_LINE]; char temp[MAX_LINE]; int id; /* variable names for file "handles" */ FILE *tmpFP; FILE *fp; /* get the parent process ID and use it to create a file name for the * temporary file with the format "tmpxxxxx" where xxxxx is the ID */ id = (int) getpid(); sprintf(id_str, "%d", id); strcpy(tmp_name,"tmp"); strcat(tmp_name, id_str); /* will not use the server socket */ Socket_close(welcome_socket); while((c = Socket_getc(connect_socket)) != EOF){ if(c != NEWLINE){ line_data[i] = c; i ++; } else{ line_data[i] = STRING_END; i++; //make sure the string is terminated if(i == MAX_LINE){ line_data[MAX_LINE - 1] = STRING_END; } cpid = fork(); /* create child == service process */ if (cpid == ERROR){ perror("fork"); exit (ERROR); } if (cpid == NORMAL) {/* code for the service process */ /* dynamically redirect stdout to the named temporary * file open for writing */ fp = freopen(tmp_name, "w", stdout); parse_input(line_data, &connect_socket); } /* end service process */ else{ i = 0; term_pid = waitpid(cpid, &chld_status, 0); if (term_pid == ERROR) perror("waitpid"); else{ if (WIFEXITED(chld_status)) sprintf(response, "End of input: PID %d exited, status = %d\n", cpid, WEXITSTATUS(chld_status)); else sprintf(response, "End of Input: PID %d did not exit normally\n", cpid); } if ((tmpFP = fopen (tmp_name, "r")) == NULL) { fprintf (stderr, "error opening tmp file\n"); exit (ERROR); } no_error = 0; while (!feof (tmpFP)) { no_error = 1; /* Get line from file */ if (fgets (new_line, sizeof(new_line), tmpFP) == NULL) break; send(new_line, &connect_socket); } rc = Socket_putc(NEWLINE, connect_socket); check_put(rc, &connect_socket); if(no_error) send(response, &connect_socket); rc = Socket_putc(STRING_END, connect_socket); check_put(rc, &connect_socket); /* delete the temporary file */ remove(tmp_name); // } } } } }
int main(int argc, char* argv[]) { bool doneFlag = false; int i; int rc; int c; unsigned char tmp_name[MAX_TMP]; unsigned char id_str[MAX_TMP]; int id; int childPID, term_pid; int chld_status; char fc; char file_line[MAX_LINE]; char * args[MAX_ARGS]; /* variable names for file "handles" */ FILE *tmpFP; FILE *fp; if (argc < 2) { printf("No port specified\n"); return (-1); } /* create a "welcoming" socket at the specified port */ welcome_socket = ServerSocket_new(atoi(argv[1])); if (welcome_socket < 0) { printf("Failed new server socket\n"); return (-1); } id = (int) getpid(); sprintf(id_str, "%d", id); strcpy(tmp_name,"tmp"); strcat(tmp_name, id_str); /* accept an incoming client connection; blocks the * process until a connection attempt by a client. * creates a new data transfer socket. */ connect_socket = ServerSocket_accept(welcome_socket); if (connect_socket < 0) { printf("Failed accept on server socket\n"); exit (-1); } Socket_close(welcome_socket); char input[MAX_LINE]={'\0'}; memset(input,'\0',sizeof(char)*MAX_LINE); while(1){ for (i = 0; i < MAX_LINE; i++) { c = Socket_getc(connect_socket); if (c == EOF) { remove(tmp_name); doneFlag = true; for (i=0; i<=strlen(ERROR2); i++){ Socket_putc(ERROR2[i], connect_socket); } // printf("Socket_getc EOF or error\n"); return; /* assume socket EOF ends service for this client */ } else { if (c == '\0') { input[i] = '\0'; break; } if (c == '\n') { i--; } else{ input[i] = c; } } } /* be sure the string is terminated if max size reached */ if (i == MAX_LINE) input[i-1] = '\0'; fp = freopen(tmp_name, "w", stdout); childPID = fork(); if (childPID == 0){ //code for child: char * token = strtok(input, " \t"); args[0] = token; // set first "argument" to the command itself int count = 1; // loop to fill args[] with the remaining arguments (if any) while (token != NULL) { token = strtok(NULL, " "); args[count] = token; count++; if (count > (MAX_ARGS+2)){ // handle it } } args[count] = NULL; // the array must be null terminated for execvp() to work int execCode = execvp(args[0], args); if (execCode == -1) { for (i=0; i<=strlen(ERROR1); i++){ Socket_putc(ERROR1[i], connect_socket); } // exit(0); //goto end; // printf("Error: invalid command.\n"); } } else if (childPID == -1) { printf("Problem forking.\n"); } else { //parent code: term_pid = waitpid(childPID, &chld_status, 0); if (doneFlag == false){ char file_c; if ((tmpFP = fopen (tmp_name, "r")) == NULL) { fprintf (stderr, "error opening tmp file\n"); exit (-1); } while ((fc = fgetc(tmpFP)) != EOF) { Socket_putc(fc, connect_socket); } } if (term_pid == -1) perror("waitpid"); else { if (WIFEXITED(chld_status)) { char str[] = "PID %d exited, status = %d\n"; char str2[256]; sprintf(str2, str, childPID, WEXITSTATUS(chld_status)); for (i=0; i<=strlen(str2); i++){ Socket_putc(str2[i], connect_socket); } //printf("PID %d exited, status = %d\n", childPID, WEXITSTATUS(chld_status)); } else{ printf("PID %d did not exit normally\n", childPID); } } } end:; } Socket_close(connect_socket); exit (0); }