/* conf.c: set up configuration information and static data */ #include <math.h> #include "autoconf.h" #include "copyright.h" #ifndef lint static char RCSid[] = "$Id: conf.c,v 1.10 1995/03/20 23:59:54 ambar Exp $"; USE(RCSid); #endif #include "externs.h" #include "interface.h" #include "command.h" #include "htab.h" #include "alloc.h" #include "attrs.h" #include "flags.h" #include "udb_defs.h" /* --------------------------------------------------------------------------- * CONFPARM: Data used to find fields in CONFDATA. */ typedef struct confparm CONF; struct confparm { char *pname; /* parm name */ int (*interpreter) (); /* routine to interp parameter */ int flags; /* control flags */ int *loc; /* where to store value */ void *extra; /* extra data for interpreter */ }; /* --------------------------------------------------------------------------- * External symbols. */ CONFDATA mudconf; STATEDATA mudstate; #ifndef STANDALONE extern NAMETAB logdata_nametab[]; extern NAMETAB logoptions_nametab[]; extern NAMETAB access_nametab[]; extern NAMETAB attraccess_nametab[]; extern NAMETAB list_names[]; extern NAMETAB sigactions_nametab[]; extern CONF conftable[]; #endif /* --------------------------------------------------------------------------- * cf_init: Initialize mudconf to default values. */ void NDECL(cf_init) { #ifndef STANDALONE int i; strcpy(mudconf.indb, "tinymush.db"); strcpy(mudconf.outdb, ""); strcpy(mudconf.crashdb, ""); strcpy(mudconf.gdbm, ""); strcpy(mudconf.status_file, "shutdown.status"); mudconf.port = 6250; mudconf.init_size = 1000; mudconf.use_global_aconn = 1; mudconf.num_guests = -1; for (i = 0; i < MAX_GUESTS; i++) mudconf.guest_chars[i] = -1; strcpy(mudconf.guest_file, "guest.txt"); strcpy(mudconf.conn_file, "connect.txt"); strcpy(mudconf.creg_file, "register.txt"); strcpy(mudconf.regf_file, "create_reg.txt"); strcpy(mudconf.motd_file, "motd.txt"); strcpy(mudconf.wizmotd_file, "wizmotd.txt"); strcpy(mudconf.quit_file, "quit.txt"); strcpy(mudconf.down_file, "down.txt"); strcpy(mudconf.full_file, "full.txt"); strcpy(mudconf.site_file, "badsite.txt"); strcpy(mudconf.crea_file, "newuser.txt"); #ifdef PUEBLO_SUPPORT strcpy(mudconf.htmlconn_file, "htmlconn.txt"); #endif /* PUEBLO_SUPPORT */ strcpy(mudconf.help_file, "help.txt"); strcpy(mudconf.help_indx, "help.indx"); strcpy(mudconf.news_file, "news.txt"); strcpy(mudconf.news_indx, "news.indx"); strcpy(mudconf.whelp_file, "wizhelp.txt"); strcpy(mudconf.whelp_indx, "wizhelp.indx"); strcpy(mudconf.motd_msg, ""); strcpy(mudconf.wizmotd_msg, ""); strcpy(mudconf.downmotd_msg, ""); strcpy(mudconf.fullmotd_msg, ""); strcpy(mudconf.dump_msg, ""); strcpy(mudconf.postdump_msg, ""); #ifdef PUEBLO_SUPPORT strcpy(mudconf.pueblo_msg, "</xch_mudtext><img xch_mode=html><tt>"); #endif /* PUEBLO_SUPPORT */ mudconf.name_spaces = 1; mudconf.fork_dump = 1; mudconf.fork_vfork = 0; mudconf.sig_action = SA_DFLT; mudconf.paranoid_alloc = 0; mudconf.max_players = -1; mudconf.garbage_chunk = 3; mudconf.dump_interval = 3600; mudconf.check_interval = 600; mudconf.dump_offset = 0; mudconf.check_offset = 300; mudconf.idle_timeout = 3600; mudconf.conn_timeout = 120; mudconf.idle_interval = 60; mudconf.retry_limit = 3; mudconf.output_limit = 16384; mudconf.paycheck = 0; mudconf.paystart = 0; mudconf.paylimit = 10000; mudconf.start_quota = mudconf.start_room_quota = mudconf.start_exit_quota = mudconf.start_thing_quota = mudconf.start_player_quota = 20; mudconf.payfind = 0; mudconf.digcost = 10; mudconf.linkcost = 1; mudconf.opencost = 1; mudconf.createmin = 10; mudconf.createmax = 505; mudconf.killmin = 10; mudconf.killmax = 100; mudconf.killguarantee = 100; mudconf.robotcost = 1000; mudconf.pagecost = 10; mudconf.searchcost = 100; mudconf.waitcost = 10; mudconf.machinecost = 64; mudconf.building_limit = 50000; mudconf.exit_quota = 1; mudconf.player_quota = 1; mudconf.room_quota = 1; mudconf.thing_quota = 1; mudconf.queuemax = 100; mudconf.queue_chunk = 10; mudconf.active_q_chunk = 10; mudconf.sacfactor = 5; mudconf.sacadjust = -1; mudconf.use_hostname = 1; mudconf.recycle = 1; mudconf.quotas = 0; mudconf.typed_quotas = 0; mudconf.ex_flags = 1; mudconf.robot_speak = 1; mudconf.clone_copy_cost = 0; mudconf.pub_flags = 1; mudconf.quiet_look = 1; mudconf.exam_public = 1; mudconf.read_rem_desc = 0; mudconf.read_rem_name = 0; mudconf.sweep_dark = 0; mudconf.player_listen = 0; mudconf.quiet_whisper = 1; mudconf.dark_sleepers = 1; mudconf.see_own_dark = 1; mudconf.idle_wiz_dark = 0; mudconf.pemit_players = 0; mudconf.pemit_any = 0; mudconf.match_mine = 0; mudconf.match_mine_pl = 0; mudconf.switch_df_all = 1; mudconf.fascist_tport = 0; mudconf.terse_look = 1; mudconf.terse_contents = 1; mudconf.terse_exits = 1; mudconf.terse_movemsg = 1; mudconf.trace_topdown = 1; mudconf.trace_limit = 200; mudconf.safe_unowned = 0; mudconf.parent_control = 0; mudconf.wiz_obey_linklock = 0; mudconf.local_masters = 1; mudconf.req_cmds_flag = 1; mudconf.parent_zones = 1; mudconf.fmt_contents = 1; mudconf.fmt_exits = 1; mudconf.ansi_colors = 0; mudconf.safer_passwords = 0; /* -- ??? Running SC on a non-SC DB may cause problems */ mudconf.space_compress = 1; mudconf.start_room = 0; mudconf.start_home = NOTHING; mudconf.default_home = NOTHING; mudconf.master_room = NOTHING; mudconf.player_parent = NOTHING; mudconf.room_parent = NOTHING; mudconf.exit_parent = NOTHING; mudconf.thing_parent = NOTHING; mudconf.player_flags.word1 = 0; mudconf.player_flags.word2 = 0; mudconf.room_flags.word1 = 0; mudconf.room_flags.word2 = 0; mudconf.exit_flags.word1 = 0; mudconf.exit_flags.word2 = 0; mudconf.thing_flags.word1 = 0; mudconf.thing_flags.word2 = 0; mudconf.robot_flags.word1 = ROBOT; mudconf.robot_flags.word2 = 0; mudconf.vattr_flags = AF_ODARK; mudconf.abort_on_bug = 0; mudconf.rwho_transmit = 0; strcpy(mudconf.mud_name, "TinyMUSH"); strcpy(mudconf.rwho_host, "139.78.1.15"); /* riemann.math.okstate.edu */ strcpy(mudconf.rwho_pass, "get_your_own"); mudconf.rwho_info_port = 6888; mudconf.rwho_data_port = 6889; mudconf.rwho_interval = 241; strcpy(mudconf.one_coin, "penny"); strcpy(mudconf.many_coins, "pennies"); mudconf.timeslice = 1000; mudconf.cmd_quota_max = 100; mudconf.cmd_quota_incr = 1; mudconf.max_cmdsecs = 120; mudconf.control_flags = 0xffffffff; /* Everything for now... */ mudconf.control_flags &= ~CF_GODMONITOR; /* Except for monitoring... */ mudconf.log_options = LOG_ALWAYS | LOG_BUGS | LOG_SECURITY | LOG_NET | LOG_LOGIN | LOG_DBSAVES | LOG_CONFIGMODS | LOG_SHOUTS | LOG_STARTUP | LOG_WIZARD | LOG_PROBLEMS | LOG_PCREATES; mudconf.log_info = LOGOPT_TIMESTAMP | LOGOPT_LOC; mudconf.markdata[0] = 0x01; mudconf.markdata[1] = 0x02; mudconf.markdata[2] = 0x04; mudconf.markdata[3] = 0x08; mudconf.markdata[4] = 0x10; mudconf.markdata[5] = 0x20; mudconf.markdata[6] = 0x40; mudconf.markdata[7] = 0x80; mudconf.func_nest_lim = 50; mudconf.func_invk_lim = 2500; mudconf.ntfy_nest_lim = 20; mudconf.lock_nest_lim = 20; mudconf.parent_nest_lim = 10; mudconf.cache_depth = CACHE_DEPTH; mudconf.cache_width = CACHE_WIDTH; mudconf.cache_names = 1; mudconf.cache_steal_dirty = 0; mudstate.initializing = 0; mudstate.panicking = 0; mudstate.dumping = 0; mudstate.logging = 0; mudstate.epoch = 0; mudstate.generation = 0; mudstate.reboot_nums = 0; mudstate.curr_player = NOTHING; mudstate.curr_enactor = NOTHING; mudstate.curr_cmd = (char *) "< none >"; mudstate.shutdown_flag = 0; mudstate.rwho_on = 0; mudstate.attr_next = A_USER_START; mudstate.debug_cmd = (char *) "< init >"; strcpy(mudstate.doing_hdr, "Doing"); mudstate.access_list = NULL; mudstate.suspect_list = NULL; mudstate.qfirst = NULL; mudstate.qlast = NULL; mudstate.qlfirst = NULL; mudstate.qllast = NULL; mudstate.qwait = NULL; mudstate.qsemfirst = NULL; mudstate.qsemlast = NULL; mudstate.badname_head = NULL; mudstate.iter_alist.data = NULL; mudstate.iter_alist.len = 0; mudstate.iter_alist.next = NULL; mudstate.mod_alist = NULL; mudstate.mod_size = 0; mudstate.mod_al_id = NOTHING; mudstate.olist_head = NULL; mudstate.olist_tail = NULL; mudstate.olist_cblock = NULL; mudstate.olist_count = 0; mudstate.olist_citm = 0; mudstate.min_size = 0; mudstate.db_top = 0; mudstate.db_size = 0; mudstate.freelist = NOTHING; mudstate.markbits = NULL; mudstate.func_nest_lev = 0; mudstate.func_invk_ctr = 0; mudstate.ntfy_nest_lev = 0; mudstate.lock_nest_lev = 0; mudstate.inpipe = 0; mudstate.pout = NULL; mudstate.poutnew = NULL; mudstate.poutbufc = NULL; mudstate.poutobj = NOTHING; for (i = 0; i < MAX_GLOBAL_REGS; i++) mudstate.global_regs[i] = NULL; #else /* match for #ifndef STANDALONE */ mudconf.paylimit = 10000; mudconf.digcost = 10; mudconf.opencost = 1; mudconf.robotcost = 1000; mudconf.createmin = 5; mudconf.createmax = 505; mudconf.sacfactor = 5; mudconf.sacadjust = -1; mudconf.room_quota = 1; mudconf.exit_quota = 1; mudconf.thing_quota = 1; mudconf.player_quota = 1; mudconf.start_room = 0; mudconf.start_home = NOTHING; mudconf.default_home = NOTHING; mudconf.vattr_flags = AF_ODARK; mudconf.log_options = 0xffffffff; mudconf.log_info = 0; mudconf.markdata[0] = 0x01; mudconf.markdata[1] = 0x02; mudconf.markdata[2] = 0x04; mudconf.markdata[3] = 0x08; mudconf.markdata[4] = 0x10; mudconf.markdata[5] = 0x20; mudconf.markdata[6] = 0x40; mudconf.markdata[7] = 0x80; mudconf.ntfy_nest_lim = 20; mudconf.cache_steal_dirty = 1; mudstate.logging = 0; mudstate.attr_next = A_USER_START; mudstate.iter_alist.data = NULL; mudstate.iter_alist.len = 0; mudstate.iter_alist.next = NULL; mudstate.mod_alist = NULL; mudstate.mod_size = 0; mudstate.mod_al_id = NOTHING; mudstate.min_size = 0; mudstate.db_top = 0; mudstate.db_size = 0; mudstate.freelist = NOTHING; mudstate.markbits = NULL; #endif /* STANDALONE */ } #ifndef STANDALONE /* --------------------------------------------------------------------------- * cf_log_notfound: Log a 'parameter not found' error. */ void cf_log_notfound(player, cmd, thingname, thing) dbref player; char *cmd, *thing; const char *thingname; { char *buff; if (mudstate.initializing) { STARTLOG(LOG_STARTUP, "CNF", "NFND") buff = alloc_lbuf("cf_log_notfound.LOG"); sprintf(buff, "%s: %s %s not found", cmd, thingname, thing); log_text(buff); free_lbuf(buff); ENDLOG } else { buff = alloc_lbuf("cf_log_notfound"); sprintf(buff, "%s %s not found", thingname, thing); notify(player, buff); free_lbuf(buff); } } /* --------------------------------------------------------------------------- * cf_log_syntax: Log a syntax error. */ void cf_log_syntax(player, cmd, template, arg) dbref player; char *cmd, *arg; const char *template; { char *buff; if (mudstate.initializing) { STARTLOG(LOG_STARTUP, "CNF", "SYNTX") buff = alloc_lbuf("cf_log_syntax.LOG"); sprintf(buff, template, arg); log_text(cmd); log_text((char *) ": "); log_text(buff); free_lbuf(buff); ENDLOG } else { buff = alloc_lbuf("cf_log_syntax"); sprintf(buff, template, arg); notify(player, buff); free_lbuf(buff); } } /* --------------------------------------------------------------------------- * cf_status_from_succfail: Return command status from succ and fail info */ int cf_status_from_succfail(player, cmd, success, failure) dbref player; char *cmd; int success, failure; { char *buff; /* If any successes, return SUCCESS(0) if no failures or PARTIAL_SUCCESS(1) if any failures. */ if (success > 0) return ((failure == 0) ? 0 : 1); /* No successes. If no failures indicate nothing done. Always return FAILURE(-1) */ if (failure == 0) { if (mudstate.initializing) { STARTLOG(LOG_STARTUP, "CNF", "NDATA") buff = alloc_lbuf("cf_status_from_succfail.LOG"); sprintf(buff, "%s: Nothing to set", cmd); log_text(buff); free_lbuf(buff); ENDLOG } else { notify(player, "Nothing to set"); } } return -1; } /* --------------------------------------------------------------------------- * cf_int: Set integer parameter. */ CF_HAND(cf_int) { /* Copy the numeric value to the parameter */ sscanf(str, "%d", vp); return 0; } /* --------------------------------------------------------------------------- * cf_bool: Set boolean parameter. */ NAMETAB bool_names[] = { {(char *) "true", 1, 0, 1}, {(char *) "false", 1, 0, 0}, {(char *) "yes", 1, 0, 1}, {(char *) "no", 1, 0, 0}, {(char *) "1", 1, 0, 1}, {(char *) "0", 1, 0, 0}, {NULL, 0, 0, 0}}; CF_HAND(cf_bool) { *vp = search_nametab(GOD, bool_names, str); if (*vp == -1) *vp = 0; return 0; } /* --------------------------------------------------------------------------- * cf_option: Select one option from many choices. */ CF_HAND(cf_option) { int i; i = search_nametab(GOD, (NAMETAB *) extra, str); if (i == -1) { cf_log_notfound(player, cmd, "Value", str); return -1; } *vp = i; return 0; } /* --------------------------------------------------------------------------- * cf_string: Set string parameter. */ CF_HAND(cf_string) { int retval; char *buff; /* Copy the string to the buffer if it is not too big */ retval = 0; if (strlen(str) >= (long) extra) { str[(long) extra - 1] = '\0'; if (mudstate.initializing) { STARTLOG(LOG_STARTUP, "CNF", "NFND") buff = alloc_lbuf("cf_string.LOG"); sprintf(buff, "%s: String truncated", cmd); log_text(buff); free_lbuf(buff); ENDLOG } else { notify(player, "String truncated"); } retval = 1; } strcpy((char *) vp, str); return retval; } /* --------------------------------------------------------------------------- * cf_alias: define a generic hash table alias. */ CF_HAND(cf_alias) { char *alias, *orig; int *cp; alias = strtok(str, " \t=,"); orig = strtok(NULL, " \t=,"); cp = hashfind(orig, (HASHTAB *) vp); if (cp == NULL) { cf_log_notfound(player, cmd, "Entry", orig); return -1; } hashadd(alias, cp, (HASHTAB *) vp); return 0; } /* --------------------------------------------------------------------------- * cf_flagalias: define a flag alias. */ CF_HAND(cf_flagalias) { char *alias, *orig; int *cp, success; success = 0; alias = strtok(str, " \t=,"); orig = strtok(NULL, " \t=,"); cp = hashfind(orig, &mudstate.flags_htab); if (cp != NULL) { hashadd(alias, cp, &mudstate.flags_htab); success++; } if (!success) cf_log_notfound(player, cmd, "Flag", orig); return ((success > 0) ? 0 : -1); } /* --------------------------------------------------------------------------- * cf_or_in_bits: OR in bits from namelist to a word. */ CF_HAND(cf_or_in_bits) { char *sp; int f, success, failure; /* Walk through the tokens */ success = failure = 0; sp = strtok(str, " \t"); while (sp != NULL) { /* Set the appropriate bit */ f = search_nametab(GOD, (NAMETAB *) extra, sp); if (f != -1) { *vp |= f; success++; } else { cf_log_notfound(player, cmd, "Entry", sp); failure++; } /* Get the next token */ sp = strtok(NULL, " \t"); } return cf_status_from_succfail(player, cmd, success, failure); } /* --------------------------------------------------------------------------- * cf_modify_bits: set or clear bits in a flag word from a namelist. */ CF_HAND(cf_modify_bits) { char *sp; int f, negate, success, failure; /* Walk through the tokens */ success = failure = 0; sp = strtok(str, " \t"); while (sp != NULL) { /* Check for negation */ negate = 0; if (*sp == '!') { negate = 1; sp++; } /* Set or clear the appropriate bit */ f = search_nametab(GOD, (NAMETAB *) extra, sp); if (f != -1) { if (negate) *vp &= ~f; else *vp |= f; success++; } else { cf_log_notfound(player, cmd, "Entry", sp); failure++; } /* Get the next token */ sp = strtok(NULL, " \t"); } return cf_status_from_succfail(player, cmd, success, failure); } /* --------------------------------------------------------------------------- * cf_set_bits: Clear flag word and then set specified bits from namelist. */ CF_HAND(cf_set_bits) { char *sp; int f, success, failure; /* Walk through the tokens */ success = failure = 0; *vp = 0; sp = strtok(str, " \t"); while (sp != NULL) { /* Set the appropriate bit */ f = search_nametab(GOD, (NAMETAB *) extra, sp); if (f != -1) { *vp |= f; success++; } else { cf_log_notfound(player, cmd, "Entry", sp); failure++; } /* Get the next token */ sp = strtok(NULL, " \t"); } return cf_status_from_succfail(player, cmd, success, failure); } /* --------------------------------------------------------------------------- * cf_set_flags: Clear flag word and then set from a flags htab. */ CF_HAND(cf_set_flags) { char *sp; FLAGENT *fp; FLAGSET *fset; int success, failure; /* Walk through the tokens */ success = failure = 0; sp = strtok(str, " \t"); fset = (FLAGSET *) vp; while (sp != NULL) { /* Set the appropriate bit */ fp = (FLAGENT *) hashfind(sp, &mudstate.flags_htab); if (fp != NULL) { if (success == 0) { (*fset).word1 = 0; (*fset).word2 = 0; } if (fp->flagflag & FLAG_EXT) (*fset).word2 |= fp->flagvalue; else (*fset).word1 |= fp->flagvalue; success++; } else { cf_log_notfound(player, cmd, "Entry", sp); failure++; } /* Get the next token */ sp = strtok(NULL, " \t"); } if ((success == 0) && (failure == 0)) { (*fset).word1 = 0; (*fset).word2 = 0; return 0; } if (success > 0) return ((failure == 0) ? 0 : 1); return -1; } /* --------------------------------------------------------------------------- * cf_badname: Disallow use of player name/alias. */ CF_HAND(cf_badname) { if ((long) extra) badname_remove(str); else badname_add(str); return 0; } /* --------------------------------------------------------------------------- * sane_inet_addr: inet_addr() does not necessarily do reasonable checking * for sane syntax. On certain operating systems, if passed less than four * octets, it will cause a segmentation violation. This is unfriendly. * We take steps here to deal with it. */ static unsigned long sane_inet_addr(str) char *str; { int i; char *p; p = str; for (i = 1; (p = (char *) index(p, '.')) != NULL; i++, p++) ; if (i < 4) return -1; else return inet_addr(str); } /* --------------------------------------------------------------------------- * cf_site: Update site information */ CF_HANDP(cf_site) { SITE *site, *last, *head; char *addr_txt, *mask_txt, *p; struct in_addr addr_num, mask_num; int i, mask_bits; if ((mask_txt = (char *) index(str, '/')) == NULL) { /* Standard IP range and netmask notation. */ addr_txt = strtok(str, " \t=,"); if (addr_txt) mask_txt = strtok(NULL, " \t=,"); if (!addr_txt || !*addr_txt || !mask_txt || !*mask_txt) { cf_log_syntax(player, cmd, "Missing host address or mask.", (char *) ""); return -1; } if ((addr_num.s_addr = sane_inet_addr(addr_txt)) == -1) { cf_log_syntax(player, cmd, "Malformed host address: %s", addr_txt); return -1; } if ((mask_num.s_addr = sane_inet_addr(mask_txt)) == -1) { cf_log_syntax(player, cmd, "Malformed mask address: %s", mask_txt); return -1; } } else { /* RFC 1517, 1518, 1519, 1520: CIDR IP prefix notation */ addr_txt = str; *mask_txt++ = '\0'; mask_bits = atoi(mask_txt); if ((mask_bits > 32) || (mask_bits < 0)) { cf_log_syntax(player, cmd, "Mask bits (%d) in CIDR IP prefix out of range.", mask_bits); return -1; } else { mask_num.s_addr = pow(2, 32) - pow(2, 32 - mask_bits); } if ((addr_num.s_addr = sane_inet_addr(addr_txt)) == -1) { cf_log_syntax(player, cmd, "Malformed host address: %s", addr_txt); return -1; } } head = (SITE *) * vp; /* Parse the access entry and allocate space for it */ if (!(site = (SITE *) XMALLOC(sizeof(SITE), "cf_site"))) return -1; /* Initialize the site entry */ site->address.s_addr = addr_num.s_addr; site->mask.s_addr = mask_num.s_addr; site->flag = (long) extra; site->next = NULL; /* Link in the entry. Link it at the start if not initializing, at * the end if initializing. This is so that entries in the config * file are processed as you would think they would be, while entries * made while running are processed first. */ if (mudstate.initializing) { if (head == NULL) { *vp = (int *) site; } else { for (last = head; last->next; last = last->next); last->next = site; } } else { site->next = head; *vp = (int *) site; } return 0; } /* --------------------------------------------------------------------------- * cf_cf_access: Set access on config directives */ CF_HAND(cf_cf_access) { CONF *tp; char *ap; for (ap = str; *ap && !isspace(*ap); ap++); if (*ap) *ap++ = '\0'; for (tp = conftable; tp->pname; tp++) { if (!strcmp(tp->pname, str)) { return (cf_modify_bits(&tp->flags, ap, extra, player, cmd)); } } cf_log_notfound(player, cmd, "Config directive", str); return -1; } /* --------------------------------------------------------------------------- * cf_include: Read another config file. Only valid during startup. */ CF_HAND(cf_include) { FILE *fp; char *cp, *ap, *zp, *buf; extern int FDECL(cf_set, (char *, char *, dbref)); if (!mudstate.initializing) return -1; fp = fopen(str, "r"); if (fp == NULL) { cf_log_notfound(player, cmd, "Config file", str); return -1; } buf = alloc_lbuf("cf_include"); fgets(buf, LBUF_SIZE, fp); while (!feof(fp)) { cp = buf; if (*cp == '#') { fgets(buf, LBUF_SIZE, fp); continue; } /* Not a comment line. Strip off the NL and any characters * following it. Then, split the line into the command and * argument portions (separated by a space). Also, trim off * the trailing comment, if any (delimited by #) */ for (cp = buf; *cp && *cp != '\n'; cp++); *cp = '\0'; /* strip \n */ for (cp = buf; *cp && isspace(*cp); cp++); /* strip spaces */ for (ap = cp; *ap && !isspace(*ap); ap++); /* skip over command */ if (*ap) *ap++ = '\0'; /* trim command */ for (; *ap && isspace(*ap); ap++); /* skip spaces */ for (zp = ap; *zp && (*zp != '#'); zp++); /* find comment */ if (*zp) *zp = '\0'; /* zap comment */ for (zp = zp - 1; zp >= ap && isspace(*zp); zp--) *zp = '\0'; /* zap trailing spcs */ cf_set(cp, ap, player); fgets(buf, LBUF_SIZE, fp); } free_lbuf(buf); fclose(fp); return 0; } /* --------------------------------------------------------------------------- * cf_dbref_list: Set a list of dbref values. extra is a pointer * to an "int" which will contain the number of dbrefs found. */ CF_HAND(cf_dbref_list) { char *tmp = strtok(str, " \t"); int *num = (int *) extra; *num = 0; while (tmp) { vp[*num] = atoi(tmp); (*num)++; tmp = strtok(NULL, " \t"); } return 0; } extern CF_HDCL(cf_access); extern CF_HDCL(cf_cmd_alias); extern CF_HDCL(cf_acmd_access); extern CF_HDCL(cf_attr_access); extern CF_HDCL(cf_ntab_access); extern CF_HDCL(cf_func_access); /* --------------------------------------------------------------------------- * conftable: Table for parsing the configuration file. */ CONF conftable[] = { {"abort_on_bug", cf_bool, CA_DISABLED, &mudconf.abort_on_bug, 0}, {"access", cf_access, CA_GOD, NULL, access_nametab}, {"alias", cf_cmd_alias, CA_GOD, (int *) &mudstate.command_htab, 0}, {"ansi_colors", cf_bool, CA_GOD, &mudconf.ansi_colors, 0}, {"attr_access", cf_attr_access, CA_GOD, NULL, attraccess_nametab}, {"attr_alias", cf_alias, CA_GOD, (int *) &mudstate.attr_name_htab, 0}, {"attr_cmd_access", cf_acmd_access, CA_GOD, NULL, access_nametab}, {"bad_name", cf_badname, CA_GOD, NULL, 0}, {"badsite_file", cf_string, CA_DISABLED, (int *) mudconf.site_file, (void *) SBUF_SIZE}, {"building_limit", cf_int, CA_GOD, &mudconf.building_limit, 0}, {"cache_depth", cf_int, CA_DISABLED, &mudconf.cache_depth, 0}, {"cache_names", cf_bool, CA_DISABLED, &mudconf.cache_names, 0}, {"cache_steal_dirty", cf_bool, CA_GOD, &mudconf.cache_steal_dirty, 0}, {"cache_width", cf_int, CA_DISABLED, &mudconf.cache_width, 0}, {"check_interval", cf_int, CA_GOD, &mudconf.check_interval, 0}, {"check_offset", cf_int, CA_GOD, &mudconf.check_offset, 0}, {"clone_copies_cost", cf_bool, CA_GOD, &mudconf.clone_copy_cost, 0}, {"command_quota_increment", cf_int, CA_GOD, &mudconf.cmd_quota_incr, 0}, {"command_quota_max", cf_int, CA_GOD, &mudconf.cmd_quota_max, 0}, {"config_access", cf_cf_access, CA_GOD, NULL, access_nametab}, {"conn_timeout", cf_int, CA_GOD, &mudconf.conn_timeout, 0}, {"connect_file", cf_string, CA_DISABLED, (int *) mudconf.conn_file, (void *) SBUF_SIZE}, {"connect_reg_file", cf_string, CA_DISABLED, (int *) mudconf.creg_file, (void *) SBUF_SIZE}, {"crash_database", cf_string, CA_DISABLED, (int *) mudconf.crashdb, (void *) PBUF_SIZE}, {"create_max_cost", cf_int, CA_GOD, &mudconf.createmax, 0}, {"create_min_cost", cf_int, CA_GOD, &mudconf.createmin, 0}, {"dark_sleepers", cf_bool, CA_GOD, &mudconf.dark_sleepers, 0}, {"default_home", cf_int, CA_GOD, &mudconf.default_home, 0}, {"dig_cost", cf_int, CA_GOD, &mudconf.digcost, 0}, {"down_file", cf_string, CA_DISABLED, (int *) mudconf.down_file, (void *) SBUF_SIZE}, {"down_motd_message", cf_string, CA_GOD, (int *) mudconf.downmotd_msg, (void *) GBUF_SIZE}, {"dump_interval", cf_int, CA_GOD, &mudconf.dump_interval, 0}, {"dump_message", cf_string, CA_GOD, (int *) mudconf.dump_msg, (void *) PBUF_SIZE}, {"postdump_message", cf_string, CA_GOD, (int *) mudconf.postdump_msg, (void *) PBUF_SIZE}, #ifdef PUEBLO_SUPPORT {"html_connect_file", cf_string, CA_DISABLED, (int *) mudconf.htmlconn_file, (void *) SBUF_SIZE}, {"pueblo_message", cf_string, CA_GOD, (int *) mudconf.pueblo_msg, (void *) GBUF_SIZE}, #endif /* PUEBLO_SUPPORT */ {"dump_offset", cf_int, CA_GOD, &mudconf.dump_offset, 0}, {"earn_limit", cf_int, CA_GOD, &mudconf.paylimit, 0}, {"examine_flags", cf_bool, CA_GOD, &mudconf.ex_flags, 0}, {"examine_public_attrs", cf_bool, CA_GOD, &mudconf.exam_public, 0}, {"exit_flags", cf_set_flags, CA_GOD, (int *) &mudconf.exit_flags, 0}, {"exit_parent", cf_int, CA_GOD, &mudconf.exit_parent, 0}, {"exit_quota", cf_int, CA_GOD, &mudconf.exit_quota, 0}, {"fascist_teleport", cf_bool, CA_GOD, &mudconf.fascist_tport, 0}, {"find_money_chance", cf_int, CA_GOD, &mudconf.payfind, 0}, {"flag_alias", cf_flagalias, CA_GOD, NULL, 0}, {"forbid_site", cf_site, CA_GOD, (int *) &mudstate.access_list, (void *) H_FORBIDDEN}, {"fork_dump", cf_bool, CA_GOD, &mudconf.fork_dump, 0}, {"fork_vfork", cf_bool, CA_GOD, &mudconf.fork_vfork, 0}, {"format_contents", cf_bool, CA_GOD, &mudconf.fmt_contents, 0}, {"format_exits", cf_bool, CA_GOD, &mudconf.fmt_exits, 0}, {"full_file", cf_string, CA_DISABLED, (int *) mudconf.full_file, (void *) SBUF_SIZE}, {"full_motd_message", cf_string, CA_GOD, (int *) mudconf.fullmotd_msg, (void *) GBUF_SIZE}, {"function_access", cf_func_access, CA_GOD, NULL, access_nametab}, {"function_alias", cf_alias, CA_GOD, (int *) &mudstate.func_htab, 0}, {"function_invocation_limit", cf_int, CA_GOD, &mudconf.func_invk_lim, 0}, {"function_recursion_limit", cf_int, CA_GOD, &mudconf.func_nest_lim, 0}, {"garbage_chunk", cf_int, CA_GOD, &mudconf.garbage_chunk, 0}, {"gdbm_database", cf_string, CA_DISABLED, (int *) mudconf.gdbm, (void *) PBUF_SIZE}, {"good_name", cf_badname, CA_GOD, NULL, (void *) 1}, {"guests", cf_dbref_list, CA_GOD, mudconf.guest_chars, &mudconf.num_guests}, {"guest_file", cf_string, CA_DISABLED, (int *) mudconf.guest_file, (void *) SBUF_SIZE}, {"guest_site", cf_site, CA_GOD, (int *) &mudstate.access_list, (void *) H_GUEST}, {"help_file", cf_string, CA_DISABLED, (int *) mudconf.help_file, (void *) SBUF_SIZE}, {"help_index", cf_string, CA_DISABLED, (int *) mudconf.help_indx, (void *) SBUF_SIZE}, {"hostnames", cf_bool, CA_GOD, &mudconf.use_hostname, 0}, {"idle_wiz_dark", cf_bool, CA_GOD, &mudconf.idle_wiz_dark, 0}, {"idle_interval", cf_int, CA_GOD, &mudconf.idle_interval, 0}, {"idle_timeout", cf_int, CA_GOD, &mudconf.idle_timeout, 0}, {"include", cf_include, CA_DISABLED, NULL, 0}, {"initial_size", cf_int, CA_DISABLED, &mudconf.init_size, 0}, {"input_database", cf_string, CA_DISABLED, (int *) mudconf.indb, (void *) PBUF_SIZE}, {"kill_guarantee_cost", cf_int, CA_GOD, &mudconf.killguarantee, 0}, {"kill_max_cost", cf_int, CA_GOD, &mudconf.killmax, 0}, {"kill_min_cost", cf_int, CA_GOD, &mudconf.killmin, 0}, {"lag_maximum", cf_int, CA_GOD, &mudconf.max_cmdsecs, 0}, {"link_cost", cf_int, CA_GOD, &mudconf.linkcost, 0}, {"list_access", cf_ntab_access, CA_GOD, (int *) list_names, access_nametab}, {"local_master_rooms", cf_bool, CA_GOD, &mudconf.local_masters, 0}, {"lock_recursion_limit", cf_int, CA_GOD, &mudconf.lock_nest_lim, 0}, {"log", cf_modify_bits, CA_GOD, &mudconf.log_options, logoptions_nametab}, {"log_options", cf_modify_bits, CA_GOD, &mudconf.log_info, logdata_nametab}, {"logout_cmd_access", cf_ntab_access, CA_GOD, (int *) logout_cmdtable, access_nametab}, {"logout_cmd_alias", cf_alias, CA_GOD, (int *) &mudstate.logout_cmd_htab, 0}, {"look_obey_terse", cf_bool, CA_GOD, &mudconf.terse_look, 0}, {"machine_command_cost", cf_int, CA_GOD, &mudconf.machinecost, 0}, {"master_room", cf_int, CA_GOD, &mudconf.master_room, 0}, {"match_own_commands", cf_bool, CA_GOD, &mudconf.match_mine, 0}, {"max_players", cf_int, CA_GOD, &mudconf.max_players, 0}, {"money_name_plural", cf_string, CA_GOD, (int *) mudconf.many_coins, (void *) SBUF_SIZE}, {"money_name_singular", cf_string, CA_GOD, (int *) mudconf.one_coin, (void *) SBUF_SIZE}, {"motd_file", cf_string, CA_DISABLED, (int *) mudconf.motd_file, (void *) SBUF_SIZE}, {"motd_message", cf_string, CA_GOD, (int *) mudconf.motd_msg, (void *) GBUF_SIZE}, {"mud_name", cf_string, CA_GOD, (int *) mudconf.mud_name, (void *) SBUF_SIZE}, {"news_file", cf_string, CA_DISABLED, (int *) mudconf.news_file, (void *) SBUF_SIZE}, {"news_index", cf_string, CA_DISABLED, (int *) mudconf.news_indx, (void *) SBUF_SIZE}, {"newuser_file", cf_string, CA_DISABLED, (int *) mudconf.crea_file, (void *) SBUF_SIZE}, {"notify_recursion_limit", cf_int, CA_GOD, &mudconf.ntfy_nest_lim, 0}, {"open_cost", cf_int, CA_GOD, &mudconf.opencost, 0}, {"output_database", cf_string, CA_DISABLED, (int *) mudconf.outdb, (void *) PBUF_SIZE}, {"output_limit", cf_int, CA_GOD, &mudconf.output_limit, 0}, {"page_cost", cf_int, CA_GOD, &mudconf.pagecost, 0}, {"paranoid_allocate", cf_bool, CA_GOD, &mudconf.paranoid_alloc, 0}, {"parentable_control_lock", cf_bool, CA_DISABLED, &mudconf.parent_control, 0}, {"parent_zones", cf_bool, CA_GOD, &mudconf.parent_zones, 0}, {"paycheck", cf_int, CA_GOD, &mudconf.paycheck, 0}, {"pemit_far_players", cf_bool, CA_GOD, &mudconf.pemit_players, 0}, {"pemit_any_object", cf_bool, CA_GOD, &mudconf.pemit_any, 0}, {"permit_site", cf_site, CA_GOD, (int *) &mudstate.access_list, 0}, {"player_flags", cf_set_flags, CA_GOD, (int *) &mudconf.player_flags, 0}, {"player_listen", cf_bool, CA_GOD, &mudconf.player_listen, 0}, {"player_match_own_commands", cf_bool, CA_GOD, &mudconf.match_mine_pl, 0}, {"player_name_spaces", cf_bool, CA_GOD, &mudconf.name_spaces, 0}, {"player_parent", cf_int, CA_GOD, &mudconf.player_parent, 0}, {"player_queue_limit", cf_int, CA_GOD, &mudconf.queuemax, 0}, {"player_quota", cf_int, CA_GOD, &mudconf.player_quota, 0}, {"player_starting_home", cf_int, CA_GOD, &mudconf.start_home, 0}, {"player_starting_room", cf_int, CA_GOD, &mudconf.start_room, 0}, {"port", cf_int, CA_DISABLED, &mudconf.port, 0}, {"power_access", cf_ntab_access, CA_GOD, (int *) powers_nametab, access_nametab}, {"public_flags", cf_bool, CA_GOD, &mudconf.pub_flags, 0}, {"queue_active_chunk", cf_int, CA_GOD, &mudconf.active_q_chunk, 0}, {"queue_idle_chunk", cf_int, CA_GOD, &mudconf.queue_chunk, 0}, {"quiet_look", cf_bool, CA_GOD, &mudconf.quiet_look, 0}, {"quiet_whisper", cf_bool, CA_GOD, &mudconf.quiet_whisper, 0}, {"quit_file", cf_string, CA_DISABLED, (int *) mudconf.quit_file, (void *) SBUF_SIZE}, {"quotas", cf_bool, CA_GOD, &mudconf.quotas, 0}, {"read_remote_desc", cf_bool, CA_GOD, &mudconf.read_rem_desc, 0}, {"read_remote_name", cf_bool, CA_GOD, &mudconf.read_rem_name, 0}, {"recycling", cf_bool, CA_GOD, &mudconf.recycle, 0}, {"register_create_file", cf_string, CA_DISABLED, (int *) mudconf.regf_file, (void *) SBUF_SIZE}, {"register_site", cf_site, CA_GOD, (int *) &mudstate.access_list, (void *) H_REGISTRATION}, {"require_cmds_flag", cf_bool, CA_GOD, &mudconf.req_cmds_flag, 0}, {"retry_limit", cf_int, CA_GOD, &mudconf.retry_limit, 0}, {"robot_cost", cf_int, CA_GOD, &mudconf.robotcost, 0}, {"robot_flags", cf_set_flags, CA_GOD, (int *) &mudconf.robot_flags, 0}, {"robot_speech", cf_bool, CA_GOD, &mudconf.robot_speak, 0}, {"room_flags", cf_set_flags, CA_GOD, (int *) &mudconf.room_flags, 0}, {"room_parent", cf_int, CA_GOD, &mudconf.room_parent, 0}, {"room_quota", cf_int, CA_GOD, &mudconf.room_quota, 0}, {"rwho_data_port", cf_int, CA_GOD, &mudconf.rwho_data_port, 0}, {"rwho_dump_interval", cf_int, CA_GOD, &mudconf.rwho_interval, 0}, {"rwho_host", cf_string, CA_GOD, (int *) mudconf.rwho_host, (void *) 64}, {"rwho_info_port", cf_int, CA_GOD, &mudconf.rwho_info_port, 0}, {"rwho_password", cf_string, CA_GOD, (int *) mudconf.rwho_pass, (void *) SBUF_SIZE}, {"rwho_transmit", cf_bool, CA_GOD, &mudconf.rwho_transmit, 0}, {"sacrifice_adjust", cf_int, CA_GOD, &mudconf.sacadjust, 0}, {"sacrifice_factor", cf_int, CA_GOD, &mudconf.sacfactor, 0}, {"safer_passwords", cf_bool, CA_GOD, &mudconf.safer_passwords, 0}, {"search_cost", cf_int, CA_GOD, &mudconf.searchcost, 0}, {"see_owned_dark", cf_bool, CA_GOD, &mudconf.see_own_dark, 0}, {"signal_action", cf_option, CA_DISABLED, &mudconf.sig_action, sigactions_nametab}, {"space_compress", cf_bool, CA_GOD, &mudconf.space_compress, 0}, {"starting_money", cf_int, CA_GOD, &mudconf.paystart, 0}, {"starting_quota", cf_int, CA_GOD, &mudconf.start_quota, 0}, {"starting_exit_quota", cf_int, CA_GOD, &mudconf.start_exit_quota, 0}, {"starting_player_quota", cf_int, CA_GOD, &mudconf.start_player_quota, 0}, {"starting_room_quota", cf_int, CA_GOD, &mudconf.start_room_quota, 0}, {"starting_thing_quota", cf_int, CA_GOD, &mudconf.start_thing_quota, 0}, {"status_file", cf_string, CA_DISABLED, (int *) mudconf.status_file, (void *) PBUF_SIZE}, {"suspect_site", cf_site, CA_GOD, (int *) &mudstate.suspect_list, (void *) H_SUSPECT}, {"sweep_dark", cf_bool, CA_GOD, &mudconf.sweep_dark, 0}, {"switch_default_all", cf_bool, CA_GOD, &mudconf.switch_df_all, 0}, {"terse_shows_contents", cf_bool, CA_GOD, &mudconf.terse_contents, 0}, {"terse_shows_exits", cf_bool, CA_GOD, &mudconf.terse_exits, 0}, {"terse_shows_move_messages", cf_bool, CA_GOD, &mudconf.terse_movemsg, 0}, {"thing_flags", cf_set_flags, CA_GOD, (int *) &mudconf.thing_flags, 0}, {"thing_parent", cf_int, CA_GOD, &mudconf.thing_parent, 0}, {"thing_quota", cf_int, CA_GOD, &mudconf.thing_quota, 0}, {"timeslice", cf_int, CA_GOD, &mudconf.timeslice, 0}, {"trace_output_limit", cf_int, CA_GOD, &mudconf.trace_limit, 0}, {"trace_topdown", cf_bool, CA_GOD, &mudconf.trace_topdown, 0}, {"trust_site", cf_site, CA_GOD, (int *) &mudstate.suspect_list, 0}, {"typed_quotas", cf_bool, CA_GOD, &mudconf.typed_quotas, 0}, {"unowned_safe", cf_bool, CA_GOD, &mudconf.safe_unowned, 0}, {"user_attr_access", cf_modify_bits, CA_GOD, &mudconf.vattr_flags, attraccess_nametab}, {"use_global_aconn", cf_bool, CA_GOD, &mudconf.use_global_aconn, 0}, {"wait_cost", cf_int, CA_GOD, &mudconf.waitcost, 0}, {"wizard_obeys_linklock", cf_bool, CA_GOD, &mudconf.wiz_obey_linklock, 0}, {"wizard_help_file", cf_string, CA_DISABLED, (int *) mudconf.whelp_file, (void *) SBUF_SIZE}, {"wizard_help_index", cf_string, CA_DISABLED, (int *) mudconf.whelp_indx, (void *) SBUF_SIZE}, {"wizard_motd_file", cf_string, CA_DISABLED, (int *) mudconf.wizmotd_file, (void *) SBUF_SIZE}, {"wizard_motd_message", cf_string, CA_GOD, (int *) mudconf.wizmotd_msg, (void *) GBUF_SIZE}, {NULL, NULL, 0, NULL, 0}}; /* --------------------------------------------------------------------------- * cf_set: Set config parameter. */ int cf_set(cp, ap, player) char *cp, *ap; dbref player; { CONF *tp; int i; char *buff; /* Search the config parameter table for the command. If we find it, call the handler to parse the argument. */ for (tp = conftable; tp->pname; tp++) { if (!strcmp(tp->pname, cp)) { if (!mudstate.initializing && !check_access(player, tp->flags)) { notify(player, "Permission denied."); return (-1); } if (!mudstate.initializing) { buff = alloc_lbuf("cf_set"); strcpy(buff, ap); } i = tp->interpreter(tp->loc, ap, tp->extra, player, cp); if (!mudstate.initializing) { STARTLOG(LOG_CONFIGMODS, "CFG", "UPDAT") log_name(player); log_text((char *) " entered config directive: "); log_text(cp); log_text((char *) " with args '"); log_text(buff); log_text((char *) "'. Status: "); switch (i) { case 0: log_text((char *) "Success."); break; case 1: log_text((char *) "Partial success."); break; case -1: log_text((char *) "Failure."); break; default: log_text((char *) "Strange."); } ENDLOG free_lbuf(buff); } return i; } } /* Config directive not found. Complain about it. */ cf_log_notfound(player, (char *) "Set", "Config directive", cp); return (-1); } /* --------------------------------------------------------------------------- * do_admin: Command handler to set config params at runtime */ void do_admin(player, cause, extra, kw, value) dbref player, cause; int extra; char *kw, *value; { int i; i = cf_set(kw, value, player); if ((i >= 0) && !Quiet(player)) notify(player, "Set."); return; } /* --------------------------------------------------------------------------- * cf_read: Read in config parameters from named file */ int cf_read(fn) char *fn; { int retval; strncpy(mudconf.config_file, fn, PBUF_SIZE - 1); mudconf.config_file[PBUF_SIZE - 1] = '\0'; mudstate.initializing = 1; retval = cf_include(NULL, fn, 0, 0, (char *) "init"); mudstate.initializing = 0; /* Fill in missing DB file names */ if (!*mudconf.outdb) { strcpy(mudconf.outdb, mudconf.indb); strcat(mudconf.outdb, ".out"); } if (!*mudconf.crashdb) { strcpy(mudconf.crashdb, mudconf.indb); strcat(mudconf.crashdb, ".CRASH"); } if (!*mudconf.gdbm) { strcpy(mudconf.gdbm, mudconf.indb); strcat(mudconf.gdbm, ".gdbm"); } return retval; } /* --------------------------------------------------------------------------- * list_cf_access: List access to config directives. */ void list_cf_access(player) dbref player; { CONF *tp; char *buff; buff = alloc_mbuf("list_cf_access"); for (tp = conftable; tp->pname; tp++) { if (God(player) || check_access(player, tp->flags)) { sprintf(buff, "%s:", tp->pname); listset_nametab(player, access_nametab, tp->flags, buff, 1); } } free_mbuf(buff); } #endif /* STANDALONE */