/* Cleanup storage allocation */ void token_cleanup() { WFREE(w_to); WFREE(w_from); WFREE(w_rtrn); WFREE(w_subj); WFREE(w_recv); WFREE(w_head); WFREE(w_mime); WFREE(w_ip); WFREE(w_url); WFREE(nonblank_line); token_clear(); /* do multi-word token cleanup */ free_token_array(); }
parse_status parse_command_string(char *cmdString, char **cmdArgs) { int nTokens; parse_status status; exec_error error; char **tokens = NULL; // Tokenize command string. nTokens = command_tokens(cmdString, &tokens); if (nTokens <= 0) { // Ignore if no commands status = IGNORE; } else if (strcmp(tokens[0], "cd") == 0) { // Command is 'cd'. Change directory to first argument or HOME if none. status = CMD_CD; if (nTokens == 1) { chdir(getenv("HOME")); } else { chdir(tokens[1]); } } else if (strcmp(tokens[0], "exit") == 0) { // Command is 'exit'. Prepare for exit. status = CMD_EXIT; } else { status = CMD_EXEC; error = prepare_command(nTokens, tokens); if (error == FILE_NOT_FOUND) { status = CMD_NOTFOUND; } else if (error == COMMAND_NOT_FOUND) { status = CMD_NOCMD; } else if (error != NONE) { status = CMD_EXEC_ERR; } } free_token_array(&tokens, nTokens); return status; }
// Takes a tokenized command string and prepares a command structures which are // then executed. exec_error prepare_command(int argc, char **cmdTokens) { int pipeIndex, argSplit1Len, argSplit2Len; char **argSplit1; char **argSplit2; Command *cmd1; Command *cmd2; exec_error error = NONE; pipeIndex = index_of(cmdTokens, argc, "|"); if (pipeIndex > 0) { // Split arguments into two for each side of the pipe. argSplit1Len = pipeIndex; argSplit1 = copy_token_array(cmdTokens, argSplit1Len); argSplit1[argSplit1Len] = '\0'; argSplit2Len = argc - pipeIndex - 1; argSplit2 = copy_token_array(cmdTokens + pipeIndex + 1, argSplit2Len); argSplit2[argSplit2Len] = '\0'; // Prepare input (left) side of pipe. First command will take // arguments from left of pipe. REDIRECT_TBA allows fd to be allocated // by command_redirect for possible input files. REDIRECT_NONE makes // sure redirection is not done to the output as this will be piped // later. cmd1 = new_command(argSplit1Len, argSplit1, REDIRECT_TBA, REDIRECT_NONE); error = command_redirect(&cmd1); if (error != NONE) { free(cmd1); return error; } // Prepare output (right) side of pipe taking the remaining arguments // on the RHS of the pipe. REDIRECT constants are switched as this // will be executed on the other half of the pipe. cmd2 = new_command(argSplit2Len, argSplit2, REDIRECT_NONE, REDIRECT_TBA); error = command_redirect(&cmd2); if (error != NONE) { free(cmd1); free(cmd2); return error; } // Execute piped command error = execute_piped(cmd1, cmd2); free_token_array(&argSplit1, argSplit1Len); free_token_array(&argSplit2, argSplit2Len); } else { // No pipe found. Prepare any redirects. cmd1 = new_command(argc, cmdTokens, REDIRECT_TBA, REDIRECT_TBA); error = command_redirect(&cmd1); if (error != NONE) { free(cmd1); return error; } error = execute_unpiped(cmd1); } return error; }