/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* configure all options BEFORE including system stuff. */ #include "config.h" #include "mud.h" #include "sym.h" #include "sbuf.h" #include "vars.h" #include "RWHO/rwho.h" /* GLOBAL !*/ int cron_quantum = 3600; /* one hour */ static int mud_running = 1; static char *mud_myname = (char *) 0; time_t cronlast; time_t currtime; static int usage (void) { fprintf (stderr, "usage: mud -c configfile -s startupfile\n"); return (1); } /* choke down a file full of commands */ static int boot_file (char *path) { FILE *bfp; char ibuf[BUFSIZ]; if ((bfp = fopen (path, "rb")) == (FILE *) 0) { log_printf ("can't open ", path, ": ", (char *) -1, "\n", (char *) 0); return (1); } while (fgets (ibuf, sizeof (ibuf), bfp) != (char *) 0) if (ibuf[0] != '#' && ibuf[0] != '\n') (void) run_boot (ibuf); fclose (bfp); return (0); } /* initiate shutdown (used in signal handlers) */ static void shutdown_mud (void) { log_printf ("mud is down.\n", (char *) 0); mud_running = 0; } /* as simple as possible */ int main (int ac, char **av) { int x; char *config = (char *) 0; char *startup = (char *) 0; for (x = 1; x < ac; x++) { if (av[x][0] == '-') { switch (av[x][1]) { case 'c': config = av[++x]; break; case 's': startup = av[++x]; break; default: return (usage ()); } } else { return (usage ()); } } /* if there is a configuration file, run it */ if (config != (char *) 0 && boot_file (config)) fatal ("configure failed.\n", (char *) 0); syminit (); WIN32STARTUP if (io_init ()) { fatal ("network init failed\n", (char *) 0); return (1); } if (cache_init ()) { fatal ("cache init failed\n", (char *) 0); return (1); } if (DB_INIT ()) { fatal ("database init failed\n", (char *) 0); return (1); } /* all I/O layers are initialized, now run startup file if one */ if (startup != (char *) 0 && boot_file (startup)) fatal ("startup failed.\n", (char *) 0); /* MUD name must be set */ if (mud_myname == (char *) 0) fatal ("mud server name is unset\n", (char *) 0); #ifdef DAEMON (void) signal (SIGINT, shutdown_mud); (void) signal (SIGTERM, shutdown_mud); (void) signal (SIGQUIT, shutdown_mud); #endif while (mud_running) { if (io_loop () != 0) break; /* flush I/O buffers */ io_sync (); /* reset cache pointers */ cache_reset (); /* maintenance/cron routines ? */ (void) time (&currtime); if (currtime - cronlast > cron_quantum) { cron_run (currtime); cronlast = currtime; } /* free any temporarily allocated memory */ tmp_sync (); } /* orderly shutdown */ (void) cache_sync (); DB_CLOSE (); #ifdef USE_RWHO rwhocli_shutdown (); #endif return (0); } /* return our protected name */ char *mud_getname (void) { return (mud_myname); } /* ARGSUSED */ int cmd__mudconfig (int ac, char *av[], char *who, char *aswho) { if (!strcmp (av[1], "shutdown")) { log_printf ("shutdown by ", who, "\n", (char *) 0); shutdown_mud (); return (UERR_NONE); } if (!strcmp (av[1], "log")) { if (ac != 3) return (UERR_ARGCNT); if (logf_open (av[2])) return (UERR_FATAL); log_printf ("log is now ", av[2], "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "chdir")) { if (ac != 3) { log_printf ("chdir: must provide directory.\n", (char *) 0); return (UERR_ARGCNT); } if (chdir (av[2])) { log_printf ("cannot cd to ", av[2], " ", (char *) -1, "\n", (char *) 0); return (UERR_FATAL); } log_printf ("working directory is now ", av[2], "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "name")) { if (ac != 3 || av[2][0] == '\0') { log_printf ("must provide mud name.\n", (char *) 0); return (UERR_ARGCNT); } if (mud_myname != (char *) 0) { log_printf ("mud name is already set!\n", (char *) 0); return (UERR_FATAL); } mud_myname = (char *) malloc ((unsigned) strlen (av[2]) + 1); if (mud_myname == (char *) 0) fatal ("cannot allocate mud name buffer!\n", (char *) 0); (void) strcpy (mud_myname, av[2]); log_printf ("mud name is ", mud_myname, "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "newusers")) { if (ac != 3 || av[2][0] == '\0') { log_printf ("can only turn on or off newusers!\n", (char *) 0); } else if (!strcmp (av[2], "on")) { log_printf ("new user logons enabled.\n", (char *) 0); newusers = 1; } else if (!strcmp (av[2], "off")) { log_printf ("new user logons disabled.\n", (char *) 0); newusers = 0; } else { log_printf ("can only turn on or off newusers!\n", (char *) 0); } return (UERR_NONE); } #ifdef DAEMON /* daemonize ourself */ if (!strcmp (av[1], "daemonize")) { (void) signal (SIGHUP, SIG_IGN); (void) signal (SIGCHLD, SIG_IGN); (void) signal (SIGALRM, SIG_IGN); if (fork ()) exit (0); #ifdef SETSID (void) setsid (); #endif log_printf ("daemonized.\n", (char *) 0); return (UERR_NONE); } #endif /* define a known remote MUD */ if (!strcmp (av[1], "defmud")) { char *timp = (char *) 0; if (ac < 9 || ac > 10) { log_printf ("usage: defmud name host symbolichost remotepassword localpassword port playerport [timeout]\n", (char *) 0); return (UERR_ARGCNT); } if (ac == 10) timp = av[9]; if (xmit_def_mudent (av[2], av[3], av[4], av[5], av[6], av[7], av[8], timp)) { log_printf ("mud entry ", av[2], " NOT defined\n", (char *) 0); return (UERR_FATAL); } log_printf ("added mud entry ", av[2], "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "defknownmud")) { if (ac != 3) { log_printf ("usage: defknownmud name\n", (char *) 0); return (UERR_ARGCNT); } if (xmit_def_knownmud (av[2])) { log_printf ("known-mud entry ", av[2], " NOT defined\n", (char *) 0); return (UERR_FATAL); } log_printf ("added known mud ", av[2], "\n", (char *) 0); return (UERR_NONE); } /* list all global macros */ if (!strcmp (av[1], "listmac")) { if (ac == 2) symlist (who, (char *) 0); else { int junk; for (junk = 2; junk < ac; junk++) symlist (who, av[junk]); } return (UERR_NONE); } /* define a global macro */ if (!strcmp (av[1], "defmac")) { if (ac != 4) { log_printf ("usage: defmac name macro\n", (char *) 0); return (UERR_ARGCNT); } if (symdef (av[2], av[3], SFLG_CMD)) { log_printf ("macro defn failed\n", (char *) 0); return (UERR_FATAL); } log_printf ("defn macro ", av[2], "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "defUmac")) { if (ac != 4) { log_printf ("usage: defmac name macro\n", (char *) 0); return (UERR_ARGCNT); } if (symdef (av[2], av[3], SFLG_UCMD)) { log_printf ("macro defn failed\n", (char *) 0); return (UERR_FATAL); } log_printf ("defn U-code ", av[2], "\n", (char *) 0); return (UERR_NONE); } /* mark a macro as priv'd */ if (!strcmp (av[1], "privmac")) { if (ac != 4) { log_printf ("usage: privmac macroname owner\n", (char *) 0); return (UERR_ARGCNT); } if (sympriv (av[2], av[3])) { log_printf ("macro setpriv failed\n", (char *) 0); return (UERR_FATAL); } log_printf ("setpriv macro ", av[2], " as ", av[3], "\n", (char *) 0); return (UERR_NONE); } /* UNdefine a global macro */ if (!strcmp (av[1], "undefmac")) { if (ac != 3) { log_printf ("usage: undefmac name\n", (char *) 0); return (UERR_ARGCNT); } if (symundef (av[2])) { log_printf ("macro undefined: ", av[2], "\n", (char *) 0); return (UERR_FATAL); } log_printf ("undefn macro ", av[2], "\n", (char *) 0); return (UERR_NONE); } #ifdef USE_RWHO if (!strcmp (av[1], "rwhoserver")) { char *info; if (ac < 4) { log_printf ("usage: rwhoserver hostname password\n", (char *) 0); return (UERR_ARGCNT); } info = ac > 4 ? av[4] : version; if (mud_myname == (char *) 0) { log_printf ("must set MUD name first\n", (char *) 0); return (UERR_FATAL); } if (rwhocli_setup (av[2], av[3], mud_myname, info)) { log_printf ("could not establish RWHO server\n", (char *) 0); return (UERR_FATAL); } return (UERR_NONE); } if (!strcmp (av[1], "rwhodown")) { rwhocli_shutdown (); log_printf ("rwho service shut down\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "rwhoupdate")) { update_rwho (); return (UERR_NONE); } #endif /* backup */ if (!strcmp (av[1], "backup")) { int sequence; int modulus = 0; char nxbuf[MAXOID]; char filename[MAXPATHLEN]; if (ac != 3 && ac != 4) { log_printf ("usage: backup <filename> [modulus]\n", (char *) 0); return (UERR_ARGCNT); } /* check for modulus */ if (ac == 4) modulus = atoi (av[3]); /* get the backup sequence number */ if (ut_getnum (system_object, var_bsequence, &sequence)) sequence = 0; sequence++; if (modulus > 0) sequence %= modulus; /* assume this works */ (void) ut_setnum (who, system_object, var_bsequence, sequence); (void) itoa (sequence, nxbuf, 10); if (cache_sync ()) { log_printf ("couldn't sync cache for backup #", nxbuf, "\n", (char *) 0); return (UERR_FATAL); } snprintf (filename, sizeof (filename), "%s.%s", av[2], nxbuf); if (DB_BACKUP (filename)) { log_printf ("couldn't write backup file ", filename, "\n", (char *) 0); return (UERR_FATAL); } log_printf ("wrote backup file ", filename, "\n", (char *) 0); return (UERR_NONE); } if (!strcmp (av[1], "help")) { say (who, av[0], " shutdown\n", (char *) 0); say (who, av[0], " log file-name\n", (char *) 0); say (who, av[0], " chdir directory-name\n", (char *) 0); say (who, av[0], " name mud-name\n", (char *) 0); #ifdef DAEMON say (who, av[0], " daemonize\n", (char *) 0); #endif say (who, av[0], " newusers [on|off]\n", (char *) 0); say (who, av[0], " defmud MUDname hostIP-addr hostname remotepassword localpassword serverport playerport [timeout]\n", (char *) 0); say (who, av[0], " defknownmud MUDname\n", (char *) 0); say (who, av[0], " defmac mac-name macro\n", (char *) 0); say (who, av[0], " defUmac mac-name U-code\n", (char *) 0); say (who, av[0], " undefmac mac-name\n", (char *) 0); say (who, av[0], " privmac mac-name object-id\n", (char *) 0); #ifdef USE_RWHO say (who, av[0], " rwhoserver hostname password [comment]\n", (char *) 0); say (who, av[0], " rwhodown\n", (char *) 0); #endif say (who, av[0], " backup file-name [modulus]\n", (char *) 0); return (UERR_NONE); } log_printf ("_mudconfig: I don't understand ", av[1], "\n", (char *) 0); return (UERR_NONE); }