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
0122