00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "autoconf.h"
00007 #include "config.h"
00008 #include "externs.h"
00009
00010 #include <sys/stat.h>
00011 #include <signal.h>
00012
00013 #include "attrs.h"
00014 #include "command.h"
00015 #include "functions.h"
00016 #include "comsys.h"
00017 #include "file_c.h"
00018 #include "mguests.h"
00019 #include "muxcli.h"
00020 #include "pcre.h"
00021 #include "powers.h"
00022 #include "help.h"
00023 #ifdef REALITY_LVLS
00024 #include "levels.h"
00025 #endif
00026
00027 void do_dump(dbref executor, dbref caller, dbref enactor, int key)
00028 {
00029 UNUSED_PARAMETER(caller);
00030 UNUSED_PARAMETER(enactor);
00031
00032 #ifndef WIN32
00033 if (mudstate.dumping)
00034 {
00035 notify(executor, "Dumping in progress. Try again later.");
00036 return;
00037 }
00038 #endif
00039 notify(executor, "Dumping...");
00040 fork_and_dump(key);
00041 }
00042
00043
00044
00045 void report(void)
00046 {
00047 STARTLOG(LOG_BUGS, "BUG", "INFO");
00048 log_text("Command: '");
00049 log_text(mudstate.debug_cmd);
00050 log_text("'");
00051 ENDLOG;
00052 if (Good_obj(mudstate.curr_executor))
00053 {
00054 STARTLOG(LOG_BUGS, "BUG", "INFO");
00055 log_text("Player: ");
00056 log_name_and_loc(mudstate.curr_executor);
00057 if ( mudstate.curr_enactor != mudstate.curr_executor
00058 && Good_obj(mudstate.curr_enactor))
00059 {
00060 log_text(" Enactor: ");
00061 log_name_and_loc(mudstate.curr_enactor);
00062 }
00063 ENDLOG;
00064 }
00065 }
00066
00067
00068
00069
00070
00071
00072 bool regexp_match
00073 (
00074 char *pattern,
00075 char *str,
00076 int case_opt,
00077 char *args[],
00078 int nargs
00079 )
00080 {
00081 int matches;
00082 int i;
00083 const char *errptr;
00084 int erroffset;
00085
00086
00087
00088
00089
00090
00091
00092 pcre *re;
00093 if ( MuxAlarm.bAlarmed
00094 || (re = pcre_compile(pattern, case_opt, &errptr, &erroffset, NULL)) == NULL)
00095 {
00096
00097
00098
00099
00100
00101 return false;
00102 }
00103
00104
00105
00106
00107 const int ovecsize = 6 * nargs;
00108 int *ovec = new int[ovecsize];
00109
00110
00111
00112
00113
00114 matches = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovec, ovecsize);
00115 if (matches < 0)
00116 {
00117 delete [] ovec;
00118 MEMFREE(re);
00119 return false;
00120 }
00121
00122 if (matches == 0)
00123 {
00124
00125
00126
00127 matches = ovecsize / 3;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137 for (i = 0; i < nargs; ++i)
00138 {
00139 args[i] = alloc_lbuf("regexp_match");
00140 if (pcre_copy_substring(str, ovec, matches, i,
00141 args[i], LBUF_SIZE) < 0)
00142 {
00143 free_lbuf(args[i]);
00144 args[i] = NULL;
00145 }
00146 }
00147
00148 delete [] ovec;
00149 MEMFREE(re);
00150 return true;
00151 }
00152
00153
00154
00155
00156
00157 static int atr_match1
00158 (
00159 dbref thing,
00160 dbref parent,
00161 dbref player,
00162 char type,
00163 char *str,
00164 char *raw_str,
00165 int check_exclude,
00166 int hash_insert
00167 )
00168 {
00169
00170
00171 if (!could_doit(player, parent, A_LUSE))
00172 {
00173 return -1;
00174 }
00175
00176 int match = 0;
00177 if ( AMATCH_CMD == type
00178 && mudstate.bfNoCommands.IsSet(parent))
00179 {
00180 return match;
00181 }
00182 else if ( AMATCH_LISTEN == type
00183 && mudstate.bfNoListens.IsSet(parent))
00184 {
00185 return match;
00186 }
00187
00188 bool bFoundCommands = false;
00189 bool bFoundListens = false;
00190
00191 char *as;
00192 atr_push();
00193 for (int atr = atr_head(parent, &as); atr; atr = atr_next(&as))
00194 {
00195 ATTR *ap = atr_num(atr);
00196
00197
00198
00199 if ( !ap
00200 || (ap->flags & AF_NOPROG))
00201 {
00202 continue;
00203 }
00204
00205
00206
00207
00208
00209 dbref aowner;
00210 int aflags;
00211 char buff[LBUF_SIZE];
00212 atr_get_str(buff, parent, atr, &aowner, &aflags);
00213
00214 if (aflags & AF_NOPROG)
00215 {
00216 continue;
00217 }
00218
00219 char *s = NULL;
00220 if ( AMATCH_CMD == buff[0]
00221 || AMATCH_LISTEN == buff[0])
00222 {
00223 s = strchr(buff+1, ':');
00224 if (s)
00225 {
00226 if (AMATCH_CMD == buff[0])
00227 {
00228 bFoundCommands = true;
00229 }
00230 else
00231 {
00232 bFoundListens = true;
00233 }
00234 }
00235 }
00236
00237
00238
00239
00240 if ( check_exclude
00241 && ( (ap->flags & AF_PRIVATE)
00242 || (aflags & AF_PRIVATE)
00243 || hashfindLEN(&(ap->number), sizeof(ap->number), &mudstate.parent_htab)))
00244 {
00245 continue;
00246 }
00247
00248
00249
00250
00251 if (hash_insert)
00252 {
00253 hashaddLEN(&(ap->number), sizeof(ap->number), &atr, &mudstate.parent_htab);
00254 }
00255
00256
00257
00258
00259
00260 if (buff[0] != type)
00261 {
00262 continue;
00263 }
00264
00265
00266
00267 if (!s)
00268 {
00269 continue;
00270 }
00271 *s++ = '\0';
00272
00273 char *args[NUM_ENV_VARS];
00274 if ( ( 0 != (aflags & AF_REGEXP)
00275 && regexp_match(buff + 1, (aflags & AF_NOPARSE) ? raw_str : str,
00276 ((aflags & AF_CASE) ? 0 : PCRE_CASELESS), args, NUM_ENV_VARS))
00277 || ( 0 == (aflags & AF_REGEXP)
00278 && wild(buff + 1, (aflags & AF_NOPARSE) ? raw_str : str,
00279 args, NUM_ENV_VARS)))
00280 {
00281 match = 1;
00282 CLinearTimeAbsolute lta;
00283 wait_que(thing, player, player, false, lta, NOTHING, 0, s,
00284 args, NUM_ENV_VARS, mudstate.global_regs);
00285
00286 for (int i = 0; i < NUM_ENV_VARS; i++)
00287 {
00288 if (args[i])
00289 {
00290 free_lbuf(args[i]);
00291 }
00292 }
00293 }
00294 }
00295 atr_pop();
00296
00297 if (bFoundCommands)
00298 {
00299 mudstate.bfNoCommands.Clear(parent);
00300 mudstate.bfCommands.Set(parent);
00301 }
00302 else
00303 {
00304 mudstate.bfCommands.Clear(parent);
00305 mudstate.bfNoCommands.Set(parent);
00306 }
00307
00308 if (bFoundListens)
00309 {
00310 mudstate.bfNoListens.Clear(parent);
00311 mudstate.bfListens.Set(parent);
00312 }
00313 else
00314 {
00315 mudstate.bfListens.Clear(parent);
00316 mudstate.bfNoListens.Set(parent);
00317 }
00318 return match;
00319 }
00320
00321 bool atr_match
00322 (
00323 dbref thing,
00324 dbref player,
00325 char type,
00326 char *str,
00327 char *raw_str,
00328 bool check_parents
00329 )
00330 {
00331 int lev, result;
00332 bool exclude, insert;
00333 dbref parent;
00334
00335
00336
00337
00338 if ( Halted(thing)
00339 || ( AMATCH_CMD == type
00340 && No_Command(thing)))
00341 {
00342 return false;
00343 }
00344
00345
00346
00347 if (AMATCH_LISTEN == type)
00348 {
00349
00350
00351
00352 size_t junk;
00353 str = strip_ansi(str, &junk);
00354 }
00355
00356
00357
00358 bool match = false;
00359 if (!check_parents)
00360 {
00361 return (atr_match1(thing, thing, player, type, str, raw_str, false, false) > 0);
00362 }
00363
00364
00365
00366 exclude = false;
00367 insert = true;
00368 hashflush(&mudstate.parent_htab);
00369 ITER_PARENTS(thing, parent, lev)
00370 {
00371 if (!Good_obj(Parent(parent)))
00372 {
00373 insert = false;
00374 }
00375 result = atr_match1(thing, parent, player, type, str, raw_str,
00376 exclude, insert);
00377 if (result > 0)
00378 {
00379 match = true;
00380 }
00381 else if (result < 0)
00382 {
00383 return match;
00384 }
00385 exclude = true;
00386 }
00387 return match;
00388 }
00389
00390
00391
00392
00393
00394
00395 static bool check_filter(dbref object, dbref player, int filter, const char *msg)
00396 {
00397 int aflags;
00398 dbref aowner;
00399 char *buf, *nbuf, *cp, *dp, *str;
00400
00401 buf = atr_pget(object, filter, &aowner, &aflags);
00402 if (!*buf)
00403 {
00404 free_lbuf(buf);
00405 return true;
00406 }
00407 char **preserve = NULL;
00408 int *preserve_len = NULL;
00409 preserve = PushPointers(MAX_GLOBAL_REGS);
00410 preserve_len = PushIntegers(MAX_GLOBAL_REGS);
00411 save_global_regs("check_filter_save", preserve, preserve_len);
00412 nbuf = dp = alloc_lbuf("check_filter");
00413 str = buf;
00414 mux_exec(nbuf, &dp, object, player, player,
00415 EV_FIGNORE | EV_EVAL | EV_TOP, &str, (char **)NULL, 0);
00416 *dp = '\0';
00417 dp = nbuf;
00418 free_lbuf(buf);
00419 restore_global_regs("check_filter_restore", preserve, preserve_len);
00420 PopIntegers(preserve_len, MAX_GLOBAL_REGS);
00421 PopPointers(preserve, MAX_GLOBAL_REGS);
00422
00423 if (!(aflags & AF_REGEXP))
00424 {
00425 do
00426 {
00427 cp = parse_to(&dp, ',', EV_STRIP_CURLY);
00428 mudstate.wild_invk_ctr = 0;
00429 if ( MuxAlarm.bAlarmed
00430 || quick_wild(cp, msg))
00431 {
00432 free_lbuf(nbuf);
00433 return false;
00434 }
00435 } while (dp != NULL);
00436 }
00437 else
00438 {
00439 int case_opt = (aflags & AF_CASE) ? 0 : PCRE_CASELESS;
00440 do
00441 {
00442 int erroffset;
00443 const char *errptr;
00444 cp = parse_to(&dp, ',', EV_STRIP_CURLY);
00445 pcre *re;
00446 if ( !MuxAlarm.bAlarmed
00447 && (re = pcre_compile(cp, case_opt, &errptr, &erroffset, NULL)) != NULL)
00448 {
00449 const int ovecsize = 33;
00450 int ovec[ovecsize];
00451 int matches = pcre_exec(re, NULL, msg, strlen(msg), 0, 0,
00452 ovec, ovecsize);
00453 if (0 <= matches)
00454 {
00455 MEMFREE(re);
00456 free_lbuf(nbuf);
00457 return false;
00458 }
00459 MEMFREE(re);
00460 }
00461 } while (dp != NULL);
00462 }
00463 free_lbuf(nbuf);
00464 return true;
00465 }
00466
00467 static char *add_prefix(dbref object, dbref player, int prefix,
00468 const char *msg, const char *dflt)
00469 {
00470 int aflags;
00471 dbref aowner;
00472 char *buf, *nbuf, *cp, *str;
00473
00474 buf = atr_pget(object, prefix, &aowner, &aflags);
00475 if (!*buf)
00476 {
00477 cp = buf;
00478 safe_str(dflt, buf, &cp);
00479 }
00480 else
00481 {
00482 char **preserve = NULL;
00483 int *preserve_len = NULL;
00484 preserve = PushPointers(MAX_GLOBAL_REGS);
00485 preserve_len = PushIntegers(MAX_GLOBAL_REGS);
00486 save_global_regs("add_prefix_save", preserve, preserve_len);
00487
00488 nbuf = cp = alloc_lbuf("add_prefix");
00489 str = buf;
00490 mux_exec(nbuf, &cp, object, player, player,
00491 EV_FIGNORE | EV_EVAL | EV_TOP, &str, (char **)NULL, 0);
00492 free_lbuf(buf);
00493
00494 restore_global_regs("add_prefix_restore", preserve, preserve_len);
00495 PopIntegers(preserve_len, MAX_GLOBAL_REGS);
00496 PopPointers(preserve, MAX_GLOBAL_REGS);
00497
00498 buf = nbuf;
00499 }
00500 if (cp != buf)
00501 {
00502 safe_chr(' ', buf, &cp);
00503 }
00504 safe_str(msg, buf, &cp);
00505 *cp = '\0';
00506 return buf;
00507 }
00508
00509 static char *dflt_from_msg(dbref sender, dbref sendloc)
00510 {
00511 char *tp, *tbuff;
00512
00513 tp = tbuff = alloc_lbuf("notify_check.fwdlist");
00514 safe_str("From ", tbuff, &tp);
00515 if (Good_obj(sendloc))
00516 {
00517 safe_str(Name(sendloc), tbuff, &tp);
00518 }
00519 else
00520 {
00521 safe_str(Name(sender), tbuff, &tp);
00522 }
00523 safe_chr(',', tbuff, &tp);
00524 *tp = '\0';
00525 return tbuff;
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 bool html_escape(const char *src, char *dest, char **destp)
00539 {
00540 const char *msg_orig;
00541 bool ret = false;
00542
00543 if (destp == 0)
00544 {
00545 char *temp = dest;
00546 destp = &temp;
00547 }
00548
00549 for (msg_orig = src; msg_orig && *msg_orig && !ret; msg_orig++)
00550 {
00551 char *p = *destp;
00552 switch (*msg_orig)
00553 {
00554 case '<':
00555 safe_str("<", dest, destp);
00556 break;
00557
00558 case '>':
00559 safe_str(">", dest, destp);
00560 break;
00561
00562 case '&':
00563 safe_str("&", dest, destp);
00564 break;
00565
00566 case '\"':
00567 safe_str(""", dest, destp);
00568 break;
00569
00570 default:
00571 safe_chr(*msg_orig, dest, destp);
00572 break;
00573 }
00574
00575
00576
00577
00578 if (p == *destp)
00579 {
00580 ret = true;
00581 }
00582 }
00583 **destp = 0;
00584 return ret;
00585 }
00586
00587 void notify_check(dbref target, dbref sender, const char *msg, int key)
00588 {
00589
00590
00591 if ( !Good_obj(target)
00592 || !msg
00593 || !*msg)
00594 {
00595 return;
00596 }
00597
00598 #ifdef WOD_REALMS
00599 if ((key & MSG_OOC) == 0)
00600 {
00601 if ((key & MSG_SAYPOSE) != 0)
00602 {
00603 if (REALM_DO_HIDDEN_FROM_YOU == DoThingToThingVisibility(target, sender, ACTION_IS_TALKING))
00604 {
00605 return;
00606 }
00607 }
00608 else
00609 {
00610 if (REALM_DO_HIDDEN_FROM_YOU == DoThingToThingVisibility(target, sender, ACTION_IS_MOVING))
00611 {
00612 return;
00613 }
00614 }
00615 }
00616 #endif // WOD_REALMS
00617
00618
00619
00620 mudstate.ntfy_nest_lev++;
00621 if (mudconf.ntfy_nest_lim <= mudstate.ntfy_nest_lev)
00622 {
00623 mudstate.ntfy_nest_lev--;
00624 return;
00625 }
00626
00627 char *msg_ns, *mp, *tbuff, *tp, *buff;
00628 char *args[NUM_ENV_VARS];
00629 dbref aowner, recip, obj;
00630 int i, nargs, aflags;
00631 FWDLIST *fp;
00632
00633
00634
00635
00636 if (key & MSG_ME)
00637 {
00638 mp = msg_ns = alloc_lbuf("notify_check");
00639 if ( Nospoof(target)
00640 && target != sender
00641 && target != mudstate.curr_enactor
00642 && target != mudstate.curr_executor)
00643 {
00644
00645
00646
00647
00648 tbuff = alloc_sbuf("notify_check.nospoof");
00649 safe_chr('[', msg_ns, &mp);
00650 safe_str(Name(sender), msg_ns, &mp);
00651 sprintf(tbuff, "(#%d)", sender);
00652 safe_str(tbuff, msg_ns, &mp);
00653
00654 if (sender != Owner(sender))
00655 {
00656 safe_chr('{', msg_ns, &mp);
00657 safe_str(Name(Owner(sender)), msg_ns, &mp);
00658 safe_chr('}', msg_ns, &mp);
00659 }
00660 if (sender != mudstate.curr_enactor)
00661 {
00662 sprintf(tbuff, "<-(#%d)", mudstate.curr_enactor);
00663 safe_str(tbuff, msg_ns, &mp);
00664 }
00665 safe_str("] ", msg_ns, &mp);
00666 free_sbuf(tbuff);
00667 }
00668 safe_str(msg, msg_ns, &mp);
00669 *mp = '\0';
00670 }
00671 else
00672 {
00673 msg_ns = NULL;
00674 }
00675
00676
00677
00678 bool check_listens = !Halted(target);
00679 switch (Typeof(target))
00680 {
00681 case TYPE_PLAYER:
00682 if (key & MSG_ME)
00683 {
00684 if (key & MSG_HTML)
00685 {
00686 raw_notify_html(target, msg_ns);
00687 }
00688 else
00689 {
00690 if (Html(target))
00691 {
00692 char *msg_ns_escaped;
00693
00694 msg_ns_escaped = alloc_lbuf("notify_check_escape");
00695 html_escape(msg_ns, msg_ns_escaped, 0);
00696 raw_notify(target, msg_ns_escaped);
00697 free_lbuf(msg_ns_escaped);
00698 }
00699 else
00700 {
00701 raw_notify(target, msg_ns);
00702 }
00703 }
00704 }
00705 if (!mudconf.player_listen)
00706 {
00707 check_listens = false;
00708 }
00709
00710
00711
00712 case TYPE_THING:
00713 case TYPE_ROOM:
00714
00715
00716
00717
00718
00719 if ( mudstate.inpipe
00720 && !isPlayer(target))
00721 {
00722 raw_notify(target, msg_ns);
00723 }
00724
00725
00726
00727 bool has_neighbors = Has_location(target);
00728 dbref targetloc = where_is(target);
00729 bool is_audible = Audible(target);
00730
00731 if ( (key & MSG_ME)
00732 && Puppet(target)
00733 && (target != Owner(target))
00734 && ( (key & MSG_PUP_ALWAYS)
00735 || ( targetloc != Location(Owner(target))
00736 && targetloc != Owner(target))))
00737 {
00738 tp = tbuff = alloc_lbuf("notify_check.puppet");
00739 safe_str(Name(target), tbuff, &tp);
00740 safe_str("> ", tbuff, &tp);
00741 safe_str(msg_ns, tbuff, &tp);
00742 *tp = '\0';
00743 raw_notify(Owner(target), tbuff);
00744 free_lbuf(tbuff);
00745 }
00746
00747
00748
00749 bool pass_listen = false;
00750 nargs = 0;
00751 if ( check_listens
00752 && (key & (MSG_ME | MSG_INV_L))
00753 && H_Listen(target))
00754 {
00755 tp = atr_get(target, A_LISTEN, &aowner, &aflags);
00756 if (*tp && wild(tp, (char *)msg, args, NUM_ENV_VARS))
00757 {
00758 for (nargs = NUM_ENV_VARS; nargs && (!args[nargs - 1] || !(*args[nargs - 1])); nargs--)
00759 {
00760 ;
00761 }
00762 pass_listen = true;
00763 }
00764 free_lbuf(tp);
00765 }
00766
00767
00768
00769
00770 bool pass_uselock = false;
00771 if ( (key & MSG_ME)
00772 && check_listens
00773 && ( pass_listen
00774 || Monitor(target)))
00775 {
00776 pass_uselock = could_doit(sender, target, A_LUSE);
00777 }
00778
00779
00780
00781 if ( (key & MSG_ME)
00782 && pass_listen
00783 && pass_uselock
00784 && mudstate.nHearNest <= 2)
00785 {
00786 mudstate.nHearNest++;
00787 if (sender != target)
00788 {
00789 did_it(sender, target, 0, NULL, 0, NULL, A_AHEAR, args, nargs);
00790 }
00791 else
00792 {
00793 did_it(sender, target, 0, NULL, 0, NULL, A_AMHEAR, args,
00794 nargs);
00795 }
00796 did_it(sender, target, 0, NULL, 0, NULL, A_AAHEAR, args, nargs);
00797 mudstate.nHearNest--;
00798 }
00799
00800
00801
00802 if (pass_listen)
00803 {
00804 for (i = 0; i < nargs; i++)
00805 {
00806 if (args[i] != NULL)
00807 {
00808 free_lbuf(args[i]);
00809 }
00810 }
00811 }
00812
00813
00814
00815 if ( (key & MSG_ME)
00816 && pass_uselock
00817 && sender != target
00818 && Monitor(target))
00819 {
00820 atr_match(target, sender, AMATCH_LISTEN, (char *)msg, (char *)msg,
00821 false);
00822 }
00823
00824
00825
00826 if ( (key & MSG_FWDLIST)
00827 && is_audible
00828 && check_filter(target, sender, A_FILTER, msg))
00829 {
00830 tbuff = dflt_from_msg(sender, target);
00831 buff = add_prefix(target, sender, A_PREFIX, msg, tbuff);
00832 free_lbuf(tbuff);
00833
00834 fp = fwdlist_get(target);
00835 if (fp)
00836 {
00837 for (i = 0; i < fp->count; i++)
00838 {
00839 recip = fp->data[i];
00840 if ( !Good_obj(recip)
00841 || recip == target)
00842 {
00843 continue;
00844 }
00845 notify_check(recip, sender, buff,
00846 MSG_ME | MSG_F_UP | MSG_F_CONTENTS | MSG_S_INSIDE);
00847 }
00848 }
00849 free_lbuf(buff);
00850 }
00851
00852
00853
00854 if (key & MSG_INV_EXITS)
00855 {
00856 DOLIST(obj, Exits(target))
00857 {
00858 recip = Location(obj);
00859 if ( Audible(obj)
00860 && ( recip != target
00861 && check_filter(obj, sender, A_FILTER, msg)))
00862 {
00863 buff = add_prefix(obj, target, A_PREFIX, msg,
00864 "From a distance,");
00865 notify_check(recip, sender, buff,
00866 MSG_ME | MSG_F_UP | MSG_F_CONTENTS | MSG_S_INSIDE);
00867 free_lbuf(buff);
00868 }
00869 }
00870 }
00871
00872
00873
00874 if ( has_neighbors
00875 && ( (key & MSG_NBR_EXITS)
00876 || ( (key & MSG_NBR_EXITS_A)
00877 && is_audible)))
00878 {
00879
00880
00881
00882 if (key & MSG_S_INSIDE)
00883 {
00884 tbuff = dflt_from_msg(sender, target);
00885 buff = add_prefix(target, sender, A_PREFIX, msg, tbuff);
00886 free_lbuf(tbuff);
00887 }
00888 else
00889 {
00890 buff = (char *)msg;
00891 }
00892
00893 DOLIST(obj, Exits(Location(target)))
00894 {
00895 recip = Location(obj);
00896 if ( Good_obj(recip)
00897 && Audible(obj)
00898 && recip != targetloc
00899 && recip != target
00900 && check_filter(obj, sender, A_FILTER, msg))
00901 {
00902 tbuff = add_prefix(obj, target, A_PREFIX, buff,
00903 "From a distance,");
00904 notify_check(recip, sender, tbuff,
00905 MSG_ME | MSG_F_UP | MSG_F_CONTENTS | MSG_S_INSIDE);
00906 free_lbuf(tbuff);
00907 }
00908 }
00909 if (key & MSG_S_INSIDE)
00910 {
00911 free_lbuf(buff);
00912 }
00913 }
00914
00915
00916
00917 if ( ( (key & MSG_INV)
00918 || ( (key & MSG_INV_L)
00919 && pass_listen))
00920 && check_filter(target, sender, A_INFILTER, msg))
00921 {
00922
00923
00924 if (key & MSG_S_OUTSIDE)
00925 {
00926 buff = add_prefix(target, sender, A_INPREFIX, msg, "");
00927 }
00928 else
00929 {
00930 buff = (char *)msg;
00931 }
00932 DOLIST(obj, Contents(target))
00933 {
00934 if (obj != target)
00935 {
00936 notify_check(obj, sender, buff,
00937 MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE | key & MSG_HTML);
00938 }
00939 }
00940 if (key & MSG_S_OUTSIDE)
00941 {
00942 free_lbuf(buff);
00943 }
00944 }
00945
00946
00947
00948 if ( has_neighbors
00949 && ( (key & MSG_NBR)
00950 || ( (key & MSG_NBR_A)
00951 && is_audible
00952 && check_filter(target, sender, A_FILTER, msg))))
00953 {
00954 if (key & MSG_S_INSIDE)
00955 {
00956 tbuff = dflt_from_msg(sender, target);
00957 buff = add_prefix(target, sender, A_PREFIX, msg, "");
00958 free_lbuf(tbuff);
00959 }
00960 else
00961 {
00962 buff = (char *)msg;
00963 }
00964 DOLIST(obj, Contents(targetloc))
00965 {
00966 if ( obj != target
00967 && obj != targetloc)
00968 {
00969 notify_check(obj, sender, buff,
00970 MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE);
00971 }
00972 }
00973 if (key & MSG_S_INSIDE)
00974 {
00975 free_lbuf(buff);
00976 }
00977 }
00978
00979
00980
00981 if ( has_neighbors
00982 && ( (key & MSG_LOC)
00983 || ( (key & MSG_LOC_A)
00984 && is_audible
00985 && check_filter(target, sender, A_FILTER, msg))))
00986 {
00987 if (key & MSG_S_INSIDE)
00988 {
00989 tbuff = dflt_from_msg(sender, target);
00990 buff = add_prefix(target, sender, A_PREFIX, msg, tbuff);
00991 free_lbuf(tbuff);
00992 }
00993 else
00994 {
00995 buff = (char *)msg;
00996 }
00997 notify_check(targetloc, sender, buff,
00998 MSG_ME | MSG_F_UP | MSG_S_INSIDE);
00999 if (key & MSG_S_INSIDE)
01000 {
01001 free_lbuf(buff);
01002 }
01003 }
01004 }
01005 if (msg_ns)
01006 {
01007 free_lbuf(msg_ns);
01008 }
01009 mudstate.ntfy_nest_lev--;
01010 }
01011
01012 void notify_except(dbref loc, dbref player, dbref exception, const char *msg, int key)
01013 {
01014 dbref first;
01015
01016 if (loc != exception)
01017 {
01018 notify_check(loc, player, msg, (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A | key));
01019 }
01020 DOLIST(first, Contents(loc))
01021 {
01022 if (first != exception)
01023 {
01024 notify_check(first, player, msg, (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE | key));
01025 }
01026 }
01027 }
01028
01029 void notify_except2(dbref loc, dbref player, dbref exc1, dbref exc2, const char *msg)
01030 {
01031 dbref first;
01032
01033 if ( loc != exc1
01034 && loc != exc2)
01035 {
01036 notify_check(loc, player, msg, (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A));
01037 }
01038 DOLIST(first, Contents(loc))
01039 {
01040 if ( first != exc1
01041 && first != exc2)
01042 {
01043 notify_check(first, player, msg, (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE));
01044 }
01045 }
01046 }
01047
01048
01049
01050
01051
01052 static void report_timecheck
01053 (
01054 dbref player,
01055 bool yes_screen,
01056 bool yes_log,
01057 bool yes_clear
01058 )
01059 {
01060 int thing, obj_counted;
01061 CLinearTimeDelta ltdPeriod, ltdTotal;
01062 CLinearTimeAbsolute ltaNow;
01063 ltaNow.GetUTC();
01064 ltdPeriod = ltaNow - mudstate.cpu_count_from;
01065
01066 if ( yes_log
01067 && (LOG_TIMEUSE & mudconf.log_options))
01068 {
01069 start_log("OBJ", "CPU");
01070 log_name(player);
01071 log_text(" checks object time use over ");
01072 log_number(ltdPeriod.ReturnSeconds());
01073 log_text(" seconds" ENDLINE);
01074 }
01075 else
01076 {
01077 yes_log = false;
01078 STARTLOG(LOG_ALWAYS, "WIZ", "TIMECHECK");
01079 log_name(player);
01080 log_text(" checks object time use over ");
01081 log_number(ltdPeriod.ReturnSeconds());
01082 log_text(" seconds");
01083 ENDLOG;
01084 }
01085
01086 obj_counted = 0;
01087 ltdTotal.Set100ns(0);
01088
01089
01090
01091 DO_WHOLE_DB(thing)
01092 {
01093 CLinearTimeDelta <d = db[thing].cpu_time_used;
01094 if (ltd.Return100ns())
01095 {
01096 ltdTotal += ltd;
01097 long used_msecs = ltd.ReturnMilliseconds();
01098 obj_counted++;
01099 if (yes_log)
01100 {
01101 Log.tinyprintf("#%d\t%ld" ENDLINE, thing, used_msecs);
01102 }
01103 if (yes_screen)
01104 {
01105 raw_notify(player, tprintf("#%d\t%ld", thing, used_msecs));
01106 }
01107 if (yes_clear)
01108 {
01109 ltd.Set100ns(0);
01110 }
01111 }
01112 }
01113
01114 long lTotal = ltdTotal.ReturnMilliseconds();
01115 long lPeriod = ltdPeriod.ReturnSeconds();
01116
01117 if (yes_screen)
01118 {
01119 raw_notify(player,
01120 tprintf("Counted %d objects using %ld msecs over %d seconds.",
01121 obj_counted, lTotal, lPeriod));
01122 }
01123
01124 if (yes_log)
01125 {
01126 Log.tinyprintf("Counted %d objects using %ld msecs over %d seconds.",
01127 obj_counted, lTotal, lPeriod);
01128 end_log();
01129 }
01130
01131 if (yes_clear)
01132 {
01133 mudstate.cpu_count_from = ltaNow;
01134 }
01135 }
01136
01137 void do_timecheck(dbref executor, dbref caller, dbref enactor, int key)
01138 {
01139 UNUSED_PARAMETER(caller);
01140 UNUSED_PARAMETER(enactor);
01141
01142 bool yes_screen, yes_log, yes_clear;
01143
01144 yes_screen = yes_log = yes_clear = false;
01145
01146 if (key == 0)
01147 {
01148
01149
01150 yes_screen = true;
01151 yes_clear = true;
01152 }
01153 else
01154 {
01155 if (key & TIMECHK_RESET)
01156 {
01157 yes_clear = true;
01158 }
01159 if (key & TIMECHK_SCREEN)
01160 {
01161 yes_screen = true;
01162 }
01163 if (key & TIMECHK_LOG)
01164 {
01165 yes_log = true;
01166 }
01167 }
01168 report_timecheck(executor, yes_screen, yes_log, yes_clear);
01169 }
01170
01171 void do_shutdown
01172 (
01173 dbref executor,
01174 dbref caller,
01175 dbref enactor,
01176 int key,
01177 char *message
01178 )
01179 {
01180 UNUSED_PARAMETER(caller);
01181 UNUSED_PARAMETER(enactor);
01182
01183 if (!Can_SiteAdmin(executor))
01184 {
01185 notify(executor, NOPERM_MESSAGE);
01186 return;
01187 }
01188
01189 raw_broadcast(0, "GAME: Shutdown by %s", Name(Owner(executor)));
01190 STARTLOG(LOG_ALWAYS, "WIZ", "SHTDN");
01191 log_text("Shutdown by ");
01192 log_name(executor);
01193 ENDLOG;
01194
01195 STARTLOG(LOG_ALWAYS, "WIZ", "SHTDN");
01196 log_text("Shutdown status: ");
01197 log_text(message);
01198 ENDLOG;
01199
01200 int fd = open(mudconf.status_file, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
01201 if (fd != -1)
01202 {
01203 write(fd, message, strlen(message));
01204 write(fd, ENDLINE, sizeof(ENDLINE)-1);
01205 DebugTotalFiles++;
01206 if (close(fd) == 0)
01207 {
01208 DebugTotalFiles--;
01209 }
01210 }
01211
01212
01213
01214
01215
01216 if (key & SHUTDN_PANIC)
01217 {
01218
01219
01220 emergency_shutdown();
01221
01222 local_presync_database();
01223
01224
01225
01226 #ifndef MEMORY_BASED
01227
01228
01229 al_store();
01230 #endif // MEMORY_BASED
01231
01232 pcache_sync();
01233 SYNC;
01234 CLOSE;
01235
01236 STARTLOG(LOG_ALWAYS, "DMP", "PANIC");
01237 log_text("Panic dump: ");
01238 log_text(mudconf.crashdb);
01239 ENDLOG;
01240 dump_database_internal(DUMP_I_PANIC);
01241 STARTLOG(LOG_ALWAYS, "DMP", "DONE");
01242 log_text("Panic dump complete: ");
01243 log_text(mudconf.crashdb);
01244 ENDLOG;
01245 }
01246
01247
01248
01249 mudstate.shutdown_flag = true;
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268 typedef struct
01269 {
01270 char **ppszOutputBase;
01271 char szOutputSuffix[14];
01272 bool bUseTemporary;
01273 int fType;
01274 char *pszErrorMessage;
01275 } DUMP_PROCEDURE;
01276
01277 static DUMP_PROCEDURE DumpProcedures[NUM_DUMP_TYPES] =
01278 {
01279 { 0, "" , false, 0, "" },
01280 { &mudconf.crashdb, "" , false, UNLOAD_VERSION | UNLOAD_FLAGS, "Opening crash file" },
01281 { &mudconf.indb, "" , true, OUTPUT_VERSION | OUTPUT_FLAGS, "Opening input file" },
01282 { &mudconf.indb, ".FLAT" , false, UNLOAD_VERSION | UNLOAD_FLAGS, "Opening flatfile" },
01283 { &mudconf.indb, ".SIG" , false, UNLOAD_VERSION | UNLOAD_FLAGS, "Opening signalled flatfile"}
01284 };
01285
01286 #ifdef WIN32
01287 #define POPEN_READ_OP "rb"
01288 #define POPEN_WRITE_OP "wb"
01289 #else // WIN32
01290 #define POPEN_READ_OP "r"
01291 #define POPEN_WRITE_OP "w"
01292 #endif // WIN32
01293
01294 void dump_database_internal(int dump_type)
01295 {
01296 char tmpfile[SIZEOF_PATHNAME+32];
01297 char outfn[SIZEOF_PATHNAME+32];
01298 char prevfile[SIZEOF_PATHNAME+32];
01299 FILE *f;
01300
01301 if ( dump_type < 0
01302 || NUM_DUMP_TYPES <= dump_type)
01303 {
01304 return;
01305 }
01306
01307 bool bPotentialConflicts = false;
01308 #ifndef WIN32
01309
01310
01311
01312
01313
01314 if ( mudstate.dumping
01315 && ( dump_type == DUMP_I_PANIC
01316 || dump_type == DUMP_I_SIGNAL))
01317 {
01318 bPotentialConflicts = true;
01319 }
01320 #endif
01321
01322
01323
01324
01325 local_dump_database(dump_type);
01326
01327 if (0 < dump_type)
01328 {
01329 DUMP_PROCEDURE *dp = &DumpProcedures[dump_type];
01330
01331 sprintf(outfn, "%s%s", *(dp->ppszOutputBase), dp->szOutputSuffix);
01332 if (dp->bUseTemporary)
01333 {
01334 sprintf(tmpfile, "%s.#%d#", outfn, mudstate.epoch);
01335 RemoveFile(tmpfile);
01336 f = fopen(tmpfile, "wb");
01337 }
01338 else
01339 {
01340 RemoveFile(outfn);
01341 f = fopen(outfn, "wb");
01342 }
01343
01344 if (f)
01345 {
01346 DebugTotalFiles++;
01347 setvbuf(f, NULL, _IOFBF, 16384);
01348 db_write(f, F_MUX, dp->fType);
01349 if (fclose(f) == 0)
01350 {
01351 DebugTotalFiles--;
01352 }
01353
01354 if (dp->bUseTemporary)
01355 {
01356 ReplaceFile(tmpfile, outfn);
01357 }
01358 }
01359 else
01360 {
01361 log_perror("DMP", "FAIL", dp->pszErrorMessage, outfn);
01362 }
01363
01364 if (!bPotentialConflicts)
01365 {
01366 if (mudconf.have_mailer)
01367 {
01368 f = fopen(mudconf.mail_db, "wb");
01369 if (f)
01370 {
01371 DebugTotalFiles++;
01372 dump_mail(f);
01373 if (fclose(f) == 0)
01374 {
01375 DebugTotalFiles--;
01376 }
01377 }
01378 }
01379 if (mudconf.have_comsys)
01380 {
01381 save_comsys(mudconf.comsys_db);
01382 }
01383 }
01384 return;
01385 }
01386
01387
01388
01389 if (mudconf.compress_db)
01390 {
01391 sprintf(prevfile, "%s.prev.gz", mudconf.outdb);
01392 sprintf(tmpfile, "%s.#%d#.gz", mudconf.outdb, mudstate.epoch - 1);
01393 RemoveFile(tmpfile);
01394 sprintf(tmpfile, "%s.#%d#.gz", mudconf.outdb, mudstate.epoch);
01395 strcpy(outfn, mudconf.outdb);
01396 strcat(outfn, ".gz");
01397
01398 f = popen(tprintf("%s > %s", mudconf.compress, tmpfile), POPEN_WRITE_OP);
01399 if (f)
01400 {
01401 DebugTotalFiles++;
01402 setvbuf(f, NULL, _IOFBF, 16384);
01403 db_write(f, F_MUX, OUTPUT_VERSION | OUTPUT_FLAGS);
01404 if (pclose(f) != -1)
01405 {
01406 DebugTotalFiles--;
01407 }
01408 ReplaceFile(outfn, prevfile);
01409 if (ReplaceFile(tmpfile, outfn) < 0)
01410 {
01411 log_perror("SAV", "FAIL", "Renaming output file to DB file", tmpfile);
01412 }
01413 }
01414 else
01415 {
01416 log_perror("SAV", "FAIL", "Opening", tmpfile);
01417 }
01418 }
01419 else
01420 {
01421 sprintf(prevfile, "%s.prev", mudconf.outdb);
01422 sprintf(tmpfile, "%s.#%d#", mudconf.outdb, mudstate.epoch - 1);
01423 RemoveFile(tmpfile);
01424 sprintf(tmpfile, "%s.#%d#", mudconf.outdb, mudstate.epoch);
01425
01426 f = fopen(tmpfile, "wb");
01427 if (f)
01428 {
01429 DebugTotalFiles++;
01430 setvbuf(f, NULL, _IOFBF, 16384);
01431 db_write(f, F_MUX, OUTPUT_VERSION | OUTPUT_FLAGS);
01432 if (fclose(f) == 0)
01433 {
01434 DebugTotalFiles--;
01435 }
01436 ReplaceFile(mudconf.outdb, prevfile);
01437 if (ReplaceFile(tmpfile, mudconf.outdb) < 0)
01438 {
01439 log_perror("SAV", "FAIL", "Renaming output file to DB file", tmpfile);
01440 }
01441 }
01442 else
01443 {
01444 log_perror("SAV", "FAIL", "Opening", tmpfile);
01445 }
01446 }
01447
01448 if (mudconf.have_mailer)
01449 {
01450 f = fopen(mudconf.mail_db, "wb");
01451 if (f)
01452 {
01453 DebugTotalFiles++;
01454 dump_mail(f);
01455 if (fclose(f) == 0)
01456 {
01457 DebugTotalFiles--;
01458 }
01459 }
01460 }
01461
01462 if (mudconf.have_comsys)
01463 {
01464 save_comsys(mudconf.comsys_db);
01465 }
01466 }
01467
01468 static void dump_database(void)
01469 {
01470 char *buff;
01471
01472 mudstate.epoch++;
01473
01474 #ifndef WIN32
01475 if (mudstate.dumping)
01476 {
01477 STARTLOG(LOG_DBSAVES, "DMP", "DUMP");
01478 log_text("Waiting on previously-forked child before dumping... ");
01479 ENDLOG;
01480
01481 while (mudstate.dumping)
01482 {
01483
01484
01485
01486 MuxAlarm.Sleep(time_1s);
01487 }
01488 }
01489 mudstate.dumping = true;
01490 mudstate.dumped = 0;
01491 #endif
01492 buff = alloc_mbuf("dump_database");
01493 sprintf(buff, "%s.#%d#", mudconf.outdb, mudstate.epoch);
01494
01495 STARTLOG(LOG_DBSAVES, "DMP", "DUMP");
01496 log_text("Dumping: ");
01497 log_text(buff);
01498 ENDLOG;
01499
01500 local_presync_database();
01501
01502 #ifndef MEMORY_BASED
01503
01504
01505 al_store();
01506 #endif // MEMORY_BASED
01507
01508 pcache_sync();
01509
01510 dump_database_internal(DUMP_I_NORMAL);
01511 SYNC;
01512
01513 STARTLOG(LOG_DBSAVES, "DMP", "DONE")
01514 log_text("Dump complete: ");
01515 log_text(buff);
01516 ENDLOG;
01517 free_mbuf(buff);
01518
01519 #ifndef WIN32
01520
01521
01522
01523 mudstate.dumping = false;
01524 local_dump_complete_signal();
01525 #endif
01526 }
01527
01528 void fork_and_dump(int key)
01529 {
01530 #ifndef WIN32
01531 static volatile bool bRequestAccepted = false;
01532
01533
01534
01535
01536 if ( bRequestAccepted
01537 || mudstate.dumping)
01538 {
01539 return;
01540 }
01541 bRequestAccepted = true;
01542 #endif
01543
01544
01545
01546 if (key == 0)
01547 {
01548 key = DUMP_TEXT+DUMP_STRUCT;
01549 }
01550
01551 if (*mudconf.dump_msg)
01552 {
01553 raw_broadcast(0, "%s", mudconf.dump_msg);
01554 }
01555 check_mail_expiration();
01556 char *buff = alloc_lbuf("fork_and_dump");
01557 if (key & (DUMP_TEXT|DUMP_STRUCT))
01558 {
01559 STARTLOG(LOG_DBSAVES, "DMP", "CHKPT");
01560 if (key & DUMP_TEXT)
01561 {
01562 log_text("SYNCing");
01563 if (key & DUMP_STRUCT)
01564 {
01565 log_text(" and ");
01566 }
01567 }
01568 if (key & DUMP_STRUCT)
01569 {
01570 mudstate.epoch++;
01571 sprintf(buff, "%s.#%d#", mudconf.outdb, mudstate.epoch);
01572 log_text("Checkpointing: ");
01573 log_text(buff);
01574 }
01575 ENDLOG;
01576 }
01577 if (key & DUMP_FLATFILE)
01578 {
01579 STARTLOG(LOG_DBSAVES, "DMP", "FLAT");
01580 log_text("Creating flatfile: ");
01581 sprintf(buff, "%s.FLAT", mudconf.outdb);
01582 log_text(buff);
01583 ENDLOG;
01584 }
01585 free_lbuf(buff);
01586
01587 local_presync_database();
01588
01589 #ifndef MEMORY_BASED
01590
01591
01592 al_store();
01593 #endif // MEMORY_BASED
01594
01595 pcache_sync();
01596 SYNC;
01597
01598 #ifndef WIN32
01599 mudstate.write_protect = true;
01600 int child = 0;
01601 bool bChildExists = false;
01602 mudstate.dumping = true;
01603 mudstate.dumped = 0;
01604 bool bAttemptFork = mudconf.fork_dump;
01605 #if !defined(HAVE_PREAD) \
01606 || !defined(HAVE_PWRITE)
01607 if (key & DUMP_FLATFILE)
01608 {
01609
01610
01611
01612 bAttemptFork = false;
01613 }
01614 #endif // !HAVE_PREAD !HAVE_PWRITE
01615 #endif // WIN32
01616 if (key & (DUMP_STRUCT|DUMP_FLATFILE))
01617 {
01618 #ifndef WIN32
01619 if (bAttemptFork)
01620 {
01621 child = fork();
01622 }
01623 if (child == 0)
01624 {
01625
01626
01627
01628 MuxAlarm.Clear();
01629 #endif
01630 if (key & DUMP_STRUCT)
01631 {
01632 dump_database_internal(DUMP_I_NORMAL);
01633 }
01634 if (key & DUMP_FLATFILE)
01635 {
01636 dump_database_internal(DUMP_I_FLAT);
01637 }
01638 #ifndef WIN32
01639 if (mudconf.fork_dump)
01640 {
01641 _exit(0);
01642 }
01643 }
01644 else if (child < 0)
01645 {
01646 log_perror("DMP", "FORK", NULL, "fork()");
01647 }
01648 else
01649 {
01650 mudstate.dumper = child;
01651 if (mudstate.dumper == mudstate.dumped)
01652 {
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663 mudstate.dumper = 0;
01664 mudstate.dumped = 0;
01665 }
01666 else
01667 {
01668 bChildExists = true;
01669 }
01670 }
01671 #endif
01672 }
01673
01674 #ifndef WIN32
01675 mudstate.write_protect = false;
01676 if (!bChildExists)
01677 {
01678
01679
01680
01681
01682
01683 mudstate.dumper = 0;
01684 mudstate.dumping = false;
01685 local_dump_complete_signal();
01686 }
01687 bRequestAccepted = false;
01688 #endif
01689
01690 if (*mudconf.postdump_msg)
01691 {
01692 raw_broadcast(0, "%s", mudconf.postdump_msg);
01693 }
01694 }
01695
01696 #define LOAD_GAME_SUCCESS 0
01697 #define LOAD_GAME_NO_INPUT_DB (-1)
01698 #define LOAD_GAME_CANNOT_OPEN (-2)
01699 #define LOAD_GAME_LOADING_PROBLEM (-3)
01700
01701 #ifdef MEMORY_BASED
01702 static int load_game(void)
01703 #else // MEMORY_BASED
01704 static int load_game(int ccPageFile)
01705 #endif // MEMORY_BASED
01706 {
01707 FILE *f = NULL;
01708 char infile[SIZEOF_PATHNAME+8];
01709 struct stat statbuf;
01710 int db_format, db_version, db_flags;
01711
01712 bool compressed = false;
01713
01714 if (mudconf.compress_db)
01715 {
01716 strcpy(infile, mudconf.indb);
01717 strcat(infile, ".gz");
01718 if (stat(infile, &statbuf) == 0)
01719 {
01720 f = popen(tprintf(" %s < %s", mudconf.uncompress, infile), POPEN_READ_OP);
01721 if (f != NULL)
01722 {
01723 DebugTotalFiles++;
01724 compressed = true;
01725 }
01726 }
01727 }
01728
01729 if (!compressed)
01730 {
01731 strcpy(infile, mudconf.indb);
01732 if (stat(infile, &statbuf) != 0)
01733 {
01734
01735
01736
01737 return LOAD_GAME_NO_INPUT_DB;
01738 }
01739 if ((f = fopen(infile, "rb")) == NULL)
01740 {
01741 return LOAD_GAME_CANNOT_OPEN;
01742 }
01743 DebugTotalFiles++;
01744 setvbuf(f, NULL, _IOFBF, 16384);
01745 }
01746
01747
01748
01749 STARTLOG(LOG_STARTUP, "INI", "LOAD")
01750 log_text("Loading: ");
01751 log_text(infile);
01752 ENDLOG
01753 if (db_read(f, &db_format, &db_version, &db_flags) < 0)
01754 {
01755
01756
01757 if (compressed)
01758 {
01759 if (pclose(f) != -1)
01760 {
01761 DebugTotalFiles--;
01762 }
01763 }
01764 else
01765 {
01766 if (fclose(f) == 0)
01767 {
01768 DebugTotalFiles--;
01769 }
01770 }
01771 f = 0;
01772
01773 STARTLOG(LOG_ALWAYS, "INI", "FATAL")
01774 log_text("Error loading ");
01775 log_text(infile);
01776 ENDLOG
01777 return LOAD_GAME_LOADING_PROBLEM;
01778 }
01779
01780
01781
01782 if (compressed)
01783 {
01784 if (pclose(f) != -1)
01785 {
01786 DebugTotalFiles--;
01787 }
01788 }
01789 else
01790 {
01791 if (fclose(f) == 0)
01792 {
01793 DebugTotalFiles--;
01794 }
01795 }
01796 f = 0;
01797
01798 #ifndef MEMORY_BASED
01799 if (db_flags & V_DATABASE)
01800 {
01801
01802
01803 if (ccPageFile == HF_OPEN_STATUS_NEW)
01804 {
01805 STARTLOG(LOG_STARTUP, "INI", "LOAD");
01806 log_text("Attributes are not present in either the input file or the attribute database.");
01807 ENDLOG;
01808 }
01809 }
01810 else
01811 {
01812
01813
01814 if (ccPageFile == HF_OPEN_STATUS_OLD)
01815 {
01816 STARTLOG(LOG_STARTUP, "INI", "LOAD");
01817 log_text("Attributes present in both the input file and the attribute database.");
01818 ENDLOG;
01819 }
01820 }
01821 #endif // !MEMORY_BASED
01822
01823 if (mudconf.have_comsys)
01824 {
01825 load_comsys(mudconf.comsys_db);
01826 }
01827
01828 if (mudconf.have_mailer)
01829 {
01830 f = fopen(mudconf.mail_db, "rb");
01831 if (f)
01832 {
01833 DebugTotalFiles++;
01834 setvbuf(f, NULL, _IOFBF, 16384);
01835 Log.tinyprintf("LOADING: %s" ENDLINE, mudconf.mail_db);
01836 load_mail(f);
01837 Log.tinyprintf("LOADING: %s (done)" ENDLINE, mudconf.mail_db);
01838 if (fclose(f) == 0)
01839 {
01840 DebugTotalFiles--;
01841 }
01842 f = 0;
01843 }
01844 }
01845 STARTLOG(LOG_STARTUP, "INI", "LOAD");
01846 log_text("Load complete.");
01847 ENDLOG;
01848
01849 return LOAD_GAME_SUCCESS;
01850 }
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862 bool list_check
01863 (
01864 dbref thing,
01865 dbref player,
01866 char type,
01867 char *str,
01868 char *raw_str,
01869 bool check_parent
01870 )
01871 {
01872 bool bMatch = false;
01873
01874 int limit = mudstate.db_top;
01875 while (NOTHING != thing)
01876 {
01877 #ifdef REALITY_LVLS
01878 if ((thing != player)
01879 && (!(No_Command(thing)))
01880 && IsReal(thing, player))
01881 #else
01882 if ( thing != player
01883 && !No_Command(thing))
01884 #endif
01885 {
01886 bMatch |= atr_match(thing, player, type, str, raw_str, check_parent);
01887 }
01888
01889
01890
01891 dbref next;
01892 if ( thing == (next = Next(thing))
01893 || --limit < 0
01894 || MuxAlarm.bAlarmed)
01895 {
01896 break;
01897 }
01898 thing = next;
01899 }
01900 return bMatch;
01901 }
01902
01903 bool Hearer(dbref thing)
01904 {
01905 if ( mudstate.inpipe
01906 && thing == mudstate.poutobj)
01907 {
01908 return true;
01909 }
01910
01911 if ( Connected(thing)
01912 || Puppet(thing)
01913 || H_Listen(thing))
01914 {
01915 return true;
01916 }
01917
01918 if (Monitor(thing))
01919 {
01920 if (mudstate.bfListens.IsSet(thing))
01921 {
01922 return true;
01923 }
01924 else if (mudstate.bfNoListens.IsSet(thing))
01925 {
01926 return false;
01927 }
01928 else
01929 {
01930 bool bFoundCommands = false;
01931
01932 char *buff = alloc_lbuf("Hearer");
01933 char *as;
01934 atr_push();
01935 for (int atr = atr_head(thing, &as); atr; atr = atr_next(&as))
01936 {
01937 ATTR *ap = atr_num(atr);
01938 if ( !ap
01939 || (ap->flags & AF_NOPROG))
01940 {
01941 continue;
01942 }
01943
01944 int aflags;
01945 dbref aowner;
01946 atr_get_str(buff, thing, atr, &aowner, &aflags);
01947
01948 if (aflags & AF_NOPROG)
01949 {
01950 continue;
01951 }
01952
01953 char *s = NULL;
01954 if ( AMATCH_CMD == buff[0]
01955 || AMATCH_LISTEN == buff[0])
01956 {
01957 s = strchr(buff+1, ':');
01958 if (s)
01959 {
01960 if (AMATCH_CMD == buff[0])
01961 {
01962 bFoundCommands = true;
01963 }
01964 else
01965 {
01966 free_lbuf(buff);
01967 atr_pop();
01968 mudstate.bfListens.Set(thing);
01969 return true;
01970 }
01971 }
01972 }
01973 }
01974 free_lbuf(buff);
01975 atr_pop();
01976
01977 mudstate.bfNoListens.Set(thing);
01978
01979 if (bFoundCommands)
01980 {
01981 mudstate.bfNoCommands.Clear(thing);
01982 mudstate.bfCommands.Set(thing);
01983 }
01984 else
01985 {
01986 mudstate.bfCommands.Clear(thing);
01987 mudstate.bfNoCommands.Set(thing);
01988 }
01989 }
01990 }
01991 return false;
01992 }
01993
01994 void do_readcache(dbref executor, dbref caller, dbref enactor, int key)
01995 {
01996 UNUSED_PARAMETER(caller);
01997 UNUSED_PARAMETER(enactor);
01998 UNUSED_PARAMETER(key);
01999
02000 helpindex_load(executor);
02001 fcache_load(executor);
02002 }
02003
02004 static void process_preload(void)
02005 {
02006 dbref thing, parent, aowner;
02007 int aflags, lev;
02008 char *tstr;
02009 FWDLIST *fp;
02010
02011 fp = (FWDLIST *) alloc_lbuf("process_preload.fwdlist");
02012 tstr = alloc_lbuf("process_preload.string");
02013 DO_WHOLE_DB(thing)
02014 {
02015
02016
02017 if (Going(thing))
02018 {
02019 continue;
02020 }
02021
02022 scheduler.RunTasks(10);
02023
02024
02025
02026 if (mudconf.run_startup)
02027 {
02028 ITER_PARENTS(thing, parent, lev)
02029 {
02030 if (Flags(thing) & HAS_STARTUP)
02031 {
02032 did_it(Owner(thing), thing, 0, NULL, 0, NULL, A_STARTUP,
02033 (char **)NULL, 0);
02034
02035
02036
02037 scheduler.RunTasks(10);
02038 break;
02039 }
02040 }
02041 }
02042
02043
02044
02045 if (H_Fwdlist(thing))
02046 {
02047 atr_get_str(tstr, thing, A_FORWARDLIST, &aowner, &aflags);
02048 if (*tstr)
02049 {
02050 fwdlist_load(fp, GOD, tstr);
02051 if (fp->count > 0)
02052 {
02053 fwdlist_set(thing, fp);
02054 }
02055 }
02056 }
02057 }
02058 free_lbuf(fp);
02059 free_lbuf(tstr);
02060 }
02061
02062 #ifndef MEMORY_BASED
02063
02064
02065
02066
02067
02068
02069 static void info(int fmt, int flags, int ver)
02070 {
02071 const char *cp;
02072
02073 if (fmt == F_MUX)
02074 {
02075 cp = "MUX";
02076 }
02077 else
02078 {
02079 cp = "*unknown*";
02080 }
02081 Log.tinyprintf("%s version %d:", cp, ver);
02082 if ((flags & MANDFLAGS) != MANDFLAGS)
02083 {
02084 Log.WriteString(" Unsupported flags");
02085 }
02086 if (flags & V_DATABASE)
02087 Log.WriteString(" Database");
02088 if (flags & V_ATRNAME)
02089 Log.WriteString(" AtrName");
02090 if (flags & V_ATRKEY)
02091 Log.WriteString(" AtrKey");
02092 if (flags & V_ATRMONEY)
02093 Log.WriteString(" AtrMoney");
02094 Log.WriteString("\n");
02095 }
02096
02097 static char *standalone_infile = NULL;
02098 static char *standalone_outfile = NULL;
02099 static char *standalone_basename = NULL;
02100 static bool standalone_check = false;
02101 static bool standalone_load = false;
02102 static bool standalone_unload = false;
02103
02104 static void dbconvert(void)
02105 {
02106 int setflags, clrflags, ver;
02107 int db_ver, db_format, db_flags;
02108
02109 Log.SetBasename("-");
02110 Log.StartLogging();
02111
02112 SeedRandomNumberGenerator();
02113
02114 pool_init(POOL_LBUF, LBUF_SIZE);
02115 pool_init(POOL_MBUF, MBUF_SIZE);
02116 pool_init(POOL_SBUF, SBUF_SIZE);
02117 pool_init(POOL_BOOL, sizeof(struct boolexp));
02118
02119 cf_init();
02120
02121
02122
02123 setflags = clrflags = ver = 0;
02124 bool do_redirect = false;
02125
02126 bool do_write = true;
02127 if (standalone_check)
02128 {
02129 do_write = false;
02130 }
02131 if (standalone_load)
02132 {
02133 clrflags = 0xffffffff;
02134 setflags = OUTPUT_FLAGS;
02135 ver = OUTPUT_VERSION;
02136 do_redirect = true;
02137 }
02138 else if (standalone_unload)
02139 {
02140 clrflags = 0xffffffff;
02141 setflags = UNLOAD_FLAGS;
02142 ver = UNLOAD_VERSION;
02143 }
02144
02145
02146
02147 init_attrtab();
02148
02149 char dirfile[SIZEOF_PATHNAME];
02150 char pagfile[SIZEOF_PATHNAME];
02151 strcpy(dirfile, standalone_basename);
02152 strcat(dirfile, ".dir");
02153 strcpy(pagfile, standalone_basename);
02154 strcat(pagfile, ".pag");
02155
02156 int cc = init_dbfile(dirfile, pagfile, 650);
02157 if (cc == HF_OPEN_STATUS_ERROR)
02158 {
02159 Log.tinyprintf("Can't open database in (%s, %s) files\n", dirfile, pagfile);
02160 exit(1);
02161 }
02162 else if (cc == HF_OPEN_STATUS_OLD)
02163 {
02164 if (setflags == OUTPUT_FLAGS)
02165 {
02166 Log.tinyprintf("Would overwrite existing database (%s, %s)\n", dirfile, pagfile);
02167 CLOSE;
02168 exit(1);
02169 }
02170 }
02171 else if (cc == HF_OPEN_STATUS_NEW)
02172 {
02173 if (setflags == UNLOAD_FLAGS)
02174 {
02175 Log.tinyprintf("Database (%s, %s) is empty.\n", dirfile, pagfile);
02176 CLOSE;
02177 exit(1);
02178 }
02179 }
02180
02181 FILE *fpIn = fopen(standalone_infile, "rb");
02182 if (!fpIn)
02183 {
02184 exit(1);
02185 }
02186
02187
02188
02189 if (do_redirect)
02190 {
02191 cache_redirect();
02192 }
02193 setvbuf(fpIn, NULL, _IOFBF, 16384);
02194 db_read(fpIn, &db_format, &db_ver, &db_flags);
02195 if (do_redirect)
02196 {
02197 cache_pass2();
02198 }
02199 Log.WriteString("Input: ");
02200 info(db_format, db_flags, db_ver);
02201
02202 if (standalone_check)
02203 {
02204 do_dbck(NOTHING, NOTHING, NOTHING, DBCK_FULL);
02205 }
02206 fclose(fpIn);
02207
02208 if (do_write)
02209 {
02210 FILE *fpOut = fopen(standalone_outfile, "wb");
02211 if (!fpOut)
02212 {
02213 exit(1);
02214 }
02215
02216 db_flags = (db_flags & ~clrflags) | setflags;
02217 if (db_format != F_MUX)
02218 {
02219 db_ver = 3;
02220 }
02221 if (ver != 0)
02222 {
02223 db_ver = ver;
02224 }
02225 Log.WriteString("Output: ");
02226 info(F_MUX, db_flags, db_ver);
02227 setvbuf(fpOut, NULL, _IOFBF, 16384);
02228 #ifndef MEMORY_BASED
02229
02230
02231 al_store();
02232 #endif // MEMORY_BASED
02233 db_write(fpOut, F_MUX, db_ver | db_flags);
02234 fclose(fpOut);
02235 }
02236 CLOSE;
02237 db_free();
02238 exit(0);
02239 }
02240 #endif // MEMORY_BASED
02241
02242 static void write_pidfile(const char *pFilename)
02243 {
02244 FILE *fp = fopen(pFilename, "wb");
02245 if (fp)
02246 {
02247 fprintf(fp, "%d" ENDLINE, game_pid);
02248 fclose(fp);
02249 }
02250 else
02251 {
02252 STARTLOG(LOG_ALWAYS, "PID", "FAIL");
02253 Log.tinyprintf("Failed to write pidfile %s\n", pFilename);
02254 ENDLOG;
02255 }
02256 }
02257
02258 long DebugTotalFiles = 3;
02259 long DebugTotalSockets = 0;
02260 #ifdef WIN32
02261 long DebugTotalThreads = 1;
02262 long DebugTotalSemaphores = 0;
02263 #endif
02264 #ifdef MEMORY_ACCOUNTING
02265 long DebugTotalMemory = 0;
02266 #endif
02267
02268 #define CLI_DO_CONFIG_FILE CLI_USER+0
02269 #define CLI_DO_MINIMAL CLI_USER+1
02270 #define CLI_DO_VERSION CLI_USER+2
02271 #define CLI_DO_USAGE CLI_USER+3
02272 #define CLI_DO_INFILE CLI_USER+4
02273 #define CLI_DO_OUTFILE CLI_USER+5
02274 #define CLI_DO_CHECK CLI_USER+6
02275 #define CLI_DO_LOAD CLI_USER+7
02276 #define CLI_DO_UNLOAD CLI_USER+8
02277 #define CLI_DO_BASENAME CLI_USER+9
02278 #define CLI_DO_PID_FILE CLI_USER+10
02279 #define CLI_DO_ERRORPATH CLI_USER+11
02280
02281 static bool bMinDB = false;
02282 static bool bSyntaxError = false;
02283 static char *conffile = NULL;
02284 static bool bVersion = false;
02285 static char *pErrorBasename = "";
02286 static bool bServerOption = false;
02287
02288 #ifdef MEMORY_BASED
02289 #define NUM_CLI_OPTIONS 6
02290 #else
02291 #define NUM_CLI_OPTIONS 12
02292 #endif
02293
02294 static CLI_OptionEntry OptionTable[NUM_CLI_OPTIONS] =
02295 {
02296 { "c", CLI_REQUIRED, CLI_DO_CONFIG_FILE },
02297 { "s", CLI_NONE, CLI_DO_MINIMAL },
02298 { "v", CLI_NONE, CLI_DO_VERSION },
02299 { "h", CLI_NONE, CLI_DO_USAGE },
02300 #ifndef MEMORY_BASED
02301 { "i", CLI_REQUIRED, CLI_DO_INFILE },
02302 { "o", CLI_REQUIRED, CLI_DO_OUTFILE },
02303 { "k", CLI_NONE, CLI_DO_CHECK },
02304 { "l", CLI_NONE, CLI_DO_LOAD },
02305 { "u", CLI_NONE, CLI_DO_UNLOAD },
02306 { "d", CLI_REQUIRED, CLI_DO_BASENAME },
02307 #endif // MEMORY_BASED
02308 { "p", CLI_REQUIRED, CLI_DO_PID_FILE },
02309 { "e", CLI_REQUIRED, CLI_DO_ERRORPATH }
02310 };
02311
02312 static void CLI_CallBack(CLI_OptionEntry *p, char *pValue)
02313 {
02314 if (p)
02315 {
02316 switch (p->m_Unique)
02317 {
02318 case CLI_DO_PID_FILE:
02319 bServerOption = true;
02320 mudconf.pid_file = pValue;
02321 break;
02322
02323 case CLI_DO_CONFIG_FILE:
02324 bServerOption = true;
02325 conffile = pValue;
02326 break;
02327
02328 case CLI_DO_MINIMAL:
02329 bServerOption = true;
02330 bMinDB = true;
02331 break;
02332
02333 case CLI_DO_VERSION:
02334 bServerOption = true;
02335 bVersion = true;
02336 break;
02337
02338 case CLI_DO_ERRORPATH:
02339 bServerOption = true;
02340 pErrorBasename = pValue;
02341 break;
02342
02343 #ifndef MEMORY_BASED
02344 case CLI_DO_INFILE:
02345 mudstate.bStandAlone = true;
02346 standalone_infile = pValue;
02347 break;
02348
02349 case CLI_DO_OUTFILE:
02350 mudstate.bStandAlone = true;
02351 standalone_outfile = pValue;
02352 break;
02353
02354 case CLI_DO_CHECK:
02355 mudstate.bStandAlone = true;
02356 standalone_check = true;
02357 break;
02358
02359 case CLI_DO_LOAD:
02360 mudstate.bStandAlone = true;
02361 standalone_load = true;
02362 break;
02363
02364 case CLI_DO_UNLOAD:
02365 mudstate.bStandAlone = true;
02366 standalone_unload = true;
02367 break;
02368
02369 case CLI_DO_BASENAME:
02370 mudstate.bStandAlone = true;
02371 standalone_basename = pValue;
02372 break;
02373 #endif
02374
02375 case CLI_DO_USAGE:
02376 default:
02377 bSyntaxError = true;
02378 break;
02379 }
02380 }
02381 else
02382 {
02383 bSyntaxError = true;
02384 }
02385 }
02386
02387 #if defined(__INTEL_COMPILER)
02388
02389 #define CPU_FD_ID 0x00200000UL
02390
02391 #define CPUID_0 0
02392
02393
02394
02395 #define INTEL_MFGSTR0 'uneG'
02396 #define INTEL_MFGSTR1 'letn'
02397 #define INTEL_MFGSTR2 'Ieni'
02398
02399
02400
02401 #define AMD_MFGSTR0 'htuA'
02402 #define AMD_MFGSTR1 'DMAc'
02403 #define AMD_MFGSTR2 'itne'
02404
02405 #define CPUID_1 1
02406
02407 #define CPU_STEPPING(x) ((x ) & 0x00000000F)
02408 #define CPU_MODEL(x) ((x >> 4) & 0x00000000F)
02409 #define CPU_FAMILY(x) ((x >> 8) & 0x00000000F)
02410 #define CPU_TYPE(x) ((x >> 12) & 0x00000000F)
02411 #define CPU_EXTMODEL(x) ((x >> 16) & 0x00000000F)
02412 #define CPU_EXTFAMILY(x) ((x >> 20) & 0x00000000F)
02413
02414 #define CPU_FEATURE_MMX 0x00800000UL
02415 #define CPU_FEATURE_FSXR 0x01000000UL
02416 #define CPU_FEATURE_SSE 0x02000000UL
02417 #define CPU_FEATURE_SSE2 0x04000000UL
02418 #define CPU_MSR_SSE3 0x00000001UL
02419
02420
02421
02422
02423
02424
02425
02426 #define CPU_TYPE_UNSPECIALIZED 0x00000001UL
02427 #define CPU_TYPE_FAMILY_5 0x00000002UL
02428 #define CPU_TYPE_FAMILY_6 0x00000004UL
02429 #define CPU_TYPE_FAMILY_5_MMX 0x00000008UL
02430 #define CPU_TYPE_FAMILY_6_MMX 0x00000010UL
02431 #define CPU_TYPE_FAMILY_6_MMX_FSXR 0x00000020UL
02432 #define CPU_TYPE_FAMILY_6_MMX_FSXR_SSE_OLDOS 0x00000040UL
02433 #define CPU_TYPE_FAMILY_6_MMX_FSXR_SSE 0x00000080UL
02434 #define CPU_TYPE_FAMILY_F_SSE2_OLDOS 0x00000100UL
02435 #define CPU_TYPE_FAMILY_F_SSE2 0x00000200UL
02436 #define CPU_TYPE_FAMILY_6_MMX_FSXR_SSE2 0x00000400UL
02437 #define CPU_TYPE_FAMILY_6_MMX_FSXR_SSE3 0x00000800UL
02438 #define CPU_TYPE_FAMILY_F_SSE3 0x00000800UL
02439
02440 static void cpu_init(void)
02441 {
02442 UINT32 dwCPUID;
02443
02444
02445
02446 __asm
02447 {
02448
02449
02450 pushfd
02451 pop eax
02452 mov dwCPUID,eax
02453
02454
02455
02456 xor eax,CPU_FD_ID
02457 push eax
02458 popfd
02459
02460
02461
02462 pushfd
02463 pop eax
02464 xor dwCPUID,eax
02465 }
02466
02467
02468
02469 if (CPU_FD_ID != dwCPUID)
02470 {
02471
02472
02473 __intel_cpu_indicator = CPU_TYPE_UNSPECIALIZED;
02474 return;
02475 }
02476
02477 UINT32 dwHighest;
02478 UINT32 dwMfgStr0;
02479 UINT32 dwMfgStr1;
02480 UINT32 dwMfgStr2;
02481
02482
02483
02484 __asm
02485 {
02486 mov eax,CPUID_0
02487 cpuid
02488 mov dwHighest,eax
02489 mov dwMfgStr0,ebx
02490 mov dwMfgStr1,ecx
02491 mov dwMfgStr2,edx
02492 }
02493
02494 if (0 == dwHighest)
02495 {
02496
02497
02498 __intel_cpu_indicator = CPU_TYPE_UNSPECIALIZED;
02499 return;
02500 }
02501
02502 typedef enum
02503 {
02504 Intel = 0,
02505 AMD
02506 } CPUMaker;
02507
02508 CPUMaker maker;
02509 if ( INTEL_MFGSTR0 == dwMfgStr0
02510 && INTEL_MFGSTR1 == dwMfgStr1
02511 && INTEL_MFGSTR2 == dwMfgStr2)
02512 {
02513 maker = Intel;
02514 }
02515 else if ( AMD_MFGSTR0 == dwMfgStr0
02516 && AMD_MFGSTR1 == dwMfgStr1
02517 && AMD_MFGSTR2 == dwMfgStr2)
02518 {
02519 maker = AMD;
02520 }
02521 else
02522 {
02523
02524
02525 __intel_cpu_indicator = CPU_TYPE_UNSPECIALIZED;
02526 return;
02527 }
02528
02529 UINT32 dwSignature;
02530 UINT32 dwBrand;
02531 UINT32 dwMSR;
02532 UINT32 dwFeatures;
02533
02534 __asm
02535 {
02536 mov eax,CPUID_1
02537 cpuid
02538 mov dwSignature,eax
02539 mov dwBrand,ebx
02540 mov dwMSR,ecx
02541 mov dwFeatures,edx
02542 }
02543
02544 (void)(dwBrand);
02545
02546
02547
02548 UINT32 dwEffFamily;
02549 if (CPU_FAMILY(dwSignature) == 0xF)
02550 {
02551 dwEffFamily = CPU_FAMILY(dwSignature) + CPU_EXTFAMILY(dwSignature);
02552 }
02553 else
02554 {
02555 dwEffFamily = CPU_FAMILY(dwSignature);
02556 }
02557 UINT32 dwEffModel;
02558 if (CPU_MODEL(dwSignature) == 0xF)
02559 {
02560 dwEffModel = CPU_MODEL(dwSignature) + (CPU_EXTMODEL(dwSignature) << 4);
02561 }
02562 else
02563 {
02564 dwEffModel = CPU_MODEL(dwSignature);
02565 }
02566
02567 #define ADVF_MMX 0x00000001UL
02568 #define ADVF_FSXR 0x00000002UL
02569 #define ADVF_SSE 0x00000004UL
02570 #define ADVF_SSE2 0x00000008UL
02571 #define ADVF_SSE3 0x00000010UL
02572
02573 UINT32 dwAdvFeatures = 0;
02574
02575
02576
02577 if (dwFeatures & CPU_FEATURE_MMX)
02578 {
02579 dwAdvFeatures |= ADVF_MMX;
02580 }
02581 if (dwFeatures & CPU_FEATURE_FSXR)
02582 {
02583 dwAdvFeatures |= ADVF_FSXR;
02584 }
02585 if (dwFeatures & CPU_FEATURE_SSE)
02586 {
02587 dwAdvFeatures |= ADVF_SSE;
02588 }
02589 if (dwFeatures & CPU_FEATURE_SSE2)
02590 {
02591 dwAdvFeatures |= ADVF_SSE2;
02592 }
02593 if ( dwEffFamily <= 5
02594 && dwMSR & CPU_MSR_SSE3)
02595 {
02596 dwAdvFeatures |= ADVF_SSE3;
02597 }
02598
02599
02600
02601 UINT32 dwUseable = dwAdvFeatures;
02602 if (dwUseable & ADVF_MMX)
02603 {
02604 try
02605 {
02606 __asm
02607 {
02608
02609
02610 emms
02611 }
02612 }
02613 catch (...)
02614 {
02615 dwUseable &= ~(ADVF_MMX|ADVF_SSE|ADVF_SSE2|ADVF_SSE3);
02616 }
02617 }
02618
02619 if (dwUseable & ADVF_SSE)
02620 {
02621 try
02622 {
02623 __asm
02624 {
02625
02626
02627 xorps xmm0, xmm0
02628 }
02629 }
02630 catch (...)
02631 {
02632 dwUseable &= ~(ADVF_SSE|ADVF_SSE2|ADVF_SSE3);
02633 }
02634 }
02635
02636 if (dwUseable & ADVF_SSE2)
02637 {
02638 try
02639 {
02640 __asm
02641 {
02642
02643
02644 xorpd xmm0, xmm0
02645 }
02646 }
02647 catch (...)
02648 {
02649 dwUseable &= ~(ADVF_SSE2|ADVF_SSE3);
02650 }
02651 }
02652
02653 if (dwUseable & ADVF_SSE3)
02654 {
02655 try
02656 {
02657 __asm
02658 {
02659
02660
02661 haddpd xmm1,xmm2
02662 }
02663 }
02664 catch (...)
02665 {
02666 dwUseable &= ~(ADVF_SSE3);
02667 }
02668 }
02669
02670
02671
02672 if (dwEffFamily <= 4)
02673 {
02674 __intel_cpu_indicator = CPU_TYPE_UNSPECIALIZED;
02675 }
02676 else if (5 == dwEffFamily)
02677 {
02678 if (dwUseable & ADVF_MMX)
02679 {
02680 __intel_cpu_indicator = CPU_TYPE_FAMILY_5_MMX;
02681 }
02682 else
02683 {
02684 __intel_cpu_indicator = CPU_TYPE_FAMILY_5;
02685 }
02686 }
02687 else
02688 {
02689 if (dwUseable & ADVF_MMX)
02690 {
02691 if (dwUseable & ADVF_FSXR)
02692 {
02693 if (dwUseable & ADVF_SSE)
02694 {
02695 if (dwUseable & ADVF_SSE2)
02696 {
02697 if (dwUseable & ADVF_SSE3)
02698 {
02699 if (dwEffFamily < 15)
02700 {
02701 __intel_cpu_indicator = CPU_TYPE_FAMILY_6_MMX_FSXR_SSE3;
02702 }
02703 else
02704 {
02705 __intel_cpu_indicator = CPU_TYPE_FAMILY_F_SSE3;
02706 }
02707 }
02708 else
02709 {
02710 if (dwEffFamily < 15)
02711 {
02712 __intel_cpu_indicator = CPU_TYPE_FAMILY_6_MMX_FSXR_SSE2;
02713 }
02714 else
02715 {
02716 __intel_cpu_indicator = CPU_TYPE_FAMILY_F_SSE2;
02717 }
02718 }
02719 }
02720 else
02721 {
02722 __intel_cpu_indicator = CPU_TYPE_FAMILY_6_MMX_FSXR_SSE;
02723 }
02724 }
02725 else
02726 {
02727 __intel_cpu_indicator = CPU_TYPE_FAMILY_6_MMX_FSXR;
02728 }
02729 }
02730 else
02731 {
02732 __intel_cpu_indicator = CPU_TYPE_FAMILY_6_MMX;
02733 }
02734 }
02735 else
02736 {
02737 __intel_cpu_indicator = CPU_TYPE_FAMILY_6;
02738 }
02739 }
02740
02741
02742
02743 fprintf(stderr, "cpu_init: %s, Family %u, Model %u, %s%s%s%s%s" ENDLINE,
02744 (Intel == maker ? "Intel" : (AMD == maker ? "AMD" : "Unknown")),
02745 dwEffFamily,
02746 dwEffModel,
02747 (dwUseable & ADVF_MMX) ? "MMX " : "",
02748 (dwUseable & ADVF_FSXR) ? "FSXR ": "",
02749 (dwUseable & ADVF_SSE) ? "SSE ": "",
02750 (dwUseable & ADVF_SSE2) ? "SSE2 ": "",
02751 (dwUseable & ADVF_SSE3) ? "SSE3 ": "");
02752
02753 if (dwUseable != dwAdvFeatures)
02754 {
02755 UINT32 dw = dwAdvFeatures & (~dwUseable);
02756 fprintf(stderr, "cpu_init: %s%s%s%s%s unsupported by OS." ENDLINE,
02757 (dw & ADVF_MMX) ? "MMX ": "",
02758 (dw & ADVF_FSXR) ? "FSXR ": "",
02759 (dw & ADVF_SSE) ? "SSE ": "",
02760 (dw & ADVF_SSE2) ? "SSE2 ": "",
02761 (dw & ADVF_SSE3) ? "SSE3 ": "");
02762 }
02763 }
02764
02765 #endif
02766
02767 #define DBCONVERT_NAME1 "dbconvert"
02768 #define DBCONVERT_NAME2 "dbconvert.exe"
02769
02770 int DCL_CDECL main(int argc, char *argv[])
02771 {
02772 #if defined(__INTEL_COMPILER)
02773 cpu_init();
02774 #endif
02775
02776 build_version();
02777
02778
02779
02780 size_t nProg = strlen(argv[0]);
02781 const char *pProg = argv[0] + nProg - 1;
02782 while ( nProg
02783 && ( mux_isalpha(*pProg)
02784 || *pProg == '.'))
02785 {
02786 nProg--;
02787 pProg--;
02788 }
02789 pProg++;
02790 mudstate.bStandAlone = false;
02791 if ( mux_stricmp(pProg, DBCONVERT_NAME1) == 0
02792 || mux_stricmp(pProg, DBCONVERT_NAME2) == 0)
02793 {
02794 mudstate.bStandAlone = true;
02795 }
02796
02797 mudconf.pid_file = "netmux.pid";
02798
02799
02800
02801 CLI_Process(argc, argv, OptionTable,
02802 sizeof(OptionTable)/sizeof(CLI_OptionEntry), CLI_CallBack);
02803
02804 #ifndef MEMORY_BASED
02805 if (mudstate.bStandAlone)
02806 {
02807 int n = 0;
02808 if (standalone_check)
02809 {
02810 n++;
02811 }
02812 if (standalone_load)
02813 {
02814 n++;
02815 }
02816 if (standalone_unload)
02817 {
02818 n++;
02819 }
02820 if ( !standalone_basename
02821 || !standalone_infile
02822 || !standalone_outfile
02823 || n != 1
02824 || bServerOption)
02825 {
02826 bSyntaxError = true;
02827 }
02828 else
02829 {
02830 dbconvert();
02831 return 0;
02832 }
02833 }
02834 else
02835 #endif // MEMORY_BASED
02836
02837 if (bVersion)
02838 {
02839 fprintf(stderr, "Version: %s" ENDLINE, mudstate.version);
02840 return 1;
02841 }
02842 if ( bSyntaxError
02843 || conffile == NULL
02844 || !bServerOption)
02845 {
02846 fprintf(stderr, "Version: %s" ENDLINE, mudstate.version);
02847 if (mudstate.bStandAlone)
02848 {
02849 fprintf(stderr, "Usage: %s -d <dbname> -i <infile> [-o <outfile>] [-l|-u|-k]" ENDLINE, pProg);
02850 fprintf(stderr, " -d Basename." ENDLINE);
02851 fprintf(stderr, " -i Input file." ENDLINE);
02852 fprintf(stderr, " -k Check." ENDLINE);
02853 fprintf(stderr, " -l Load." ENDLINE);
02854 fprintf(stderr, " -o Output file." ENDLINE);
02855 fprintf(stderr, " -u Unload." ENDLINE);
02856 }
02857 else
02858 {
02859 fprintf(stderr, "Usage: %s [-c <filename>] [-p <filename>] [-h] [-s] [-v]" ENDLINE, pProg);
02860 fprintf(stderr, " -c Specify configuration file." ENDLINE);
02861 fprintf(stderr, " -e Specify logfile basename (or '-' for stderr)." ENDLINE);
02862 fprintf(stderr, " -h Display this help." ENDLINE);
02863 fprintf(stderr, " -p Specify process ID file." ENDLINE);
02864 fprintf(stderr, " -s Start with a minimal database." ENDLINE);
02865 fprintf(stderr, " -v Display version string." ENDLINE ENDLINE);
02866 }
02867 return 1;
02868 }
02869
02870 mudstate.bStandAlone = false;
02871
02872 FLOAT_Initialize();
02873 TIME_Initialize();
02874 SeedRandomNumberGenerator();
02875
02876 Log.SetBasename(pErrorBasename);
02877 Log.StartLogging();
02878 game_pid = getpid();
02879 write_pidfile(mudconf.pid_file);
02880
02881 BuildSignalNamesTable();
02882
02883 #ifdef MEMORY_ACCOUNTING
02884 extern CHashFile hfAllocData;
02885 extern CHashFile hfIdentData;
02886 extern bool bMemAccountingInitialized;
02887 hfAllocData.Open("svdptrs.dir", "svdptrs.pag", 40);
02888 hfIdentData.Open("svdlines.dir", "svdlines.pag", 40);
02889 bMemAccountingInitialized = true;
02890 #endif
02891
02892 #ifdef WIN32
02893
02894
02895
02896 OSVERSIONINFO VersionInformation;
02897
02898 VersionInformation.dwOSVersionInfoSize = sizeof (VersionInformation);
02899 GetVersionEx(&VersionInformation);
02900 platform = VersionInformation.dwPlatformId;
02901 hGameProcess = GetCurrentProcess();
02902 if (platform == VER_PLATFORM_WIN32_NT)
02903 {
02904 Log.WriteString("Running under Windows NT" ENDLINE);
02905
02906
02907
02908 HINSTANCE hInstKernel32 = LoadLibrary("kernel32");
02909 if (!hInstKernel32)
02910 {
02911 Log.WriteString("LoadLibrary of kernel32 for a CancelIo entry point failed. Cannot continue." ENDLINE);
02912 return 1;
02913 }
02914
02915
02916
02917
02918
02919
02920
02921 fpCancelIo = (FCANCELIO *)GetProcAddress(hInstKernel32, "CancelIo");
02922 if (fpCancelIo == NULL)
02923 {
02924 Log.WriteString("GetProcAddress of _CancelIo failed. Cannot continue." ENDLINE);
02925 return 1;
02926 }
02927 fpGetProcessTimes = (FGETPROCESSTIMES *)GetProcAddress(hInstKernel32, "GetProcessTimes");
02928 if (fpGetProcessTimes == NULL)
02929 {
02930 Log.WriteString("GetProcAddress of GetProcessTimes failed. Cannot continue." ENDLINE);
02931 return 1;
02932 }
02933 }
02934 else
02935 {
02936 Log.WriteString("Running under Windows 95/98" ENDLINE);
02937 }
02938
02939
02940
02941 WORD wVersionRequested = MAKEWORD(2,2);
02942 WSADATA wsaData;
02943 if (WSAStartup(wVersionRequested, &wsaData) != 0)
02944 {
02945 Log.WriteString("ERROR: Could not initialize WinSock." ENDLINE);
02946 return 101;
02947 }
02948
02949 if ( LOBYTE(wsaData.wVersion) != 2
02950 || HIBYTE(wsaData.wVersion) != 2)
02951 {
02952
02953
02954 Log.tinyprintf("INFO: WinSock v%d.%d instead of v2.2." ENDLINE,
02955 LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
02956
02957
02958 }
02959 if (!bCryptoAPI)
02960 {
02961 Log.WriteString("Crypto API unavailable.\r\n");
02962 }
02963 #endif // WIN32
02964
02965 mudstate.start_time.GetLocal();
02966 mudstate.cpu_count_from.GetUTC();
02967 pool_init(POOL_LBUF, LBUF_SIZE);
02968 pool_init(POOL_MBUF, MBUF_SIZE);
02969 pool_init(POOL_SBUF, SBUF_SIZE);
02970 pool_init(POOL_BOOL, sizeof(struct boolexp));
02971
02972 pool_init(POOL_DESC, sizeof(DESC));
02973 pool_init(POOL_QENTRY, sizeof(BQUE));
02974 tcache_init();
02975 pcache_init();
02976 cf_init();
02977 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
02978 init_rlimit();
02979 #endif // HAVE_SETRLIMIT RLIMIT_NOFILE
02980 init_cmdtab();
02981 init_logout_cmdtab();
02982 init_flagtab();
02983 init_powertab();
02984 init_functab();
02985 init_attrtab();
02986 init_version();
02987
02988 mudconf.config_file = StringClone(conffile);
02989 cf_read();
02990
02991 fcache_init();
02992 helpindex_init();
02993
02994 #ifdef MEMORY_BASED
02995 db_free();
02996 #else // MEMORY_BASED
02997 if (bMinDB)
02998 {
02999 RemoveFile(mudconf.game_dir);
03000 RemoveFile(mudconf.game_pag);
03001 }
03002 int ccPageFile = init_dbfile(mudconf.game_dir, mudconf.game_pag, mudconf.cache_pages);
03003 if (HF_OPEN_STATUS_ERROR == ccPageFile)
03004 {
03005 STARTLOG(LOG_ALWAYS, "INI", "LOAD");
03006 log_text("Couldn't load text database: ");
03007 log_text(mudconf.game_dir);
03008 log_text(mudconf.game_pag);
03009 ENDLOG;
03010 return 2;
03011 }
03012 #endif // MEMORY_BASED
03013
03014 mudstate.record_players = 0;
03015
03016 if (bMinDB)
03017 {
03018 db_make_minimal();
03019 }
03020 else
03021 {
03022 #ifdef MEMORY_BASED
03023 int ccInFile = load_game();
03024 #else // MEMORY_BASED
03025 int ccInFile = load_game(ccPageFile);
03026 #endif // MEMORY_BASED
03027 if (LOAD_GAME_NO_INPUT_DB == ccInFile)
03028 {
03029
03030
03031 #ifndef MEMORY_BASED
03032 if (HF_OPEN_STATUS_NEW == ccPageFile)
03033 {
03034
03035
03036
03037 #endif // !MEMORY_BASED
03038 db_make_minimal();
03039 ccInFile = LOAD_GAME_SUCCESS;
03040 #ifndef MEMORY_BASED
03041 }
03042 #endif // !MEMORY_BASED
03043 }
03044 if (ccInFile != LOAD_GAME_SUCCESS)
03045 {
03046 STARTLOG(LOG_ALWAYS, "INI", "LOAD")
03047 log_text("Couldn't load: ");
03048 log_text(mudconf.indb);
03049 ENDLOG
03050 return 2;
03051 }
03052 }
03053 set_signals();
03054 Guest.StartUp();
03055
03056
03057
03058 do_dbck(NOTHING, NOTHING, NOTHING, 0);
03059
03060
03061
03062 hashreset(&mudstate.command_htab);
03063 hashreset(&mudstate.channel_htab);
03064 hashreset(&mudstate.mail_htab);
03065 hashreset(&mudstate.logout_cmd_htab);
03066 hashreset(&mudstate.func_htab);
03067 hashreset(&mudstate.flags_htab);
03068 hashreset(&mudstate.attr_name_htab);
03069 hashreset(&mudstate.player_htab);
03070 hashreset(&mudstate.fwdlist_htab);
03071 hashreset(&mudstate.desc_htab);
03072
03073 int i;
03074 for (i = 0; i < MAX_GLOBAL_REGS; i++)
03075 {
03076 mudstate.global_regs[i] = alloc_lbuf("main.global_reg");
03077 mudstate.glob_reg_len[i] = 0;
03078 }
03079
03080 ValidateConfigurationDbrefs();
03081 process_preload();
03082
03083 #ifndef WIN32
03084 load_restart_db();
03085 if (!mudstate.restarting)
03086 #endif // !WIN32
03087 {
03088 if (fclose(stdout) == 0)
03089 {
03090 DebugTotalFiles--;
03091 }
03092 if (fclose(stdin) == 0)
03093 {
03094 DebugTotalFiles--;
03095 }
03096 }
03097 SetupPorts(&nMainGamePorts, aMainGamePorts, &mudconf.ports);
03098 boot_slave(GOD, GOD, GOD, 0);
03099 #ifdef QUERY_SLAVE
03100 boot_sqlslave(GOD, GOD, GOD, 0);
03101 #endif // QUERY_SLAVE
03102
03103
03104
03105
03106 local_startup();
03107
03108 init_timer();
03109
03110 #ifdef WIN32
03111 if (platform == VER_PLATFORM_WIN32_NT)
03112 {
03113 process_output = process_outputNT;
03114 shovecharsNT(nMainGamePorts, aMainGamePorts);
03115 }
03116 else
03117 {
03118 process_output = process_output9x;
03119 shovechars9x(nMainGamePorts, aMainGamePorts);
03120 }
03121 #else // WIN32
03122 shovechars(nMainGamePorts, aMainGamePorts);
03123 #endif // WIN32
03124
03125 close_sockets(false, "Going down - Bye");
03126 dump_database();
03127
03128
03129
03130
03131 local_shutdown();
03132 CLOSE;
03133
03134 #ifndef WIN32
03135 CleanUpSlaveSocket();
03136 CleanUpSlaveProcess();
03137 #endif
03138 #ifdef QUERY_SLAVE
03139 CleanUpSQLSlaveSocket();
03140 CleanUpSQLSlaveProcess();
03141 #endif
03142
03143
03144
03145
03146 for (i = 0; i < mudstate.nHelpDesc; i++)
03147 {
03148 helpindex_clean(i);
03149 }
03150
03151 db_free();
03152
03153 #ifdef WIN32
03154
03155
03156 if (platform == VER_PLATFORM_WIN32_NT)
03157 {
03158 DeleteCriticalSection(&csDescriptorList);
03159 }
03160 WSACleanup();
03161 #endif // WIN32
03162
03163 return 0;
03164 }
03165
03166 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
03167 void init_rlimit(void)
03168 {
03169 struct rlimit *rlp;
03170
03171 rlp = (struct rlimit *)alloc_lbuf("rlimit");
03172
03173 if (getrlimit(RLIMIT_NOFILE, rlp))
03174 {
03175 log_perror("RLM", "FAIL", NULL, "getrlimit()");
03176 free_lbuf(rlp);
03177 return;
03178 }
03179 rlp->rlim_cur = rlp->rlim_max;
03180 if (setrlimit(RLIMIT_NOFILE, rlp))
03181 {
03182 log_perror("RLM", "FAIL", NULL, "setrlimit()");
03183 }
03184 free_lbuf(rlp);
03185
03186 }
03187 #endif // HAVE_SETRLIMIT RLIMIT_NOFILE