mux/src/conf.cpp

Go to the documentation of this file.
00001 // conf.cpp -- Set up configuration information and static data.
00002 //
00003 // $Id: conf.cpp,v 1.71 2006/05/18 18:43:44 sdennis Exp $
00004 //
00005 
00006 #include "copyright.h"
00007 #include "autoconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010 
00011 #include "attrs.h"
00012 #include "command.h"
00013 #include "interface.h"
00014 
00015 // ---------------------------------------------------------------------------
00016 // CONFPARM: Data used to find fields in CONFDATA.
00017 //
00018 typedef struct confparm
00019 {
00020     char *pname;            // parm name
00021     int (*interpreter)(int *vp, char *str, void *pExtra, UINT32 nExtra,
00022                        dbref player, char *cmd); // routine to interp parameter
00023     int flags;              // control flags
00024     int rperms;             // read permissino flags.
00025     int *loc;               // where to store value
00026     void *pExtra;           // extra pointer for interpreter
00027     UINT32 nExtra;          // extra data for interpreter
00028 } CONF;
00029 
00030 // ---------------------------------------------------------------------------
00031 // External symbols.
00032 //
00033 CONFDATA mudconf;
00034 STATEDATA mudstate;
00035 
00036 // ---------------------------------------------------------------------------
00037 // cf_init: Initialize mudconf to default values.
00038 //
00039 void cf_init(void)
00040 {
00041     int i;
00042 
00043     mudconf.indb = StringClone("netmux.db");
00044     mudconf.outdb = StringClone("");
00045     mudconf.crashdb = StringClone("");
00046     mudconf.game_dir = StringClone("");
00047     mudconf.game_pag = StringClone("");
00048     mudconf.mail_db   = StringClone("mail.db");
00049     mudconf.comsys_db = StringClone("comsys.db");
00050 
00051     mudconf.compress_db = false;
00052     mudconf.compress = StringClone("gzip");
00053     mudconf.uncompress = StringClone("gzip -d");
00054     mudconf.status_file = StringClone("shutdown.status");
00055     mudconf.max_cache_size = 1*1024*1024;
00056 
00057     mudconf.ports.n = 1;
00058     mudconf.ports.pi = (int *)MEMALLOC(sizeof(int));
00059     ISOUTOFMEMORY(mudconf.ports.pi);
00060     mudconf.ports.pi[0] = 2860;
00061 
00062     mudconf.init_size = 1000;
00063     mudconf.guest_char = -1;
00064     mudconf.guest_nuker = GOD;
00065     mudconf.number_guests = 30;
00066     mudconf.min_guests = 1;
00067     strcpy(mudconf.guest_prefix, "Guest");
00068     mudconf.guest_file     = StringClone("text/guest.txt");
00069     mudconf.conn_file      = StringClone("text/connect.txt");
00070     mudconf.creg_file      = StringClone("text/register.txt");
00071     mudconf.regf_file      = StringClone("text/create_reg.txt");
00072     mudconf.motd_file      = StringClone("text/motd.txt");
00073     mudconf.wizmotd_file   = StringClone("text/wizmotd.txt");
00074     mudconf.quit_file      = StringClone("text/quit.txt");
00075     mudconf.down_file      = StringClone("text/down.txt");
00076     mudconf.full_file      = StringClone("text/full.txt");
00077     mudconf.site_file      = StringClone("text/badsite.txt");
00078     mudconf.crea_file      = StringClone("text/newuser.txt");
00079     mudconf.motd_msg[0] = '\0';
00080     mudconf.wizmotd_msg[0] = '\0';
00081     mudconf.downmotd_msg[0] = '\0';
00082     mudconf.fullmotd_msg[0] = '\0';
00083     mudconf.dump_msg[0] = '\0';
00084     mudconf.postdump_msg[0] = '\0';
00085     mudconf.fixed_home_msg[0] = '\0';
00086     mudconf.fixed_tel_msg[0] = '\0';
00087     strcpy(mudconf.public_channel, "Public");
00088     strcpy(mudconf.public_channel_alias, "pub");
00089     strcpy(mudconf.guests_channel, "Guests");
00090     strcpy(mudconf.guests_channel_alias, "g");
00091     strcpy(mudconf.pueblo_msg, "</xch_mudtext><img xch_mode=html>");
00092     mudconf.art_rules = NULL;
00093     mudconf.indent_desc = false;
00094     mudconf.name_spaces = true;
00095 #ifndef WIN32
00096     mudconf.fork_dump = true;
00097     mudstate.dumping  = false;
00098     mudstate.dumper   = 0;
00099     mudstate.dumped   = 0;
00100     mudstate.write_protect = false;
00101 #endif
00102     mudconf.restrict_home = false;
00103     mudconf.have_comsys = true;
00104     mudconf.have_mailer = true;
00105     mudconf.have_zones = true;
00106     mudconf.paranoid_alloc = false;
00107     mudconf.sig_action = SA_DFLT;
00108     mudconf.max_players = -1;
00109     mudconf.dump_interval = 3600;
00110     mudconf.check_interval = 600;
00111     mudconf.events_daily_hour = 7;
00112     mudconf.dump_offset = 0;
00113     mudconf.check_offset = 300;
00114     mudconf.idle_timeout = 3600;
00115     mudconf.conn_timeout = 120;
00116     mudconf.idle_interval = 60;
00117     mudconf.retry_limit = 3;
00118     mudconf.output_limit = 16384;
00119     mudconf.paycheck = 0;
00120     mudconf.paystart = 0;
00121     mudconf.paylimit = 10000;
00122 #ifdef REALITY_LVLS
00123     mudconf.no_levels = 0;
00124     mudconf.def_room_rx = 1;
00125     mudconf.def_room_tx = ~(RLEVEL)0;
00126     mudconf.def_player_rx = 1;
00127     mudconf.def_player_tx = 1;
00128     mudconf.def_exit_rx = 1;
00129     mudconf.def_exit_tx = 1;
00130     mudconf.def_thing_rx = 1;
00131     mudconf.def_thing_tx = 1;
00132 #endif /* REALITY_LVLS */
00133     mudconf.start_quota = 20;
00134     mudconf.site_chars = 25;
00135     mudconf.payfind = 0;
00136     mudconf.digcost = 10;
00137     mudconf.linkcost = 1;
00138     mudconf.opencost = 1;
00139     mudconf.createmin = 10;
00140     mudconf.createmax = 505;
00141     mudconf.killmin = 10;
00142     mudconf.killmax = 100;
00143     mudconf.killguarantee = 100;
00144     mudconf.robotcost = 1000;
00145     mudconf.pagecost = 10;
00146     mudconf.searchcost = 100;
00147     mudconf.waitcost = 10;
00148     mudconf.machinecost = 64;
00149     mudconf.exit_quota = 1;
00150     mudconf.player_quota = 1;
00151     mudconf.room_quota = 1;
00152     mudconf.thing_quota = 1;
00153     mudconf.mail_expiration = 14;
00154     mudconf.queuemax = 100;
00155     mudconf.queue_chunk = 10;
00156     mudconf.active_q_chunk  = 10;
00157     mudconf.sacfactor       = 5;
00158     mudconf.sacadjust       = -1;
00159     mudconf.trace_limit     = 200;
00160 
00161     mudconf.autozone        = true;
00162     mudconf.use_hostname    = true;
00163     mudconf.clone_copy_cost = false;
00164     mudconf.dark_sleepers   = true;
00165     mudconf.ex_flags        = true;
00166     mudconf.exam_public     = true;
00167     mudconf.fascist_tport   = false;
00168     mudconf.idle_wiz_dark   = false;
00169     mudconf.match_mine      = true;
00170     mudconf.match_mine_pl   = true;
00171     mudconf.pemit_players   = false;
00172     mudconf.pemit_any       = false;
00173     mudconf.player_listen   = false;
00174     mudconf.pub_flags       = true;
00175     mudconf.quiet_look      = true;
00176     mudconf.quiet_whisper   = true;
00177     mudconf.quotas          = false;
00178     mudconf.read_rem_desc   = false;
00179     mudconf.read_rem_name   = false;
00180     mudconf.reset_players   = false;
00181     mudconf.robot_speak     = true;
00182     mudconf.safe_unowned    = false;
00183     mudconf.safer_passwords = false;
00184     mudconf.see_own_dark    = true;
00185     mudconf.sweep_dark      = false;
00186     mudconf.switch_df_all   = true;
00187     mudconf.terse_contents  = true;
00188     mudconf.terse_exits     = true;
00189     mudconf.terse_look      = true;
00190     mudconf.terse_movemsg   = true;
00191     mudconf.trace_topdown   = true;
00192     mudconf.use_http        = false;
00193 
00194     // -- ??? Running SC on a non-SC DB may cause problems.
00195     //
00196     mudconf.space_compress = true;
00197     mudconf.allow_guest_from_registered_site = true;
00198     mudconf.start_room = 0;
00199     mudconf.start_home = NOTHING;
00200     mudconf.default_home = NOTHING;
00201     mudconf.master_room = NOTHING;
00202 
00203     for (i = FLAG_WORD1; i <= FLAG_WORD3; i++)
00204     {
00205         mudconf.player_flags.word[i] = 0;
00206         mudconf.room_flags.word[i] = 0;
00207         mudconf.exit_flags.word[i] = 0;
00208         mudconf.thing_flags.word[i] = 0;
00209         mudconf.robot_flags.word[i] = 0;
00210     }
00211     mudconf.robot_flags.word[FLAG_WORD1] |= ROBOT;
00212 
00213     mudconf.vattr_flags = AF_ODARK;
00214     strcpy(mudconf.mud_name, "MUX");
00215     strcpy(mudconf.one_coin, "penny");
00216     strcpy(mudconf.many_coins, "pennies");
00217     mudconf.timeslice.SetSeconds(1);
00218     mudconf.cmd_quota_max = 100;
00219     mudconf.cmd_quota_incr = 1;
00220     mudconf.rpt_cmdsecs.SetSeconds(120);
00221     mudconf.max_cmdsecs.SetSeconds(60);
00222     mudconf.cache_tick_period.SetSeconds(30);
00223     mudconf.control_flags = 0xffffffff; // Everything for now...
00224     mudconf.log_options = LOG_ALWAYS | LOG_BUGS | LOG_SECURITY |
00225         LOG_NET | LOG_LOGIN | LOG_DBSAVES | LOG_CONFIGMODS |
00226         LOG_SHOUTS | LOG_STARTUP | LOG_WIZARD | LOG_SUSPECTCMDS |
00227         LOG_PROBLEMS | LOG_PCREATES | LOG_TIMEUSE;
00228     mudconf.log_info = LOGOPT_TIMESTAMP | LOGOPT_LOC;
00229     mudconf.markdata[0] = 0x01;
00230     mudconf.markdata[1] = 0x02;
00231     mudconf.markdata[2] = 0x04;
00232     mudconf.markdata[3] = 0x08;
00233     mudconf.markdata[4] = 0x10;
00234     mudconf.markdata[5] = 0x20;
00235     mudconf.markdata[6] = 0x40;
00236     mudconf.markdata[7] = 0x80;
00237     mudconf.func_nest_lim = 50;
00238     mudconf.func_invk_lim = 2500;
00239     mudconf.wild_invk_lim = 100000;
00240     mudconf.ntfy_nest_lim = 20;
00241     mudconf.lock_nest_lim = 20;
00242     mudconf.parent_nest_lim = 10;
00243     mudconf.zone_nest_lim = 20;
00244     mudconf.stack_limit = 50;
00245     mudconf.cache_names = true;
00246     mudconf.toad_recipient = -1;
00247     mudconf.eval_comtitle = true;
00248     mudconf.run_startup = true;
00249     mudconf.safe_wipe = false;
00250     mudconf.destroy_going_now = false;
00251     mudconf.nStackLimit = 10000;
00252     mudconf.hook_obj = NOTHING;
00253     mudconf.global_error_obj = NOTHING;
00254     mudconf.cache_pages = 40;
00255     mudconf.mail_per_hour = 50;
00256     mudconf.vattr_per_hour = 5000;
00257     mudconf.pcreate_per_hour = 100;
00258 
00259     mudstate.events_flag = 0;
00260     mudstate.bReadingConfiguration = false;
00261     mudstate.bCanRestart = false;
00262     mudstate.panicking = false;
00263     mudstate.logging = 0;
00264     mudstate.epoch = 0;
00265     mudstate.generation = 0;
00266     mudstate.curr_executor = NOTHING;
00267     mudstate.curr_enactor = NOTHING;
00268     mudstate.shutdown_flag  = false;
00269     mudstate.attr_next = A_USER_START;
00270     mudstate.debug_cmd = "< init >";
00271     mudstate.curr_cmd  = "< none >";
00272     strcpy(mudstate.doing_hdr, "Doing");
00273     mudstate.access_list = NULL;
00274     mudstate.suspect_list = NULL;
00275     mudstate.badname_head = NULL;
00276     mudstate.mstat_ixrss[0] = 0;
00277     mudstate.mstat_ixrss[1] = 0;
00278     mudstate.mstat_idrss[0] = 0;
00279     mudstate.mstat_idrss[1] = 0;
00280     mudstate.mstat_isrss[0] = 0;
00281     mudstate.mstat_isrss[1] = 0;
00282     mudstate.mstat_secs[0] = 0;
00283     mudstate.mstat_secs[1] = 0;
00284     mudstate.mstat_curr = 0;
00285     mudstate.iter_alist.data = NULL;
00286     mudstate.iter_alist.len = 0;
00287     mudstate.iter_alist.next = NULL;
00288     mudstate.mod_alist = NULL;
00289     mudstate.mod_alist_len = 0;
00290     mudstate.mod_size = 0;
00291     mudstate.mod_al_id = NOTHING;
00292     mudstate.olist = NULL;
00293     mudstate.min_size = 0;
00294     mudstate.db_top = 0;
00295     mudstate.db_size = 0;
00296     mudstate.mail_db_top = 0;
00297     mudstate.mail_db_size = 0;
00298     mudstate.freelist = NOTHING;
00299     mudstate.markbits = NULL;
00300     mudstate.func_nest_lev = 0;
00301     mudstate.func_invk_ctr = 0;
00302     mudstate.wild_invk_ctr = 0;
00303     mudstate.ntfy_nest_lev = 0;
00304     mudstate.train_nest_lev = 0;
00305     mudstate.lock_nest_lev = 0;
00306     mudstate.zone_nest_num = 0;
00307     mudstate.pipe_nest_lev = 0;
00308     mudstate.inpipe = false;
00309     mudstate.pout = NULL;
00310     mudstate.poutnew = NULL;
00311     mudstate.poutbufc = NULL;
00312     mudstate.poutobj = NOTHING;
00313     for (i = 0; i < MAX_GLOBAL_REGS; i++)
00314     {
00315         mudstate.global_regs[i] = NULL;
00316         mudstate.glob_reg_len[i] = 0;
00317     }
00318     mudstate.nObjEvalNest = 0;
00319     mudstate.in_loop = 0;
00320     mudstate.bStackLimitReached = false;
00321     mudstate.nStackNest = 0;
00322     mudstate.nHearNest  = 0;
00323     mudstate.aHelpDesc = NULL;
00324     mudstate.mHelpDesc = 0;
00325     mudstate.nHelpDesc = 0;
00326 }
00327 
00328 // ---------------------------------------------------------------------------
00329 // cf_log_notfound: Log a 'parameter not found' error.
00330 //
00331 void cf_log_notfound(dbref player, char *cmd, const char *thingname, char *thing)
00332 {
00333     if (mudstate.bReadingConfiguration)
00334     {
00335         STARTLOG(LOG_STARTUP, "CNF", "NFND");
00336         Log.tinyprintf("%s: %s %s not found", cmd, thingname, thing);
00337         ENDLOG;
00338     }
00339     else
00340     {
00341         notify(player, tprintf("%s %s not found", thingname, thing));
00342     }
00343 }
00344 
00345 // ---------------------------------------------------------------------------
00346 // cf_log_syntax: Log a syntax error.
00347 //
00348 void DCL_CDECL cf_log_syntax(dbref player, char *cmd, const char *fmt, ...)
00349 {
00350     va_list ap;
00351     va_start(ap, fmt);
00352 
00353     char *buf = alloc_lbuf("cf_log_syntax");
00354     mux_vsnprintf(buf, LBUF_SIZE, fmt, ap);
00355     if (mudstate.bReadingConfiguration)
00356     {
00357         STARTLOG(LOG_STARTUP, "CNF", "SYNTX")
00358         log_text(cmd);
00359         log_text(": ");
00360         log_text(buf);
00361         ENDLOG;
00362     }
00363     else
00364     {
00365         notify(player, buf);
00366     }
00367     free_lbuf(buf);
00368     va_end(ap);
00369 }
00370 
00371 // ---------------------------------------------------------------------------
00372 // cf_status_from_succfail: Return command status from succ and fail info
00373 //
00374 static int cf_status_from_succfail(dbref player, char *cmd, int success, int failure)
00375 {
00376     char *buff;
00377 
00378     // If any successes, return SUCCESS(0) if no failures or
00379     // PARTIAL_SUCCESS(1) if any failures.
00380     //
00381     if (success > 0)
00382         return ((failure == 0) ? 0 : 1);
00383 
00384     // No successes.  If no failures indicate nothing done. Always return
00385     // FAILURE(-1)
00386     //
00387     if (failure == 0)
00388     {
00389         if (mudstate.bReadingConfiguration)
00390         {
00391             STARTLOG(LOG_STARTUP, "CNF", "NDATA")
00392             buff = alloc_lbuf("cf_status_from_succfail.LOG");
00393             sprintf(buff, "%s: Nothing to set", cmd);
00394             log_text(buff);
00395             free_lbuf(buff);
00396             ENDLOG
00397         }
00398         else
00399         {
00400             notify(player, "Nothing to set");
00401         }
00402     }
00403     return -1;
00404 }
00405 
00406 //---------------------------------------------------------------------------
00407 // cf_rlevel
00408 //
00409 
00410 #ifdef REALITY_LVLS
00411 
00412 CF_HAND(cf_rlevel)
00413 {
00414     CONFDATA *mc = (CONFDATA *)vp;
00415     int i;
00416 
00417     if(mc->no_levels >= 32)
00418         return 1;
00419     for(i=0; *str && !mux_isspace[*str]; ++str)
00420         if(i < 8)
00421             mc->reality_level[mc->no_levels].name[i++] = *str;
00422     mc->reality_level[mc->no_levels].name[i] = '\0';
00423     mc->reality_level[mc->no_levels].value = 1;
00424     strcpy(mc->reality_level[mc->no_levels].attr, "DESC");
00425     for(; *str && mux_isspace[*str]; ++str);
00426     for(i=0; *str && mux_isdigit[*str]; ++str)
00427         i = i * 10 + (*str - '0');
00428     if(i)
00429         mc->reality_level[mc->no_levels].value = (RLEVEL) i;
00430     for(; *str && mux_isspace[*str]; ++str);
00431     if(*str)
00432         strncpy(mc->reality_level[mc->no_levels].attr, str, 32);
00433     mc->no_levels++;
00434     return 0;
00435 }
00436 #endif /* REALITY_LVLS */
00437 
00438 // ---------------------------------------------------------------------------
00439 // cf_int_array: Setup array of integers.
00440 //
00441 static CF_HAND(cf_int_array)
00442 {
00443     UNUSED_PARAMETER(pExtra);
00444     UNUSED_PARAMETER(player);
00445     UNUSED_PARAMETER(cmd);
00446 
00447     int *aPorts = (int *)MEMALLOC(nExtra*sizeof(int));
00448     ISOUTOFMEMORY(aPorts);
00449     unsigned int nPorts = 0;
00450 
00451     char *p;
00452     MUX_STRTOK_STATE tts;
00453     mux_strtok_src(&tts, str);
00454     mux_strtok_ctl(&tts, " \t\n\r");
00455     while ((p = mux_strtok_parse(&tts)) != NULL)
00456     {
00457         int unused;
00458         if (is_integer(p, &unused))
00459         {
00460             aPorts[nPorts++] = mux_atol(p);
00461             if (nPorts >= nExtra)
00462             {
00463                 break;
00464             }
00465         }
00466     }
00467 
00468     IntArray *pia = (IntArray *)vp;
00469     if (nPorts)
00470     {
00471         if (pia->pi)
00472         {
00473             MEMFREE(pia->pi);
00474             pia->pi = NULL;
00475         }
00476         pia->pi = (int *)MEMALLOC(nPorts * sizeof(int));
00477         ISOUTOFMEMORY(pia->pi);
00478         pia->n = nPorts;
00479         for (unsigned int i = 0; i < nPorts; i++)
00480         {
00481             pia->pi[i] = aPorts[i];
00482         }
00483     }
00484     MEMFREE(aPorts);
00485     return 0;
00486 }
00487 
00488 // ---------------------------------------------------------------------------
00489 // cf_int: Set integer parameter.
00490 //
00491 static CF_HAND(cf_int)
00492 {
00493     UNUSED_PARAMETER(pExtra);
00494     UNUSED_PARAMETER(nExtra);
00495     UNUSED_PARAMETER(player);
00496     UNUSED_PARAMETER(cmd);
00497 
00498     // Copy the numeric value to the parameter.
00499     //
00500     *vp = mux_atol(str);
00501     return 0;
00502 }
00503 
00504 // ---------------------------------------------------------------------------
00505 // cf_dbref: Set dbref parameter....looking for an ignoring the leading '#'.
00506 //
00507 static CF_HAND(cf_dbref)
00508 {
00509     UNUSED_PARAMETER(pExtra);
00510     UNUSED_PARAMETER(nExtra);
00511     UNUSED_PARAMETER(player);
00512     UNUSED_PARAMETER(cmd);
00513 
00514     char *p = str;
00515     while (mux_isspace(*p))
00516     {
00517         p++;
00518     }
00519     if (*p == '#')
00520     {
00521         p++;
00522     }
00523 
00524     // Copy the numeric value to the parameter.
00525     //
00526     *vp = mux_atol(p);
00527     return 0;
00528 }
00529 
00530 // ---------------------------------------------------------------------------
00531 // cf_seconds: Set CLinearTimeDelta in units of seconds.
00532 //
00533 static CF_HAND(cf_seconds)
00534 {
00535     UNUSED_PARAMETER(pExtra);
00536     UNUSED_PARAMETER(nExtra);
00537     UNUSED_PARAMETER(player);
00538     UNUSED_PARAMETER(cmd);
00539 
00540     CLinearTimeDelta *pltd = (CLinearTimeDelta *)vp;
00541     pltd->SetSecondsString(str);
00542     return 0;
00543 }
00544 
00545 // ---------------------------------------------------------------------------
00546 // cf_bool: Set boolean parameter.
00547 //
00548 static NAMETAB bool_names[] =
00549 {
00550     {"true",    1,  0,  true},
00551     {"false",   1,  0,  false},
00552     {"yes",     1,  0,  true},
00553     {"no",      1,  0,  false},
00554     {"1",       1,  0,  true},
00555     {"0",       1,  0,  false},
00556     {NULL,      0,  0,  0}
00557 };
00558 
00559 static CF_HAND(cf_bool)
00560 {
00561     UNUSED_PARAMETER(pExtra);
00562     UNUSED_PARAMETER(nExtra);
00563 
00564     int i;
00565     if (!search_nametab(GOD, bool_names, str, &i))
00566     {
00567         cf_log_notfound(player, cmd, "Value", str);
00568         return -1;
00569     }
00570     bool *pb = (bool *)vp;
00571     *pb = isTRUE(i);
00572     return 0;
00573 }
00574 
00575 // ---------------------------------------------------------------------------
00576 // cf_option: Select one option from many choices.
00577 //
00578 static CF_HAND(cf_option)
00579 {
00580     UNUSED_PARAMETER(nExtra);
00581 
00582     int i;
00583     if (!search_nametab(GOD, (NAMETAB *)pExtra, str, &i))
00584     {
00585         cf_log_notfound(player, cmd, "Value", str);
00586         return -1;
00587     }
00588     *vp = i;
00589     return 0;
00590 }
00591 
00592 // ---------------------------------------------------------------------------
00593 // cf_string: Set string parameter.
00594 //
00595 static CF_HAND(cf_string)
00596 {
00597     UNUSED_PARAMETER(pExtra);
00598 
00599     char *pc = (char *)vp;
00600 
00601     // The following should never happen because extra is always a non-zero
00602     // constant in the config table.
00603     //
00604     if (nExtra <= 0)
00605     {
00606         return 1;
00607     }
00608 
00609     // Copy the string to the buffer if it is not too big.
00610     //
00611     int retval = 0;
00612     unsigned int nStr = strlen(str);
00613     if (nStr >= nExtra)
00614     {
00615         nStr = nExtra - 1;
00616         if (mudstate.bReadingConfiguration)
00617         {
00618             STARTLOG(LOG_STARTUP, "CNF", "NFND");
00619             Log.tinyprintf("%s: String truncated", cmd);
00620             ENDLOG;
00621         }
00622         else
00623         {
00624             notify(player, "String truncated");
00625         }
00626         retval = 1;
00627     }
00628     memcpy(pc, str, nStr+1);
00629     pc[nStr] = '\0';
00630 
00631     if (pc == mudconf.mud_name)
00632     {
00633         // We are changing the name of the MUD. Form a prefix from the
00634         // mudname and let the logger know.
00635         //
00636         char *buff = alloc_sbuf("cf_string.prefix");
00637         char *p = buff;
00638         char *q = strip_ansi(mudconf.mud_name);
00639         size_t nLen = 0;
00640         while (  *q
00641               && nLen < SBUF_SIZE)
00642         {
00643             if (mux_isalnum(*q))
00644             {
00645                 *p++ = *q;
00646                 nLen++;
00647             }
00648             q++;
00649         }
00650         *p = '\0';
00651         Log.SetPrefix(buff);
00652         free_sbuf(buff);
00653     }
00654     return retval;
00655 }
00656 
00657 // ---------------------------------------------------------------------------
00658 // cf_string_dyn: Set string parameter using dynamically allocated memory.
00659 //
00660 static CF_HAND(cf_string_dyn)
00661 {
00662     UNUSED_PARAMETER(pExtra);
00663 
00664     char **ppc = (char **)vp;
00665 
00666     // Allocate memory for buffer and copy string to it. If nExtra is non-zero,
00667     // then there is a size limitation as well.
00668     //
00669     int retval = 0;
00670     unsigned int nStr = strlen(str);
00671     if (nExtra && nStr >= nExtra)
00672     {
00673         nStr = nExtra - 1;
00674         if (mudstate.bReadingConfiguration)
00675         {
00676             STARTLOG(LOG_STARTUP, "CNF", "NFND");
00677             Log.tinyprintf("%s: String truncated", cmd);
00678             ENDLOG;
00679         }
00680         else
00681         {
00682             notify(player, "String truncated");
00683         }
00684         retval = 1;
00685     }
00686     char *confbuff = StringCloneLen(str, nStr);
00687 
00688     // Free previous memory for buffer.
00689     //
00690     if (*ppc != NULL)
00691     {
00692         MEMFREE(*ppc);
00693     }
00694     *ppc = confbuff;
00695 
00696     return retval;
00697 }
00698 
00699 // ---------------------------------------------------------------------------
00700 // cf_alias: define a generic hash table alias.
00701 //
00702 static CF_HAND(cf_alias)
00703 {
00704     UNUSED_PARAMETER(pExtra);
00705     UNUSED_PARAMETER(nExtra);
00706 
00707     MUX_STRTOK_STATE tts;
00708     mux_strtok_src(&tts, str);
00709     mux_strtok_ctl(&tts, " \t=,");
00710     char *alias = mux_strtok_parse(&tts);
00711     char *orig = mux_strtok_parse(&tts);
00712 
00713     if (orig)
00714     {
00715         mux_strlwr(orig);
00716         void *cp = hashfindLEN(orig, strlen(orig), (CHashTable *) vp);
00717         if (cp == NULL)
00718         {
00719             mux_strupr(orig);
00720             cp = hashfindLEN(orig, strlen(orig), (CHashTable *) vp);
00721             if (cp == NULL)
00722             {
00723                 cf_log_notfound(player, cmd, "Entry", orig);
00724                 return -1;
00725             }
00726         }
00727         if (!hashfindLEN(alias, strlen(alias), (CHashTable *) vp))
00728         {
00729             hashaddLEN(alias, strlen(alias), cp, (CHashTable *) vp);
00730         }
00731         return 0;
00732     }
00733     return -1;
00734 }
00735 
00736 // ---------------------------------------------------------------------------
00737 // cf_flagalias: define a flag alias.
00738 //
00739 static CF_HAND(cf_flagalias)
00740 {
00741     UNUSED_PARAMETER(vp);
00742     UNUSED_PARAMETER(pExtra);
00743     UNUSED_PARAMETER(nExtra);
00744 
00745     MUX_STRTOK_STATE tts;
00746     mux_strtok_src(&tts, str);
00747     mux_strtok_ctl(&tts, " \t=,");
00748     char *alias = mux_strtok_parse(&tts);
00749     char *orig = mux_strtok_parse(&tts);
00750 
00751     bool success = false;
00752     int  nName;
00753     bool bValid;
00754     void *cp;
00755     char *pName = MakeCanonicalFlagName(orig, &nName, &bValid);
00756     if (bValid)
00757     {
00758         cp = hashfindLEN(pName, nName, &mudstate.flags_htab);
00759         if (cp)
00760         {
00761             pName = MakeCanonicalFlagName(alias, &nName, &bValid);
00762             if (bValid)
00763             {
00764                 if (!hashfindLEN(pName, nName, &mudstate.flags_htab))
00765                 {
00766                     hashaddLEN(pName, nName, cp, &mudstate.flags_htab);
00767                     success = true;
00768                }
00769             }
00770         }
00771     }
00772     if (!success)
00773     {
00774         cf_log_notfound(player, cmd, "Flag", orig);
00775     }
00776     return (success ? 0 : -1);
00777 }
00778 
00779 // ---------------------------------------------------------------------------
00780 // cf_poweralias: define a power alias.
00781 //
00782 static CF_HAND(cf_poweralias)
00783 {
00784     UNUSED_PARAMETER(vp);
00785     UNUSED_PARAMETER(pExtra);
00786     UNUSED_PARAMETER(nExtra);
00787 
00788     MUX_STRTOK_STATE tts;
00789     mux_strtok_src(&tts, str);
00790     mux_strtok_ctl(&tts, " \t=,");
00791     char *alias = mux_strtok_parse(&tts);
00792     char *orig = mux_strtok_parse(&tts);
00793 
00794     bool success = false;
00795     int  nName;
00796     bool bValid;
00797     void *cp;
00798     char *pName = MakeCanonicalFlagName(orig, &nName, &bValid);
00799     if (bValid)
00800     {
00801         cp = hashfindLEN(pName, nName, &mudstate.powers_htab);
00802         if (cp)
00803         {
00804             pName = MakeCanonicalFlagName(alias, &nName, &bValid);
00805             if (bValid)
00806             {
00807                 hashaddLEN(pName, nName, cp, &mudstate.powers_htab);
00808                 success = true;
00809             }
00810         }
00811     }
00812     if (!success)
00813     {
00814         cf_log_notfound(player, cmd, "Power", orig);
00815     }
00816     return (success ? 0 : -1);
00817 }
00818 
00819 #if 0
00820 // ---------------------------------------------------------------------------
00821 // cf_or_in_bits: OR in bits from namelist to a word.
00822 //
00823 static CF_HAND(cf_or_in_bits)
00824 {
00825     UNUSED_PARAMETER(nExtra);
00826 
00827     int f, success, failure;
00828 
00829     // Walk through the tokens.
00830     //
00831     success = failure = 0;
00832     MUX_STRTOK_STATE tts;
00833     mux_strtok_src(&tts, str);
00834     mux_strtok_ctl(&tts, " \t");
00835     char *sp = mux_strtok_parse(&tts);
00836     while (sp != NULL)
00837     {
00838         // Set the appropriate bit.
00839         //
00840         if (search_nametab(GOD, (NAMETAB *)pExtra, sp, &f))
00841         {
00842             *vp |= f;
00843             success++;
00844         }
00845         else
00846         {
00847             cf_log_notfound(player, cmd, "Entry", sp);
00848             failure++;
00849         }
00850 
00851         // Get the next token.
00852         //
00853         sp = mux_strtok_parse(&tts);
00854     }
00855     return cf_status_from_succfail(player, cmd, success, failure);
00856 }
00857 #endif
00858 
00859 // ---------------------------------------------------------------------------
00860 // cf_modify_bits: set or clear bits in a flag word from a namelist.
00861 //
00862 CF_HAND(cf_modify_bits)
00863 {
00864     UNUSED_PARAMETER(nExtra);
00865 
00866     int f, success, failure;
00867     bool negate;
00868 
00869     // Walk through the tokens.
00870     //
00871     success = failure = 0;
00872     MUX_STRTOK_STATE tts;
00873     mux_strtok_src(&tts, str);
00874     mux_strtok_ctl(&tts, " \t");
00875     char *sp = mux_strtok_parse(&tts);
00876     while (sp != NULL)
00877     {
00878         // Check for negation.
00879         //
00880         negate = false;
00881         if (*sp == '!')
00882         {
00883             negate = true;
00884             sp++;
00885         }
00886 
00887         // Set or clear the appropriate bit.
00888         //
00889         if (search_nametab(GOD, (NAMETAB *)pExtra, sp, &f))
00890         {
00891             if (negate)
00892                 *vp &= ~f;
00893             else
00894