Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 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
}
Пример #4
0
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);
}
Пример #5
0
/**
 * 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);
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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);
}
Пример #10
0
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;
}