void delete_player(dbref who) { int result; result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); /* Nuke the alias managed by this dbref. This will not remove any aliases * that were manually set on #0, but they should auto-clean as the lookups * are attempted. */ rotate_alias(who, 1); if (result) { int i; wall_wizards(MARK "WARNING: Playername hashtable is inconsistent. Rebuilding it."); clear_players(); for (i = db_top; i-- > 0;) { if (Typeof(i) == TYPE_PLAYER) { add_player(i); } } result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); if (result) { wall_wizards(MARK "WARNING: Playername hashtable still inconsistent after rebuild."); } } return; }
void delete_player(dbref who) { int result; result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); if (result) { int i; wall_wizards("## WARNING: Playername hashtable is inconsistent. Rebuilding it."); clear_players(); for (i = db_top; i-->0; ) { if (Typeof(i) == TYPE_PLAYER) { add_player(i); } } result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); if (result) { wall_wizards("## WARNING: Playername hashtable still inconsistent after rebuild."); } } return; }
/* * Named "fork_and_dump()" mostly for historical reasons... */ void fork_and_dump(void) { epoch++; #ifndef DISKBASE if (global_dumper_pid != 0) { wall_wizards("## Dump already in progress. Skipping redundant scheduled dump."); return; } #endif last_monolithic_time = time(NULL); log_status("CHECKPOINTING: %s.#%d#", dumpfile, epoch); if (tp_dbdump_warning) wall_and_flush(tp_dumping_mesg); #ifdef DISKBASE dump_database_internal(); #else # ifndef WIN32 if ((global_dumper_pid=fork())==0) { /* We are the child. */ forked_dump_process_flag = 1; # ifdef NICEVAL /* Requested by snout of SPR, reduce the priority of the * dumper child. */ nice(NICEVAL); # endif /* NICEVAL */ set_dumper_signals(); dump_database_internal(); _exit(0); } if (global_dumper_pid < 0) { global_dumper_pid = 0; wall_wizards("## Could not fork for database dumping. Possibly out of memory."); wall_wizards("## Please restart the server when next convenient."); } # else /* !WIN32 */ dump_database_internal(); /* TODO: This is not thread safe - disabled for now... */ /*global_dumper_pid = (long) _beginthread(fork_dump_thread, 0, 0); if (global_dumper_pid == -1L) { wall_wizards("## Could not create thread for database dumping"); }*/ # endif #endif }
void do_gripe(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN]; if (Guest(player)) { anotify_fmt(player, CFAIL "%s", tp_noguest_mesg); return; } if (!message || !*message) { if (Wiz(player)) { spit_file(player, LOG_GRIPE); } else { anotify_nolisten2(player, CINFO "What's wrong?"); } return; } loc = DBFETCH(player)->location; log_gripe("%s(%d) in %s(%d): %s\n", NAME(player), player, NAME(loc), loc, message); anotify_nolisten2(player, CINFO "Your complaint has been filed."); sprintf(buf, MARK "Gripe from %s: %s", NAME(player), message); wall_wizards(buf); }
/** * Send status to wizards and log file * * @private * @param s the message to send */ static void wall_status(char *s) { char buf[BUFFER_LEN]; log_status(s); snprintf(buf, sizeof(buf), "## %s", s); wall_wizards(buf); }
void delete_player(dbref who) { int result; result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); if (result) { log_status(HASH1_MSG); wall_wizards(MARK HASH1_MSG); refresh_players(); result = free_hash(NAME(who), player_list, PLAYER_HASH_SIZE); if (result) { log_status(HASH2_MSG); wall_wizards(MARK HASH2_MSG); } } return; }
void add_player(dbref who) { hash_data hd; hd.dbval = who; if (add_hash(NAME(who), hd, player_list, PLAYER_HASH_SIZE) == NULL) panic("Out of memory"); if(who != lookup_player(NAME(who))) { log_status(HASH1_MSG); wall_wizards(MARK HASH1_MSG); refresh_players(); if(who != lookup_player(NAME(who))) { log_status(HASH2_MSG); wall_wizards(MARK HASH2_MSG); } } return; }
dbref connect_player(const char *name, const char *password) { dbref player, i; if (*name == '#' && number(name+1) && atoi(name+1)) { player = (dbref) atoi(name + 1); if ((!OkObj(player)) || (Typeof(player) != TYPE_PLAYER)) player = NOTHING; } else { player = lookup_player(name); } if (player == NOTHING) { /* Check for a player not in the hashtable */ for(i = (db_top - 1); i > NOTHING; i--) { if(Typeof(i) == TYPE_PLAYER) { if(!string_compare(name, NAME(i))) { /* Oooga, found a player that lookup didn't! */ log_status(HASH1_MSG); wall_wizards(MARK HASH1_MSG); refresh_players(); player = lookup_player(name); if(player == NOTHING) { log_status(HASH2_MSG); wall_wizards(MARK HASH2_MSG); } break; } } } if(player == NOTHING) return NOTHING; } if (DBFETCH(player)->sp.player.password && *DBFETCH(player)->sp.player.password && strcmp(DBFETCH(player)->sp.player.password, password)) return NOTHING; return player; }
void do_gripe(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN]; if (!message || !*message) { if (Wizard(player)) { spit_file(player, LOG_GRIPE); } else { notify(player, "If you wish to gripe, use 'gripe <message>'."); } return; } loc = DBFETCH(player)->location; log_gripe("GRIPE from %s(%d) in %s(%d): %s", NAME(player), player, NAME(loc), loc, message); notify(player, "Your complaint has been duly noted."); snprintf(buf, sizeof(buf), "## GRIPE from %s: %s", NAME(player), message); wall_wizards(buf); }
RETSIGTYPE sig_reap(int i) { /* If DISKBASE is not defined, then there are two types of * children that can die. First is the nameservice resolver. * Second is the database dumper. If resolver exits, we should * note it in the log -- at least give the admin the option of * knowing about it, and dealing with it as necessary. */ /* The fix for SSL connections getting closed when databases were * saved with DISKBASE disabled required closing all sockets * when the server fork()ed. This made it impossible for that * process to spit out the "save done" message. However, because * that process dies as soon as it finishes dumping the database, * can detect that the child died, and broadcast the "save done" * message anyway. */ int status = 0; int reapedpid = 0; reapedpid = waitpid(-1, &status, WNOHANG); if(!reapedpid) { #ifdef DETACH log2file(LOG_ERR_FILE,"SIG_CHILD signal handler called with no pid!"); #else fprintf(stderr, "SIG_CHILD signal handler called with no pid!\n"); #endif } else { if (reapedpid == global_resolver_pid) { log_status("resolver exited with status %d", status); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { /* If the resolver exited with an error, respawn it. */ spawn_resolver(); } else if (WIFSIGNALED(status)) { /* If the resolver exited due to a signal, respawn it. */ spawn_resolver(); } #ifndef DISKBASE } else if(reapedpid == global_dumper_pid) { int warnflag = 0; log_status("forked DB dump task exited with status %d", status); if (WIFSIGNALED(status)) { warnflag = 1; } else if (WIFEXITED(status)) { /* In case NOCOREDUMP is defined, check for panic()s exit codes. */ int statres = WEXITSTATUS(status); if (statres == 135 || statres == 136) { warnflag = 1; } } if (warnflag) { wall_wizards("# WARNING: The forked DB save process crashed while saving the database."); wall_wizards("# This is probably due to memory corruption, which can crash this server."); wall_wizards("# Unless you have a REALLY good unix programmer around who can try to fix"); wall_wizards("# this process live with a debugger, you should try to restart this Muck"); wall_wizards("# as soon as possible, and accept the data lost since the previous DB save."); } global_dumpdone = 1; global_dumper_pid = 0; #endif } else { fprintf(stderr, "unknown child process (pid %d) exited with status %d\n", reapedpid, status); } } return RETSIGVAL; }