void free_run_event_state(struct run_event_state *state) { if (state) { strbuf_free(state->command_output); free_commands(state); free(state); } }
/** * \fn int exittimeout() * \brief send timeout and exit propely */ int exittimeout () { clearData (); sendTxt ("451 timeout\r\n"); free_commands (); freeconfig (); exit (0); return 451; }
/** * \fn quit(char *c) * \brief send goodbye message and close the quit the process */ int quit (char *c) { clearData (); sendTxt ("221 Service closing transmission channel\r\n"); free_commands (); freeconfig (); freeAllPlugin (); exit (0); return 221; }
int prepare_commands(struct run_event_state *state, const char *dump_dir_name, const char *event ) { free_commands(state); state->children_count = 0; strbuf_clear(state->command_output); GList *rule_list = load_rule_list(NULL, CONF_DIR"/report_event.conf", /*recursion_depth:*/ 0); state->rule_list = rule_list; return rule_list != NULL; }
/** * \fn void exitTalkEarlier() * \brief exit when the client don't wait the 220 greeting message */ void exitTalkEarlier () { sendTxt ("451 you must wait 220 code\r\n"); if (config->exitTalkEarlier) { clearData (); sendTxt ("451 you must wait 220 code\r\n"); free_commands (); freeconfig (); exit (0); } }
/* Synchronous command execution: */ int run_event_on_dir_name(struct run_event_state *state, const char *dump_dir_name, const char *event ) { prepare_commands(state, dump_dir_name, event); /* Execute every command in shell */ int retval = 0; while (spawn_next_command(state, dump_dir_name, event, /*execflags:*/ 0) >= 0) { retval = consume_event_command_output(state, dump_dir_name); if (retval != 0) break; } free_commands(state); return retval; }
void write_commands(t_info *info, int fd) { t_list *crawl; t_list *temp; t_command com; crawl = info->commands; while (crawl != NULL) { com = *((t_command *)crawl->data); write(fd, &com.opcode, sizeof(com.opcode)); if (com.encoding_byte != '\0') write(fd, &com.encoding_byte, sizeof(com.encoding_byte)); handle_params(info, com, fd); temp = crawl; crawl = crawl->next; } while (crawl != NULL) { free_commands((t_command *)crawl->data); free(temp); } }
/* * Clean all memory on exit to help find leaks * Yeah I know, one big ugly function -Druid * Added to AFKMud by Samson on 5-8-03. */ void cleanup_memory( void ) { int hash; #ifdef IMC fprintf( stdout, "%s", "IMC2 Data.\n" ); free_imcdata( true ); imc_delete_info( ); #endif fprintf( stdout, "%s", "Quote List.\n" ); free_quotes( ); fprintf( stdout, "%s", "Random Environment Data.\n" ); free_envs( ); fprintf( stdout, "%s", "Auction Sale Data.\n" ); free_sales( ); fprintf( stdout, "%s", "Project Data.\n" ); free_projects( ); fprintf( stdout, "%s", "Ban Data.\n" ); free_bans( ); fprintf( stdout, "%s", "Auth List.\n" ); free_all_auths( ); fprintf( stdout, "%s", "Morph Data.\n" ); free_morphs( ); fprintf( stdout, "%s", "Rune Data.\n" ); free_runedata( ); fprintf( stdout, "%s", "Connection History Data.\n" ); free_connhistory( 0 ); fprintf( stdout, "%s", "Slay Table.\n" ); free_slays( ); fprintf( stdout, "%s", "Holidays.\n" ); free_holidays( ); fprintf( stdout, "%s", "Specfun List.\n" ); free_specfuns( ); fprintf( stdout, "%s", "Wizinfo Data.\n" ); clear_wizinfo( ); fprintf( stdout, "%s", "Skyship landings.\n" ); free_landings( ); fprintf( stdout, "%s", "Ships.\n" ); free_ships( ); fprintf( stdout, "%s", "Overland Landmarks.\n" ); free_landmarks( ); fprintf( stdout, "%s", "Overland Exits.\n" ); free_mapexits( ); fprintf( stdout, "%s", "Mixtures and Liquids.\n" ); free_liquiddata( ); fprintf( stdout, "%s", "DNS Cache data.\n" ); free_dns_list( ); fprintf( stdout, "%s", "Local Channels.\n" ); free_mudchannels( ); // Helps fprintf( stdout, "%s", "Helps.\n" ); free_helps( ); // Commands fprintf( stdout, "%s", "Commands.\n" ); free_commands( ); #ifdef MULTIPORT // Shell Commands fprintf( stdout, "%s", "Shell Commands.\n" ); free_shellcommands( ); #endif // Socials fprintf( stdout, "%s", "Socials.\n" ); free_socials( ); // Languages fprintf( stdout, "%s", "Languages.\n" ); free_tongues( ); // Boards fprintf( stdout, "%s", "Boards.\n" ); free_boards( ); // Events fprintf( stdout, "%s", "Events.\n" ); free_all_events( ); // Find and eliminate all running chess games fprintf( stdout, "%s", "Ending chess games.\n" ); free_all_chess_games( ); // Whack supermob fprintf( stdout, "%s", "Whacking supermob.\n" ); if( supermob ) { supermob->from_room( ); charlist.remove( supermob ); deleteptr( supermob ); } // Free Characters fprintf( stdout, "%s", "Characters.\n" ); extract_all_chars( ); // Free Objects fprintf( stdout, "%s", "Objects.\n" ); extract_all_objs( ); // Descriptors fprintf( stdout, "%s", "Descriptors.\n" ); free_all_descs( ); // Deities fprintf( stdout, "%s", "Deities.\n" ); free_deities( ); // Clans fprintf( stdout, "%s", "Clans.\n" ); free_clans( ); // Races fprintf( stdout, "%s", "Races.\n" ); free_all_races( ); // Classes fprintf( stdout, "%s", "Classes.\n" ); free_all_classes( ); // Teleport lists fprintf( stdout, "%s", "Teleport Data.\n" ); free_teleports( ); // Areas - this includes killing off the hash tables and such fprintf( stdout, "%s", "Area Data Tables.\n" ); close_all_areas( ); // Get rid of auction pointer MUST BE AFTER OBJECTS DESTROYED fprintf( stdout, "%s", "Auction.\n" ); deleteptr( auction ); // Title table fprintf( stdout, "%s", "Title table.\n" ); free_all_titles( ); // Skills fprintf( stdout, "%s", "Skills and Herbs.\n" ); free_skills( ); // Prog Act lists fprintf( stdout, "%s", "Mudprog act lists.\n" ); free_prog_actlists( ); // Questbit data fprintf( stdout, "%s", "Abit/Qbit Data.\n" ); free_questbits( ); free_mssp_info(); fprintf( stdout, "%s", "Checking string hash for leftovers.\n" ); { for( hash = 0; hash < 1024; ++hash ) hash_dump( hash ); } #if !defined(__CYGWIN__) && defined(SQL) fprintf( stdout, "%s", "Closing database connection.\n" ); close_db( ); #endif // Last but not least, close the libdl and dispose of sysdata - Samson fprintf( stdout, "%s", "System data.\n" ); dlclose( sysdata->dlHandle ); deleteptr( sysdata ); fprintf( stdout, "%s", "Memory cleanup complete, exiting.\n" ); }
int main(void) { // Helpful Flags bool IS_NOT_ALONE, IS_ALONE, IS_INTERNAL, IS_EXTERNAL, IS_CD, IS_EXIT; bool IS_PARENT, IS_CHILD, IS_REDIRECTED, IS_FIRST, IS_LAST, IS_MIDDLE; // Pipe Holders int *pipe_left; int *pipe_right; // Holders for dup'd STDIN, OUT in case of redirected internal commands int ORIGINAL_STDIN, ORIGINAL_STDOUT; // Holder for command string from STDIO. char *str; // This gets the current username char *login; login = getlogin(); // This is the current working directory // This will be updated on cd commands run internally char cwd[MAXPATH]; getcwd(cwd, MAXPATH); // pointer to pid holder for children and waiting pid_t child_pid; // for execution & internal/external checking char *command_name; size_t command_length; // parsed command holder + pointer for counting number of commands command *comms = NULL; command *command_walker; char prompt[80]; // for loop iteration variable int i; // This will never be freed until we exit (and then by default). pipe_left = malloc(2*sizeof(int)); pipe_right = malloc(2*sizeof(int)); if ((pipe_left == NULL) || (pipe_right == NULL)) { fprintf(stderr, "%s: Could not allocate holder for potential pipes. Exiting.\n", SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } /** * Curiosity Shell Control Flow * The structure of the program is broken up as follows: * Pipe Creation * Fork Handler * Pipe Cleanup * Redirection (Including for Parent Internal Commands) * Command Run (Child, Parent), Parent Wait (if appropriate) * Reset Temporary Parent Redirection for Internal Commands * Get Next User Input */ while(1){ // Free the previous command free_commands(comms); // Display prompt. sprintf(prompt, "%s:%s> ", login, cwd); str = readline(prompt); if (str == NULL) { exit(EXIT_SUCCESS); } // Save the history. if (str && *str) add_history (str); // Prepare to tokenize command_length = strlen((const char *) str); if (command_length == 0) { comms = NULL; continue; } // Tokenize & parse into discrete commands comms = get_commands(str); if (str != NULL) free(str); // If no commands, create another prompt in the next iteration if (comms == NULL) { continue; } // count number of commands, command_length command_length = 0; command_walker = comms; while (command_walker->argv != NULL) { command_length += 1; command_walker += 1; } // Set IS_ALONE, IS_NOT_ALONE Flags IS_ALONE = false; IS_NOT_ALONE = false; if (command_length == 1) IS_ALONE = true; if (command_length > 1) IS_NOT_ALONE = true; /* Handle Latest Set of Commands */ for (i = 0; i < command_length; i++) { /* Set Flags for THIS command IS_FIRST, IS_MIDDLE, IS_LAST, IS_INTERNAL, IS_EXTERNAL, IS_CD, IS_EXIT */ command_name = comms[i].argv[0]; IS_FIRST = false; IS_MIDDLE = false; IS_LAST = false; if (i == 0) { IS_FIRST = true; } if (i == (command_length-1)) { IS_LAST = true; } if ((!IS_FIRST) && (!IS_LAST)) { IS_MIDDLE = true; } IS_INTERNAL = false; IS_EXTERNAL = true; IS_CD = false; IS_EXIT = false; if (strcmp((const char *)command_name, (const char *) "cd") == 0) { IS_CD = true; } if (strcmp((const char *)command_name, (const char *) "exit") == 0) { IS_EXIT = true; } if (IS_CD || IS_EXIT) { IS_INTERNAL = true; } if (IS_INTERNAL) { IS_EXTERNAL = false; } /* Pipe & Fork Handler (fork_yourself), Set IS_PARENT, IS_CHILD in fork_yourself, and use its return value to determine error */ if (IS_FIRST && IS_ALONE) { // No piping // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // No pipe handling } else if (IS_FIRST && IS_NOT_ALONE) { // pipe to pipe_right, check for pipe errors & return to prompt // if errors found. if (!pipe_creation_handler(&pipe_left, &pipe_right, 1)) { fprintf(stderr, "%s: Right-pipe creation error for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closes pipe_right_write // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_right[1]); } // child closes pipe_right_read // child duplicates pipe_right_write to stdout, then closes it. // errors reported by close are inconsequential if (IS_CHILD) { close(pipe_right[0]); if (dup2(pipe_right[1], STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_right[1]); } } else if (IS_LAST && IS_NOT_ALONE) { // swap pipe_left/pipe_right // no piping pipe_creation_handler(&pipe_left, &pipe_right, 0); // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closees pipe_left_read // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_left[0]); } // child duplicates pipe_left_read to its stdin, then closes it // errors reported by close are inconsequential if (IS_CHILD) { if (dup2(pipe_left[0], STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_left[0]); } } else if (IS_MIDDLE && IS_NOT_ALONE) { // swap pipe_left/pipe_right pipe_creation_handler(&pipe_left, &pipe_right, 0); // pipe to pipe_right, check for pipe errors & return to prompt if // errors found. if (!pipe_creation_handler(&pipe_left, &pipe_right, 1)) { fprintf(stderr, "%s: Right-pipe creation error for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } // Fork and set IS_PARENT, IS_CHILD if (!fork_yourself(IS_INTERNAL, IS_ALONE, &IS_PARENT, &IS_CHILD, &child_pid)) { break; } // parent closes pipe_left_read and pipe_right_write // errors reported by close are inconsequential if (IS_PARENT) { close(pipe_left[0]); close(pipe_right[1]); } // child closes pipe_right_read, duplicates pipe_left_read to stdin, // pipe_right_write to stdout, then closes both. // errors reported by close are inconsequential if (IS_CHILD) { close(pipe_right[0]); if (dup2(pipe_left[0], STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } if (dup2(pipe_right[1], STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(pipe_left[0]); close(pipe_right[1]); } } else { // Unknown case. fprintf(stderr, "%s: Unexpected pipe handling case for command %s.\n", SHELL_ERROR_IDENTIFIER, command_name); break; } /* Redirection Handler Set IS_REDIRECTED flag Save STDIN/STDOUT/STDERR for later restoration This implementation possibly racks up "erroneous file handlers" unless dup() removes those on error. */ IS_REDIRECTED = false; if (IS_PARENT && IS_INTERNAL) { if (comms[i].ifile != NULL) { IS_REDIRECTED = true; ORIGINAL_STDIN = dup(STDIN_FILENO); if (ORIGINAL_STDIN == -1) { perror(SHELL_ERROR_IDENTIFIER); break; } } if (comms[i].ofile != NULL) { IS_REDIRECTED = true; ORIGINAL_STDOUT = dup(STDOUT_FILENO); if (ORIGINAL_STDOUT == -1) { perror(SHELL_ERROR_IDENTIFIER); break; } } // Not necessary as we do not handle STDERR redirection // ORIGINAL_STDERR = dup(STDERR_FILENO); // if (ORIGINAL_STDERR == -1) { // perror(SHELL_ERROR_IDENTIFIER); // break; // } if (!redirection(comms[i].ifile, comms[i].ofile, comms[i].append)) { break; } } else if (IS_CHILD) { IS_REDIRECTED = true; if (!redirection(comms[i].ifile, comms[i].ofile, comms[i].append)) { break; } } /* Run/Wait Handler */ if(IS_CHILD && IS_INTERNAL){ if(!run_internal(IS_CD, IS_EXIT, cwd, comms[i].argv, comms[i].argc)){ exit(EXIT_FAILURE); } else{ exit(EXIT_SUCCESS); } } if(IS_CHILD && IS_EXTERNAL){ execute(comms[i].argv); } if(IS_PARENT && IS_INTERNAL && IS_ALONE){ run_internal(IS_CD, IS_EXIT, cwd, comms[i].argv, comms[i].argc); } if(IS_PARENT && IS_INTERNAL && IS_NOT_ALONE){ if(!(waiting(child_pid))){ break; } } if(IS_PARENT && IS_EXTERNAL){ if(!(waiting(child_pid))){ break; } } /* Parent STDIO Reset In case of Single Internal Command with Redirection */ /* On failure, MUST EXIT as user can no longer target STDIN or see our STDOUT, possibly. */ if (IS_PARENT && IS_INTERNAL && IS_ALONE && IS_REDIRECTED) { if (comms[i].ifile != NULL) { if (dup2(ORIGINAL_STDIN, STDIN_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(ORIGINAL_STDIN); } if (comms[i].ofile != NULL) { if (dup2(ORIGINAL_STDOUT, STDOUT_FILENO) == -1) { perror(SHELL_ERROR_IDENTIFIER); exit(EXIT_FAILURE); } close(ORIGINAL_STDOUT); } // Do not need to handle STDERR, we do not support it's redirection } } } exit(EXIT_SUCCESS); }