/* conf.c */ #include "config.h" /* * This file is part of TeenyMUD II. * Copyright(C) 1993, 1994, 1995 by Jason Downs. * All rights reserved. * * TeenyMUD II is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * TeenyMUD II is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file 'COPYING'); if not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * */ #include <stdio.h> #include <sys/types.h> #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ #include <ctype.h> #include "conf.h" #include "teeny.h" #include "commands.h" #include "externs.h" #include "hash/hash.h" /* dynamic configuration system, command aliases, etc. */ typedef enum { CONF_BOOL, CONF_FLAGS, CONF_SHORT, CONF_INT, CONF_TIME, CONF_STRING, CONF_SARRAY } cf_typ; #define CONF_NORM 0x00 #define CONF_INITONLY 0x01 extern int errno; static int ConfHash_Inited = 0; static Hash_Table ConfHash; static int conf_load _ANSI_ARGS_((char *)); static int conf_parse _ANSI_ARGS_((char *, char *)); INLINE static void parse_bool _ANSI_ARGS_((char *, bool *)); INLINE static void parse_short _ANSI_ARGS_((char *, short *)); INLINE static void parse_int _ANSI_ARGS_((char *, int *)); static void parse_string _ANSI_ARGS_((char *, char **)); static int parse_sarray _ANSI_ARGS_((char *, char *[])); #ifndef INTERNAL static void unparse_time _ANSI_ARGS_((char *, size_t, char *, time_t)); static void unparse_sarray _ANSI_ARGS_((char *, size_t, char *, char *[])); #endif /* INTERNAL */ /* keep in sync with struct conf */ struct conftab { char *key; VOID *ptr; cf_typ typ; short flags; }; #ifndef INTERNAL static void conf_dumpopt _ANSI_ARGS_((int, int, struct conftab *, char *, size_t)); #endif /* INTERNAL */ /* parse keyword table. */ static struct conftab ctable[] = { {"mudname", (VOID *) &mudconf.name, CONF_STRING, CONF_INITONLY}, {"hostnames", (VOID *) &mudconf.hostnames, CONF_BOOL, CONF_NORM}, {"registration", (VOID *) &mudconf.registration, CONF_BOOL, CONF_NORM}, {"registername", (VOID *) &mudconf.registername, CONF_BOOL, CONF_NORM}, {"logcommands", (VOID *) &mudconf.logcommands, CONF_BOOL, CONF_NORM}, {"enable_quota", (VOID *) &mudconf.enable_quota, CONF_BOOL, CONF_NORM}, {"enable_money", (VOID *) &mudconf.enable_money, CONF_BOOL, CONF_NORM}, {"enable_groups", (VOID *) &mudconf.enable_groups, CONF_BOOL, CONF_NORM}, {"enable_autotoad", (VOID *) &mudconf.enable_autotoad, CONF_BOOL, CONF_NORM}, {"enable_autohome", (VOID *) &mudconf.enable_autohome, CONF_BOOL, CONF_NORM}, {"enable_pueblo", (VOID *) &mudconf.enable_pueblo, CONF_BOOL, CONF_NORM}, #ifdef notyet {"enable_compress", (VOID *) &mudconf.enable_compress, CONF_BOOL, CONF_INITONLY}, #endif {"wizwhoall", (VOID *) &mudconf.wizwhoall, CONF_BOOL, CONF_NORM}, {"dark_sleep", (VOID *) &mudconf.dark_sleep, CONF_BOOL, CONF_NORM}, {"compact_contents", (VOID *) &mudconf.compact_contents, CONF_BOOL, CONF_NORM}, {"file_access", (VOID *) &mudconf.file_access, CONF_BOOL, CONF_INITONLY}, {"file_exec", (VOID *) &mudconf.file_exec, CONF_BOOL, CONF_INITONLY}, {"enable_rwho", (VOID *) &mudconf.enable_rwho, CONF_BOOL, CONF_INITONLY}, {"hfile_autoload", (VOID *) &mudconf.hfile_autoload, CONF_BOOL, CONF_NORM}, {"default_port", (VOID *) &mudconf.default_port, CONF_INT, CONF_INITONLY}, {"rwho_port", (VOID *) &mudconf.rwho_port, CONF_INT, CONF_INITONLY}, {"starting_loc", (VOID *) &mudconf.starting_loc, CONF_INT, CONF_NORM}, {"root_location", (VOID *) &mudconf.root_location, CONF_INT, CONF_NORM}, {"player_god", (VOID *) &mudconf.player_god, CONF_INT, CONF_INITONLY}, {"parent_depth", (VOID *) &mudconf.parent_depth, CONF_SHORT, CONF_NORM}, {"exit_depth", (VOID *) &mudconf.exit_depth, CONF_SHORT, CONF_NORM}, {"room_depth", (VOID *) &mudconf.room_depth, CONF_SHORT, CONF_NORM}, {"growth_increment", (VOID *) &mudconf.growth_increment, CONF_INT, CONF_INITONLY}, {"slack", (VOID *) &mudconf.slack, CONF_INT, CONF_INITONLY}, {"starting_quota", (VOID *) &mudconf.starting_quota, CONF_SHORT, CONF_NORM}, {"starting_money", (VOID *) &mudconf.starting_money, CONF_SHORT, CONF_NORM}, {"daily_paycheck", (VOID *) &mudconf.daily_paycheck, CONF_SHORT, CONF_NORM}, {"queue_commands", (VOID *) &mudconf.queue_commands, CONF_SHORT, CONF_NORM}, {"queue_cost", (VOID *) &mudconf.queue_cost, CONF_SHORT, CONF_NORM}, {"find_cost", (VOID *) &mudconf.find_cost, CONF_SHORT, CONF_NORM}, {"limfind_cost", (VOID *) &mudconf.limfind_cost, CONF_SHORT, CONF_NORM}, {"stat_cost", (VOID *) &mudconf.stat_cost, CONF_SHORT, CONF_NORM}, {"fullstat_cost", (VOID *) &mudconf.fullstat_cost, CONF_SHORT, CONF_NORM}, {"room_cost", (VOID *) &mudconf.room_cost, CONF_SHORT, CONF_NORM}, {"thing_cost", (VOID *) &mudconf.thing_cost, CONF_SHORT, CONF_NORM}, {"exit_cost", (VOID *) &mudconf.exit_cost, CONF_SHORT, CONF_NORM}, {"minkill_cost", (VOID *) &mudconf.minkill_cost, CONF_SHORT, CONF_NORM}, {"maxkill_cost", (VOID *) &mudconf.maxkill_cost, CONF_SHORT, CONF_NORM}, {"max_list", (VOID *) &mudconf.max_list, CONF_SHORT, CONF_NORM}, {"max_commands", (VOID *) &mudconf.max_commands, CONF_SHORT, CONF_NORM}, {"max_pennies", (VOID *) &mudconf.max_pennies, CONF_INT, CONF_NORM}, {"cache_size", (VOID *) &mudconf.cache_size, CONF_INT, CONF_INITONLY}, {"cache_width", (VOID *) &mudconf.cache_width, CONF_INT, CONF_INITONLY}, {"cache_depth", (VOID *) &mudconf.cache_depth, CONF_INT, CONF_INITONLY}, {"queue_slice", (VOID *) &mudconf.queue_slice, CONF_SHORT, CONF_NORM}, {"build_flags", (VOID *) mudconf.build_flags, CONF_FLAGS, CONF_NORM}, {"robot_flags", (VOID *) mudconf.robot_flags, CONF_FLAGS, CONF_NORM}, {"wizard_flags", (VOID *) mudconf.wizard_flags, CONF_FLAGS, CONF_INITONLY}, {"god_flags", (VOID *) mudconf.god_flags, CONF_FLAGS, CONF_INITONLY}, {"guest_flags", (VOID *) mudconf.guest_flags, CONF_FLAGS, CONF_NORM}, {"player_flags", (VOID *) mudconf.newp_flags, CONF_FLAGS, CONF_NORM}, {"bad_pnames", (VOID *) mudconf.bad_pnames, CONF_SARRAY, CONF_NORM}, {"dump_interval", (VOID *) &mudconf.dump_interval, CONF_TIME, CONF_NORM}, {"login_timeout", (VOID *) &mudconf.login_timeout, CONF_TIME, CONF_NORM}, {"player_timeout", (VOID *) &mudconf.player_timeout, CONF_TIME, CONF_NORM}, {"rwho_interval", (VOID *) &mudconf.rwho_interval, CONF_TIME, CONF_NORM}, {"money_penny", (VOID *) &mudconf.money_penny, CONF_STRING, CONF_NORM}, {"money_nickle", (VOID *) &mudconf.money_nickle, CONF_STRING, CONF_NORM}, {"money_dime", (VOID *) &mudconf.money_dime, CONF_STRING, CONF_NORM}, {"money_quarter", (VOID *) &mudconf.money_quarter, CONF_STRING, CONF_NORM}, {"money_dollar", (VOID *) &mudconf.money_dollar, CONF_STRING, CONF_NORM}, {"money_pennies", (VOID *) &mudconf.money_pennies, CONF_STRING, CONF_NORM}, {"money_nickles", (VOID *) &mudconf.money_nickles, CONF_STRING, CONF_NORM}, {"money_dimes", (VOID *) &mudconf.money_dimes, CONF_STRING, CONF_NORM}, {"money_quarters", (VOID *) &mudconf.money_quarters, CONF_STRING, CONF_NORM}, {"money_dollars", (VOID *) &mudconf.money_dollars, CONF_STRING, CONF_NORM}, {"rwho_passwd", (VOID *) &mudconf.rwho_passwd, CONF_STRING, CONF_INITONLY}, {"rwho_host", (VOID *) &mudconf.rwho_host, CONF_STRING, CONF_INITONLY}, {"dbm_file", (VOID *) &mudconf.dbm_file, CONF_STRING, CONF_INITONLY}, {"db_file", (VOID *) &mudconf.db_file, CONF_STRING, CONF_INITONLY}, {"help_file", (VOID *) &mudconf.help_file, CONF_STRING, CONF_NORM}, {"news_file", (VOID *) &mudconf.news_file, CONF_STRING, CONF_NORM}, {"motd_file", (VOID *) &mudconf.motd_file, CONF_STRING, CONF_NORM}, {"wizn_file", (VOID *) &mudconf.wizn_file, CONF_STRING, CONF_NORM}, {"greet_file", (VOID *) &mudconf.greet_file, CONF_STRING, CONF_NORM}, {"newp_file", (VOID *) &mudconf.newp_file, CONF_STRING, CONF_NORM}, {"register_file", (VOID *) &mudconf.register_file, CONF_STRING, CONF_NORM}, {"bye_file", (VOID *) &mudconf.bye_file, CONF_STRING, CONF_NORM}, {"shtd_file", (VOID *) &mudconf.shtd_file, CONF_STRING, CONF_NORM}, {"guest_file", (VOID *) &mudconf.guest_file, CONF_STRING, CONF_NORM}, {"timeout_file", (VOID *) &mudconf.timeout_file, CONF_STRING, CONF_NORM}, {"badconn_file", (VOID *) &mudconf.badconn_file, CONF_STRING, CONF_NORM}, {"badcrt_file", (VOID *) &mudconf.badcrt_file, CONF_STRING, CONF_NORM}, {"help_url", (VOID *) &mudconf.help_url, CONF_STRING, CONF_NORM}, {"news_url", (VOID *) &mudconf.news_url, CONF_STRING, CONF_NORM}, {"status_file", (VOID *) &mudconf.logstatus_file, CONF_STRING, CONF_NORM}, {"gripe_file", (VOID *) &mudconf.loggripe_file, CONF_STRING, CONF_NORM}, {"command_file", (VOID *) &mudconf.logcommand_file, CONF_STRING, CONF_NORM}, {"error_file", (VOID *) &mudconf.logerror_file, CONF_STRING, CONF_NORM}, {"panic_file", (VOID *) &mudconf.logpanic_file, CONF_STRING, CONF_NORM}, {"chdir_path", (VOID *) &mudconf.chdir_path, CONF_STRING, CONF_INITONLY}, {"files_path", (VOID *) &mudconf.files_path, CONF_STRING, CONF_INITONLY}, {(char *)NULL, (VOID *)NULL, CONF_BOOL, CONF_NORM} }; /* read in the configuration file. */ int conf_init(fname) char *fname; { register struct conftab *cptr; register Hash_Entry *entry; /* set up parse table */ if (!ConfHash_Inited) { Hash_InitTable(&ConfHash, 0, HASH_STRCASE_KEYS); for(cptr = ctable; cptr->key != (char *)NULL; cptr++){ entry = Hash_CreateEntry(&ConfHash, cptr->key, NULL); Hash_SetValue(entry, (char *)cptr); } ConfHash_Inited = 1; } /* initialize suitable defaults -- keep in sync with struct conf */ mudconf.name = ty_strdup("TeenyMUD", "conf_init"); #ifdef notyet mudconf.peers = (struct mpeer *)NULL; /* linked list. */ #endif mudconf.hostnames = 1; mudconf.registration = 0; mudconf.registername = 1; mudconf.logcommands = 0; mudconf.enable_quota = 1; mudconf.enable_money = 1; mudconf.enable_groups = 1; mudconf.enable_autotoad = 0; mudconf.enable_autohome = 0; mudconf.enable_pueblo = 0; mudconf.wizwhoall = 0; mudconf.dark_sleep = 0; mudconf.compact_contents = 0; mudconf.file_access = 0; mudconf.file_exec = 0; mudconf.enable_rwho = 0; mudconf.hfile_autoload = 1; mudconf.default_port = 4201; mudconf.rwho_port = 6888; mudconf.starting_loc = 0; mudconf.root_location = 0; mudconf.player_god = 1; mudconf.parent_depth = 50; mudconf.exit_depth = 50; mudconf.room_depth = 50; mudconf.growth_increment = 1024; mudconf.slack = 512; mudconf.starting_quota = 250; mudconf.starting_money = 100; mudconf.daily_paycheck = 50; mudconf.queue_commands = 36; mudconf.queue_cost = 1; mudconf.find_cost = 100; mudconf.limfind_cost = 25; mudconf.stat_cost = 100; mudconf.fullstat_cost = 25; mudconf.room_cost = 10; mudconf.thing_cost = 10; mudconf.exit_cost = 1; mudconf.minkill_cost = 10; mudconf.maxkill_cost = 100; mudconf.max_list = 512; mudconf.max_commands = 10; mudconf.max_pennies = 10000; mudconf.cache_size = 20480; mudconf.cache_width = 10; mudconf.cache_depth = 10; mudconf.queue_slice = 10; mudconf.build_flags[0] = BUILDER; mudconf.build_flags[1] = 0; mudconf.robot_flags[0] = ROBOT; mudconf.robot_flags[1] = 0; mudconf.wizard_flags[0] = 0; mudconf.wizard_flags[1] = WIZARD; mudconf.god_flags[0] = 0; mudconf.god_flags[1] = GOD; mudconf.guest_flags[0] = GUEST; mudconf.guest_flags[1] = 0; mudconf.newp_flags[0] = 0; mudconf.newp_flags[1] = 0; bzero((VOID *)mudconf.bad_pnames, sizeof(mudconf.bad_pnames)); mudconf.dump_interval = 108000; mudconf.login_timeout = 18000; mudconf.player_timeout = 216000; mudconf.rwho_interval = 200; mudconf.money_penny = ty_strdup("penny", "conf_init"); mudconf.money_nickle = ty_strdup("nickle", "conf_init"); mudconf.money_dime = ty_strdup("dime", "conf_init"); mudconf.money_quarter = ty_strdup("quarter", "conf_init"); mudconf.money_dollar = ty_strdup("dollar", "conf_init"); mudconf.money_pennies = ty_strdup("pennies", "conf_init"); mudconf.money_nickles = ty_strdup("nickles", "conf_init"); mudconf.money_dimes = ty_strdup("dimes", "conf_init"); mudconf.money_quarters = ty_strdup("quarters", "conf_init"); mudconf.money_dollars = ty_strdup("dollars", "conf_init"); mudconf.rwho_passwd = ty_strdup("none", "conf_init"); mudconf.rwho_host = ty_strdup("none", "conf_init"); mudconf.dbm_file = ty_strdup("teeny.dbm", "conf_init"); mudconf.db_file = ty_strdup("teeny.db", "conf_init"); mudconf.help_file = ty_strdup("help.txt", "conf_init"); mudconf.news_file = ty_strdup("news.txt", "conf_init"); mudconf.motd_file = ty_strdup("motd.txt", "conf_init"); mudconf.wizn_file = ty_strdup("wiznews.txt", "conf_init"); mudconf.greet_file = ty_strdup("greet.txt", "conf_init"); mudconf.newp_file = ty_strdup("welcome.txt", "conf_init"); mudconf.register_file = ty_strdup("register.txt", "conf_init"); mudconf.bye_file = ty_strdup("goodbye.txt", "conf_init"); mudconf.shtd_file = ty_strdup("shutdown.txt", "conf_init"); mudconf.guest_file = ty_strdup("guest.txt", "conf_init"); mudconf.timeout_file = ty_strdup("timeout.txt", "conf_init"); mudconf.badconn_file = ty_strdup("badconn.txt", "conf_init"); mudconf.badcrt_file = ty_strdup("badcrt.txt", "conf_init"); mudconf.help_url = ty_strdup("<A HREF=\"http://www.teeny.org/help/\">Help@teeny.org</A>", "conf_init"); mudconf.news_url = ty_strdup("<A HREF=\"http://www.teeny.org/news/\">News@teeny.org</A>", "conf_init"); mudconf.logstatus_file = ty_strdup("status.log", "conf_init"); mudconf.loggripe_file = ty_strdup("gripe.log", "conf_init"); mudconf.logcommand_file = ty_strdup("commands.log", "conf_init"); mudconf.logerror_file = ty_strdup("errors.log", "conf_init"); mudconf.logpanic_file = ty_strdup("panic.log", "conf_init"); mudconf.chdir_path = ty_strdup(".", "conf_init"); mudconf.files_path = ty_strdup("files/", "conf_init"); /* these aren't conf options, but need to be initialized here. */ mudstat.exmotd = (char *)NULL; mudstat.exwiz = (char *)NULL; return(conf_load(fname)); } /* * What actually reads the file. Can be recursive. */ static int conf_load(fname) char *fname; { FILE *fp; char buffer[BUFFSIZ]; int line = 1; /* read in the file */ fp = fopen(fname, "r"); if(fp == (FILE *)NULL) { logfile(LOG_ERROR, "Unable to load configuration file '%s', %s.\n", fname, strerror(errno)); return(-1); } while(!feof(fp) && (fgets(buffer, BUFFSIZ, fp) != (char *)NULL)) { if((buffer[0] == '\n') || (buffer[0] == '#')) { line++; continue; } if(conf_parse(buffer, fname) == -1) { logfile(LOG_ERROR, "Configuration error in file '%s' at line %d.\n", fname, line); return(-1); } line++; } fclose(fp); return(0); } INLINE static void parse_bool(str, ptr) register char *str; register bool *ptr; { /* default to false */ if((strcasecmp(str, "yes") == 0) || ((str[0] == 'y') && (str[1] == '\0')) || (strcasecmp(str, "on") == 0) || (strcasecmp(str, "true") == 0) || ((str[0] == '1') && (str[1] == '\0'))) { *ptr = 1; } else { *ptr = 0; } } INLINE static void parse_short(str, ptr) register char *str; register short *ptr; { *ptr = (short)strtol(str, NULL, 10); } INLINE static void parse_int(str, ptr) register char *str; register int *ptr; { *ptr = (int)strtol(str, NULL, 10); } static void parse_string(str, ptr) register char *str, **ptr; { ty_free(*ptr); *ptr = ty_strdup(str, "parse_string"); } static int parse_sarray(sptr, ptr) register char *sptr; char *ptr[]; { register int index; register char *qptr; for(index = 0; index < 64; index++) { if(ptr[index] != (char *)NULL) { ty_free(ptr[index]); ptr[index] = (char *)NULL; } } for(index = 0; index < 64; index++) { if(*sptr) { while(*sptr && isspace(*sptr)) sptr++; if(*sptr && (*sptr == '{')) { sptr++; for(qptr = sptr; *qptr && (*qptr != '}'); qptr++); if(*qptr) { *qptr++ = '\0'; ptr[index] = ty_strdup(sptr, "parse_sarray.ptr"); sptr = qptr; } else goto sarray_fail; } else if(*sptr && (*sptr == '"')) { sptr++; for(qptr = sptr; *qptr && (*qptr != '"'); qptr++); if(*qptr) { *qptr++ = '\0'; ptr[index] = ty_strdup(sptr, "parse_sarray.ptr"); sptr = qptr; } else goto sarray_fail; } else if(*sptr) { for(qptr = sptr; *qptr && !isspace(*qptr); qptr++); if(*qptr) *qptr++ = '\0'; ptr[index] = ty_strdup(sptr, "parse_sarray.ptr"); sptr = qptr; } } else break; } ptr[index] = (char *)NULL; return(0); sarray_fail: for(index = 0; index < 64; index++) { if(ptr[index] != (char *)NULL) { ty_free(ptr[index]); ptr[index] = (char *)NULL; } } return(-1); } #ifndef INTERNAL static void unparse_time(buffer, blen, key, val) char *buffer; size_t blen; char *key; time_t val; { if((val % 86400) == 0) { /* days */ snprintf(buffer, blen, "[%s] = %ldd", key, (val / 86400)); } else if((val % 3600) == 0) { /* hours */ snprintf(buffer, blen, "[%s] = %ldh", key, (val / 3600)); } else if((val % 60) == 0) { /* minutes */ snprintf(buffer, blen, "[%s] = %ldm", key, (val / 60)); } else snprintf(buffer, blen, "[%s] = %ld", key, val); } static void unparse_sarray(buffer, blen, key, val) char *buffer; size_t blen; char *key; char *val[]; { register char index; register int doneone = 0; snprintf(buffer, blen, "[%s] = ", key); if (val != (char **)NULL) { for(index = 0; index < 64; index++) { if(val[index] != (char *)NULL) { if(strchr(val[index], ' ') == (char *)NULL) { strncat(buffer, val[index], (blen - strlen(buffer) - 1)); strncat(buffer, ", ", (blen - strlen(buffer) - 1)); } else { snprintf(&buffer[strlen(buffer)], (blen - strlen(buffer) - 1), "\"%s\", ", val[index]); } doneone++; } else break; } } if (doneone) buffer[strlen(buffer) - 2] = '\0'; } VOID do_config(player, cause, switches, argone, argtwo) int player, cause, switches; char *argone, *argtwo; { static char err[] = "But what do you want to do with the config?"; char buff[MEDBUFFSIZ]; register Hash_Entry *entry; register struct conftab *cptr; if(switches & CONFIG_SET) { if((argone == (char *)NULL) || (argone[0] == '\0') || (argtwo == (char *)NULL) || (argtwo[0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, err, NOT_QUIET); return; } entry = Hash_FindEntry(&ConfHash, argone); if(entry != (Hash_Entry *)NULL) { cptr = (struct conftab *)Hash_GetValue(entry); if(cptr->flags & CONF_INITONLY) { /* security */ if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "That may not be changed now.", NOT_QUIET); return; } switch(cptr->typ) { case CONF_BOOL: parse_bool(argtwo, (bool *)cptr->ptr); break; case CONF_FLAGS: parse_flags(argtwo, (int *)cptr->ptr); break; case CONF_SHORT: parse_short(argtwo, (short *)cptr->ptr); break; case CONF_INT: parse_int(argtwo, (int *)cptr->ptr); break; case CONF_TIME: parse_time(argtwo, (time_t *)cptr->ptr); break; case CONF_STRING: parse_string(argtwo, (char **)cptr->ptr); break; case CONF_SARRAY: parse_sarray(argtwo, (char **)cptr->ptr); break; default: notify_bad(player); return; } if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Configuration set.", NOT_QUIET); return; } else { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "No such configuration option.", NOT_QUIET); return; } } else if(switches & CONFIG_ALIAS) { register char *swptr; if((argone == (char *)NULL) || (argone[0] == '\0') || (argtwo == (char *)NULL) || (argtwo[0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, err, NOT_QUIET); return; } for(swptr = argone; *swptr && (*swptr != '/'); swptr++); if(*swptr == '/') { *swptr++ = '\0'; } else { swptr = (char *)NULL; } if(command_alias(argone, argtwo, swptr) == -1) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Error aliasing command.", NOT_QUIET); } else if(!(switches & CMD_QUIET)) { notify_player(player, cause, player, "Command aliased.", NOT_QUIET); } return; } else if(switches & CONFIG_UNALIAS) { if((argone == (char *)NULL) || (argone[0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, err, NOT_QUIET); return; } if(command_unalias(argone) == -1) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Error removing command alias.", NOT_QUIET); } else if(!(switches & CMD_QUIET)) { notify_player(player, cause, player, "Command alias removed.", NOT_QUIET); } return; } else if(switches & CONFIG_EXPAND) { char retbuf[128]; if((argone == (char *)NULL) || (argone[0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, err, NOT_QUIET); return; } if(command_aliasexp(argone, retbuf, sizeof(retbuf)) == -1) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Error expanding alias.", NOT_QUIET); } else { snprintf(buff, sizeof(buff), "[%s] = %s", argone, retbuf); notify_player(player, cause, player, buff, 0); } } else { /* display configuration */ if((argone == (char *)NULL) || (argone[0] == '\0')) { for(cptr = ctable; cptr->key != (char *)NULL; cptr++) { conf_dumpopt(player, cause, cptr, buff, sizeof(buff)); } } else { entry = Hash_FindEntry(&ConfHash, argone); if(entry != (Hash_Entry *)NULL) { conf_dumpopt(player, cause, (struct conftab *)Hash_GetValue(entry), buff, sizeof(buff)); } } notify_player(player, cause, player, "***End of list***", 0); } } static void conf_dumpopt(player, cause, cptr, buffer, blen) int player, cause; register struct conftab *cptr; register char *buffer; size_t blen; { short *sptr; /* Compiler GOO. */ int *iptr; /* Compiler GOO. */ bool *bptr; /* Compiler GOO. */ time_t *tptr; /* Compiler GOO. */ char **chptr; /* Compiler GOO. */ switch(cptr->typ) { case CONF_BOOL: bptr = (bool *)cptr->ptr; snprintf(buffer, blen, "[%s] = %s", cptr->key, ((*bptr) ? "on" : "off")); break; case CONF_FLAGS: snprintf(buffer, blen, "[%s] = %s", cptr->key, display_objflags((int *)cptr->ptr, 1)); break; case CONF_SHORT: sptr = (short *)cptr->ptr; snprintf(buffer, blen, "[%s] = %d", cptr->key, (*sptr)); break; case CONF_INT: iptr = (int *)cptr->ptr; snprintf(buffer, blen, "[%s] = %d", cptr->key, (*iptr)); break; case CONF_TIME: tptr = (time_t *)cptr->ptr; unparse_time(buffer, blen, cptr->key, (*tptr)); break; case CONF_STRING: chptr = (char **)cptr->ptr; snprintf(buffer, blen, "[%s] = %s", cptr->key, (*chptr)); break; case CONF_SARRAY: unparse_sarray(buffer, blen, cptr->key, (char **)cptr->ptr); break; } notify_player(player, cause, player, buffer, 0); } #endif /* INTERNAL */ static int conf_parse(line, fname) char *line, *fname; { register char *ptr, *eptr; register Hash_Entry *entry; register struct conftab *cptr; /* remove leading whitespace */ while(*line && isspace(*line)) line++; if(!*line) return(1); /* parse out first word */ for(ptr = line; *ptr && !isspace(*ptr); ptr++); if(!*ptr) return(-1); for(*ptr++ = '\0'; *ptr && isspace(*ptr); ptr++); if(!*ptr) return(-1); /* remove trailing whitespace */ for(eptr = &ptr[strlen(ptr)-1]; (eptr > ptr) && ((*eptr == '\n') || isspace(*eptr)); *eptr-- = '\0'); entry = Hash_FindEntry(&ConfHash, line); if(entry != (Hash_Entry *)NULL) { cptr = (struct conftab *)Hash_GetValue(entry); switch(cptr->typ) { case CONF_BOOL: parse_bool(ptr, (bool *)cptr->ptr); break; case CONF_FLAGS: parse_flags(ptr, (int *)cptr->ptr); break; case CONF_SHORT: parse_short(ptr, (short *)cptr->ptr); break; case CONF_INT: parse_int(ptr, (int *)cptr->ptr); break; case CONF_TIME: parse_time(ptr, (time_t *)cptr->ptr); break; case CONF_STRING: parse_string(ptr, (char **)cptr->ptr); break; case CONF_SARRAY: parse_sarray(ptr, (char **)cptr->ptr); break; } return(0); } else { /* try other hard coded keywords. */ if(strcasecmp(line, "include") == 0) { /* include file */ /* ptr is the file name. */ if(strcmp(fname, ptr) == 0) /* can't include ourself. */ return(-1); /* launch it. */ return(conf_load(ptr)); } #ifndef INTERNAL else if(strcasecmp(line, "alias") == 0) { /* command alias */ register char *swptr; /* parse out the next argument */ for(eptr = ptr; *eptr && !isspace(*eptr); eptr++); if(!*eptr) return(-1); *eptr++ = '\0'; while(*eptr && isspace(*eptr)) eptr++; if(!*eptr) return(-1); for(swptr = ptr; *swptr && (*swptr != '/'); swptr++); if(*swptr == '/') { *swptr++ = '\0'; } else { swptr = (char *)NULL; } /* ptr is the command, eptr is the alias, swptr is switches */ return(command_alias(ptr, eptr, swptr)); } else if(strcasecmp(line, "unalias") == 0) { /* only need one argument */ return(command_unalias(ptr)); #ifdef notyet } else if(strcasecmp(line, "peer") == 0) { register struct mpeer *newp; char *kptr; newp = (struct mpeer *)ty_malloc(sizeof(struct mpeer), "conf_parse.newp"); /* parse out the next argument */ for(eptr = ptr; *eptr && !isspace(*eptr); eptr++); if(!*eptr) { ty_free((VOID *)newp); return(-1); } *eptr++ = '\0'; while(*eptr && isspace(*eptr)) eptr++; if(!*eptr) { ty_free((VOID *)newp); return(-1); } /* ptr is hostname, eptr is port and password. */ newp->hostname = ty_strdup(ptr, "conf_parse.newp"); newp->port = (int)strtol(eptr, &kptr, 10); if(kptr == eptr) { ty_free((VOID *)newp->hostname); ty_free((VOID *)newp); return(-1); } /* parse out password. */ while(*kptr && isspace(*kptr)) kptr++; if(!*kptr) newp->pword = (char *)NULL; else newp->pword = ty_strdup(kptr, "conf_parse.newp"); /* link it in. */ newp->next = mudconf.peers; mudconf.peers = newp; #endif } else { /* default: site lockout/allow string */ /* parse out the next argument */ for(eptr = ptr; *eptr && !isspace(*eptr); eptr++); if(*eptr) { *eptr++ = '\0'; while(*eptr && isspace(*eptr)) eptr++; } else eptr = (char *)NULL; /* messages can be null, damnit */ /* line is the command, ptr is the host, and eptr is the message. */ return(lockout_add(line, ptr, eptr)); } #else return(0); #endif /* INTERNAL */ } /*return(-1);*/ }