00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include "ansi.h"
00015 #include "attrs.h"
00016 #include "command.h"
00017 #include "functions.h"
00018 #include "funmath.h"
00019 #include "interface.h"
00020 #include "misc.h"
00021 #include "pcre.h"
00022 #ifdef REALITY_LVLS
00023 #include "levels.h"
00024 #endif
00025
00026 UFUN *ufun_head;
00027
00028 SEP sepSpace = { 1, " " };
00029
00030
00031
00032
00033 char *trim_space_sep_LEN(char *str, int nStr, SEP *sep, int *nTrim)
00034 {
00035 if ( sep->n != 1
00036 || sep->str[0] != ' ')
00037 {
00038 *nTrim = nStr;
00039 return str;
00040 }
00041
00042
00043
00044 char *pBegin = str;
00045 char *pEnd = str + nStr - 1;
00046 while (*pBegin == ' ')
00047 {
00048 pBegin++;
00049 }
00050
00051
00052
00053 for (; pEnd > pBegin && *pEnd == ' '; pEnd--)
00054 {
00055
00056 }
00057 pEnd++;
00058
00059 *pEnd = '\0';
00060 *nTrim = pEnd - pBegin;
00061 return pBegin;
00062 }
00063
00064
00065
00066
00067 char *trim_space_sep(char *str, SEP *sep)
00068 {
00069 if ( sep->n != 1
00070 || sep->str[0] != ' ')
00071 {
00072 return str;
00073 }
00074 while (*str == ' ')
00075 {
00076 str++;
00077 }
00078 char *p;
00079 for (p = str; *p; p++)
00080 {
00081
00082 }
00083 for (p--; p > str && *p == ' '; p--)
00084 {
00085
00086 }
00087 p++;
00088 *p = '\0';
00089 return str;
00090 }
00091
00092
00093
00094
00095 static char *next_token_LEN(char *str, int *nStr, SEP *psep)
00096 {
00097 char *pBegin = str;
00098 if (psep->n == 1)
00099 {
00100 while ( *pBegin != '\0'
00101 && *pBegin != psep->str[0])
00102 {
00103 pBegin++;
00104 }
00105 if (!*pBegin)
00106 {
00107 *nStr = 0;
00108 return NULL;
00109 }
00110 pBegin++;
00111 if (psep->str[0] == ' ')
00112 {
00113 while (*pBegin == ' ')
00114 {
00115 pBegin++;
00116 }
00117 }
00118 }
00119 else
00120 {
00121 char *p = strstr(pBegin, psep->str);
00122 if (p)
00123 {
00124 pBegin = p + psep->n;
00125 }
00126 else
00127 {
00128 *nStr = 0;
00129 return NULL;
00130 }
00131 }
00132 *nStr -= pBegin - str;
00133 return pBegin;
00134 }
00135
00136
00137
00138 char *next_token(char *str, SEP *psep)
00139 {
00140 if (psep->n == 1)
00141 {
00142 while ( *str != '\0'
00143 && *str != psep->str[0])
00144 {
00145 str++;
00146 }
00147 if (!*str)
00148 {
00149 return NULL;
00150 }
00151 str++;
00152 if (psep->str[0] == ' ')
00153 {
00154 while (*str == ' ')
00155 {
00156 str++;
00157 }
00158 }
00159 }
00160 else
00161 {
00162 char *p = strstr(str, psep->str);
00163 if (p)
00164 {
00165 str = p + psep->n;
00166 }
00167 else
00168 {
00169 return NULL;
00170 }
00171 }
00172 return str;
00173 }
00174
00175
00176
00177
00178 static char *split_token_LEN(char **sp, int *nStr, SEP *psep, int *nToken)
00179 {
00180 char *str = *sp;
00181 char *save = str;
00182 if (!str)
00183 {
00184 *nStr = 0;
00185 *sp = NULL;
00186 *nToken = 0;
00187 return NULL;
00188 }
00189
00190 if (psep->n == 1)
00191 {
00192
00193
00194 while ( *str
00195 && *str != psep->str[0])
00196 {
00197 str++;
00198 }
00199 *nToken = str - save;
00200
00201 if (*str)
00202 {
00203 *str++ = '\0';
00204 if (psep->str[0] == ' ')
00205 {
00206 while (*str == ' ')
00207 {
00208 str++;
00209 }
00210 }
00211 *nStr -= str - save;
00212 }
00213 else
00214 {
00215 *nStr = 0;
00216 str = NULL;
00217 }
00218 }
00219 else
00220 {
00221 char *p = strstr(str, psep->str);
00222 if (p)
00223 {
00224 *p = '\0';
00225 str = p + psep->n;
00226 }
00227 else
00228 {
00229 str = NULL;
00230 }
00231 }
00232 *sp = str;
00233 return save;
00234 }
00235
00236
00237
00238
00239 char *split_token(char **sp, SEP *psep)
00240 {
00241 char *str = *sp;
00242 char *save = str;
00243
00244 if (!str)
00245 {
00246 *sp = NULL;
00247 return NULL;
00248 }
00249 if (psep->n == 1)
00250 {
00251 while ( *str
00252 && *str != psep->str[0])
00253 {
00254 str++;
00255 }
00256 if (*str)
00257 {
00258 *str++ = '\0';
00259 if (psep->str[0] == ' ')
00260 {
00261 while (*str == ' ')
00262 {
00263 str++;
00264 }
00265 }
00266 }
00267 else
00268 {
00269 str = NULL;
00270 }
00271 }
00272 else
00273 {
00274 char *p = strstr(str, psep->str);
00275 if (p)
00276 {
00277 *p = '\0';
00278 str = p + psep->n;
00279 }
00280 else
00281 {
00282 str = NULL;
00283 }
00284 }
00285 *sp = str;
00286 return save;
00287 }
00288
00289
00290
00291
00292
00293 #define ASCII_LIST 1
00294 #define NUMERIC_LIST 2
00295 #define DBREF_LIST 4
00296 #define FLOAT_LIST 8
00297 #define CI_ASCII_LIST 16
00298 #define ALL_LIST (ASCII_LIST|NUMERIC_LIST|DBREF_LIST|FLOAT_LIST)
00299
00300 static int autodetect_list(char *ptrs[], int nitems)
00301 {
00302 int could_be = ALL_LIST;
00303 for (int i = 0; i < nitems; i++)
00304 {
00305 char *p = ptrs[i];
00306 if (p[0] != NUMBER_TOKEN)
00307 {
00308 could_be &= ~DBREF_LIST;
00309 }
00310 if ( (could_be & DBREF_LIST)
00311 && !is_integer(p+1, NULL))
00312 {
00313 could_be &= ~(DBREF_LIST|NUMERIC_LIST|FLOAT_LIST);
00314 }
00315 if ( (could_be & FLOAT_LIST)
00316 && !is_real(p))
00317 {
00318 could_be &= ~(NUMERIC_LIST|FLOAT_LIST);
00319 }
00320 if ( (could_be & NUMERIC_LIST)
00321 && !is_integer(p, NULL))
00322 {
00323 could_be &= ~NUMERIC_LIST;
00324 }
00325
00326 if (could_be == ASCII_LIST)
00327 {
00328 return ASCII_LIST;
00329 }
00330 }
00331 if (could_be & NUMERIC_LIST)
00332 {
00333 return NUMERIC_LIST;
00334 }
00335 else if (could_be & FLOAT_LIST)
00336 {
00337 return FLOAT_LIST;
00338 }
00339 else if (could_be & DBREF_LIST)
00340 {
00341 return DBREF_LIST;
00342 }
00343 return ASCII_LIST;
00344 }
00345
00346 static int get_list_type
00347 (
00348 char *fargs[],
00349 int nfargs,
00350 int type_pos,
00351 char *ptrs[],
00352 int nitems
00353 )
00354 {
00355 if (nfargs >= type_pos)
00356 {
00357 switch (mux_tolower(*fargs[type_pos - 1]))
00358 {
00359 case 'd':
00360 return DBREF_LIST;
00361 case 'n':
00362 return NUMERIC_LIST;
00363 case 'f':
00364 return FLOAT_LIST;
00365 case 'i':
00366 return CI_ASCII_LIST;
00367 case '\0':
00368 return autodetect_list(ptrs, nitems);
00369 default:
00370 return ASCII_LIST;
00371 }
00372 }
00373 return autodetect_list(ptrs, nitems);
00374 }
00375
00376 int list2arr(char *arr[], int maxlen, char *list, SEP *psep)
00377 {
00378 list = trim_space_sep(list, psep);
00379 if (list[0] == '\0')
00380 {
00381 return 0;
00382 }
00383 char *p = split_token(&list, psep);
00384 int i;
00385 for (i = 0; p && i < maxlen; i++, p = split_token(&list, psep))
00386 {
00387 arr[i] = p;
00388 }
00389 return i;
00390 }
00391
00392 void arr2list(char *arr[], int alen, char *list, char **bufc, SEP *psep)
00393 {
00394 int i;
00395 for (i = 0; i < alen-1; i++)
00396 {
00397 safe_str(arr[i], list, bufc);
00398 print_sep(psep, list, bufc);
00399 }
00400 if (alen)
00401 {
00402 safe_str(arr[i], list, bufc);
00403 }
00404 }
00405
00406 static int dbnum(char *dbr)
00407 {
00408 if (dbr[0] != '#' || dbr[1] == '\0')
00409 {
00410 return 0;
00411 }
00412 else
00413 {
00414 return mux_atol(dbr + 1);
00415 }
00416 }
00417
00418
00419
00420
00421
00422 static bool nearby_or_control(dbref player, dbref thing)
00423 {
00424 if (!Good_obj(player) || !Good_obj(thing))
00425 {
00426 return false;
00427 }
00428 if (Controls(player, thing))
00429 {
00430 return true;
00431 }
00432 if (!nearby(player, thing))
00433 {
00434 return false;
00435 }
00436 return true;
00437 }
00438
00439
00440
00441
00442 bool delim_check
00443 (
00444 char *buff, char **bufc,
00445 dbref executor, dbref caller, dbref enactor,
00446 char *fargs[], int nfargs,
00447 char *cargs[], int ncargs,
00448 int sep_arg, SEP *sep, int dflags
00449 )
00450 {
00451 bool bSuccess = true;
00452 if (sep_arg <= nfargs)
00453 {
00454
00455
00456 char *tstr = fargs[sep_arg-1];
00457 int tlen = strlen(tstr);
00458
00459 if (tlen <= 1)
00460 {
00461 dflags &= ~DELIM_EVAL;
00462 }
00463 if (dflags & DELIM_EVAL)
00464 {
00465 char *str = tstr;
00466 char *bp = tstr = alloc_lbuf("delim_check");
00467 mux_exec(tstr, &bp, executor, caller, enactor,
00468 EV_EVAL | EV_FCHECK, &str, cargs, ncargs);
00469 *bp = '\0';
00470 tlen = bp - tstr;
00471 }
00472
00473
00474
00475
00476 if (tlen == 1)
00477 {
00478 sep->n = 1;
00479 memcpy(sep->str, tstr, tlen+1);
00480 }
00481 else if (tlen == 0)
00482 {
00483 sep->n = 1;
00484 memcpy(sep->str, " ", 2);
00485 }
00486 else if ( tlen == 2
00487 && (dflags & DELIM_NULL)
00488 && memcmp(tstr, NULL_DELIM_VAR, 2) == 0)
00489 {
00490 sep->n = 0;
00491 sep->str[0] = '\0';
00492 }
00493 else if ( tlen == 2
00494 && (dflags & DELIM_EVAL)
00495 && memcmp(tstr, "\r\n", 2) == 0)
00496 {
00497 sep->n = 2;
00498 memcpy(sep->str, "\r\n", 3);
00499 }
00500 else if (dflags & DELIM_STRING)
00501 {
00502 if (tlen <= MAX_SEP_LEN)
00503 {
00504 sep->n = tlen;
00505 memcpy(sep->str, tstr, tlen);
00506 sep->str[sep->n] = '\0';
00507 }
00508 else
00509 {
00510 safe_str("#-1 SEPARATOR IS TOO LARGE", buff, bufc);
00511 bSuccess = false;
00512 }
00513 }
00514 else
00515 {
00516 safe_str("#-1 SEPARATOR MUST BE ONE CHARACTER", buff, bufc);
00517 bSuccess = false;
00518 }
00519
00520
00521
00522 if (dflags & DELIM_EVAL)
00523 {
00524 free_lbuf(tstr);
00525 }
00526 }
00527 else if (!(dflags & DELIM_INIT))
00528 {
00529 sep->n = 1;
00530 memcpy(sep->str, " ", 2);
00531 }
00532 return bSuccess;
00533 }
00534
00535
00536
00537
00538
00539
00540 int countwords(char *str, SEP *psep)
00541 {
00542 int n;
00543
00544 str = trim_space_sep(str, psep);
00545 if (!*str)
00546 {
00547 return 0;
00548 }
00549 for (n = 0; str; str = next_token(str, psep), n++)
00550 {
00551 ;
00552 }
00553 return n;
00554 }
00555
00556 static FUNCTION(fun_words)
00557 {
00558 if (nfargs == 0)
00559 {
00560 safe_chr('0', buff, bufc);
00561 return;
00562 }
00563
00564 SEP sep;
00565 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
00566 {
00567 return;
00568 }
00569
00570 safe_ltoa(countwords(strip_ansi(fargs[0]), &sep), buff, bufc);
00571 }
00572
00573
00574
00575
00576
00577
00578 static FUNCTION(fun_flags)
00579 {
00580 UNUSED_PARAMETER(caller);
00581 UNUSED_PARAMETER(nfargs);
00582 UNUSED_PARAMETER(cargs);
00583 UNUSED_PARAMETER(ncargs);
00584
00585 dbref it;
00586 ATTR *pattr;
00587 if (parse_attrib(executor, fargs[0], &it, &pattr))
00588 {
00589 if ( pattr
00590 && See_attr(executor, it, pattr))
00591 {
00592 dbref aowner;
00593 int aflags;
00594 atr_pget_info(it, pattr->number, &aowner, &aflags);
00595 char xbuf[11];
00596 decode_attr_flags(aflags, xbuf);
00597 safe_str(xbuf, buff, bufc);
00598 }
00599 }
00600 else
00601 {
00602 it = match_thing_quiet(executor, fargs[0]);
00603 if (!Good_obj(it))
00604 {
00605 safe_match_result(it, buff, bufc);
00606 return;
00607 }
00608 if ( mudconf.pub_flags
00609 || Examinable(executor, it)
00610 || it == enactor)
00611 {
00612 char *buff2 = decode_flags(executor, &(db[it].fs));
00613 safe_str(buff2, buff, bufc);
00614 free_sbuf(buff2);
00615 }
00616 else
00617 {
00618 safe_noperm(buff, bufc);
00619 }
00620 }
00621 }
00622
00623
00624
00625
00626
00627 static FUNCTION(fun_rand)
00628 {
00629 UNUSED_PARAMETER(executor);
00630 UNUSED_PARAMETER(caller);
00631 UNUSED_PARAMETER(enactor);
00632 UNUSED_PARAMETER(cargs);
00633 UNUSED_PARAMETER(ncargs);
00634
00635 int nDigits;
00636 switch (nfargs)
00637 {
00638 case 1:
00639 if (is_integer(fargs[0], &nDigits))
00640 {
00641 int num = mux_atol(fargs[0]);
00642 if (num < 1)
00643 {
00644 safe_chr('0', buff, bufc);
00645 }
00646 else
00647 {
00648 safe_ltoa(RandomINT32(0, num-1), buff, bufc);
00649 }
00650 }
00651 else
00652 {
00653 safe_str("#-1 ARGUMENT MUST BE INTEGER", buff, bufc);
00654 }
00655 break;
00656
00657 case 2:
00658 if ( is_integer(fargs[0], &nDigits)
00659 && is_integer(fargs[1], &nDigits))
00660 {
00661 int lower = mux_atol(fargs[0]);
00662 int higher = mux_atol(fargs[1]);
00663 if ( lower <= higher
00664 && (unsigned int)(higher-lower) <= INT32_MAX_VALUE)
00665 {
00666 safe_ltoa(RandomINT32(lower, higher), buff, bufc);
00667 }
00668 else
00669 {
00670 safe_range(buff, bufc);
00671 }
00672 }
00673 else
00674 {
00675 safe_str("#-1 ARGUMENT MUST BE INTEGER", buff, bufc);
00676 }
00677 break;
00678 }
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 static FUNCTION(fun_time)
00691 {
00692 UNUSED_PARAMETER(executor);
00693 UNUSED_PARAMETER(caller);
00694 UNUSED_PARAMETER(enactor);
00695 UNUSED_PARAMETER(cargs);
00696 UNUSED_PARAMETER(ncargs);
00697
00698 CLinearTimeAbsolute ltaNow;
00699 if ( nfargs == 0
00700 || mux_stricmp("utc", fargs[0]) != 0)
00701 {
00702 ltaNow.GetLocal();
00703 }
00704 else
00705 {
00706 ltaNow.GetUTC();
00707 }
00708 int nPrecision = 0;
00709 if (nfargs == 2)
00710 {
00711 nPrecision = mux_atol(fargs[1]);
00712 }
00713 char *temp = ltaNow.ReturnDateString(nPrecision);
00714 safe_str(temp, buff, bufc);
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 static FUNCTION(fun_secs)
00729 {
00730 UNUSED_PARAMETER(executor);
00731 UNUSED_PARAMETER(caller);
00732 UNUSED_PARAMETER(enactor);
00733 UNUSED_PARAMETER(cargs);
00734 UNUSED_PARAMETER(ncargs);
00735
00736 CLinearTimeAbsolute ltaNow;
00737 if ( nfargs == 0
00738 || mux_stricmp("local", fargs[0]) != 0)
00739 {
00740 ltaNow.GetUTC();
00741 }
00742 else
00743 {
00744 ltaNow.GetLocal();
00745 }
00746 int nPrecision = 0;
00747 if (nfargs == 2)
00748 {
00749 nPrecision = mux_atol(fargs[1]);
00750 }
00751 safe_str(ltaNow.ReturnSecondsString(nPrecision), buff, bufc);
00752 }
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 static FUNCTION(fun_convsecs)
00770 {
00771 UNUSED_PARAMETER(executor);
00772 UNUSED_PARAMETER(caller);
00773 UNUSED_PARAMETER(enactor);
00774 UNUSED_PARAMETER(cargs);
00775 UNUSED_PARAMETER(ncargs);
00776
00777 CLinearTimeAbsolute lta;
00778 if (lta.SetSecondsString(fargs[0]))
00779 {
00780 if ( nfargs == 1
00781 || mux_stricmp("utc", fargs[1]) != 0)
00782 {
00783 lta.UTC2Local();
00784 }
00785 int nPrecision = 0;
00786 if (nfargs == 3)
00787 {
00788 nPrecision = mux_atol(fargs[2]);
00789 }
00790 char *temp = lta.ReturnDateString(nPrecision);
00791 safe_str(temp, buff, bufc);
00792 }
00793 else
00794 {
00795 safe_str("#-1 INVALID DATE", buff, bufc);
00796 }
00797 }
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 static FUNCTION(fun_convtime)
00818 {
00819 UNUSED_PARAMETER(executor);
00820 UNUSED_PARAMETER(caller);
00821 UNUSED_PARAMETER(enactor);
00822 UNUSED_PARAMETER(cargs);
00823 UNUSED_PARAMETER(ncargs);
00824
00825 CLinearTimeAbsolute lta;
00826 bool bZoneSpecified = false;
00827 if ( lta.SetString(fargs[0])
00828 || ParseDate(lta, fargs[0], &bZoneSpecified))
00829 {
00830 if ( !bZoneSpecified
00831 && ( nfargs == 1
00832 || mux_stricmp("utc", fargs[1]) != 0))
00833 {
00834 lta.Local2UTC();
00835 }
00836 int nPrecision = 0;
00837 if (nfargs == 3)
00838 {
00839 nPrecision = mux_atol(fargs[2]);
00840 }
00841 safe_str(lta.ReturnSecondsString(nPrecision), buff, bufc);
00842 }
00843 else
00844 {
00845 safe_str("#-1 INVALID DATE", buff, bufc);
00846 }
00847 }
00848
00849
00850
00851
00852
00853
00854 static FUNCTION(fun_starttime)
00855 {
00856 UNUSED_PARAMETER(executor);
00857 UNUSED_PARAMETER(caller);
00858 UNUSED_PARAMETER(enactor);
00859 UNUSED_PARAMETER(fargs);
00860 UNUSED_PARAMETER(nfargs);
00861 UNUSED_PARAMETER(cargs);
00862 UNUSED_PARAMETER(ncargs);
00863
00864 char *temp = mudstate.start_time.ReturnDateString();
00865 safe_str(temp, buff, bufc);
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 static const char *DayOfWeekStringLong[7] =
00880 {
00881 "Sunday",
00882 "Monday",
00883 "Tuesday",
00884 "Wednesday",
00885 "Thursday",
00886 "Friday",
00887 "Saturday"
00888 };
00889
00890 static const char *MonthTableLong[] =
00891 {
00892 "January",
00893 "February",
00894 "March",
00895 "April",
00896 "May",
00897 "June",
00898 "July",
00899 "August",
00900 "September",
00901 "October",
00902 "November",
00903 "December"
00904 };
00905
00906 static const int Map24to12[24] =
00907 {
00908 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
00909 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
00910 };
00911
00912 static FUNCTION(fun_timefmt)
00913 {
00914 UNUSED_PARAMETER(executor);
00915 UNUSED_PARAMETER(caller);
00916 UNUSED_PARAMETER(enactor);
00917 UNUSED_PARAMETER(cargs);
00918 UNUSED_PARAMETER(ncargs);
00919
00920 CLinearTimeAbsolute lta, ltaUTC;
00921 if (nfargs == 2)
00922 {
00923 ltaUTC.SetSecondsString(fargs[1]);
00924 }
00925 else
00926 {
00927 ltaUTC.GetUTC();
00928 }
00929 lta = ltaUTC;
00930 lta.UTC2Local();
00931
00932 FIELDEDTIME ft;
00933 lta.ReturnFields(&ft);
00934
00935
00936
00937 CLinearTimeDelta ltd = lta - ltaUTC;
00938 int iTZSecond = ltd.ReturnSeconds();
00939 int iTZSign;
00940 if (iTZSecond < 0)
00941 {
00942 iTZSign = '-';
00943 iTZSecond = -iTZSecond;
00944 }
00945 else
00946 {
00947 iTZSign = '+';
00948 }
00949 int iTZHour = iTZSecond / 3600;
00950 iTZSecond %= 3600;
00951 int iTZMinute = iTZSecond/60;
00952 int iHour12 = Map24to12[ft.iHour];
00953
00954
00955
00956 int iWeekOfYearSunday = (ft.iDayOfYear-ft.iDayOfWeek+6)/7;
00957 int iDayOfWeekMonday = (ft.iDayOfWeek == 0)?7:ft.iDayOfWeek;
00958 int iWeekOfYearMonday = (ft.iDayOfYear-iDayOfWeekMonday+7)/7;
00959
00960
00961
00962
00963 int iYearISO = ft.iYear;
00964 int iWeekISO = 0;
00965 int iTemp = 0;
00966 if ( ft.iMonth == 12
00967 && 35 <= 7 + ft.iDayOfMonth - iDayOfWeekMonday)
00968 {
00969 iYearISO++;
00970 iWeekISO = 1;
00971 }
00972 else if ( ft.iMonth == 1
00973 && ft.iDayOfMonth <= 3
00974 && (iTemp = 7 - ft.iDayOfMonth + iDayOfWeekMonday) >= 11)
00975 {
00976 iYearISO--;
00977 if ( iTemp == 11
00978 || ( iTemp == 12
00979 && isLeapYear(iYearISO)))
00980 {
00981 iWeekISO = 53;
00982 }
00983 else
00984 {
00985 iWeekISO = 52;
00986 }
00987 }
00988 else
00989 {
00990 iWeekISO = (7 + ft.iDayOfYear - iDayOfWeekMonday)/7;
00991 if (4 <= (7 + ft.iDayOfYear - iDayOfWeekMonday)%7)
00992 {
00993 iWeekISO++;
00994 }
00995 }
00996
00997 char *q;
00998 char *p = fargs[0];
00999 while ((q = strchr(p, '$')) != NULL)
01000 {
01001 size_t nLen = q - p;
01002 safe_copy_buf(p, nLen, buff, bufc);
01003 p = q;
01004
01005
01006
01007 p++;
01008
01009
01010
01011 int iOption = 0;
01012 int ch = *p++;
01013 if (ch == '#' || ch == 'E' || ch == 'O')
01014 {
01015 iOption = ch;
01016 ch = *p++;
01017 }
01018
01019
01020
01021 switch (ch)
01022 {
01023 case 'a':
01024 safe_str(DayOfWeekString[ft.iDayOfWeek], buff, bufc);
01025 break;
01026
01027 case 'A':
01028 safe_str(DayOfWeekStringLong[ft.iDayOfWeek], buff, bufc);
01029 break;
01030
01031 case 'b':
01032 case 'h':
01033 safe_str(monthtab[ft.iMonth-1], buff, bufc);
01034 break;
01035
01036 case 'B':
01037 safe_str(MonthTableLong[ft.iMonth-1], buff, bufc);
01038 break;
01039
01040 case 'c':
01041 if (iOption == '#')
01042 {
01043
01044
01045 safe_tprintf_str(buff, bufc, "%s, %s %d, %d, %02d:%02d:%02d",
01046 DayOfWeekStringLong[ft.iDayOfWeek],
01047 MonthTableLong[ft.iMonth-1],
01048 ft.iDayOfMonth, ft.iYear, ft.iHour, ft.iMinute,
01049 ft.iSecond);
01050 }
01051 else
01052 {
01053 safe_str(lta.ReturnDateString(7), buff, bufc);
01054 }
01055 break;
01056
01057 case 'C':
01058 safe_tprintf_str(buff, bufc, "%d", ft.iYear / 100);
01059 break;
01060
01061 case 'd':
01062 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01063 ft.iDayOfMonth);
01064 break;
01065
01066 case 'x':
01067 if (iOption == '#')
01068 {
01069 safe_tprintf_str(buff, bufc, "%s, %s %d, %d",
01070 DayOfWeekStringLong[ft.iDayOfWeek],
01071 MonthTableLong[ft.iMonth-1],
01072 ft.iDayOfMonth, ft.iYear);
01073 break;
01074 }
01075
01076
01077
01078 case 'D':
01079 safe_tprintf_str(buff, bufc, "%02d/%02d/%02d", ft.iMonth,
01080 ft.iDayOfMonth, ft.iYear % 100);
01081 break;
01082
01083 case 'e':
01084
01085 safe_tprintf_str(buff, bufc, "%2d", ft.iDayOfMonth);
01086 break;
01087
01088 case 'F':
01089 safe_tprintf_str(buff, bufc, "%d-%02d-%02d", ft.iYear, ft.iMonth,
01090 ft.iDayOfMonth);
01091 break;
01092
01093 case 'g':
01094 safe_tprintf_str(buff, bufc, "%02d", iYearISO%100);
01095 break;
01096
01097 case 'G':
01098 safe_tprintf_str(buff, bufc, "%04d", iYearISO);
01099 break;
01100
01101 case 'H':
01102 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d", ft.iHour);
01103 break;
01104
01105 case 'I':
01106 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d", iHour12);
01107 break;
01108
01109 case 'j':
01110 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%03d",
01111 ft.iDayOfYear);
01112 break;
01113
01114 case 'k':
01115 safe_tprintf_str(buff, bufc, "%2d", ft.iHour);
01116 break;
01117
01118 case 'l':
01119 safe_tprintf_str(buff, bufc, "%2d", iHour12);
01120 break;
01121
01122 case 'm':
01123 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01124 ft.iMonth);
01125 break;
01126
01127 case 'M':
01128 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01129 ft.iMinute);
01130 break;
01131
01132 case 'n':
01133 safe_str("\r\n", buff, bufc);
01134 break;
01135
01136 case 'p':
01137 safe_str((ft.iHour < 12)?"AM":"PM", buff, bufc);
01138 break;
01139
01140 case 'P':
01141 safe_str((ft.iHour < 12)?"am":"pm", buff, bufc);
01142 break;
01143
01144 case 'r':
01145 safe_tprintf_str(buff, bufc,
01146 (iOption=='#')?"%d:%02d:%02d %s":"%02d:%02d:%02d %s",
01147 iHour12, ft.iMinute, ft.iSecond,
01148 (ft.iHour<12)?"AM":"PM");
01149 break;
01150
01151 case 'R':
01152 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d:%02d":"%02d:%02d",
01153 ft.iHour, ft.iMinute);
01154 break;
01155
01156 case 's':
01157 safe_str(ltaUTC.ReturnSecondsString(7), buff, bufc);
01158 break;
01159
01160 case 'S':
01161 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01162 ft.iSecond);
01163 break;
01164
01165 case 't':
01166 safe_chr('\t', buff, bufc);
01167 break;
01168
01169 case 'X':
01170 case 'T':
01171 safe_tprintf_str(buff, bufc,
01172 (iOption=='#')?"%d:%02d:%02d":"%02d:%02d:%02d",
01173 ft.iHour, ft.iMinute, ft.iSecond);
01174 break;
01175
01176 case 'u':
01177 safe_ltoa(iDayOfWeekMonday, buff, bufc);
01178 break;
01179
01180 case 'U':
01181 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01182 iWeekOfYearSunday);
01183 break;
01184
01185 case 'V':
01186 safe_tprintf_str(buff, bufc, "%02d", iWeekISO);
01187 break;
01188
01189 case 'w':
01190 safe_ltoa(ft.iDayOfWeek, buff, bufc);
01191 break;
01192
01193 case 'W':
01194 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01195 iWeekOfYearMonday);
01196 break;
01197
01198 case 'y':
01199 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%02d",
01200 ft.iYear % 100);
01201 break;
01202
01203 case 'Y':
01204 safe_tprintf_str(buff, bufc, (iOption=='#')?"%d":"%04d",
01205 ft.iYear);
01206 break;
01207
01208 case 'z':
01209 safe_tprintf_str(buff, bufc, "%c%02d%02d", iTZSign, iTZHour,
01210 iTZMinute);
01211 break;
01212
01213 case 'Z':
01214
01215 break;
01216
01217 case '$':
01218 safe_chr(ch, buff, bufc);
01219 break;
01220
01221 default:
01222 safe_chr('$', buff, bufc);
01223 p = q + 1;
01224 break;
01225 }
01226 }
01227 safe_str(p, buff, bufc);
01228 }
01229
01230
01231
01232
01233
01234 #define GET_GET 1
01235 #define GET_XGET 2
01236 #define GET_EVAL 4
01237 #define GET_GEVAL 8
01238
01239 static void get_handler(char *buff, char **bufc, dbref executor, char *fargs[], int key)
01240 {
01241 bool bFreeBuffer = false;
01242 char *pRefAttrib = fargs[0];
01243
01244 if ( key == GET_XGET
01245 || key == GET_EVAL)
01246 {
01247 pRefAttrib = alloc_lbuf("get_handler");
01248 char *bufp = pRefAttrib;
01249 safe_tprintf_str(pRefAttrib, &bufp, "%s/%s", fargs[0], fargs[1]);
01250 bFreeBuffer = true;
01251 }
01252 dbref thing;
01253 ATTR *pattr;
01254 bool bNoMatch = !parse_attrib(executor, pRefAttrib, &thing, &pattr);
01255 if (bFreeBuffer)
01256 {
01257 free_lbuf(pRefAttrib);
01258 }
01259
01260 if (bNoMatch)
01261 {
01262 safe_nomatch(buff, bufc);
01263 return;
01264 }
01265
01266 if (!pattr)
01267 {
01268 return;
01269 }
01270
01271 if ( (pattr->flags & AF_IS_LOCK)
01272 || !bCanReadAttr(executor, thing, pattr, true))
01273 {
01274 safe_noperm(buff, bufc);
01275 return;
01276 }
01277
01278 dbref aowner;
01279 int aflags;
01280 size_t nLen = 0;
01281 char *atr_gotten = atr_pget_LEN(thing, pattr->number, &aowner, &aflags, &nLen);
01282
01283 if ( key == GET_EVAL
01284 || key == GET_GEVAL)
01285 {
01286 char *str = atr_gotten;
01287 mux_exec(buff, bufc, thing, executor, executor, EV_FIGNORE | EV_EVAL,
01288 &str, (char **)NULL, 0);
01289 }
01290 else
01291 {
01292 if (nLen)
01293 {
01294 safe_copy_buf(atr_gotten, nLen, buff, bufc);
01295 }
01296 }
01297 free_lbuf(atr_gotten);
01298 }
01299
01300 static FUNCTION(fun_get)
01301 {
01302 UNUSED_PARAMETER(caller);
01303 UNUSED_PARAMETER(enactor);
01304 UNUSED_PARAMETER(nfargs);
01305 UNUSED_PARAMETER(cargs);
01306 UNUSED_PARAMETER(ncargs);
01307
01308 get_handler(buff, bufc, executor, fargs, GET_GET);
01309 }
01310
01311 static FUNCTION(fun_xget)
01312 {
01313 UNUSED_PARAMETER(caller);
01314 UNUSED_PARAMETER(enactor);
01315 UNUSED_PARAMETER(nfargs);
01316 UNUSED_PARAMETER(cargs);
01317 UNUSED_PARAMETER(ncargs);
01318
01319 if (!*fargs[0] || !*fargs[1])
01320 {
01321 return;
01322 }
01323
01324 get_handler(buff, bufc, executor, fargs, GET_XGET);
01325 }
01326
01327
01328 static FUNCTION(fun_get_eval)
01329 {
01330 UNUSED_PARAMETER(caller);
01331 UNUSED_PARAMETER(enactor);
01332 UNUSED_PARAMETER(nfargs);
01333 UNUSED_PARAMETER(cargs);
01334 UNUSED_PARAMETER(ncargs);
01335
01336 get_handler(buff, bufc, executor, fargs, GET_GEVAL);
01337 }
01338
01339 static FUNCTION(fun_subeval)
01340 {
01341 UNUSED_PARAMETER(nfargs);
01342 UNUSED_PARAMETER(cargs);
01343 UNUSED_PARAMETER(ncargs);
01344
01345 char *str = fargs[0];
01346 mux_exec(buff, bufc, executor, caller, enactor,
01347 EV_EVAL|EV_NO_LOCATION|EV_NOFCHECK|EV_FIGNORE|EV_NO_COMPRESS,
01348 &str, (char **)NULL, 0);
01349 }
01350
01351 static FUNCTION(fun_eval)
01352 {
01353 UNUSED_PARAMETER(cargs);
01354 UNUSED_PARAMETER(ncargs);
01355
01356 if (nfargs == 1)
01357 {
01358 char *str = fargs[0];
01359 mux_exec(buff, bufc, executor, caller, enactor, EV_EVAL, &str,
01360 (char **)NULL, 0);
01361 return;
01362 }
01363 if (!*fargs[0] || !*fargs[1])
01364 {
01365 return;
01366 }
01367
01368 get_handler(buff, bufc, executor, fargs, GET_EVAL);
01369 }
01370
01371
01372
01373
01374
01375
01376 static void do_ufun(char *buff, char **bufc, dbref executor, dbref caller,
01377 dbref enactor,
01378 char *fargs[], int nfargs,
01379 char *cargs[], int ncargs,
01380 bool is_local)
01381 {
01382 UNUSED_PARAMETER(caller);
01383 UNUSED_PARAMETER(cargs);
01384 UNUSED_PARAMETER(ncargs);
01385
01386 char *atext;
01387 dbref thing;
01388 if (!parse_and_get_attrib(executor, fargs, &atext, &thing, buff, bufc))
01389 {
01390 return;
01391 }
01392
01393
01394
01395 char **preserve = NULL;
01396 int *preserve_len = NULL;
01397 if (is_local)
01398 {
01399 preserve = PushPointers(MAX_GLOBAL_REGS);
01400 preserve_len = PushIntegers(MAX_GLOBAL_REGS);
01401 save_global_regs("fun_ulocal_save", preserve, preserve_len);
01402 }
01403
01404
01405
01406 char *str = atext;
01407 mux_exec(buff, bufc, thing, executor, enactor, EV_FCHECK | EV_EVAL,
01408 &str, &(fargs[1]), nfargs - 1);
01409 free_lbuf(atext);
01410
01411
01412
01413 if (is_local)
01414 {
01415 restore_global_regs("fun_ulocal_restore", preserve, preserve_len);
01416 PopIntegers(preserve_len, MAX_GLOBAL_REGS);
01417 PopPointers(preserve, MAX_GLOBAL_REGS);
01418 }
01419 }
01420
01421 static FUNCTION(fun_u)
01422 {
01423 do_ufun(buff, bufc, executor, caller, enactor, fargs, nfargs, cargs,
01424 ncargs, false);
01425 }
01426
01427 static FUNCTION(fun_ulocal)
01428 {
01429 do_ufun(buff, bufc, executor, caller, enactor, fargs, nfargs, cargs,
01430 ncargs, true);
01431 }
01432
01433
01434
01435
01436
01437
01438 static FUNCTION(fun_parent)
01439 {
01440 UNUSED_PARAMETER(caller);
01441 UNUSED_PARAMETER(nfargs);
01442 UNUSED_PARAMETER(cargs);
01443 UNUSED_PARAMETER(ncargs);
01444
01445 dbref it = match_thing_quiet(executor, fargs[0]);
01446 if (!Good_obj(it))
01447 {
01448 safe_match_result(it, buff, bufc);
01449 return;
01450 }
01451 if ( Examinable(executor, it)
01452 || it == enactor)
01453 {
01454 safe_tprintf_str(buff, bufc, "#%d", Parent(it));
01455 }
01456 else
01457 {
01458 safe_noperm(buff, bufc);
01459 }
01460 }
01461
01462
01463
01464
01465
01466
01467 static FUNCTION(fun_mid)
01468 {
01469 UNUSED_PARAMETER(executor);
01470 UNUSED_PARAMETER(caller);
01471 UNUSED_PARAMETER(enactor);
01472 UNUSED_PARAMETER(nfargs);
01473 UNUSED_PARAMETER(cargs);
01474 UNUSED_PARAMETER(ncargs);
01475
01476
01477
01478
01479 int iPosition0 = mux_atol(fargs[1]);
01480 int nLength = mux_atol(fargs[2]);
01481 if (nLength < 0)
01482 {
01483 iPosition0 += nLength;
01484 nLength = -nLength;
01485 }
01486
01487 if (iPosition0 < 0)
01488 {
01489 iPosition0 = 0;
01490 }
01491 else if (LBUF_SIZE-1 < iPosition0)
01492 {
01493 iPosition0 = LBUF_SIZE-1;
01494 }
01495
01496
01497
01498
01499 struct ANSI_In_Context aic;
01500 ANSI_String_In_Init(&aic, fargs[0], ANSI_ENDGOAL_NORMAL);
01501 int nDone;
01502 ANSI_String_Skip(&aic, iPosition0, &nDone);
01503 if (nDone < iPosition0)
01504 {
01505 return;
01506 }
01507
01508 struct ANSI_Out_Context aoc;
01509 int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01510 ANSI_String_Out_Init(&aoc, *bufc, nBufferAvailable, nLength, ANSI_ENDGOAL_NORMAL);
01511 ANSI_String_Copy(&aoc, &aic, nLength);
01512 int nSize = ANSI_String_Finalize(&aoc, &nDone);
01513 *bufc += nSize;
01514 }
01515
01516
01517
01518
01519
01520 static FUNCTION(fun_right)
01521 {
01522 UNUSED_PARAMETER(executor);
01523 UNUSED_PARAMETER(caller);
01524 UNUSED_PARAMETER(enactor);
01525 UNUSED_PARAMETER(nfargs);
01526 UNUSED_PARAMETER(cargs);
01527 UNUSED_PARAMETER(ncargs);
01528
01529
01530
01531 long lLength = mux_atol(fargs[1]);
01532 size_t nLength;
01533 if (lLength < 0)
01534 {
01535 safe_range(buff, bufc);
01536 return;
01537 }
01538 else if (LBUF_SIZE-1 < lLength)
01539 {
01540 nLength = LBUF_SIZE-1;
01541 }
01542 else
01543 {
01544 nLength = lLength;
01545 }
01546
01547
01548
01549 size_t iPosition1 = strlen(strip_ansi(fargs[0]));
01550
01551
01552
01553 size_t iPosition0;
01554 if (iPosition1 <= nLength)
01555 {
01556 iPosition0 = 0;
01557 }
01558 else
01559 {
01560 iPosition0 = iPosition1 - nLength;
01561 }
01562
01563
01564
01565
01566 struct ANSI_In_Context aic;
01567 ANSI_String_In_Init(&aic, fargs[0], ANSI_ENDGOAL_NORMAL);
01568 int nDone;
01569 ANSI_String_Skip(&aic, iPosition0, &nDone);
01570 if ((size_t)nDone < iPosition0)
01571 {
01572 return;
01573 }
01574
01575 struct ANSI_Out_Context aoc;
01576 int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
01577 ANSI_String_Out_Init(&aoc, *bufc, nBufferAvailable, nLength, ANSI_ENDGOAL_NORMAL);
01578 ANSI_String_Copy(&aoc, &aic, nLength);
01579 int nSize = ANSI_String_Finalize(&aoc, &nDone);
01580 *bufc += nSize;
01581 }
01582
01583
01584
01585
01586
01587
01588 static FUNCTION(fun_first)
01589 {
01590
01591
01592 if (nfargs == 0)
01593 {
01594 return;
01595 }
01596
01597 SEP sep;
01598 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
01599 {
01600 return;
01601 }
01602
01603 char *s = trim_space_sep(fargs[0], &sep);
01604 char *first = split_token(&s, &sep);
01605 if (first)
01606 {
01607 safe_str(first, buff, bufc);
01608 }
01609 }
01610
01611
01612
01613
01614
01615
01616
01617 static FUNCTION(fun_rest)
01618 {
01619
01620
01621 if (nfargs == 0)
01622 {
01623 return;
01624 }
01625
01626 SEP sep;
01627 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
01628 {
01629 return;
01630 }
01631
01632 char *s = trim_space_sep(fargs[0], &sep);
01633 split_token(&s, &sep);
01634 if (s)
01635 {
01636 safe_str(s, buff, bufc);
01637 }
01638 }
01639
01640
01641
01642
01643
01644
01645 static FUNCTION(fun_v)
01646 {
01647 UNUSED_PARAMETER(nfargs);
01648
01649 dbref aowner;
01650 int aflags;
01651 char *sbuf, *sbufc, *tbuf, *str;
01652 ATTR *ap;
01653
01654 tbuf = fargs[0];
01655 if (mux_AttrNameInitialSet(tbuf[0]) && tbuf[1])
01656 {
01657
01658
01659
01660 ap = atr_str(fargs[0]);
01661 if (!ap)
01662 {
01663 return;
01664 }
01665
01666
01667
01668
01669 size_t nLen;
01670 tbuf = atr_pget_LEN(executor, ap->number, &aowner, &aflags, &nLen);
01671 if (See_attr(executor, executor, ap))
01672 {
01673 safe_copy_buf(tbuf, nLen, buff, bufc);
01674 }
01675 free_lbuf(tbuf);
01676 return;
01677 }
01678
01679
01680
01681 sbuf = alloc_sbuf("fun_v");
01682 sbufc = sbuf;
01683 safe_sb_chr('%', sbuf, &sbufc);
01684 safe_sb_str(fargs[0], sbuf, &sbufc);
01685 *sbufc = '\0';
01686 str = sbuf;
01687 mux_exec(buff, bufc, executor, caller, enactor, EV_EVAL|EV_FIGNORE, &str,
01688 cargs, ncargs);
01689 free_sbuf(sbuf);
01690 }
01691
01692
01693
01694
01695
01696
01697 static FUNCTION(fun_s)
01698 {
01699 UNUSED_PARAMETER(nfargs);
01700
01701 char *str = fargs[0];
01702 mux_exec(buff, bufc, executor, caller, enactor, EV_FIGNORE | EV_EVAL, &str,
01703 cargs, ncargs);
01704 }
01705
01706
01707
01708
01709
01710
01711 static FUNCTION(fun_con)
01712 {
01713 UNUSED_PARAMETER(caller);
01714 UNUSED_PARAMETER(nfargs);
01715 UNUSED_PARAMETER(cargs);
01716 UNUSED_PARAMETER(ncargs);
01717
01718 dbref it = match_thing_quiet(executor, fargs[0]);
01719 if (!Good_obj(it))
01720 {
01721 safe_match_result(it, buff, bufc);
01722 }
01723 else if (Has_contents(it))
01724 {
01725 if ( Examinable(executor, it)
01726 || where_is(executor) == it
01727 || it == enactor)
01728 {
01729 safe_tprintf_str(buff, bufc, "#%d", Contents(it));
01730 }
01731 else
01732 {
01733 safe_noperm(buff, bufc);
01734 }
01735 }
01736 else
01737 {
01738 safe_nothing(buff, bufc);
01739 }
01740 }
01741
01742
01743
01744
01745
01746
01747 static FUNCTION(fun_exit)
01748 {
01749 UNUSED_PARAMETER(caller);
01750 UNUSED_PARAMETER(enactor);
01751 UNUSED_PARAMETER(nfargs);
01752 UNUSED_PARAMETER(cargs);
01753 UNUSED_PARAMETER(ncargs);
01754
01755 dbref it = match_thing_quiet(executor, fargs[0]);
01756 if (!Good_obj(it))
01757 {
01758 safe_match_result(it, buff, bufc);
01759 }
01760 else if ( Has_exits(it)
01761 && Good_obj(Exits(it)))
01762 {
01763 int key = 0;
01764 if (Examinable(executor, it))
01765 {
01766 key |= VE_LOC_XAM;
01767 }
01768 if (Dark(it))
01769 {
01770 key |= VE_LOC_DARK;
01771 }
01772 dbref exit;
01773 DOLIST(exit, Exits(it))
01774 {
01775 if (exit_visible(exit, executor, key))
01776 {
01777 safe_tprintf_str(buff, bufc, "#%d", exit);
01778 return;
01779 }
01780 }
01781 safe_notfound(buff, bufc);
01782 }
01783 else
01784 {
01785 safe_nothing(buff, bufc);
01786 }
01787 }
01788
01789
01790
01791
01792
01793
01794 static FUNCTION(fun_next)
01795 {
01796 UNUSED_PARAMETER(caller);
01797 UNUSED_PARAMETER(enactor);
01798 UNUSED_PARAMETER(nfargs);
01799 UNUSED_PARAMETER(cargs);
01800 UNUSED_PARAMETER(ncargs);
01801
01802 dbref it = match_thing_quiet(executor, fargs[0]);
01803 if (!Good_obj(it))
01804 {
01805 safe_match_result(it, buff, bufc);
01806 }
01807 else if (Has_siblings(it))
01808 {
01809 dbref loc = where_is(it);
01810 bool ex_here = Good_obj(loc) ? Examinable(executor, loc) : false;
01811 if ( ex_here
01812 || loc == executor
01813 || loc == where_is(executor))
01814 {
01815 if (!isExit(it))
01816 {
01817 safe_tprintf_str(buff, bufc, "#%d", Next(it));
01818 }
01819 else
01820 {
01821 int key = 0;
01822 if (ex_here)
01823 {
01824 key |= VE_LOC_XAM;
01825 }
01826 if (Dark(loc))
01827 {
01828 key |= VE_LOC_DARK;
01829 }
01830 dbref exit;
01831 DOLIST(exit, it)
01832 {
01833 if ( exit != it
01834 && exit_visible(exit, executor, key))
01835 {
01836 safe_tprintf_str(buff, bufc, "#%d", exit);
01837 return;
01838 }
01839 }
01840 safe_notfound(buff, bufc);
01841 }
01842 }
01843 else
01844 {
01845 safe_noperm(buff, bufc);
01846 }
01847 }
01848 else
01849 {
01850 safe_nothing(buff, bufc);
01851 }
01852 }
01853
01854
01855
01856
01857
01858
01859 static FUNCTION(fun_loc)
01860 {
01861 UNUSED_PARAMETER(caller);
01862 UNUSED_PARAMETER(nfargs);
01863 UNUSED_PARAMETER(cargs);
01864 UNUSED_PARAMETER(ncargs);
01865
01866 dbref it = match_thing_quiet(executor, fargs[0]);
01867 if (!Good_obj(it))
01868 {
01869 safe_match_result(it, buff, bufc);
01870 }
01871 else if (locatable(executor, it, enactor))
01872 {
01873 safe_tprintf_str(buff, bufc, "#%d", Location(it));
01874 }
01875 else
01876 {
01877 safe_nothing(buff, bufc);
01878 }
01879 }
01880
01881
01882
01883
01884
01885
01886 static FUNCTION(fun_where)
01887 {
01888 UNUSED_PARAMETER(caller);
01889 UNUSED_PARAMETER(nfargs);
01890 UNUSED_PARAMETER(cargs);
01891 UNUSED_PARAMETER(ncargs);
01892
01893 dbref it = match_thing_quiet(executor, fargs[0]);
01894 if (!Good_obj(it))
01895 {
01896 safe_match_result(it, buff, bufc);
01897 }
01898 else if (locatable(executor, it, enactor))
01899 {
01900 safe_tprintf_str(buff, bufc, "#%d", where_is(it));
01901 }
01902 else
01903 {
01904 safe_nothing(buff, bufc);
01905 }
01906 }
01907
01908
01909
01910
01911
01912
01913 static FUNCTION(fun_rloc)
01914 {
01915 UNUSED_PARAMETER(caller);
01916 UNUSED_PARAMETER(nfargs);
01917 UNUSED_PARAMETER(cargs);
01918 UNUSED_PARAMETER(ncargs);
01919
01920 int levels = mux_atol(fargs[1]);
01921 if (levels > mudconf.ntfy_nest_lim)
01922 {
01923 levels = mudconf.ntfy_nest_lim;
01924 }
01925
01926 dbref it = match_thing_quiet(executor, fargs[0]);
01927 if (!Good_obj(it))
01928 {
01929 safe_match_result(it, buff, bufc);
01930 }
01931 else if (locatable(executor, it, enactor))
01932 {
01933 for (int i = 0; i < levels; i++)
01934 {
01935 if ( Good_obj(it)
01936 && ( isExit(it)
01937 || Has_location(it)))
01938 {
01939 it = Location(it);
01940 }
01941 else
01942 {
01943 break;
01944 }
01945 }
01946 safe_tprintf_str(buff, bufc, "#%d", it);
01947 }
01948 else
01949 {
01950 safe_nothing(buff, bufc);
01951 }
01952 }
01953
01954
01955
01956
01957
01958
01959 static FUNCTION(fun_room)
01960 {
01961 UNUSED_PARAMETER(caller);
01962 UNUSED_PARAMETER(nfargs);
01963 UNUSED_PARAMETER(cargs);
01964 UNUSED_PARAMETER(ncargs);
01965
01966 dbref it = match_thing_quiet(executor, fargs[0]);
01967 if (!Good_obj(it))
01968 {
01969 safe_match_result(it, buff, bufc);
01970 }
01971 else if (locatable(executor, it, enactor))
01972 {
01973 int count;
01974 for (count = mudconf.ntfy_nest_lim; count > 0; count--)
01975 {
01976 it = Location(it);
01977 if (!Good_obj(it))
01978 {
01979 break;
01980 }
01981 if (isRoom(it))
01982 {
01983 safe_tprintf_str(buff, bufc, "#%d", it);
01984 return;
01985 }
01986 }
01987 safe_nothing(buff, bufc);
01988 }
01989 else if (isRoom(it))
01990 {
01991 safe_tprintf_str(buff, bufc, "#%d", it);
01992 }
01993 else
01994 {
01995 safe_nothing(buff, bufc);
01996 }
01997 }
01998
01999
02000
02001
02002
02003
02004 static FUNCTION(fun_owner)
02005 {
02006 UNUSED_PARAMETER(caller);
02007 UNUSED_PARAMETER(enactor);
02008 UNUSED_PARAMETER(nfargs);
02009 UNUSED_PARAMETER(cargs);
02010 UNUSED_PARAMETER(ncargs);
02011
02012 dbref it;
02013 ATTR *pattr;
02014 if (parse_attrib(executor, fargs[0], &it, &pattr))
02015 {
02016 if ( !pattr
02017 || !See_attr(executor, it, pattr))
02018 {
02019 safe_nothing(buff, bufc);
02020 return;
02021 }
02022 else
02023 {
02024 dbref aowner;
02025 int aflags;
02026 atr_pget_info(it, pattr->number, &aowner, &aflags);
02027 it = aowner;
02028 }
02029 }
02030 else
02031 {
02032 it = match_thing_quiet(executor, fargs[0]);
02033 if (!Good_obj(it))
02034 {
02035 safe_match_result(it, buff, bufc);
02036 return;
02037 }
02038 it = Owner(it);
02039 }
02040 safe_tprintf_str(buff, bufc, "#%d", it);
02041 }
02042
02043
02044
02045
02046
02047
02048 static FUNCTION(fun_controls)
02049 {
02050 UNUSED_PARAMETER(caller);
02051 UNUSED_PARAMETER(enactor);
02052 UNUSED_PARAMETER(nfargs);
02053 UNUSED_PARAMETER(cargs);
02054 UNUSED_PARAMETER(ncargs);
02055
02056 dbref x = match_thing_quiet(executor, fargs[0]);
02057 if (!Good_obj(x))
02058 {
02059 safe_match_result(x, buff, bufc);
02060 safe_str(" (ARG1)", buff, bufc);
02061 return;
02062 }
02063 dbref y = match_thing_quiet(executor, fargs[1]);
02064 if (!Good_obj(y))
02065 {
02066 safe_match_result(x, buff, bufc);
02067 safe_str(" (ARG2)", buff, bufc);
02068 return;
02069 }
02070 safe_bool(Controls(x,y), buff, bufc);
02071 }
02072
02073
02074
02075
02076
02077
02078 static FUNCTION(fun_fullname)
02079 {
02080 UNUSED_PARAMETER(caller);
02081 UNUSED_PARAMETER(enactor);
02082 UNUSED_PARAMETER(nfargs);
02083 UNUSED_PARAMETER(cargs);
02084 UNUSED_PARAMETER(ncargs);
02085
02086 dbref it = match_thing_quiet(executor, fargs[0]);
02087 if (!Good_obj(it))
02088 {
02089 safe_match_result(it, buff, bufc);
02090 return;
02091 }
02092 if (!mudconf.read_rem_name)
02093 {
02094 if ( !nearby_or_control(executor, it)
02095 && !isPlayer(it))
02096 {
02097 safe_str("#-1 TOO FAR AWAY TO SEE", buff, bufc);
02098 return;
02099 }
02100 }
02101 safe_str(Name(it), buff, bufc);
02102 }
02103
02104
02105
02106
02107
02108
02109 static FUNCTION(fun_name)
02110 {
02111 UNUSED_PARAMETER(caller);
02112 UNUSED_PARAMETER(enactor);
02113 UNUSED_PARAMETER(nfargs);
02114 UNUSED_PARAMETER(cargs);
02115 UNUSED_PARAMETER(ncargs);
02116
02117 dbref it = match_thing_quiet(executor, fargs[0]);
02118 if (!Good_obj(it))
02119 {
02120 safe_match_result(it, buff, bufc);
02121 return;
02122 }
02123 if (!mudconf.read_rem_name)
02124 {
02125 if ( !nearby_or_control(executor, it)
02126 && !isPlayer(it)
02127 && !Long_Fingers(executor))
02128 {
02129 safe_str("#-1 TOO FAR AWAY TO SEE", buff, bufc);
02130 return;
02131 }
02132 }
02133 char *temp = *bufc;
02134 safe_str(Name(it), buff, bufc);
02135 if (isExit(it))
02136 {
02137 char *s;
02138 for (s = temp; (s != *bufc) && (*s != ';'); s++)
02139 {
02140
02141
02142 ;
02143 }
02144 if (*s == ';')
02145 {
02146 *bufc = s;
02147 }
02148 }
02149 }
02150
02151
02152
02153
02154
02155
02156
02157 static FUNCTION(fun_match)
02158 {
02159 SEP sep;
02160 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
02161 {
02162 return;
02163 }
02164
02165
02166
02167
02168 int wcount = 1;
02169 char *s = trim_space_sep(fargs[0], &sep);
02170 do {
02171 char *r = split_token(&s, &sep);
02172 mudstate.wild_invk_ctr = 0;
02173 if (quick_wild(fargs[1], r))
02174 {
02175 safe_ltoa(wcount, buff, bufc);
02176 return;
02177 }
02178 wcount++;
02179 } while (s);
02180 safe_chr('0', buff, bufc);
02181 }
02182
02183 static FUNCTION(fun_strmatch)
02184 {
02185 UNUSED_PARAMETER(executor);
02186 UNUSED_PARAMETER(caller);
02187 UNUSED_PARAMETER(enactor);
02188 UNUSED_PARAMETER(nfargs);
02189 UNUSED_PARAMETER(cargs);
02190 UNUSED_PARAMETER(ncargs);
02191
02192
02193
02194 mudstate.wild_invk_ctr = 0;
02195 bool cc = quick_wild(fargs[1], fargs[0]);
02196 safe_bool(cc, buff, bufc);
02197 }
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209 static FUNCTION(fun_extract)
02210 {
02211 SEP sep;
02212 if (!OPTIONAL_DELIM(4, sep, DELIM_DFLT|DELIM_STRING))
02213 {
02214 return;
02215 }
02216
02217 SEP osep = sep;
02218 if (!OPTIONAL_DELIM(5, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
02219 {
02220 return;
02221 }
02222
02223 int start = mux_atol(fargs[1]);
02224 int len = mux_atol(fargs[2]);
02225
02226 if ( start < 1
02227 || len < 1)
02228 {
02229 return;
02230 }
02231
02232
02233
02234 start--;
02235 char *s = trim_space_sep(fargs[0], &sep);
02236 while ( start
02237 && s)
02238 {
02239 s = next_token(s, &sep);
02240 start--;
02241 }
02242
02243
02244
02245 if (!s || !*s)
02246 {
02247 return;
02248 }
02249
02250
02251
02252 bool bFirst = true;
02253 while ( len
02254 && s)
02255 {
02256 char *t = split_token(&s, &sep);
02257 if (!bFirst)
02258 {
02259 print_sep(&osep, buff, bufc);
02260 }
02261 else
02262 {
02263 bFirst = false;
02264 }
02265 safe_str(t, buff, bufc);
02266 len--;
02267 }
02268 }
02269
02270
02271
02272 bool xlate(char *arg)
02273 {
02274 const char *p = arg;
02275 if (p[0] == '#')
02276 {
02277 if (p[1] == '-')
02278 {
02279
02280
02281
02282
02283 return false;
02284 }
02285 return true;
02286 }
02287
02288 PARSE_FLOAT_RESULT pfr;
02289 if (ParseFloat(&pfr, p))
02290 {
02291
02292
02293 if (pfr.iString)
02294 {
02295
02296
02297 return false;
02298 }
02299
02300
02301
02302
02303
02304
02305 while (pfr.nDigitsA--)
02306 {
02307 if (*pfr.pDigitsA != '0')
02308 {
02309 return true;
02310 }
02311 pfr.pDigitsA++;
02312 }
02313 while (pfr.nDigitsB--)
02314 {
02315 if (*pfr.pDigitsB != '0')
02316 {
02317 return true;
02318 }
02319 pfr.pDigitsB++;
02320 }
02321 return false;
02322 }
02323 while (mux_isspace(*p))
02324 {
02325 p++;
02326 }
02327 if (p[0] == '\0')
02328 {
02329 return false;
02330 }
02331 return true;
02332 }
02333
02334
02335
02336
02337
02338
02339
02340 static FUNCTION(fun_index)
02341 {
02342 UNUSED_PARAMETER(executor);
02343 UNUSED_PARAMETER(caller);
02344 UNUSED_PARAMETER(enactor);
02345 UNUSED_PARAMETER(nfargs);
02346 UNUSED_PARAMETER(cargs);
02347 UNUSED_PARAMETER(ncargs);
02348
02349 int start, end;
02350 char c, *s, *p;
02351
02352 s = fargs[0];
02353 c = *fargs[1];
02354 start = mux_atol(fargs[2]);
02355 end = mux_atol(fargs[3]);
02356
02357 if ((start < 1) || (end < 1) || (*s == '\0'))
02358 {
02359 return;
02360 }
02361 if (c == '\0')
02362 {
02363 c = ' ';
02364 }
02365
02366
02367
02368 start--;
02369 while (start && s && *s)
02370 {
02371 if ((s = strchr(s, c)) != NULL)
02372 {
02373 s++;
02374 }
02375 start--;
02376 }
02377
02378
02379
02380 while (s && (*s == ' '))
02381 {
02382 s++;
02383 }
02384 if (!s || !*s)
02385 {
02386 return;
02387 }
02388
02389
02390
02391 p = s;
02392 while (end && p && *p)
02393 {
02394 if ((p = strchr(p, c)) != NULL)
02395 {
02396 if (--end == 0)
02397 {
02398 do {
02399 p--;
02400 } while ((*p == ' ') && (p > s));
02401 *(++p) = '\0';
02402 safe_str(s, buff, bufc);
02403 return;
02404 }
02405 else
02406 {
02407 p++;
02408 }
02409 }
02410 }
02411
02412
02413
02414 safe_str(s, buff, bufc);
02415 }
02416
02417
02418 static FUNCTION(fun_cat)
02419 {
02420 UNUSED_PARAMETER(executor);
02421 UNUSED_PARAMETER(caller);
02422 UNUSED_PARAMETER(enactor);
02423 UNUSED_PARAMETER(cargs);
02424 UNUSED_PARAMETER(ncargs);
02425
02426 if (nfargs)
02427 {
02428 safe_str(fargs[0], buff, bufc);
02429 for (int i = 1; i < nfargs; i++)
02430 {
02431 safe_chr(' ', buff, bufc);
02432 safe_str(fargs[i], buff, bufc);
02433 }
02434 }
02435 }
02436
02437 static FUNCTION(fun_version)
02438 {
02439 UNUSED_PARAMETER(executor);
02440 UNUSED_PARAMETER(caller);
02441 UNUSED_PARAMETER(enactor);
02442 UNUSED_PARAMETER(fargs);
02443 UNUSED_PARAMETER(nfargs);
02444 UNUSED_PARAMETER(cargs);
02445 UNUSED_PARAMETER(ncargs);
02446
02447 safe_str(mudstate.version, buff, bufc);
02448 }
02449
02450 static FUNCTION(fun_strlen)
02451 {
02452 UNUSED_PARAMETER(executor);
02453 UNUSED_PARAMETER(caller);
02454 UNUSED_PARAMETER(enactor);
02455 UNUSED_PARAMETER(cargs);
02456 UNUSED_PARAMETER(ncargs);
02457
02458 size_t n = 0;
02459 if (nfargs >= 1)
02460 {
02461 strip_ansi(fargs[0], &n);
02462 }
02463 safe_ltoa(n, buff, bufc);
02464 }
02465
02466 static FUNCTION(fun_strmem)
02467 {
02468 UNUSED_PARAMETER(executor);
02469 UNUSED_PARAMETER(caller);
02470 UNUSED_PARAMETER(enactor);
02471 UNUSED_PARAMETER(cargs);
02472 UNUSED_PARAMETER(ncargs);
02473
02474 size_t n = 0;
02475 if (nfargs >= 1)
02476 {
02477 n = strlen(fargs[0]);
02478 }
02479 safe_ltoa(n, buff, bufc);
02480 }
02481
02482 static FUNCTION(fun_num)
02483 {
02484 UNUSED_PARAMETER(caller);
02485 UNUSED_PARAMETER(enactor);
02486 UNUSED_PARAMETER(nfargs);
02487 UNUSED_PARAMETER(cargs);
02488 UNUSED_PARAMETER(ncargs);
02489
02490 safe_tprintf_str(buff, bufc, "#%d", match_thing_quiet(executor, fargs[0]));
02491 }
02492
02493 static void internalPlayerFind
02494 (
02495 char* buff,
02496 char** bufc,
02497 dbref player,
02498 char* name,
02499 int bVerifyPlayer
02500 )
02501 {
02502 dbref thing;
02503 if (*name == '#')
02504 {
02505 thing = match_thing_quiet(player, name);
02506 if (bVerifyPlayer)
02507 {
02508 if (!Good_obj(thing))
02509 {
02510 safe_match_result(thing, buff, bufc);
02511 return;
02512 }
02513 if (!isPlayer(thing))
02514 {
02515 safe_nomatch(buff, bufc);
02516 return;
02517 }
02518 }
02519 }
02520 else
02521 {
02522 char *nptr = name;
02523 if (*nptr == '*')
02524 {
02525
02526
02527 nptr++;
02528 }
02529 thing = lookup_player(player, nptr, true);
02530 if ( (!Good_obj(thing))
02531 || (!isPlayer(thing) && bVerifyPlayer))
02532 {
02533 safe_nomatch(buff, bufc);
02534 return;
02535 }
02536 }
02537 ITL pContext;
02538 ItemToList_Init(&pContext, buff, bufc, '#');
02539 ItemToList_AddInteger(&pContext, thing);
02540 ItemToList_Final(&pContext);
02541 }
02542
02543
02544 static FUNCTION(fun_pmatch)
02545 {
02546 UNUSED_PARAMETER(caller);
02547 UNUSED_PARAMETER(enactor);
02548 UNUSED_PARAMETER(nfargs);
02549 UNUSED_PARAMETER(cargs);
02550 UNUSED_PARAMETER(ncargs);
02551
02552 internalPlayerFind(buff, bufc, executor, fargs[0], true);
02553 }
02554
02555 static FUNCTION(fun_pfind)
02556 {
02557 UNUSED_PARAMETER(caller);
02558 UNUSED_PARAMETER(enactor);
02559 UNUSED_PARAMETER(nfargs);
02560 UNUSED_PARAMETER(cargs);
02561 UNUSED_PARAMETER(ncargs);
02562
02563 internalPlayerFind(buff, bufc, executor, fargs[0], false);
02564 }
02565
02566
02567
02568
02569
02570
02571 static FUNCTION(fun_comp)
02572 {
02573 UNUSED_PARAMETER(executor);
02574 UNUSED_PARAMETER(caller);
02575 UNUSED_PARAMETER(enactor);
02576 UNUSED_PARAMETER(nfargs);
02577 UNUSED_PARAMETER(cargs);
02578 UNUSED_PARAMETER(ncargs);
02579
02580 int x;
02581
02582 x = strcmp(fargs[0], fargs[1]);
02583 if (x < 0)
02584 {
02585 safe_str("-1", buff, bufc);
02586 }
02587 else
02588 {
02589 safe_bool((x != 0), buff, bufc);
02590 }
02591 }
02592
02593 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
02594 static FUNCTION(fun_cansee)
02595 {
02596 UNUSED_PARAMETER(caller);
02597 UNUSED_PARAMETER(enactor);
02598 UNUSED_PARAMETER(cargs);
02599 UNUSED_PARAMETER(ncargs);
02600
02601 dbref looker = match_thing_quiet(executor, fargs[0]);
02602 if (!Good_obj(looker))
02603 {
02604 safe_match_result(looker, buff, bufc);
02605 safe_str(" (LOOKER)", buff, bufc);
02606 return;
02607 }
02608 dbref lookee = match_thing_quiet(executor, fargs[1]);
02609 if (!Good_obj(lookee))
02610 {
02611 safe_match_result(looker, buff, bufc);
02612 safe_str(" (LOOKEE)", buff, bufc);
02613 return;
02614 }
02615 int mode;
02616 if (nfargs == 3)
02617 {
02618 mode = mux_atol(fargs[2]);
02619 switch (mode)
02620 {
02621 case ACTION_IS_STATIONARY:
02622 case ACTION_IS_MOVING:
02623 case ACTION_IS_TALKING:
02624 break;
02625
02626 default:
02627 mode = ACTION_IS_STATIONARY;
02628 break;
02629 }
02630 }
02631 else
02632 {
02633 mode = ACTION_IS_STATIONARY;
02634 }
02635
02636
02637
02638 int Realm_Do = DoThingToThingVisibility(looker, lookee, mode);
02639 bool bResult = false;
02640 if ((Realm_Do & REALM_DO_MASK) != REALM_DO_HIDDEN_FROM_YOU)
02641 {
02642 #ifdef REALITY_LVLS
02643 bResult = (!Dark(lookee) && IsReal(looker, lookee));
02644 #else
02645 bResult = !Dark(lookee);
02646 #endif
02647 }
02648 safe_bool(bResult, buff, bufc);
02649 }
02650 #endif
02651
02652
02653
02654
02655
02656
02657 static FUNCTION(fun_lcon)
02658 {
02659 UNUSED_PARAMETER(caller);
02660 UNUSED_PARAMETER(nfargs);
02661 UNUSED_PARAMETER(cargs);
02662 UNUSED_PARAMETER(ncargs);
02663
02664 dbref it = match_thing_quiet(executor, fargs[0]);
02665 if (!Good_obj(it))
02666 {
02667 safe_match_result(it, buff, bufc);
02668 return;
02669 }
02670 if (!Has_contents(it))
02671 {
02672 safe_nothing(buff, bufc);
02673 return;
02674 }
02675 if ( Examinable(executor, it)
02676 || Location(executor) == it
02677 || it == enactor)
02678 {
02679 dbref thing;
02680 ITL pContext;
02681 ItemToList_Init(&pContext, buff, bufc, '#');
02682 DOLIST(thing, Contents(it))
02683 {
02684 #ifdef WOD_REALMS
02685 int iRealmAction = DoThingToThingVisibility(executor, thing,
02686 ACTION_IS_STATIONARY);
02687 if (iRealmAction != REALM_DO_HIDDEN_FROM_YOU)
02688 {
02689 #endif
02690 if ( Can_Hide(thing)
02691 && Hidden(thing)
02692 && !See_Hidden(executor))
02693 {
02694 continue;
02695 }
02696
02697 if (!ItemToList_AddInteger(&pContext, thing))
02698 {
02699 break;
02700 }
02701 #ifdef WOD_REALMS
02702 }
02703 #endif
02704 }
02705 ItemToList_Final(&pContext);
02706 }
02707 else
02708 {
02709 safe_noperm(buff, bufc);
02710 }
02711 }
02712
02713
02714
02715
02716
02717
02718 static FUNCTION(fun_lexits)
02719 {
02720 UNUSED_PARAMETER(caller);
02721 UNUSED_PARAMETER(nfargs);
02722 UNUSED_PARAMETER(cargs);
02723 UNUSED_PARAMETER(ncargs);
02724
02725 dbref it = match_thing_quiet(executor, fargs[0]);
02726 if (!Good_obj(it))
02727 {
02728 safe_match_result(it, buff, bufc);
02729 return;
02730 }
02731 if (!Has_exits(it))
02732 {
02733 safe_nothing(buff, bufc);
02734 return;
02735 }
02736 bool bExam = Examinable(executor, it);
02737 if ( !bExam
02738 && where_is(executor) != it
02739 && it != enactor)
02740 {
02741 safe_noperm(buff, bufc);
02742 return;
02743 }
02744
02745
02746
02747 bool bDone = false;
02748 dbref parent;
02749 int lev;
02750 ITL pContext;
02751 ItemToList_Init(&pContext, buff, bufc, '#');
02752 ITER_PARENTS(it, parent, lev)
02753 {
02754
02755
02756 if (!Has_exits(parent))
02757 {
02758 continue;
02759 }
02760 int key = 0;
02761 if (Examinable(executor, parent))
02762 {
02763 key |= VE_LOC_XAM;
02764 }
02765 if (Dark(parent))
02766 {
02767 key |= VE_LOC_DARK;
02768 }
02769 if (Dark(it))
02770 {
02771 key |= VE_BASE_DARK;
02772 }
02773
02774 dbref thing;
02775 DOLIST(thing, Exits(parent))
02776 {
02777 if ( exit_visible(thing, executor, key)
02778 && !ItemToList_AddInteger(&pContext, thing))
02779 {
02780 bDone = true;
02781 break;
02782 }
02783 }
02784 if (bDone)
02785 {
02786 break;
02787 }
02788 }
02789 ItemToList_Final(&pContext);
02790 }
02791
02792
02793
02794
02795 FUNCTION(fun_entrances)
02796 {
02797 UNUSED_PARAMETER(caller);
02798 UNUSED_PARAMETER(enactor);
02799 UNUSED_PARAMETER(cargs);
02800 UNUSED_PARAMETER(ncargs);
02801
02802 char *p;
02803 dbref i;
02804
02805 dbref low_bound = 0;
02806 if (3 <= nfargs)
02807 {
02808 p = fargs[2];
02809 if (NUMBER_TOKEN == p[0])
02810 {
02811 p++;
02812 }
02813 i = mux_atol(p);
02814 if (Good_dbref(i))
02815 {
02816 low_bound = i;
02817 }
02818 }
02819
02820 dbref high_bound = mudstate.db_top - 1;
02821 if (4 == nfargs)
02822 {
02823 p = fargs[3];
02824 if (NUMBER_TOKEN == p[0])
02825 {
02826 p++;
02827 }
02828 i = mux_atol(p);
02829 if (Good_dbref(i))
02830 {
02831 high_bound = i;
02832 }
02833 }
02834
02835 bool find_ex = false;
02836 bool find_th = false;
02837 bool find_pl = false;
02838 bool find_rm = false;
02839
02840 if (2 <= nfargs)
02841 {
02842 for (p = fargs[1]; *p; p++)
02843 {
02844 switch(mux_toupper(*p))
02845 {
02846 case 'A':
02847 find_ex = find_th = find_pl = find_rm = true;
02848 break;
02849
02850 case 'E':
02851 find_ex = true;
02852 break;
02853
02854 case 'T':
02855 find_th = true;
02856 break;
02857
02858 case 'P':
02859 find_pl = true;
02860 break;
02861
02862 case 'R':
02863 find_rm = true;
02864 break;
02865
02866 default:
02867 safe_str("#-1 INVALID TYPE", buff, bufc);
02868 return;
02869 }
02870 }
02871 }
02872
02873 if (!(find_ex || find_th || find_pl || find_rm))
02874 {
02875 find_ex = find_th = find_pl = find_rm = true;
02876 }
02877
02878 dbref thing;
02879 if ( nfargs == 0
02880 || *fargs[0] == '\0')
02881 {
02882 if (Has_location(executor))
02883 {
02884 thing = Location(executor);
02885 }
02886 else
02887 {
02888 thing = executor;
02889 }
02890 if (!Good_obj(thing))
02891 {
02892 safe_nothing(buff, bufc);
02893 return;
02894 }
02895 }
02896 else
02897 {
02898 init_match(executor, fargs[0], NOTYPE);
02899 match_everything(MAT_EXIT_PARENTS);
02900 thing = noisy_match_result();
02901 if (!Good_obj(thing))
02902 {
02903 safe_nothing(buff, bufc);
02904 return;
02905 }
02906 }
02907
02908 if (!payfor(executor, mudconf.searchcost))
02909 {
02910 notify(executor, tprintf("You don't have enough %s.",
02911 mudconf.many_coins));
02912 safe_nothing(buff, bufc);
02913 return;
02914 }
02915
02916 int control_thing = Examinable(executor, thing);
02917 ITL itl;
02918 ItemToList_Init(&itl, buff, bufc, '#');
02919 for (i = low_bound; i <= high_bound; i++)
02920 {
02921 if ( control_thing
02922 || Examinable(executor, i))
02923 {
02924 if ( ( find_ex
02925 && isExit(i)
02926 && Location(i) == thing)
02927 || ( find_rm
02928 && isRoom(i)
02929 && Dropto(i) == thing)
02930 || ( find_th
02931 && isThing(i)
02932 && Home(i) == thing)
02933 || ( find_pl
02934 && isPlayer(i)
02935 && Home(i) == thing))
02936 {
02937 if (!ItemToList_AddInteger(&itl, i))
02938 {
02939 break;
02940 }
02941 }
02942 }
02943 }
02944 ItemToList_Final(&itl);
02945 }
02946
02947
02948
02949
02950
02951
02952 static FUNCTION(fun_home)
02953 {
02954 UNUSED_PARAMETER(caller);
02955 UNUSED_PARAMETER(enactor);
02956 UNUSED_PARAMETER(nfargs);
02957 UNUSED_PARAMETER(cargs);
02958 UNUSED_PARAMETER(ncargs);
02959
02960 dbref it = match_thing_quiet(executor, fargs[0]);
02961 if (!Good_obj(it))
02962 {
02963 safe_match_result(it, buff, bufc);
02964 }
02965 else if (!Examinable(executor, it))
02966 {
02967 safe_noperm(buff, bufc);
02968 }
02969 else if (Has_home(it))
02970 {
02971 safe_tprintf_str(buff, bufc, "#%d", Home(it));
02972 }
02973 else if (Has_dropto(it))
02974 {
02975 safe_tprintf_str(buff, bufc, "#%d", Dropto(it));
02976 }
02977 else if (isExit(it))
02978 {
02979 safe_tprintf_str(buff, bufc, "#%d", where_is(it));
02980 }
02981 else
02982 {
02983 safe_nothing(buff, bufc);
02984 }
02985 }
02986
02987
02988
02989
02990
02991
02992 static FUNCTION(fun_money)
02993 {
02994 UNUSED_PARAMETER(caller);
02995 UNUSED_PARAMETER(enactor);
02996 UNUSED_PARAMETER(nfargs);
02997 UNUSED_PARAMETER(cargs);
02998 UNUSED_PARAMETER(ncargs);
02999
03000 dbref it = match_thing_quiet(executor, fargs[0]);
03001 if (!Good_obj(it))
03002 {
03003 safe_match_result(it, buff, bufc);
03004 return;
03005 }
03006 if (Examinable(executor, it))
03007 {
03008 safe_ltoa(Pennies(it), buff, bufc);
03009 }
03010 else
03011 {
03012 safe_noperm(buff, bufc);
03013 }
03014 }
03015
03016
03017
03018
03019
03020
03021 static FUNCTION(fun_pos)
03022 {
03023 UNUSED_PARAMETER(executor);
03024 UNUSED_PARAMETER(caller);
03025 UNUSED_PARAMETER(enactor);
03026 UNUSED_PARAMETER(nfargs);
03027 UNUSED_PARAMETER(cargs);
03028 UNUSED_PARAMETER(ncargs);
03029
03030
03031
03032
03033
03034
03035
03036
03037 size_t nPat = 0;
03038 char aPatBuf[LBUF_SIZE];
03039 char *pPatStrip = strip_ansi(fargs[0], &nPat);
03040 memcpy(aPatBuf, pPatStrip, nPat);
03041
03042
03043
03044 size_t nSrc;
03045 char *pSrc = strip_ansi(fargs[1], &nSrc);
03046
03047
03048
03049 int i = -1;
03050 if (nPat == 1)
03051 {
03052
03053
03054 char *p = strchr(pSrc, aPatBuf[0]);
03055 if (p)
03056 {
03057 i = p - pSrc + 1;
03058 }
03059 }
03060 else if (nPat > 1)
03061 {
03062
03063
03064 i = BMH_StringSearch(nPat, aPatBuf, nSrc, pSrc)+1;
03065 }
03066
03067 if (i > 0)
03068 {
03069 safe_ltoa(i, buff, bufc);
03070 }
03071 else
03072 {
03073 safe_nothing(buff, bufc);
03074 }
03075 }
03076
03077
03078
03079
03080
03081
03082
03083 static FUNCTION(fun_lpos)
03084 {
03085 UNUSED_PARAMETER(executor);
03086 UNUSED_PARAMETER(caller);
03087 UNUSED_PARAMETER(enactor);
03088 UNUSED_PARAMETER(nfargs);
03089 UNUSED_PARAMETER(cargs);
03090 UNUSED_PARAMETER(ncargs);
03091
03092 if (*fargs[0] == '\0')
03093 {
03094 return;
03095 }
03096
03097 char c = *fargs[1];
03098 if (!c)
03099 {
03100 c = ' ';
03101 }
03102
03103 int i;
03104 char *bb_p = *bufc;
03105 char *s = strip_ansi(fargs[0]);
03106 for (i = 0; *s; i++, s++)
03107 {
03108 if (*s == c)
03109 {
03110 if (*bufc != bb_p)
03111 {
03112 safe_chr(' ', buff, bufc);
03113 }
03114 safe_ltoa(i, buff, bufc);
03115 }
03116 }
03117 }
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131 #define IF_DELETE 0
03132 #define IF_REPLACE 1
03133 #define IF_INSERT 2
03134
03135 static void do_itemfuns(char *buff, char **bufc, char *str, int el,
03136 char *word, SEP *psep, int flag)
03137 {
03138 int ct;
03139 char *sptr, *iptr, *eptr;
03140 int slen = 0, ilen = 0, elen = 0;
03141 bool overrun;
03142
03143
03144
03145
03146 if ( ( !str
03147 || !*str)
03148 && ( flag != IF_INSERT
03149 || el != 1))
03150 {
03151 return;
03152 }
03153 int nStr = strlen(str);
03154
03155
03156
03157 if (el < 1)
03158 {
03159 safe_copy_buf(str, nStr, buff, bufc);
03160 return;
03161 }
03162
03163
03164
03165
03166 if (el == 1)
03167 {
03168
03169
03170 sptr = NULL;
03171 slen = 0;
03172 if (!str || !*str)
03173 {
03174 eptr = NULL;
03175 iptr = NULL;
03176 }
03177 else
03178 {
03179 eptr = trim_space_sep_LEN(str, nStr, psep, &elen);
03180 iptr = split_token_LEN(&eptr, &elen, psep, &ilen);
03181 }
03182 }
03183 else
03184 {
03185
03186
03187 sptr = eptr = trim_space_sep_LEN(str, nStr, psep, &elen);
03188 overrun = true;
03189 for ( ct = el;
03190 ct > 2 && eptr;
03191 eptr = next_token_LEN(eptr, &elen, psep), ct--)
03192 {
03193
03194 }
03195 if (eptr)
03196 {
03197
03198
03199
03200
03201 overrun = false;
03202 iptr = split_token_LEN(&eptr, &elen, psep, &ilen);
03203 slen = (iptr - sptr) + ilen;
03204 }
03205
03206
03207
03208
03209
03210 if (!( eptr
03211 || ( flag == IF_INSERT
03212 && !overrun)))
03213 {
03214 safe_copy_buf(str, nStr, buff, bufc);
03215 return;
03216 }
03217
03218
03219
03220 if (eptr)
03221 {
03222 iptr = split_token_LEN(&eptr, &elen, psep, &ilen);
03223 }
03224 else
03225 {
03226 iptr = NULL;
03227 ilen = 0;
03228 }
03229 }
03230
03231 switch (flag)
03232 {
03233 case IF_DELETE:
03234
03235
03236
03237 if (sptr)
03238 {
03239 safe_copy_buf(sptr, slen, buff, bufc);
03240 if (eptr)
03241 {
03242 safe_chr(psep->str[0], buff, bufc);
03243 }
03244 }
03245 if (eptr)
03246 {
03247 safe_copy_buf(eptr, elen, buff, bufc);
03248 }
03249 break;
03250
03251 case IF_REPLACE:
03252
03253
03254
03255 if (sptr)
03256 {
03257 safe_copy_buf(sptr, slen, buff, bufc);
03258 safe_chr(psep->str[0], buff, bufc);
03259 }
03260 safe_str(word, buff, bufc);
03261 if (eptr)
03262 {
03263 safe_chr(psep->str[0], buff, bufc);
03264 safe_copy_buf(eptr, elen, buff, bufc);
03265 }
03266 break;
03267
03268 case IF_INSERT:
03269
03270
03271
03272 if (sptr)
03273 {
03274 safe_copy_buf(sptr, slen, buff, bufc);
03275 safe_chr(psep->str[0], buff, bufc);
03276 }
03277 safe_str(word, buff, bufc);
03278 if (iptr)
03279 {
03280 safe_chr(psep->str[0], buff, bufc);
03281 safe_copy_buf(iptr, ilen, buff, bufc);
03282 }
03283 if (eptr)
03284 {
03285 safe_chr(psep->str[0], buff, bufc);
03286 safe_copy_buf(eptr, elen, buff, bufc);
03287 }
03288 break;
03289 }
03290 }
03291
03292
03293 static FUNCTION(fun_ldelete)
03294 {
03295 SEP sep;
03296 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
03297 {
03298 return;
03299 }
03300
03301
03302
03303 do_itemfuns(buff, bufc, fargs[0], mux_atol(fargs[1]), NULL, &sep, IF_DELETE);
03304 }
03305
03306 static FUNCTION(fun_replace)
03307 {
03308 SEP sep;
03309 if (!OPTIONAL_DELIM(4, sep, DELIM_DFLT|DELIM_STRING))
03310 {
03311 return;
03312 }
03313
03314
03315
03316 do_itemfuns(buff, bufc, fargs[0], mux_atol(fargs[1]), fargs[2], &sep, IF_REPLACE);
03317 }
03318
03319 static FUNCTION(fun_insert)
03320 {
03321 SEP sep;
03322 if (!OPTIONAL_DELIM(4, sep, DELIM_DFLT|DELIM_STRING))
03323 {
03324 return;
03325 }
03326
03327
03328
03329 do_itemfuns(buff, bufc, fargs[0], mux_atol(fargs[1]), fargs[2], &sep, IF_INSERT);
03330 }
03331
03332
03333
03334
03335
03336
03337 static FUNCTION(fun_remove)
03338 {
03339 SEP sep;
03340 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
03341 {
03342 return;
03343 }
03344 SEP osep = sep;
03345 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
03346 {
03347 return;
03348 }
03349
03350 char *s, *sp, *word;
03351 bool first, found;
03352
03353 if (strstr(fargs[1], sep.str))
03354 {
03355 safe_str("#-1 CAN ONLY REMOVE ONE ELEMENT", buff, bufc);
03356 return;
03357 }
03358 s = fargs[0];
03359 word = fargs[1];
03360
03361
03362
03363
03364 sp = s;
03365 found = false;
03366 first = true;
03367 while (s)
03368 {
03369 sp = split_token(&s, &sep);
03370 if ( found
03371 || strcmp(sp, word) != 0)
03372 {
03373 if (!first)
03374 {
03375 print_sep(&osep, buff, bufc);
03376 }
03377 else
03378 {
03379 first = false;
03380 }
03381 safe_str(sp, buff, bufc);
03382 }
03383 else
03384 {
03385 found = true;
03386 }
03387 }
03388 }
03389
03390
03391
03392
03393
03394
03395 static FUNCTION(fun_member)
03396 {
03397 SEP sep;
03398 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
03399 {
03400 return;
03401 }
03402
03403 int wcount;
03404 char *r, *s;
03405
03406 wcount = 1;
03407 s = trim_space_sep(fargs[0], &sep);
03408 do
03409 {
03410 r = split_token(&s, &sep);
03411 if (!strcmp(fargs[1], r))
03412 {
03413 safe_ltoa(wcount, buff, bufc);
03414 return;
03415 }
03416 wcount++;
03417 } while (s);
03418 safe_chr('0', buff, bufc);
03419 }
03420
03421
03422
03423
03424
03425 static FUNCTION(fun_secure)
03426 {
03427 UNUSED_PARAMETER(executor);
03428 UNUSED_PARAMETER(caller);
03429 UNUSED_PARAMETER(enactor);
03430 UNUSED_PARAMETER(nfargs);
03431 UNUSED_PARAMETER(cargs);
03432 UNUSED_PARAMETER(ncargs);
03433
03434 char *pString = fargs[0];
03435 int nString = strlen(pString);
03436
03437 while (nString)
03438 {
03439 int nTokenLength0;
03440 int nTokenLength1;
03441 int iType = ANSI_lex(nString, pString, &nTokenLength0, &nTokenLength1);
03442
03443 if (iType == TOKEN_TEXT_ANSI)
03444 {
03445
03446
03447 nString -= nTokenLength0;
03448 while (nTokenLength0--)
03449 {
03450 if (mux_issecure(*pString))
03451 {
03452 safe_chr(' ', buff, bufc);
03453 }
03454 else
03455 {
03456 safe_chr(*pString, buff, bufc);
03457 }
03458 pString++;
03459 }
03460 nTokenLength0 = nTokenLength1;
03461 }
03462
03463 if (nTokenLength0)
03464 {
03465
03466
03467 safe_copy_buf(pString, nTokenLength0, buff, bufc);
03468 pString += nTokenLength0;
03469 nString -= nTokenLength0;
03470 }
03471 }
03472 }
03473
03474
03475
03476
03477
03478
03479 static FUNCTION(fun_escape)
03480 {
03481 UNUSED_PARAMETER(executor);
03482 UNUSED_PARAMETER(caller);
03483 UNUSED_PARAMETER(enactor);
03484 UNUSED_PARAMETER(fargs);
03485 UNUSED_PARAMETER(nfargs);
03486 UNUSED_PARAMETER(cargs);
03487 UNUSED_PARAMETER(ncargs);
03488
03489 char *pString = fargs[0];
03490 int nString = strlen(pString);
03491
03492 while (nString)
03493 {
03494 int nTokenLength0;
03495 int nTokenLength1;
03496 int iType = ANSI_lex(nString, pString, &nTokenLength0, &nTokenLength1);
03497
03498 if (iType == TOKEN_TEXT_ANSI)
03499 {
03500
03501
03502 nString -= nTokenLength0;
03503 while (nTokenLength0--)
03504 {
03505 if ( mux_isescape(*pString)
03506 || pString == fargs[0])
03507 {
03508 safe_chr('\\', buff, bufc);
03509 }
03510 safe_chr(*pString, buff, bufc);
03511 pString++;
03512 }
03513 nTokenLength0 = nTokenLength1;
03514 }
03515
03516 if (nTokenLength0)
03517 {
03518
03519
03520 safe_copy_buf(pString, nTokenLength0, buff, bufc);
03521 pString += nTokenLength0;
03522 nString -= nTokenLength0;
03523 }
03524 }
03525 }
03526
03527
03528
03529
03530
03531 static FUNCTION(fun_wordpos)
03532 {
03533 SEP sep;
03534 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
03535 {
03536 return;
03537 }
03538
03539 unsigned int charpos = mux_atol(fargs[1]);
03540 char *cp = fargs[0];
03541 size_t ncp = strlen(cp);
03542 if ( charpos > 0
03543 && charpos <= ncp)
03544 {
03545 int ncp_trimmed;
03546 char *tp = &(cp[charpos - 1]);
03547 cp = trim_space_sep_LEN(cp, ncp, &sep, &ncp_trimmed);
03548 char *xp = split_token(&cp, &sep);
03549
03550 int i;
03551 for (i = 1; xp; i++)
03552 {
03553 if (tp < xp + strlen(xp))
03554 {
03555 break;
03556 }
03557 xp = split_token(&cp, &sep);
03558 }
03559 safe_ltoa(i, buff, bufc);
03560 return;
03561 }
03562 safe_nothing(buff, bufc);
03563 }
03564
03565 static FUNCTION(fun_type)
03566 {
03567 UNUSED_PARAMETER(caller);
03568 UNUSED_PARAMETER(enactor);
03569 UNUSED_PARAMETER(nfargs);
03570 UNUSED_PARAMETER(cargs);
03571 UNUSED_PARAMETER(ncargs);
03572
03573 dbref it = match_thing_quiet(executor, fargs[0]);
03574 if (!Good_obj(it))
03575 {
03576 safe_match_result(it, buff, bufc);
03577 return;
03578 }
03579 switch (Typeof(it))
03580 {
03581 case TYPE_ROOM:
03582 safe_str("ROOM", buff, bufc);
03583 break;
03584 case TYPE_EXIT:
03585 safe_str("EXIT", buff, bufc);
03586 break;
03587 case TYPE_PLAYER:
03588 safe_str("PLAYER", buff, bufc);
03589 break;
03590 case TYPE_THING:
03591 safe_str("THING", buff, bufc);
03592 break;
03593 default:
03594 safe_str("#-1 ILLEGAL TYPE", buff, bufc);
03595 }
03596 }
03597
03598 typedef struct
03599 {
03600 const char *pName;
03601 int iMask;
03602 } ATR_HAS_FLAG_ENTRY;
03603
03604 static ATR_HAS_FLAG_ENTRY atr_has_flag_table[] =
03605 {
03606 { "dark", AF_DARK },
03607 { "wizard", AF_WIZARD },
03608 { "hidden", AF_MDARK },
03609 { "html", AF_HTML },
03610 { "locked", AF_LOCK },
03611 { "no_command", AF_NOPROG },
03612 { "no_parse", AF_NOPARSE },
03613 { "regexp", AF_REGEXP },
03614 { "god", AF_GOD },
03615 { "visual", AF_VISUAL },
03616 { "no_inherit", AF_PRIVATE },
03617 { "const", AF_CONST },
03618 { NULL, 0 }
03619 };
03620
03621 static bool atr_has_flag
03622 (
03623 dbref player,
03624 dbref thing,
03625 ATTR* pattr,
03626 dbref aowner,
03627 int aflags,
03628 const char *flagname
03629 )
03630 {
03631 UNUSED_PARAMETER(aowner);
03632
03633 if (See_attr(player, thing, pattr))
03634 {
03635 ATR_HAS_FLAG_ENTRY *pEntry = atr_has_flag_table;
03636 while (pEntry->pName)
03637 {
03638 if (string_prefix(pEntry->pName, flagname))
03639 {
03640 return ((aflags & (pEntry->iMask)) ? true : false);
03641 }
03642 pEntry++;
03643 }
03644 }
03645 return false;
03646 }
03647
03648 static FUNCTION(fun_hasflag)
03649 {
03650 UNUSED_PARAMETER(caller);
03651 UNUSED_PARAMETER(nfargs);
03652 UNUSED_PARAMETER(cargs);
03653 UNUSED_PARAMETER(ncargs);
03654
03655 dbref it;
03656 ATTR *pattr;
03657
03658 if (parse_attrib(executor, fargs[0], &it, &pattr))
03659 {
03660 if ( !pattr
03661 || !See_attr(executor, it, pattr))
03662 {
03663 safe_notfound(buff, bufc);
03664 }
03665 else
03666 {
03667 int aflags;
03668 dbref aowner;
03669 atr_pget_info(it, pattr->number, &aowner, &aflags);
03670 bool cc = atr_has_flag(executor, it, pattr, aowner, aflags, fargs[1]);
03671 safe_bool(cc, buff, bufc);
03672 }
03673 }
03674 else
03675 {
03676 it = match_thing_quiet(executor, fargs[0]);
03677 if (!Good_obj(it))
03678 {
03679 safe_match_result(it, buff, bufc);
03680 }
03681 else if ( mudconf.pub_flags
03682 || Examinable(executor, it)
03683 || it == enactor)
03684 {
03685 bool cc = has_flag(executor, it, fargs[1]);
03686 safe_bool(cc, buff, bufc);
03687 }
03688 else
03689 {
03690 safe_noperm(buff, bufc);
03691 }
03692 }
03693 }
03694
03695 static FUNCTION(fun_haspower)
03696 {
03697 UNUSED_PARAMETER(caller);
03698 UNUSED_PARAMETER(nfargs);
03699 UNUSED_PARAMETER(cargs);
03700 UNUSED_PARAMETER(ncargs);
03701
03702 dbref it = match_thing_quiet(executor, fargs[0]);
03703 if (!Good_obj(it))
03704 {
03705 safe_match_result(it, buff, bufc);
03706 return;
03707 }
03708 if ( mudconf.pub_flags
03709 || Examinable(executor, it)
03710 || it == enactor)
03711 {
03712 safe_bool(has_power(executor, it, fargs[1]), buff, bufc);
03713 }
03714 else
03715 {
03716 safe_noperm(buff, bufc);
03717 }
03718 }
03719
03720 #ifdef REALITY_LVLS
03721 static FUNCTION(fun_hasrxlevel)
03722 {
03723 dbref it;
03724 RLEVEL rl;
03725
03726 it = match_thing(executor, fargs[0]);
03727 if (!Good_obj(it))
03728 {
03729 safe_str("#-1 NOT FOUND", buff, bufc);
03730 return;
03731 }
03732 rl = find_rlevel(fargs[1]);
03733 if (!rl)
03734 {
03735 safe_str("#-1 INVALID RLEVEL", buff, bufc);
03736 return;
03737 }
03738 if (Examinable(executor, it))
03739 {
03740 if ((RxLevel(it) & rl) == rl)
03741 {
03742 safe_chr('1', buff, bufc);
03743 }
03744 else
03745 {
03746 safe_chr('0', buff, bufc);
03747 }
03748 }
03749 else
03750 {
03751 safe_str("#-1 PERMISSION DENIED", buff, bufc);
03752 }
03753 }
03754
03755 static FUNCTION(fun_hastxlevel)
03756 {
03757 dbref it;
03758 RLEVEL rl;
03759
03760 it = match_thing(executor, fargs[0]);
03761 if (!Good_obj(it))
03762 {
03763 safe_str("#-1 NOT FOUND", buff, bufc);
03764 return;
03765 }
03766 rl = find_rlevel(fargs[1]);
03767 if (!rl)
03768 {
03769 safe_str("#-1 INVALID RLEVEL", buff, bufc);
03770 return;
03771 }
03772 if (Examinable(executor, it))
03773 {
03774 if ((TxLevel(it) & rl) == rl)
03775 {
03776 safe_chr('1', buff, bufc);
03777 }
03778 else
03779 {
03780 safe_chr('0', buff, bufc);
03781 }
03782 }
03783 else
03784 {
03785 safe_str("#-1 PERMISSION DENIED", buff, bufc);
03786 }
03787 }
03788
03789 static FUNCTION(fun_listrlevels)
03790 {
03791 int i, add_space, cmp_x, cmp_y, cmp_z;
03792
03793 cmp_x = sizeof(mudconf.reality_level);
03794 cmp_y = sizeof(mudconf.reality_level[0]);
03795 if ( cmp_y == 0 )
03796 cmp_z = 0;
03797 else
03798 cmp_z = cmp_x / cmp_y;
03799 if ( mudconf.no_levels < 1 ) {
03800 safe_str("#-1 NO REALITY LEVELS DEFINED", buff, bufc);
03801 } else {
03802 for (add_space = i = 0; (i < mudconf.no_levels) && (i < cmp_z); ++i) {
03803 if(add_space)
03804 safe_chr(' ', buff, bufc);
03805 safe_str(mudconf.reality_level[i].name, buff, bufc);
03806 add_space = 1;
03807 }
03808 }
03809 }
03810
03811 static FUNCTION(fun_rxlevel)
03812 {
03813 dbref it;
03814 char levelbuff[2048];
03815 int i;
03816 RLEVEL lev;
03817
03818 it = match_thing(executor, fargs[0]);
03819 if (!Good_obj(it))
03820 {
03821 safe_str("#-1 NOT FOUND", buff, bufc);
03822 return;
03823 }
03824 if (Examinable(executor, it))
03825 {
03826 lev = RxLevel(it);
03827 levelbuff[0]='\0';
03828 for(i = 0; i < mudconf.no_levels; ++i)
03829 if((lev & mudconf.reality_level[i].value) == mudconf.reality_level[i].value)
03830 {
03831 strcat(levelbuff, mudconf.reality_level[i].name);
03832 strcat(levelbuff, " ");
03833 }
03834 safe_tprintf_str(buff, bufc, "%s", levelbuff);
03835 }
03836 else
03837 safe_str("#-1 PERMISSION DENIED", buff, bufc);
03838 }
03839
03840 static FUNCTION(fun_txlevel)
03841 {
03842 dbref it;
03843 char levelbuff[2048];
03844 int i;
03845 RLEVEL lev;
03846
03847 it = match_thing(executor, fargs[0]);
03848 if (!Good_obj(it))
03849 {
03850 safe_str("#-1 NOT FOUND", buff, bufc);
03851 return;
03852 }
03853 if (Examinable(executor, it))
03854 {
03855 lev = TxLevel(it);
03856 levelbuff[0]='\0';
03857 for(i = 0; i < mudconf.no_levels; ++i)
03858 if((lev & mudconf.reality_level[i].value) == mudconf.reality_level[i].value)
03859 {
03860 strcat(levelbuff, mudconf.reality_level[i].name);
03861 strcat(levelbuff, " ");
03862 }
03863 safe_tprintf_str(buff, bufc, "%s", levelbuff);
03864 }
03865 else
03866 safe_str("#-1 PERMISSION DENIED", buff, bufc);
03867 }
03868 #endif
03869
03870 static FUNCTION(fun_powers)
03871 {
03872 UNUSED_PARAMETER(caller);
03873 UNUSED_PARAMETER(nfargs);
03874 UNUSED_PARAMETER(cargs);
03875 UNUSED_PARAMETER(ncargs);
03876
03877 dbref it = match_thing_quiet(executor, fargs[0]);
03878 if (!Good_obj(it))
03879 {
03880 safe_match_result(it, buff, bufc);
03881 return;
03882 }
03883 if ( mudconf.pub_flags
03884 || Examinable(executor, it)
03885 || it == enactor)
03886 {
03887 char *buf = powers_list(executor, it);
03888 safe_str(buf, buff, bufc);
03889 free_lbuf(buf);
03890 }
03891 else
03892 {
03893 safe_noperm(buff, bufc);
03894 }
03895 }
03896
03897 static FUNCTION(fun_delete)
03898 {
03899 UNUSED_PARAMETER(executor);
03900 UNUSED_PARAMETER(caller);
03901 UNUSED_PARAMETER(enactor);
03902 UNUSED_PARAMETER(nfargs);
03903 UNUSED_PARAMETER(cargs);
03904 UNUSED_PARAMETER(ncargs);
03905
03906 char *s = fargs[0];
03907 int iStart = mux_atol(fargs[1]);
03908 int nChars = mux_atol(fargs[2]);
03909 int nLen = strlen(s);
03910
03911 int iEnd;
03912 if (0 <= nChars)
03913 {
03914 iEnd = iStart + nChars;
03915 }
03916 else
03917 {
03918 iEnd = iStart;
03919 iStart = iEnd + nChars;
03920 }
03921
03922
03923
03924 if ( iEnd <= 0
03925 || nLen <= iStart)
03926 {
03927 if (nLen)
03928 {
03929 safe_copy_buf(s, nLen, buff, bufc);
03930 }
03931 return;
03932 }
03933
03934 if (iStart < 0) iStart = 0;
03935 if (nLen < iEnd) iEnd = nLen;
03936
03937
03938
03939
03940 if (iStart)
03941 {
03942 safe_copy_buf(s, iStart, buff, bufc);
03943 }
03944 if (iEnd < nLen)
03945 {
03946 safe_copy_buf(s + iEnd, nLen - iEnd, buff, bufc);
03947 }
03948 }
03949
03950 static FUNCTION(fun_lock)
03951 {
03952 UNUSED_PARAMETER(caller);
03953 UNUSED_PARAMETER(enactor);
03954 UNUSED_PARAMETER(nfargs);
03955 UNUSED_PARAMETER(cargs);
03956 UNUSED_PARAMETER(ncargs);
03957
03958 dbref it, aowner;
03959 int aflags;
03960 ATTR *pattr;
03961 struct boolexp *pBoolExp;
03962
03963
03964
03965 if (!get_obj_and_lock(executor, fargs[0], &it, &pattr, buff, bufc))
03966 {
03967 return;
03968 }
03969
03970
03971
03972 char *tbuf = atr_get(it, pattr->number, &aowner, &aflags);
03973 if (bCanReadAttr(executor, it, pattr, false))
03974 {
03975 pBoolExp = parse_boolexp(executor, tbuf, true);
03976 free_lbuf(tbuf);
03977 tbuf = unparse_boolexp_function(executor, pBoolExp);
03978 free_boolexp(pBoolExp);
03979 safe_str(tbuf, buff, bufc);
03980 }
03981 else
03982 {
03983 free_lbuf(tbuf);
03984 }
03985 }
03986
03987 static FUNCTION(fun_elock)
03988 {
03989 UNUSED_PARAMETER(caller);
03990 UNUSED_PARAMETER(nfargs);
03991 UNUSED_PARAMETER(cargs);
03992 UNUSED_PARAMETER(ncargs);
03993
03994 dbref it, aowner;
03995 int aflags;
03996 ATTR *pattr;
03997 struct boolexp *pBoolExp;
03998
03999
04000
04001 if (!get_obj_and_lock(executor, fargs[0], &it, &pattr, buff, bufc))
04002 {
04003 return;
04004 }
04005 else if (!locatable(executor, it, enactor))
04006 {
04007 safe_nothing(buff, bufc);
04008 }
04009
04010
04011
04012 dbref victim = match_thing_quiet(executor, fargs[1]);
04013 if (!Good_obj(victim))
04014 {
04015 safe_match_result(victim, buff, bufc);
04016 }
04017 else if (!locatable(executor, victim, enactor))
04018 {
04019 safe_nothing(buff, bufc);
04020 }
04021 else if ( nearby_or_control(executor, victim)
04022 || nearby_or_control(executor, it))
04023 {
04024 char *tbuf = atr_get(it, pattr->number, &aowner, &aflags);
04025 if ( pattr->number == A_LOCK
04026 || bCanReadAttr(executor, it, pattr, false))
04027 {
04028 pBoolExp = parse_boolexp(executor, tbuf, true);
04029 safe_bool(eval_boolexp(victim, it, it, pBoolExp), buff, bufc);
04030 free_boolexp(pBoolExp);
04031 }
04032 else
04033 {
04034 safe_chr('0', buff, bufc);
04035 }
04036 free_lbuf(tbuf);
04037 }
04038 else
04039 {
04040 safe_str("#-1 TOO FAR AWAY", buff, bufc);
04041 }
04042 }
04043
04044
04045
04046
04047
04048 static FUNCTION(fun_lwho)
04049 {
04050 UNUSED_PARAMETER(caller);
04051 UNUSED_PARAMETER(enactor);
04052 UNUSED_PARAMETER(cargs);
04053 UNUSED_PARAMETER(ncargs);
04054
04055 bool bPorts = false;
04056 if (nfargs == 1)
04057 {
04058 bPorts = xlate(fargs[0]);
04059 if ( bPorts
04060 && !Wizard(executor))
04061 {
04062 safe_noperm(buff, bufc);
04063 return;
04064 }
04065 }
04066 make_ulist(executor, buff, bufc, bPorts);
04067 }
04068
04069
04070
04071
04072
04073 static FUNCTION(fun_lports)
04074 {
04075 UNUSED_PARAMETER(caller);
04076 UNUSED_PARAMETER(enactor);
04077 UNUSED_PARAMETER(fargs);
04078 UNUSED_PARAMETER(nfargs);
04079 UNUSED_PARAMETER(cargs);
04080 UNUSED_PARAMETER(ncargs);
04081
04082 make_port_ulist(executor, buff, bufc);
04083 }
04084
04085
04086
04087
04088
04089 static FUNCTION(fun_nearby)
04090 {
04091 UNUSED_PARAMETER(caller);
04092 UNUSED_PARAMETER(enactor);
04093 UNUSED_PARAMETER(nfargs);
04094 UNUSED_PARAMETER(cargs);
04095 UNUSED_PARAMETER(ncargs);
04096
04097 dbref obj1 = match_thing_quiet(executor, fargs[0]);
04098 if (!Good_obj(obj1))
04099 {
04100 safe_match_result(obj1, buff, bufc);
04101 safe_str(" (ARG1)", buff, bufc);
04102 return;
04103 }
04104 dbref obj2 = match_thing_quiet(executor, fargs[1]);
04105 if (!Good_obj(obj2))
04106 {
04107 safe_match_result(obj2, buff, bufc);
04108 safe_str(" (ARG2)", buff, bufc);
04109 return;
04110 }
04111 bool bResult = ( ( nearby_or_control(executor, obj1)
04112 || nearby_or_control(executor, obj2))
04113 && nearby(obj1, obj2));
04114 safe_bool(bResult, buff, bufc);
04115 }
04116
04117
04118
04119
04120
04121
04122 static void process_sex(dbref player, char *what, const char *token, char *buff, char **bufc)
04123 {
04124 dbref it = match_thing_quiet(player, strip_ansi(what));
04125 if (!Good_obj(it))
04126 {
04127 safe_match_result(it, buff, bufc);
04128 return;
04129 }
04130 if ( !isPlayer(it)
04131 && !nearby_or_control(player, it))
04132 {
04133 safe_nomatch(buff, bufc);
04134 }
04135 else
04136 {
04137 char *str = (char *)token;
04138 mux_exec(buff, bufc, it, it, it, EV_EVAL, &str, (char **)NULL, 0);
04139 }
04140 }
04141
04142 static FUNCTION(fun_obj)
04143 {
04144 UNUSED_PARAMETER(caller);
04145 UNUSED_PARAMETER(enactor);
04146 UNUSED_PARAMETER(nfargs);
04147 UNUSED_PARAMETER(cargs);
04148 UNUSED_PARAMETER(ncargs);
04149
04150 process_sex(executor, fargs[0], "%o", buff, bufc);
04151 }
04152
04153 static FUNCTION(fun_poss)
04154 {
04155 UNUSED_PARAMETER(caller);
04156 UNUSED_PARAMETER(enactor);
04157 UNUSED_PARAMETER(nfargs);
04158 UNUSED_PARAMETER(cargs);
04159 UNUSED_PARAMETER(ncargs);
04160
04161 process_sex(executor, fargs[0], "%p", buff, bufc);
04162 }
04163
04164 static FUNCTION(fun_subj)
04165 {
04166 UNUSED_PARAMETER(caller);
04167 UNUSED_PARAMETER(enactor);
04168 UNUSED_PARAMETER(nfargs);
04169 UNUSED_PARAMETER(cargs);
04170 UNUSED_PARAMETER(ncargs);
04171
04172 process_sex(executor, fargs[0], "%s", buff, bufc);
04173 }
04174
04175 static FUNCTION(fun_aposs)
04176 {
04177 UNUSED_PARAMETER(caller);
04178 UNUSED_PARAMETER(enactor);
04179 UNUSED_PARAMETER(nfargs);
04180 UNUSED_PARAMETER(cargs);
04181 UNUSED_PARAMETER(ncargs);
04182
04183 process_sex(executor, fargs[0], "%a", buff, bufc);
04184 }
04185
04186
04187
04188
04189
04190
04191 static FUNCTION(fun_mudname)
04192 {
04193 UNUSED_PARAMETER(executor);
04194 UNUSED_PARAMETER(caller);
04195 UNUSED_PARAMETER(enactor);
04196 UNUSED_PARAMETER(fargs);
04197 UNUSED_PARAMETER(nfargs);
04198 UNUSED_PARAMETER(cargs);
04199 UNUSED_PARAMETER(ncargs);
04200
04201 safe_str(mudconf.mud_name, buff, bufc);
04202 }
04203
04204
04205
04206
04207
04208 static FUNCTION(fun_connrecord)
04209 {
04210 UNUSED_PARAMETER(executor);
04211 UNUSED_PARAMETER(caller);
04212 UNUSED_PARAMETER(enactor);
04213 UNUSED_PARAMETER(fargs);
04214 UNUSED_PARAMETER(nfargs);
04215 UNUSED_PARAMETER(cargs);
04216 UNUSED_PARAMETER(ncargs);
04217
04218 safe_ltoa(mudstate.record_players, buff, bufc);
04219 }
04220
04221
04222
04223
04224
04225 FUNCTION(fun_fcount)
04226 {
04227 UNUSED_PARAMETER(executor);
04228 UNUSED_PARAMETER(caller);
04229 UNUSED_PARAMETER(enactor);
04230 UNUSED_PARAMETER(fargs);
04231 UNUSED_PARAMETER(nfargs);
04232 UNUSED_PARAMETER(cargs);
04233 UNUSED_PARAMETER(ncargs);
04234
04235 safe_ltoa(mudstate.func_invk_ctr, buff, bufc);
04236 }
04237
04238
04239
04240
04241
04242 FUNCTION(fun_fdepth)
04243 {
04244 UNUSED_PARAMETER(executor);
04245 UNUSED_PARAMETER(caller);
04246 UNUSED_PARAMETER(enactor);
04247 UNUSED_PARAMETER(fargs);
04248 UNUSED_PARAMETER(nfargs);
04249 UNUSED_PARAMETER(cargs);
04250 UNUSED_PARAMETER(ncargs);
04251
04252 safe_ltoa(mudstate.func_nest_lev, buff, bufc);
04253 }
04254
04255
04256
04257
04258
04259 static FUNCTION(fun_ctime)
04260 {
04261 UNUSED_PARAMETER(caller);
04262 UNUSED_PARAMETER(enactor);
04263 UNUSED_PARAMETER(cargs);
04264 UNUSED_PARAMETER(ncargs);
04265
04266 dbref thing;
04267 if (nfargs == 1)
04268 {
04269 thing = match_thing_quiet(executor, fargs[0]);
04270 }
04271 else
04272 {
04273 thing = executor;
04274 }
04275 if (!Good_obj(thing))
04276 {
04277 safe_match_result(thing, buff, bufc);
04278 }
04279 else if (Examinable(executor, thing))
04280 {
04281 safe_str(atr_get_raw(thing, A_CREATED), buff, bufc);
04282 }
04283 else
04284 {
04285 safe_noperm(buff, bufc);
04286 }
04287 }
04288
04289
04290
04291
04292
04293 static FUNCTION(fun_mtime)
04294 {
04295 UNUSED_PARAMETER(caller);
04296 UNUSED_PARAMETER(enactor);
04297 UNUSED_PARAMETER(cargs);
04298 UNUSED_PARAMETER(ncargs);
04299
04300 dbref thing;
04301 if (nfargs == 1)
04302 {
04303 thing = match_thing_quiet(executor, fargs[0]);
04304 }
04305 else
04306 {
04307 thing = executor;
04308 }
04309 if (!Good_obj(thing))
04310 {
04311 safe_match_result(thing, buff, bufc);
04312 }
04313 else if (Examinable(executor, thing))
04314 {
04315 safe_str(atr_get_raw(thing, A_MODIFIED), buff, bufc);
04316 }
04317 else
04318 {
04319 safe_noperm(buff, bufc);
04320 }
04321 }
04322
04323
04324
04325
04326 static FUNCTION(fun_moniker)
04327 {
04328 UNUSED_PARAMETER(caller);
04329 UNUSED_PARAMETER(enactor);
04330 UNUSED_PARAMETER(cargs);
04331 UNUSED_PARAMETER(ncargs);
04332
04333 dbref thing;
04334 if (nfargs == 1)
04335 {
04336 thing = match_thing_quiet(executor, fargs[0]);
04337 }
04338 else
04339 {
04340 thing = executor;
04341 }
04342 if (!Good_obj(thing))
04343 {
04344 safe_match_result(thing, buff, bufc);
04345 return;
04346 }
04347 safe_str(Moniker(thing), buff, bufc);
04348 }
04349
04350 static void ANSI_TransformTextWithTable
04351 (
04352 char *buff,
04353 char **bufc,
04354 char *pString,
04355 const unsigned char xfrmTable[256])
04356 {
04357 int nString = strlen(pString);
04358 char *pBuffer = *bufc;
04359 int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
04360 while (nString)
04361 {
04362 int nTokenLength0;
04363 int nTokenLength1;
04364 int iType = ANSI_lex(nString, pString, &nTokenLength0, &nTokenLength1);
04365
04366 if (iType == TOKEN_TEXT_ANSI)
04367 {
04368
04369
04370 int nMove = nTokenLength0;
04371 if (nMove > nBufferAvailable)
04372 {
04373 nMove = nBufferAvailable;
04374 }
04375 nBufferAvailable -= nMove;
04376
04377
04378
04379 char *p = pString;
04380 nString -= nTokenLength0;
04381 pString += nTokenLength0;
04382
04383
04384
04385 while (nMove--)
04386 {
04387 *pBuffer++ = xfrmTable[(unsigned char)*p++];
04388 }
04389
04390
04391
04392 if (nTokenLength1)
04393 {
04394 if (nTokenLength1 <= nBufferAvailable)
04395 {
04396 memcpy(pBuffer, pString, nTokenLength1);
04397 pBuffer += nTokenLength1;
04398 nBufferAvailable -= nTokenLength1;
04399 }
04400 nString -= nTokenLength1;
04401 pString += nTokenLength1;
04402 }
04403 }
04404 else
04405 {
04406
04407
04408
04409
04410 if (nTokenLength0 <= nBufferAvailable)
04411 {
04412 memcpy(pBuffer, pString, nTokenLength0);
04413 pBuffer += nTokenLength0;
04414 nBufferAvailable -= nTokenLength0;
04415 }
04416 nString -= nTokenLength0;
04417 pString += nTokenLength0;
04418 }
04419 }
04420 *pBuffer = '\0';
04421 *bufc = pBuffer;
04422 }
04423
04424
04425
04426
04427
04428
04429 static FUNCTION(fun_lcstr)
04430 {
04431 UNUSED_PARAMETER(executor);
04432 UNUSED_PARAMETER(caller);
04433 UNUSED_PARAMETER(enactor);
04434 UNUSED_PARAMETER(nfargs);
04435 UNUSED_PARAMETER(cargs);
04436 UNUSED_PARAMETER(ncargs);
04437
04438 ANSI_TransformTextWithTable(buff, bufc, fargs[0], mux_tolower);
04439 }
04440
04441 static FUNCTION(fun_ucstr)
04442 {
04443 UNUSED_PARAMETER(executor);
04444 UNUSED_PARAMETER(caller);
04445 UNUSED_PARAMETER(enactor);
04446 UNUSED_PARAMETER(nfargs);
04447 UNUSED_PARAMETER(cargs);
04448 UNUSED_PARAMETER(ncargs);
04449
04450 ANSI_TransformTextWithTable(buff, bufc, fargs[0], mux_toupper);
04451 }
04452
04453 static FUNCTION(fun_capstr)
04454 {
04455 UNUSED_PARAMETER(executor);
04456 UNUSED_PARAMETER(caller);
04457 UNUSED_PARAMETER(enactor);
04458 UNUSED_PARAMETER(nfargs);
04459 UNUSED_PARAMETER(cargs);
04460 UNUSED_PARAMETER(ncargs);
04461
04462 char *pString = fargs[0];
04463 char *pBuffer = *bufc;
04464 int nString = strlen(pString);
04465 nString = safe_copy_buf(pString, nString, buff, bufc);
04466
04467
04468
04469 while (nString)
04470 {
04471 int nTokenLength0;
04472 int nTokenLength1;
04473 int iType = ANSI_lex(nString, pBuffer, &nTokenLength0, &nTokenLength1);
04474 if (iType == TOKEN_TEXT_ANSI)
04475 {
04476 *pBuffer = mux_toupper(*pBuffer);
04477 return;
04478 }
04479 else
04480 {
04481
04482
04483 pBuffer += nTokenLength0;
04484 nString -= nTokenLength0;
04485 }
04486 }
04487 }
04488
04489
04490
04491
04492
04493 static FUNCTION(fun_lnum)
04494 {
04495 SEP sep;
04496 if ( nfargs == 0
04497 || !OPTIONAL_DELIM(3, sep, DELIM_NULL|DELIM_CRLF|DELIM_STRING))
04498 {
04499 return;
04500 }
04501
04502 int bot = 0, top;
04503 if (nfargs == 1)
04504 {
04505 top = mux_atol(fargs[0]) - 1;
04506 if (top < 0)
04507 {
04508 return;
04509 }
04510 }
04511 else
04512 {
04513 bot = mux_atol(fargs[0]);
04514 top = mux_atol(fargs[1]);
04515 }
04516
04517 int i;
04518 if (bot == top)
04519 {
04520 safe_ltoa(bot, buff, bufc);
04521 }
04522 else if (bot < top)
04523 {
04524 safe_ltoa(bot, buff, bufc);
04525 for (i = bot+1; i <= top; i++)
04526 {
04527 print_sep(&sep, buff, bufc);
04528 char *p = *bufc;
04529 safe_ltoa(i, buff, bufc);
04530 if (p == *bufc) return;
04531 }
04532 }
04533 else if (top < bot)
04534 {
04535 safe_ltoa(bot, buff, bufc);
04536 for (i = bot-1; i >= top; i--)
04537 {
04538 print_sep(&sep, buff, bufc);
04539 char *p = *bufc;
04540 safe_ltoa(i, buff, bufc);
04541 if (p == *bufc)
04542 {
04543 return;
04544 }
04545 }
04546 }
04547 }
04548
04549
04550
04551
04552
04553 static void lattr_handler(char *buff, char **bufc, dbref executor, char *fargs[],
04554 bool bCheckParent)
04555 {
04556 dbref thing;
04557 int ca;
04558 bool bFirst;
04559
04560
04561
04562
04563
04564 bFirst = true;
04565 olist_push();
04566 if (parse_attrib_wild(executor, fargs[0], &thing, bCheckParent, false, true))
04567 {
04568 for (ca = olist_first(); ca != NOTHING; ca = olist_next())
04569 {
04570 ATTR *pattr = atr_num(ca);
04571 if (pattr)
04572 {
04573 if (!bFirst)
04574 {
04575 safe_chr(' ', buff, bufc);
04576 }
04577 bFirst = false;
04578 safe_str(pattr->name, buff, bufc);
04579 }
04580 }
04581 }
04582 else
04583 {
04584 safe_nomatch(buff, bufc);
04585 }
04586 olist_pop();
04587 }
04588
04589 static FUNCTION(fun_lattr)
04590 {
04591 UNUSED_PARAMETER(caller);
04592 UNUSED_PARAMETER(enactor);
04593 UNUSED_PARAMETER(nfargs);
04594 UNUSED_PARAMETER(cargs);
04595 UNUSED_PARAMETER(ncargs);
04596
04597 lattr_handler(buff, bufc, executor, fargs, false);
04598 }
04599
04600 static FUNCTION(fun_lattrp)
04601 {
04602 UNUSED_PARAMETER(caller);
04603 UNUSED_PARAMETER(enactor);
04604 UNUSED_PARAMETER(nfargs);
04605 UNUSED_PARAMETER(cargs);
04606 UNUSED_PARAMETER(ncargs);
04607
04608 lattr_handler(buff, bufc, executor, fargs, true);
04609 }
04610
04611
04612
04613
04614 static FUNCTION(fun_attrcnt)
04615 {
04616 UNUSED_PARAMETER(caller);
04617 UNUSED_PARAMETER(enactor);
04618 UNUSED_PARAMETER(nfargs);
04619 UNUSED_PARAMETER(cargs);
04620 UNUSED_PARAMETER(ncargs);
04621
04622 dbref thing;
04623 int ca, count = 0;
04624
04625
04626
04627 olist_push();
04628 if (parse_attrib_wild(executor, fargs[0], &thing, false, false, true))
04629 {
04630 for (ca = olist_first(); ca != NOTHING; ca = olist_next())
04631 {
04632 ATTR *pattr = atr_num(ca);
04633 if (pattr)
04634 {
04635 count++;
04636 }
04637 }
04638 safe_ltoa(count, buff, bufc);
04639 }
04640 else
04641 {
04642 safe_nomatch(buff, bufc);
04643 }
04644 olist_pop();
04645 }
04646
04647
04648
04649
04650
04651
04652 static void mux_memrevcpy(char *dest, char *src, unsigned int n)
04653 {
04654 dest += n - 1;
04655 while (n--)
04656 {
04657 *dest-- = *src++;
04658 }
04659 }
04660
04661 typedef void MEMXFORM(char *dest, char *src, unsigned int n);
04662 static void ANSI_TransformTextReverseWithFunction
04663 (
04664 char *buff,
04665 char **bufc,
04666 char *pString,
04667 MEMXFORM *pfMemXForm
04668 )
04669 {
04670
04671
04672 unsigned int nString = strlen(pString);
04673 char *pBuffer = *bufc;
04674 unsigned int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
04675 if (nString > nBufferAvailable)
04676 {
04677 nString = nBufferAvailable;
04678 pString[nString] = '\0';
04679 }
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693 int nANSI = 0;
04694 char *pANSI = pString;
04695 pBuffer += nString;
04696 *bufc = pBuffer;
04697 **bufc = '\0';
04698 while (nString)
04699 {
04700 int nTokenLength0;
04701 int nTokenLength1;
04702 int iType = ANSI_lex(nString, pString, &nTokenLength0, &nTokenLength1);
04703
04704 if (iType == TOKEN_TEXT_ANSI)
04705 {
04706
04707
04708 pBuffer -= nANSI + nTokenLength0;
04709 memcpy(pBuffer, pANSI, nANSI);
04710 pfMemXForm(pBuffer+nANSI, pString, nTokenLength0);
04711
04712
04713
04714 nString -= nTokenLength0;
04715 pString += nTokenLength0;
04716 pANSI = pString;
04717 nANSI = 0;
04718
04719 nTokenLength0 = nTokenLength1;
04720 }
04721
04722
04723 nString -= nTokenLength0;
04724 pString += nTokenLength0;
04725 nANSI += nTokenLength0;
04726 }
04727
04728
04729
04730
04731
04732 pBuffer -= nANSI;
04733 memcpy(pBuffer, pANSI, nANSI);
04734 }
04735
04736 static FUNCTION(fun_reverse)
04737 {
04738 UNUSED_PARAMETER(executor);
04739 UNUSED_PARAMETER(caller);
04740 UNUSED_PARAMETER(enactor);
04741 UNUSED_PARAMETER(nfargs);
04742 UNUSED_PARAMETER(cargs);
04743 UNUSED_PARAMETER(ncargs);
04744
04745 ANSI_TransformTextReverseWithFunction(buff, bufc, fargs[0], mux_memrevcpy);
04746 }
04747
04748 static char ReverseWordsInText_Seperator;
04749
04750 static void ReverseWordsInText(char *dest, char *src, unsigned int n)
04751 {
04752 char chSave = src[n];
04753 src[n] = '\0';
04754 dest += n;
04755 while (n)
04756 {
04757 char *pWord = strchr(src, ReverseWordsInText_Seperator);
04758 int nLen;
04759 if (pWord)
04760 {
04761 nLen = (pWord - src);
04762 }
04763 else
04764 {
04765 nLen = n;
04766 }
04767 dest -= nLen;
04768 memcpy(dest, src, nLen);
04769 src += nLen;
04770 n -= nLen;
04771 if (pWord)
04772 {
04773 dest--;
04774 *dest = ReverseWordsInText_Seperator;
04775 src++;
04776 n--;
04777 }
04778 }
04779 src[n] = chSave;
04780 }
04781
04782 static FUNCTION(fun_revwords)
04783 {
04784
04785
04786 if (nfargs == 0)
04787 {
04788 return;
04789 }
04790 SEP sep;
04791 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT))
04792 {
04793 return;
04794 }
04795 ReverseWordsInText_Seperator = sep.str[0];
04796 ANSI_TransformTextReverseWithFunction(buff, bufc, fargs[0], ReverseWordsInText);
04797 }
04798
04799
04800
04801
04802
04803
04804 static FUNCTION(fun_after)
04805 {
04806 UNUSED_PARAMETER(executor);
04807 UNUSED_PARAMETER(caller);
04808 UNUSED_PARAMETER(enactor);
04809 UNUSED_PARAMETER(cargs);
04810 UNUSED_PARAMETER(ncargs);
04811
04812 char *mp;
04813 int mlen;
04814
04815
04816
04817 char *bp = fargs[0];
04818 if (nfargs > 1)
04819 {
04820 mp = fargs[1];
04821 mlen = strlen(mp);
04822 }
04823 else
04824 {
04825 mp = " ";
04826 mlen = 1;
04827 }
04828
04829 if ( mlen == 1
04830 && *mp == ' ')
04831 {
04832 bp = trim_space_sep(bp, &sepSpace);
04833 }
04834
04835
04836
04837 int nText = strlen(bp);
04838 int i = BMH_StringSearch(mlen, mp, nText, bp);
04839 if (i >= 0)
04840 {
04841
04842
04843 bp += i + mlen;
04844 safe_copy_buf(bp, nText-i-mlen, buff, bufc);
04845 }
04846
04847
04848 }
04849
04850 static FUNCTION(fun_before)
04851 {
04852 UNUSED_PARAMETER(executor);
04853 UNUSED_PARAMETER(caller);
04854 UNUSED_PARAMETER(enactor);
04855 UNUSED_PARAMETER(cargs);
04856 UNUSED_PARAMETER(ncargs);
04857
04858 char *mp, *ip;
04859 int mlen;
04860
04861
04862
04863 char *bp = fargs[0];
04864 if (nfargs > 1)
04865 {
04866 mp = fargs[1];
04867 mlen = strlen(mp);
04868 }
04869 else
04870 {
04871 mp = " ";
04872 mlen = 1;
04873 }
04874
04875 if ( mlen == 1
04876 && *mp == ' ')
04877 {
04878 bp = trim_space_sep(bp, &sepSpace);
04879 }
04880
04881 ip = bp;
04882
04883
04884
04885 int i = BMH_StringSearch(mlen, mp, strlen(bp), bp);
04886 if (i >= 0)
04887 {
04888
04889
04890 safe_copy_buf(ip, i, buff, bufc);
04891 return;
04892 }
04893
04894
04895 safe_str(ip, buff, bufc);
04896 }
04897
04898
04899
04900
04901
04902
04903 static FUNCTION(fun_search)
04904 {
04905 UNUSED_PARAMETER(cargs);
04906 UNUSED_PARAMETER(ncargs);
04907
04908 char *pArg = NULL;
04909 if (nfargs != 0)
04910 {
04911 pArg = fargs[0];
04912 }
04913
04914
04915
04916 SEARCH searchparm;
04917 if (!search_setup(executor, pArg, &searchparm))
04918 {
04919 safe_str("#-1 ERROR DURING SEARCH", buff, bufc);
04920 return;
04921 }
04922
04923
04924
04925 olist_push();
04926 search_perform(executor, caller, enactor, &searchparm);
04927 dbref thing;
04928 ITL pContext;
04929 ItemToList_Init(&pContext, buff, bufc, '#');
04930 for (thing = olist_first(); thing != NOTHING; thing = olist_next())
04931 {
04932 if (!ItemToList_AddInteger(&pContext, thing))
04933 {
04934 break;
04935 }
04936 }
04937 ItemToList_Final(&pContext);
04938 olist_pop();
04939 }
04940
04941
04942
04943
04944
04945
04946 static FUNCTION(fun_stats)
04947 {
04948 UNUSED_PARAMETER(caller);
04949 UNUSED_PARAMETER(enactor);
04950 UNUSED_PARAMETER(cargs);
04951 UNUSED_PARAMETER(ncargs);
04952
04953 dbref who;
04954
04955 if ( nfargs == 0
04956 || (!fargs[0])
04957 || !*fargs[0]
04958 || !string_compare(fargs[0], "all"))
04959 {
04960 who = NOTHING;
04961 }
04962 else
04963 {
04964 who = lookup_player(executor, fargs[0], true);
04965 if (who == NOTHING)
04966 {
04967 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
04968 return;
04969 }
04970 }
04971 STATS statinfo;
04972 if (!get_stats(executor, who, &statinfo))
04973 {
04974 safe_str("#-1 ERROR GETTING STATS", buff, bufc);
04975 return;
04976 }
04977 safe_tprintf_str(buff, bufc, "%d %d %d %d %d %d", statinfo.s_total, statinfo.s_rooms,
04978 statinfo.s_exits, statinfo.s_things, statinfo.s_players, statinfo.s_garbage);
04979 }
04980
04981
04982
04983
04984
04985
04986
04987
04988
04989 static FUNCTION(fun_merge)
04990 {
04991 UNUSED_PARAMETER(executor);
04992 UNUSED_PARAMETER(caller);
04993 UNUSED_PARAMETER(enactor);
04994 UNUSED_PARAMETER(nfargs);
04995 UNUSED_PARAMETER(cargs);
04996 UNUSED_PARAMETER(ncargs);
04997
04998 char *str, *rep;
04999 char c;
05000
05001
05002
05003 size_t n0 = strlen(fargs[0]);
05004 size_t n1 = strlen(fargs[1]);
05005 if (n0 != n1)
05006 {
05007 safe_str("#-1 STRING LENGTHS MUST BE EQUAL", buff, bufc);
05008 return;
05009 }
05010 if (strlen(fargs[2]) > 1)
05011 {
05012 safe_str("#-1 TOO MANY CHARACTERS", buff, bufc);
05013 return;
05014 }
05015
05016
05017
05018
05019 if (!*fargs[2])
05020 c = ' ';
05021 else
05022 c = *fargs[2];
05023
05024
05025
05026 for (str = fargs[0], rep = fargs[1];
05027 *str && *rep && ((*bufc - buff) < (LBUF_SIZE-1));
05028 str++, rep++, (*bufc)++)
05029 {
05030 if (*str == c)
05031 **bufc = *rep;
05032 else
05033 **bufc = *str;
05034 }
05035 return;
05036 }
05037
05038
05039
05040
05041
05042 static FUNCTION(fun_splice)
05043 {
05044 SEP sep;
05045 if (!OPTIONAL_DELIM(4, sep, DELIM_DFLT|DELIM_STRING))
05046 {
05047 return;
05048 }
05049 SEP osep = sep;
05050 if (!OPTIONAL_DELIM(5, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
05051 {
05052 return;
05053 }
05054
05055
05056
05057 if (countwords(fargs[2], &sep) > 1)
05058 {
05059 safe_str("#-1 TOO MANY WORDS", buff, bufc);
05060 return;
05061 }
05062 int words = countwords(fargs[0], &sep);
05063 if (words != countwords(fargs[1], &sep))
05064 {
05065 safe_str("#-1 NUMBER OF WORDS MUST BE EQUAL", buff, bufc);
05066 return;
05067 }
05068
05069
05070
05071 char *p1 = fargs[0];
05072 char *q1 = fargs[1];
05073 char *p2, *q2;
05074 bool first = true;
05075 int i;
05076 for (i = 0; i < words; i++)
05077 {
05078 p2 = split_token(&p1, &sep);
05079 q2 = split_token(&q1, &sep);
05080 if (!first)
05081 {
05082 print_sep(&osep, buff, bufc);
05083 }
05084 if (strcmp(p2, fargs[2]) == 0)
05085 {
05086 safe_str(q2, buff, bufc);
05087 }
05088 else
05089 {
05090 safe_str(p2, buff, bufc);
05091 }
05092 first = false;
05093 }
05094 }
05095
05096
05097
05098
05099
05100 static FUNCTION(fun_repeat)
05101 {
05102 UNUSED_PARAMETER(executor);
05103 UNUSED_PARAMETER(caller);
05104 UNUSED_PARAMETER(enactor);
05105 UNUSED_PARAMETER(nfargs);
05106 UNUSED_PARAMETER(cargs);
05107 UNUSED_PARAMETER(ncargs);
05108
05109 int times = mux_atol(fargs[1]);
05110 if (times < 1 || *fargs[0] == '\0')
05111 {
05112
05113
05114 return;
05115 }
05116 else if (times == 1)
05117 {
05118
05119
05120 safe_str(fargs[0], buff, bufc);
05121 }
05122 else
05123 {
05124 int len = strlen(fargs[0]);
05125 if (len == 1)
05126 {
05127
05128
05129 safe_fill(buff, bufc, *fargs[0], times);
05130 }
05131 else
05132 {
05133 int nSize = len*times;
05134 if ( times > LBUF_SIZE - 1
05135 || nSize > LBUF_SIZE - 1)
05136 {
05137 safe_str("#-1 STRING TOO LONG", buff, bufc);
05138 }
05139 else
05140 {
05141 int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
05142 if (nSize > nBufferAvailable)
05143 {
05144 nSize = nBufferAvailable;
05145 }
05146 int nFullCopies = nSize / len;
05147 int nPartial = nSize - nFullCopies * len;
05148 while (nFullCopies--)
05149 {
05150 memcpy(*bufc, fargs[0], len);
05151 *bufc += len;
05152 }
05153 if (nPartial)
05154 {
05155 memcpy(*bufc, fargs[0], nPartial);
05156 *bufc += nPartial;
05157 }
05158 }
05159 }
05160 }
05161 }
05162
05163
05164
05165
05166
05167
05168
05169 static FUNCTION(fun_iter)
05170 {
05171
05172
05173 SEP sep;
05174 if (!OPTIONAL_DELIM(3, sep, DELIM_EVAL|DELIM_STRING))
05175 {
05176 return;
05177 }
05178
05179
05180
05181 SEP osep;
05182 if (!OPTIONAL_DELIM(4, osep, DELIM_EVAL|DELIM_NULL|DELIM_CRLF|DELIM_STRING))
05183 {
05184 return;
05185 }
05186
05187 char *curr = alloc_lbuf("fun_iter");
05188 char *dp = curr;
05189 char *str = fargs[0];
05190 mux_exec(curr, &dp, executor, caller, enactor,
05191 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05192 *dp = '\0';
05193 int ncp;
05194 char *cp = trim_space_sep_LEN(curr, dp-curr, &sep, &ncp);
05195 if (!*cp)
05196 {
05197 free_lbuf(curr);
05198 return;
05199 }
05200 bool first = true;
05201 int number = 0;
05202 bool bLoopInBounds = ( 0 <= mudstate.in_loop
05203 && mudstate.in_loop < MAX_ITEXT);
05204 if (bLoopInBounds)
05205 {
05206 mudstate.itext[mudstate.in_loop] = NULL;
05207 mudstate.inum[mudstate.in_loop] = number;
05208 }
05209 mudstate.in_loop++;
05210 while ( cp
05211 && mudstate.func_invk_ctr < mudconf.func_invk_lim
05212 && !MuxAlarm.bAlarmed)
05213 {
05214 if (!first)
05215 {
05216 print_sep(&osep, buff, bufc);
05217 }
05218 first = false;
05219 number++;
05220 char *objstring = split_token(&cp, &sep);
05221 if (bLoopInBounds)
05222 {
05223 mudstate.itext[mudstate.in_loop-1] = objstring;
05224 mudstate.inum[mudstate.in_loop-1] = number;
05225 }
05226 char *buff2 = replace_tokens(fargs[1], objstring, mux_ltoa_t(number),
05227 NULL);
05228 str = buff2;
05229 mux_exec(buff, bufc, executor, caller, enactor,
05230 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05231 free_lbuf(buff2);
05232 }
05233 mudstate.in_loop--;
05234 if (bLoopInBounds)
05235 {
05236 mudstate.itext[mudstate.in_loop] = NULL;
05237 mudstate.inum[mudstate.in_loop] = 0;
05238 }
05239 free_lbuf(curr);
05240 }
05241
05242 static void iter_value(char *buff, char **bufc, char *fargs[], int nfargs, bool bWhich)
05243 {
05244 int number = 0;
05245 if (nfargs > 0)
05246 {
05247 number = mux_atol(fargs[0]);
05248 if (number < 0)
05249 {
05250 number = 0;
05251 }
05252 }
05253
05254 number++;
05255 int val = mudstate.in_loop - number;
05256 if ( 0 <= val
05257 && val < MAX_ITEXT)
05258 {
05259 if (bWhich)
05260 {
05261 safe_ltoa(mudstate.inum[val], buff, bufc);
05262 }
05263 else
05264 {
05265 safe_str(mudstate.itext[val], buff, bufc);
05266 }
05267 }
05268 }
05269
05270 static FUNCTION(fun_itext)
05271 {
05272 UNUSED_PARAMETER(executor);
05273 UNUSED_PARAMETER(caller);
05274 UNUSED_PARAMETER(enactor);
05275 UNUSED_PARAMETER(cargs);
05276 UNUSED_PARAMETER(ncargs);
05277
05278 iter_value(buff, bufc, fargs, nfargs, false);
05279 }
05280
05281 static FUNCTION(fun_inum)
05282 {
05283 UNUSED_PARAMETER(executor);
05284 UNUSED_PARAMETER(caller);
05285 UNUSED_PARAMETER(enactor);
05286 UNUSED_PARAMETER(cargs);
05287 UNUSED_PARAMETER(ncargs);
05288
05289 iter_value(buff, bufc, fargs, nfargs, true);
05290 }
05291
05292 static FUNCTION(fun_list)
05293 {
05294 SEP sep;
05295 if (!OPTIONAL_DELIM(3, sep, DELIM_EVAL|DELIM_STRING))
05296 {
05297 return;
05298 }
05299
05300 char *objstring, *result, *str;
05301
05302 char *curr = alloc_lbuf("fun_list");
05303 char *dp = curr;
05304 str = fargs[0];
05305 mux_exec(curr, &dp, executor, caller, enactor,
05306 EV_TOP | EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05307 *dp = '\0';
05308
05309 int ncp;
05310 char *cp = trim_space_sep_LEN(curr, dp-curr, &sep, &ncp);
05311 if (!*cp)
05312 {
05313 free_lbuf(curr);
05314 return;
05315 }
05316 int number = 0;
05317 bool bLoopInBounds = ( 0 <= mudstate.in_loop
05318 && mudstate.in_loop < MAX_ITEXT);
05319 if (bLoopInBounds)
05320 {
05321 mudstate.itext[mudstate.in_loop] = NULL;
05322 mudstate.inum[mudstate.in_loop] = number;
05323 }
05324 mudstate.in_loop++;
05325 while ( cp
05326 && mudstate.func_invk_ctr < mudconf.func_invk_lim
05327 && !MuxAlarm.bAlarmed)
05328 {
05329 number++;
05330 objstring = split_token(&cp, &sep);
05331 if (bLoopInBounds)
05332 {
05333 mudstate.itext[mudstate.in_loop-1] = objstring;
05334 mudstate.inum[mudstate.in_loop-1] = number;
05335 }
05336 char *buff2 = replace_tokens(fargs[1], objstring, mux_ltoa_t(number),
05337 NULL);
05338 dp = result = alloc_lbuf("fun_list.2");
05339 str = buff2;
05340 mux_exec(result, &dp, executor, caller, enactor,
05341 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05342 *dp = '\0';
05343 free_lbuf(buff2);
05344 notify(enactor, result);
05345 free_lbuf(result);
05346 }
05347 mudstate.in_loop--;
05348 if (bLoopInBounds)
05349 {
05350 mudstate.itext[mudstate.in_loop] = NULL;
05351 mudstate.inum[mudstate.in_loop] = 0;
05352 }
05353 free_lbuf(curr);
05354 }
05355
05356 static FUNCTION(fun_ilev)
05357 {
05358 UNUSED_PARAMETER(executor);
05359 UNUSED_PARAMETER(caller);
05360 UNUSED_PARAMETER(enactor);
05361 UNUSED_PARAMETER(fargs);
05362 UNUSED_PARAMETER(nfargs);
05363 UNUSED_PARAMETER(cargs);
05364 UNUSED_PARAMETER(ncargs);
05365
05366 safe_ltoa(mudstate.in_loop-1, buff, bufc);
05367 }
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384 static FUNCTION(fun_fold)
05385 {
05386 SEP sep;
05387 if (!OPTIONAL_DELIM(4, sep, DELIM_DFLT|DELIM_STRING))
05388 {
05389 return;
05390 }
05391
05392 char *atext;
05393 dbref thing;
05394 if (!parse_and_get_attrib(executor, fargs, &atext, &thing, buff, bufc))
05395 {
05396 return;
05397 }
05398
05399
05400
05401 char *curr = fargs[1];
05402 char *cp = curr;
05403 char *atextbuf = alloc_lbuf("fun_fold");
05404 strcpy(atextbuf, atext);
05405
05406 char *result, *bp, *str, *clist[2];
05407
05408
05409
05410 if ( nfargs >= 3
05411 && fargs[2])
05412 {
05413 clist[0] = fargs[2];
05414 clist[1] = split_token(&cp, &sep);
05415 result = bp = alloc_lbuf("fun_fold");
05416 str = atextbuf;
05417 mux_exec(result, &bp, thing, executor, enactor,
05418 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, clist, 2);
05419 *bp = '\0';
05420 }
05421 else
05422 {
05423 clist[0] = split_token(&cp, &sep);
05424 clist[1] = split_token(&cp, &sep);
05425 result = bp = alloc_lbuf("fun_fold");
05426 str = atextbuf;
05427 mux_exec(result, &bp, thing, executor, enactor,
05428 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, clist, 2);
05429 *bp = '\0';
05430 }
05431
05432 char *rstore = result;
05433 result = alloc_lbuf("fun_fold");
05434
05435 while ( cp
05436 && mudstate.func_invk_ctr < mudconf.func_invk_lim
05437 && !MuxAlarm.bAlarmed)
05438 {
05439 clist[0] = rstore;
05440 clist[1] = split_token(&cp, &sep);
05441 strcpy(atextbuf, atext);
05442 bp = result;
05443 str = atextbuf;
05444 mux_exec(result, &bp, thing, executor, enactor,
05445 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, clist, 2);
05446 *bp = '\0';
05447 strcpy(rstore, result);
05448 }
05449 free_lbuf(result);
05450 safe_str(rstore, buff, bufc);
05451 free_lbuf(rstore);
05452 free_lbuf(atext);
05453 free_lbuf(atextbuf);
05454 }
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465 static FUNCTION(fun_itemize)
05466 {
05467 SEP sep;
05468 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
05469 {
05470 return;
05471 }
05472
05473 const char *lconj = "and";
05474 if (nfargs > 2)
05475 {
05476 lconj = fargs[2];
05477 }
05478 const char *punc = ",";
05479 if (nfargs > 3)
05480 {
05481 punc = fargs[3];
05482 }
05483
05484 int pos = 1;
05485 char *cp = trim_space_sep(fargs[0], &sep);
05486 char *word = split_token(&cp, &sep);
05487 while (cp && *cp)
05488 {
05489 pos++;
05490 safe_str(word, buff, bufc);
05491 char *nextword = split_token(&cp, &sep);
05492
05493 if (!cp || !*cp)
05494 {
05495
05496
05497 if (pos >= 3)
05498 {
05499 safe_str(punc, buff, bufc);
05500 }
05501 safe_chr(' ', buff, bufc);
05502 safe_str(lconj, buff, bufc);
05503 }
05504 else
05505 {
05506 safe_str(punc, buff, bufc);
05507 }
05508 safe_chr(' ', buff, bufc);
05509
05510 word = nextword;
05511 }
05512 safe_str(word, buff, bufc);
05513 }
05514
05515
05516
05517
05518
05519 static FUNCTION(fun_choose)
05520 {
05521 SEP isep;
05522 if (!OPTIONAL_DELIM(3, isep, DELIM_DFLT|DELIM_STRING))
05523 {
05524 return;
05525 }
05526
05527 char *elems[LBUF_SIZE/2], *weights[LBUF_SIZE/2];
05528 int n_elems = list2arr(elems, LBUF_SIZE/2, fargs[0], &isep);
05529 int n_weights = list2arr(weights, LBUF_SIZE/2, fargs[1], &sepSpace);
05530
05531 if (n_elems != n_weights)
05532 {
05533 safe_str("#-1 LISTS MUST BE OF EQUAL SIZE", buff, bufc);
05534 return;
05535 }
05536
05537
05538
05539 int i;
05540 int sum = 0;
05541 int ip[LBUF_SIZE/2];
05542 for (i = 0; i < n_weights; i++)
05543 {
05544 int num = mux_atol(weights[i]);
05545 if (num < 0)
05546 {
05547 num = 0;
05548 }
05549 if (num == 0)
05550 {
05551 ip[i] = 0;
05552 }
05553 else
05554 {
05555 int sum_next = sum + num;
05556 if (sum_next < sum)
05557 {
05558 safe_str("#-1 OVERFLOW", buff, bufc);
05559 return;
05560 }
05561 sum = sum_next;
05562 ip[i] = sum;
05563 }
05564 }
05565
05566 INT32 num = RandomINT32(0, sum-1);
05567
05568 for (i = 0; i < n_weights; i++)
05569 {
05570 if ( ip[i] != 0
05571 && num < ip[i])
05572 {
05573 safe_str(elems[i], buff, bufc);
05574 break;
05575 }
05576 }
05577 }
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590
05591
05592 static void filter_handler(char *buff, char **bufc, dbref executor, dbref enactor,
05593 char *fargs[], SEP *psep, SEP *posep, bool bBool)
05594 {
05595 char *atext;
05596 dbref thing;
05597 if (!parse_and_get_attrib(executor, fargs, &atext, &thing, buff, bufc))
05598 {
05599 return;
05600 }
05601
05602
05603
05604 char *curr = trim_space_sep(fargs[1], psep);
05605 char *cp = curr;
05606 char *atextbuf = alloc_lbuf("fun_filter");
05607 char *result = alloc_lbuf("fun_filter");
05608 bool bFirst = true;
05609 while ( cp
05610 && mudstate.func_invk_ctr < mudconf.func_invk_lim
05611 && !MuxAlarm.bAlarmed)
05612 {
05613 char *objstring = split_token(&cp, psep);
05614 strcpy(atextbuf, atext);
05615 char *bp = result;
05616 char *str = atextbuf;
05617 mux_exec(result, &bp, thing, executor, enactor,
05618 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, &objstring, 1);
05619 *bp = '\0';
05620
05621 if ( ( bBool
05622 && xlate(result))
05623 || ( !bBool
05624 && result[0] == '1'
05625 && result[1] == '\0'))
05626 {
05627 if (!bFirst)
05628 {
05629 print_sep(posep, buff, bufc);
05630 }
05631 safe_str(objstring, buff, bufc);
05632 bFirst = false;
05633 }
05634 }
05635 free_lbuf(result);
05636 free_lbuf(atext);
05637 free_lbuf(atextbuf);
05638 }
05639
05640 static FUNCTION(fun_filter)
05641 {
05642 SEP sep;
05643 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
05644 {
05645 return;
05646 }
05647 SEP osep = sep;
05648 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
05649 {
05650 return;
05651 }
05652 filter_handler(buff, bufc, executor, enactor, fargs, &sep, &osep, false);
05653 }
05654
05655 static FUNCTION(fun_filterbool)
05656 {
05657 SEP sep;
05658 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
05659 {
05660 return;
05661 }
05662 SEP osep = sep;
05663 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
05664 {
05665 return;
05666 }
05667 filter_handler(buff, bufc, executor, enactor, fargs, &sep, &osep, true);
05668 }
05669
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680 static FUNCTION(fun_map)
05681 {
05682 SEP sep;
05683 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
05684 {
05685 return;
05686 }
05687
05688 SEP osep = sep;
05689 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
05690 {
05691 return;
05692 }
05693
05694 char *atext;
05695 dbref thing;
05696 if (!parse_and_get_attrib(executor, fargs, &atext, &thing, buff, bufc))
05697 {
05698 return;
05699 }
05700
05701
05702
05703 char *cp = trim_space_sep(fargs[1], &sep);
05704 char *atextbuf = alloc_lbuf("fun_map");
05705 bool first = true;
05706 char *objstring, *str;
05707 while ( cp
05708 && mudstate.func_invk_ctr < mudconf.func_invk_lim
05709 && !MuxAlarm.bAlarmed)
05710 {
05711 if (!first)
05712 {
05713 print_sep(&osep, buff, bufc);
05714 }
05715 first = false;
05716 objstring = split_token(&cp, &sep);
05717 strcpy(atextbuf, atext);
05718 str = atextbuf;
05719 mux_exec(buff, bufc, thing, executor, enactor,
05720 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, &objstring, 1);
05721 }
05722 free_lbuf(atext);
05723 free_lbuf(atextbuf);
05724 }
05725
05726
05727
05728
05729
05730
05731 static FUNCTION(fun_edit)
05732 {
05733 UNUSED_PARAMETER(executor);
05734 UNUSED_PARAMETER(caller);
05735 UNUSED_PARAMETER(enactor);
05736 UNUSED_PARAMETER(nfargs);
05737 UNUSED_PARAMETER(cargs);
05738 UNUSED_PARAMETER(ncargs);
05739
05740 char *tstr;
05741
05742 edit_string(strip_ansi(fargs[0]), &tstr, fargs[1], fargs[2]);
05743 safe_str(tstr, buff, bufc);
05744 free_lbuf(tstr);
05745 }
05746
05747
05748
05749
05750
05751 static FUNCTION(fun_locate)
05752 {
05753 UNUSED_PARAMETER(caller);
05754 UNUSED_PARAMETER(enactor);
05755 UNUSED_PARAMETER(nfargs);
05756 UNUSED_PARAMETER(cargs);
05757 UNUSED_PARAMETER(ncargs);
05758
05759 bool check_locks, verbose, multiple;
05760 dbref thing, what;
05761 char *cp;
05762
05763 int pref_type = NOTYPE;
05764 check_locks = verbose = multiple = false;
05765
05766
05767
05768 if (See_All(executor))
05769 {
05770 thing = match_thing_quiet(executor, fargs[0]);
05771 }
05772 else
05773 {
05774 thing = match_controlled_quiet(executor, fargs[0]);
05775 }
05776 if (!Good_obj(thing))
05777 {
05778 safe_match_result(thing, buff, bufc);
05779 return;
05780 }
05781
05782
05783
05784 for (cp = fargs[2]; *cp; cp++)
05785 {
05786 switch (*cp)
05787 {
05788 case 'E':
05789 pref_type = TYPE_EXIT;
05790 break;
05791 case 'L':
05792 check_locks = true;
05793 break;
05794 case 'P':
05795 pref_type = TYPE_PLAYER;
05796 break;
05797 case 'R':
05798 pref_type = TYPE_ROOM;
05799 break;
05800 case 'T':
05801 pref_type = TYPE_THING;
05802 break;
05803 case 'V':
05804 verbose = true;
05805 break;
05806 case 'X':
05807 multiple = true;
05808 break;
05809 }
05810 }
05811
05812
05813
05814 if (check_locks)
05815 {
05816 init_match_check_keys(thing, fargs[1], pref_type);
05817 }
05818 else
05819 {
05820 init_match(thing, fargs[1], pref_type);
05821 }
05822
05823
05824
05825 for (cp = fargs[2]; *cp; cp++)
05826 {
05827 switch (*cp)
05828 {
05829 case 'a':
05830 match_absolute();
05831 break;
05832 case 'c':
05833 match_carried_exit_with_parents();
05834 break;
05835 case 'e':
05836 match_exit_with_parents();
05837 break;
05838 case 'h':
05839 match_here();
05840 break;
05841 case 'i':
05842 match_possession();
05843 break;
05844 case 'm':
05845 match_me();
05846 break;
05847 case 'n':
05848 match_neighbor();
05849 break;
05850 case 'p':
05851 match_player();
05852 break;
05853 case '*':
05854 match_everything(MAT_EXIT_PARENTS);
05855 break;
05856 }
05857 }
05858
05859
05860
05861 if (multiple)
05862 {
05863 what = last_match_result();
05864 }
05865 else
05866 {
05867 what = match_result();
05868 }
05869
05870 if (verbose)
05871 {
05872 (void)match_status(executor, what);
05873 }
05874
05875 safe_tprintf_str(buff, bufc, "#%d", what);
05876 }
05877
05878 static void switch_handler
05879 (
05880 char *buff, char **bufc,
05881 dbref executor, dbref caller, dbref enactor,
05882 char *fargs[], int nfargs,
05883 char *cargs[], int ncargs,
05884 bool bSwitch
05885 )
05886 {
05887
05888
05889 char *mbuff = alloc_lbuf("fun_switch");
05890 char *bp = mbuff;
05891 char *str = fargs[0];
05892 mux_exec(mbuff, &bp, executor, caller, enactor,
05893 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05894 *bp = '\0';
05895
05896 char *tbuff = alloc_lbuf("fun_switch.2");
05897
05898
05899
05900 int i;
05901 for (i = 1; i < nfargs-1
05902 && fargs[i]
05903 && fargs[i+1]
05904 && !MuxAlarm.bAlarmed; i += 2)
05905 {
05906 bp = tbuff;
05907 str = fargs[i];
05908 mux_exec(tbuff, &bp, executor, caller, enactor,
05909 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05910 *bp = '\0';
05911
05912 if (bSwitch ? wild_match(tbuff, mbuff) : strcmp(tbuff, mbuff) == 0)
05913 {
05914 free_lbuf(tbuff);
05915 tbuff = replace_tokens(fargs[i+1], NULL, NULL, mbuff);
05916 free_lbuf(mbuff);
05917 str = tbuff;
05918 mux_exec(buff, bufc, executor, caller, enactor,
05919 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05920 free_lbuf(tbuff);
05921 return;
05922 }
05923 }
05924 free_lbuf(tbuff);
05925
05926
05927
05928 if ( i < nfargs
05929 && fargs[i])
05930 {
05931 tbuff = replace_tokens(fargs[i], NULL, NULL, mbuff);
05932 str = tbuff;
05933 mux_exec(buff, bufc, executor, caller, enactor,
05934 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
05935 free_lbuf(tbuff);
05936 }
05937 free_lbuf(mbuff);
05938 }
05939
05940
05941
05942
05943
05944
05945 static FUNCTION(fun_switch)
05946 {
05947 switch_handler
05948 (
05949 buff, bufc,
05950 executor, caller, enactor,
05951 fargs, nfargs,
05952 cargs, ncargs,
05953 true
05954 );
05955 }
05956
05957 static FUNCTION(fun_case)
05958 {
05959 switch_handler
05960 (
05961 buff, bufc,
05962 executor, caller, enactor,
05963 fargs, nfargs,
05964 cargs, ncargs,
05965 false
05966 );
05967 }
05968
05969
05970
05971
05972
05973
05974 static FUNCTION(fun_space)
05975 {
05976 UNUSED_PARAMETER(executor);
05977 UNUSED_PARAMETER(caller);
05978 UNUSED_PARAMETER(enactor);
05979 UNUSED_PARAMETER(cargs);
05980 UNUSED_PARAMETER(ncargs);
05981
05982
05983
05984 int num;
05985 if (nfargs == 0 || *fargs[0] == '\0')
05986 {
05987 num = 1;
05988 }
05989 else
05990 {
05991 num = mux_atol(fargs[0]);
05992 if (num == 0)
05993 {
05994
05995
05996
05997 if (!is_integer(fargs[0], NULL))
05998 {
05999 num = 1;
06000 }
06001 }
06002 else if (num < 0)
06003 {
06004 num = 0;
06005 }
06006
06007 }
06008 safe_fill(buff, bufc, ' ', num);
06009 }
06010
06011 static FUNCTION(fun_height)
06012 {
06013 UNUSED_PARAMETER(caller);
06014 UNUSED_PARAMETER(enactor);
06015 UNUSED_PARAMETER(nfargs);
06016 UNUSED_PARAMETER(cargs);
06017 UNUSED_PARAMETER(ncargs);
06018
06019 long nHeight = 24;
06020 if (is_rational(fargs[0]))
06021 {
06022 SOCKET s = mux_atol(fargs[0]);
06023 DESC *d;
06024 DESC_ITER_CONN(d)
06025 {
06026 if (d->descriptor == s)
06027 {
06028 nHeight = d->height;
06029 break;
06030 }
06031 }
06032 }
06033 else
06034 {
06035 char *pTargetName = fargs[0];
06036 if ('*' == *pTargetName)
06037 {
06038 pTargetName++;
06039 }
06040 dbref target = lookup_player(executor, pTargetName, true);
06041 if (Good_obj(target))
06042 {
06043 if ( executor == target
06044 || See_All(executor))
06045 {
06046 nHeight = fetch_height(target);
06047 }
06048 }
06049 }
06050 safe_ltoa(nHeight, buff, bufc);
06051 }
06052
06053
06054 static FUNCTION(fun_width)
06055 {
06056 UNUSED_PARAMETER(caller);
06057 UNUSED_PARAMETER(enactor);
06058 UNUSED_PARAMETER(nfargs);
06059 UNUSED_PARAMETER(cargs);
06060 UNUSED_PARAMETER(ncargs);
06061
06062 long nWidth = 24;
06063 if (is_rational(fargs[0]))
06064 {
06065 SOCKET s = mux_atol(fargs[0]);
06066 DESC *d;
06067 DESC_ITER_CONN(d)
06068 {
06069 if (d->descriptor == s)
06070 {
06071 nWidth = d->width;
06072 break;
06073 }
06074 }
06075 }
06076 else
06077 {
06078 char *pTargetName = fargs[0];
06079 if ('*' == *pTargetName)
06080 {
06081 pTargetName++;
06082 }
06083 dbref target = lookup_player(executor, pTargetName, true);
06084 if (Good_obj(target))
06085 {
06086 if ( executor == target
06087 || See_All(executor))
06088 {
06089 nWidth = fetch_width(target);
06090 }
06091 }
06092 }
06093 safe_ltoa(nWidth, buff, bufc);
06094 }
06095
06096
06097
06098
06099
06100
06101 static FUNCTION(fun_idle)
06102 {
06103 UNUSED_PARAMETER(caller);
06104 UNUSED_PARAMETER(enactor);
06105 UNUSED_PARAMETER(nfargs);
06106 UNUSED_PARAMETER(cargs);
06107 UNUSED_PARAMETER(ncargs);
06108
06109 long nIdle = -1;
06110 if (is_rational(fargs[0]))
06111 {
06112 SOCKET s = mux_atol(fargs[0]);
06113 bool bFound = false;
06114 DESC *d;
06115 CLinearTimeAbsolute ltaNow;
06116 ltaNow.GetUTC();
06117 DESC_ITER_CONN(d)
06118 {
06119 if (d->descriptor == s)
06120 {
06121 bFound = true;
06122 break;
06123 }
06124 }
06125 if ( bFound
06126 && ( d->player == executor
06127 || Wizard_Who(executor)))
06128 {
06129 CLinearTimeDelta ltdResult = ltaNow - d->last_time;
06130 nIdle = ltdResult.ReturnSeconds();
06131 }
06132 }
06133 else
06134 {
06135 char *pTargetName = fargs[0];
06136 if (*pTargetName == '*')
06137 {
06138 pTargetName++;
06139 }
06140 dbref target = lookup_player(executor, pTargetName, true);
06141 if ( Good_obj(target)
06142 && ( !Hidden(target)
06143 || See_Hidden(executor)))
06144 {
06145 nIdle = fetch_idle(target);
06146 }
06147 }
06148 safe_ltoa(nIdle, buff, bufc);
06149 }
06150
06151 static FUNCTION(fun_conn)
06152 {
06153 UNUSED_PARAMETER(caller);
06154 UNUSED_PARAMETER(enactor);
06155 UNUSED_PARAMETER(nfargs);
06156 UNUSED_PARAMETER(cargs);
06157 UNUSED_PARAMETER(ncargs);
06158
06159 long nConnected = -1;
06160 if (is_rational(fargs[0]))
06161 {
06162 SOCKET s = mux_atol(fargs[0]);
06163 bool bFound = false;
06164 DESC *d;
06165 CLinearTimeAbsolute ltaNow;
06166 ltaNow.GetUTC();
06167 DESC_ITER_CONN(d)
06168 {
06169 if (d->descriptor == s)
06170 {
06171 bFound = true;
06172 break;
06173 }
06174 }
06175 if ( bFound
06176 && ( d->player == executor
06177 || Wizard_Who(executor)))
06178 {
06179 CLinearTimeDelta ltdResult = ltaNow - d->connected_at;
06180 nConnected = ltdResult.ReturnSeconds();
06181 }
06182 }
06183 else
06184 {
06185 char *pTargetName = fargs[0];
06186 if (*pTargetName == '*')
06187 {
06188 pTargetName++;
06189 }
06190 dbref target = lookup_player(executor, pTargetName, true);
06191 if ( Good_obj(target)
06192 && ( !Hidden(target)
06193 || See_Hidden(executor)))
06194 {
06195 nConnected = fetch_connect(target);
06196 }
06197 }
06198 safe_ltoa(nConnected, buff, bufc);
06199 }
06200
06201
06202
06203
06204
06205
06206 typedef struct f_record
06207 {
06208 double data;
06209 char *str;
06210 } f_rec;
06211
06212 typedef struct i_record
06213 {
06214 long data;
06215 char *str;
06216 } i_rec;
06217
06218 typedef struct i64_record
06219 {
06220 INT64 data;
06221 char *str;
06222 } i64_rec;
06223
06224 static int DCL_CDECL a_comp(const void *s1, const void *s2)
06225 {
06226 return strcmp(*(char **)s1, *(char **)s2);
06227 }
06228
06229 static int DCL_CDECL a_casecomp(const void *s1, const void *s2)
06230 {
06231 return mux_stricmp(*(char **)s1, *(char **)s2);
06232 }
06233
06234 static int DCL_CDECL f_comp(const void *s1, const void *s2)
06235 {
06236 if (((f_rec *) s1)->data > ((f_rec *) s2)->data)
06237 {
06238 return 1;
06239 }
06240 else if (((f_rec *) s1)->data < ((f_rec *) s2)->data)
06241 {
06242 return -1;
06243 }
06244 return 0;
06245 }
06246
06247 static int DCL_CDECL i_comp(const void *s1, const void *s2)
06248 {
06249 if (((i_rec *) s1)->data > ((i_rec *) s2)->data)
06250 {
06251 return 1;
06252 }
06253 else if (((i_rec *) s1)->data < ((i_rec *) s2)->data)
06254 {
06255 return -1;
06256 }
06257 return 0;
06258 }
06259
06260 static int DCL_CDECL i64_comp(const void *s1, const void *s2)
06261 {
06262 if (((i64_rec *) s1)->data > ((i64_rec *) s2)->data)
06263 {
06264 return 1;
06265 }
06266 else if (((i64_rec *) s1)->data < ((i64_rec *) s2)->data)
06267 {
06268 return -1;
06269 }
06270 return 0;
06271 }
06272
06273 static void do_asort(char *s[], int n, int sort_type)
06274 {
06275 int i;
06276 f_rec *fp;
06277 i_rec *ip;
06278 i64_rec *i64p;
06279
06280 switch (sort_type)
06281 {
06282 case ASCII_LIST:
06283 qsort(s, n, sizeof(char *), a_comp);
06284 break;
06285
06286 case NUMERIC_LIST:
06287 i64p = (i64_rec *) MEMALLOC(n * sizeof(i64_rec));
06288 ISOUTOFMEMORY(i64p);
06289 for (i = 0; i < n; i++)
06290 {
06291 i64p[i].str = s[i];
06292 i64p[i].data = mux_atoi64(s[i]);
06293 }
06294 qsort(i64p, n, sizeof(i64_rec), i64_comp);
06295 for (i = 0; i < n; i++)
06296 {
06297 s[i] = i64p[i].str;
06298 }
06299 MEMFREE(i64p);
06300 i64p = NULL;
06301 break;
06302
06303 case DBREF_LIST:
06304 ip = (i_rec *) MEMALLOC(n * sizeof(i_rec));
06305 ISOUTOFMEMORY(ip);
06306 for (i = 0; i < n; i++)
06307 {
06308 ip[i].str = s[i];
06309 ip[i].data = dbnum(s[i]);
06310 }
06311 qsort(ip, n, sizeof(i_rec), i_comp);
06312 for (i = 0; i < n; i++)
06313 {
06314 s[i] = ip[i].str;
06315 }
06316 MEMFREE(ip);
06317 ip = NULL;
06318 break;
06319
06320 case FLOAT_LIST:
06321 fp = (f_rec *) MEMALLOC(n * sizeof(f_rec));
06322 ISOUTOFMEMORY(fp);
06323 for (i = 0; i < n; i++)
06324 {
06325 fp[i].str = s[i];
06326 fp[i].data = mux_atof(s[i], false);
06327 }
06328 qsort(fp, n, sizeof(f_rec), f_comp);
06329 for (i = 0; i < n; i++)
06330 {
06331 s[i] = fp[i].str;
06332 }
06333 MEMFREE(fp);
06334 fp = NULL;
06335 break;
06336
06337 case CI_ASCII_LIST:
06338 qsort(s, n, sizeof(char *), a_casecomp);
06339 break;
06340 }
06341 }
06342
06343 static FUNCTION(fun_sort)
06344 {
06345 SEP sep;
06346 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
06347 {
06348 return;
06349 }
06350
06351 SEP osep = sep;
06352 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
06353 {
06354 return;
06355 }
06356
06357 char *ptrs[LBUF_SIZE / 2];
06358
06359
06360
06361 char *list = alloc_lbuf("fun_sort");
06362 strcpy(list, fargs[0]);
06363 int nitems = list2arr(ptrs, LBUF_SIZE / 2, list, &sep);
06364 int sort_type = get_list_type(fargs, nfargs, 2, ptrs, nitems);
06365 do_asort(ptrs, nitems, sort_type);
06366 arr2list(ptrs, nitems, buff, bufc, &osep);
06367 free_lbuf(list);
06368 }
06369
06370
06371
06372
06373
06374 #define SET_UNION 1
06375 #define SET_INTERSECT 2
06376 #define SET_DIFF 3
06377
06378 static void handle_sets
06379 (
06380 char *fargs[],
06381 char *buff,
06382 char **bufc,
06383 int oper,
06384 SEP *psep,
06385 SEP *posep
06386 )
06387 {
06388 char *ptrs1[LBUF_SIZE], *ptrs2[LBUF_SIZE];
06389 int val;
06390
06391 char *list1 = alloc_lbuf("fun_setunion.1");
06392 strcpy(list1, fargs[0]);
06393 int n1 = list2arr(ptrs1, LBUF_SIZE, list1, psep);
06394 do_asort(ptrs1, n1, ASCII_LIST);
06395
06396 char *list2 = alloc_lbuf("fun_setunion.2");
06397 strcpy(list2, fargs[1]);
06398 int n2 = list2arr(ptrs2, LBUF_SIZE, list2, psep);
06399 do_asort(ptrs2, n2, ASCII_LIST);
06400
06401 int i1 = 0;
06402 int i2 = 0;
06403 char *oldp = NULL;
06404 bool bFirst = true;
06405
06406 switch (oper)
06407 {
06408 case SET_UNION:
06409
06410
06411
06412
06413
06414 if ( n1 == 1
06415 && n2 == 1
06416 && strcmp(ptrs1[0], ptrs2[0]) == 0)
06417 {
06418 safe_str(ptrs1[0], buff, bufc);
06419 break;
06420 }
06421
06422
06423
06424 while ( i1 < n1
06425 && i2 < n2)
06426 {
06427
06428
06429 if ( i1 > 0
06430 || i2 > 0)
06431 {
06432 while ( i1 < n1
06433 && oldp
06434 && strcmp(ptrs1[i1], oldp) == 0)
06435 {
06436 i1++;
06437 }
06438 while ( i2 < n2
06439 && oldp
06440 && strcmp(ptrs2[i2], oldp) == 0)
06441 {
06442 i2++;
06443 }
06444 }
06445
06446
06447
06448 if ( i1 < n1
06449 && i2 < n2)
06450 {
06451 if (!bFirst)
06452 {
06453 print_sep(posep, buff, bufc);
06454 }
06455 bFirst = false;
06456 if (strcmp(ptrs1[i1], ptrs2[i2]) < 0)
06457 {
06458 oldp = ptrs1[i1];
06459 safe_str(ptrs1[i1], buff, bufc);
06460 i1++;
06461 }
06462 else
06463 {
06464 oldp = ptrs2[i2];
06465 safe_str(ptrs2[i2], buff, bufc);
06466 i2++;
06467 }
06468 }
06469 }
06470
06471
06472
06473 for (; i1 < n1; i1++)
06474 {
06475 if ( !oldp
06476 || strcmp(oldp, ptrs1[i1]) != 0)
06477 {
06478 if (!bFirst)
06479 {
06480 print_sep(posep, buff, bufc);
06481 }
06482 bFirst = false;
06483 oldp = ptrs1[i1];
06484 safe_str(ptrs1[i1], buff, bufc);
06485 }
06486 }
06487 for (; i2 < n2; i2++)
06488 {
06489 if ( !oldp
06490 || strcmp(oldp, ptrs2[i2]) != 0)
06491 {
06492 if (!bFirst)
06493 {
06494 print_sep(posep, buff, bufc);
06495 }
06496 bFirst = false;
06497 oldp = ptrs2[i2];
06498 safe_str(ptrs2[i2], buff, bufc);
06499 }
06500 }
06501 break;
06502
06503 case SET_INTERSECT:
06504
06505
06506
06507 while ( i1 < n1
06508 && i2 < n2)
06509 {
06510 val = strcmp(ptrs1[i1], ptrs2[i2]);
06511 if (!val)
06512 {
06513
06514
06515 if (!bFirst)
06516 {
06517 print_sep(posep, buff, bufc);
06518 }
06519 bFirst = false;
06520 oldp = ptrs1[i1];
06521 safe_str(ptrs1[i1], buff, bufc);
06522 i1++;
06523 i2++;
06524 while ( i1 < n1
06525 && strcmp(ptrs1[i1], oldp) == 0)
06526 {
06527 i1++;
06528 }
06529 while ( i2 < n2
06530 && strcmp(ptrs2[i2], oldp) == 0)
06531 {
06532 i2++;
06533 }
06534 }
06535 else if (val < 0)
06536 {
06537 i1++;
06538 }
06539 else
06540 {
06541 i2++;
06542 }
06543 }
06544 break;
06545
06546 case SET_DIFF:
06547
06548
06549
06550 while ( i1 < n1
06551 && i2 < n2)
06552 {
06553 val = strcmp(ptrs1[i1], ptrs2[i2]);
06554 if (!val)
06555 {
06556
06557
06558 oldp = ptrs1[i1];
06559 while ( i1 < n1
06560 && strcmp(ptrs1[i1], oldp) == 0)
06561 {
06562 i1++;
06563 }
06564 while ( i2 < n2
06565 && strcmp(ptrs2[i2], oldp) == 0)
06566 {
06567 i2++;
06568 }
06569 }
06570 else if (val < 0)
06571 {
06572
06573
06574 if (!bFirst)
06575 {
06576 print_sep(posep, buff, bufc);
06577 }
06578 bFirst = false;
06579 safe_str(ptrs1[i1], buff, bufc);
06580 oldp = ptrs1[i1];
06581 i1++;
06582 while ( i1 < n1
06583 && strcmp(ptrs1[i1], oldp) == 0)
06584 {
06585 i1++;
06586 }
06587 }
06588 else
06589 {
06590
06591
06592 oldp = ptrs2[i2];
06593 i2++;
06594 while ( i2 < n2
06595 && strcmp(ptrs2[i2], oldp) == 0)
06596 {
06597 i2++;
06598 }
06599 }
06600 }
06601
06602
06603
06604 while (i1 < n1)
06605 {
06606 if (!bFirst)
06607 {
06608 print_sep(posep, buff, bufc);
06609 }
06610 bFirst = false;
06611 safe_str(ptrs1[i1], buff, bufc);
06612 oldp = ptrs1[i1];
06613 i1++;
06614 while ( i1 < n1
06615 && strcmp(ptrs1[i1], oldp) == 0)
06616 {
06617 i1++;
06618 }
06619 }
06620 }
06621 free_lbuf(list1);
06622 free_lbuf(list2);
06623 }
06624
06625 static FUNCTION(fun_setunion)
06626 {
06627 SEP sep;
06628 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
06629 {
06630 return;
06631 }
06632
06633 SEP osep = sep;
06634 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
06635 {
06636 return;
06637 }
06638 handle_sets(fargs, buff, bufc, SET_UNION, &sep, &osep);
06639 }
06640
06641 static FUNCTION(fun_setdiff)
06642 {
06643 SEP sep;
06644 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
06645 {
06646 return;
06647 }
06648
06649 SEP osep = sep;
06650 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
06651 {
06652 return;
06653 }
06654 handle_sets(fargs, buff, bufc, SET_DIFF, &sep, &osep);
06655 }
06656
06657 static FUNCTION(fun_setinter)
06658 {
06659 SEP sep;
06660 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
06661 {
06662 return;
06663 }
06664
06665 SEP osep = sep;
06666 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_INIT|DELIM_STRING))
06667 {
06668 return;
06669 }
06670 handle_sets(fargs, buff, bufc, SET_INTERSECT, &sep, &osep);
06671 }
06672
06673
06674
06675
06676 #define CJC_CENTER 0
06677 #define CJC_LJUST 1
06678 #define CJC_RJUST 2
06679
06680 static void centerjustcombo
06681 (
06682 int iType,
06683 char *buff,
06684 char **bufc,
06685 char *fargs[],
06686 int nfargs
06687 )
06688 {
06689
06690
06691 if (!is_integer(fargs[1], NULL))
06692 {
06693 return;
06694 }
06695 int width = mux_atol(fargs[1]);
06696 if (width <= 0 || LBUF_SIZE <= width)
06697 {
06698 safe_range(buff, bufc);
06699 return;
06700 }
06701
06702
06703
06704 int vwPad = 0;
06705 int nPad = -1;
06706 char aPad[SBUF_SIZE];
06707 struct ANSI_In_Context aic;
06708 struct ANSI_Out_Context aoc;
06709 if (nfargs == 3 && *fargs[2])
06710 {
06711 char *p = RemoveSetOfCharacters(fargs[2], "\r\n\t");
06712 ANSI_String_In_Init(&aic, p, ANSI_ENDGOAL_NORMAL);
06713 ANSI_String_Out_Init(&aoc, aPad, sizeof(aPad), sizeof(aPad), ANSI_ENDGOAL_LEAK);
06714 ANSI_String_Copy(&aoc, &aic, sizeof(aPad));
06715 nPad = ANSI_String_Finalize(&aoc, &vwPad);
06716 }
06717 if (nPad <= 0)
06718 {
06719 aPad[0] = ' ';
06720 aPad[1] = '\0';
06721 nPad = 1;
06722 vwPad = 1;
06723 }
06724
06725 int vwStr;
06726 char aStr[LBUF_SIZE];
06727 int nStr = ANSI_TruncateToField(fargs[0], sizeof(aStr), aStr,
06728 width, &vwStr, ANSI_ENDGOAL_NORMAL);
06729
06730
06731
06732
06733
06734 if (vwStr == width)
06735 {
06736 safe_copy_buf(aStr, nStr, buff, bufc);
06737 return;
06738 }
06739
06740 int vwLeading = 0;
06741 if (iType == CJC_CENTER)
06742 {
06743 vwLeading = (width - vwStr)/2;
06744 }
06745 else if (iType == CJC_RJUST)
06746 {
06747 vwLeading = width - vwStr;
06748 }
06749 int vwTrailing = width - vwLeading - vwStr;
06750
06751
06752
06753
06754 if (nPad == 1 && vwPad == 1)
06755 {
06756 safe_fill(buff, bufc, aPad[0], vwLeading);
06757 safe_copy_buf(aStr, nStr, buff, bufc);
06758 safe_fill(buff, bufc, aPad[0], vwTrailing);
06759 return;
06760 }
06761
06762
06763
06764
06765
06766
06767
06768
06769
06770
06771
06772
06773
06774
06775
06776 int nLeadFull = 0;
06777 int vwLeadPartial = 0;
06778 if (vwLeading)
06779 {
06780 nLeadFull = vwLeading / vwPad;
06781 vwLeadPartial = vwLeading - nLeadFull * vwPad;
06782 }
06783
06784
06785
06786
06787
06788
06789 int vwTrailSkip0 = 0;
06790 int vwTrailPartial0 = 0;
06791 int nTrailFull = 0;
06792 int vwTrailPartial1 = 0;
06793 if (vwTrailing)
06794 {
06795 vwTrailSkip0 = (vwLeading + vwStr) % vwPad;
06796 vwTrailPartial0 = 0;
06797 if (vwTrailSkip0)
06798 {
06799 vwTrailPartial0 = vwPad - vwTrailSkip0;
06800 if (vwTrailing < vwTrailPartial0)
06801 {
06802 vwTrailPartial0 = vwTrailing;
06803 vwTrailing = 0;
06804 }
06805 else
06806 {
06807 vwTrailing -= vwTrailPartial0;
06808 }
06809 }
06810 nTrailFull = vwTrailing / vwPad;
06811 vwTrailPartial1 = vwTrailing - nTrailFull * vwPad;
06812 }
06813
06814 int nBufferAvailable = LBUF_SIZE - (*bufc - buff) - 1;
06815 ANSI_String_Out_Init(&aoc, *bufc, nBufferAvailable,
06816 LBUF_SIZE-1, ANSI_ENDGOAL_NORMAL);
06817 int vwDone;
06818
06819
06820
06821 int i, n;
06822 for (i = 0; i < nLeadFull; i++)
06823 {
06824 ANSI_String_In_Init(&aic, aPad, ANSI_ENDGOAL_NORMAL);
06825 ANSI_String_Copy(&aoc, &aic, vwPad);
06826 }
06827
06828
06829
06830 if (vwLeadPartial > 0)
06831 {
06832 ANSI_String_In_Init(&aic, aPad, ANSI_ENDGOAL_NORMAL);
06833 ANSI_String_Copy(&aoc, &aic, vwLeadPartial);
06834 }
06835
06836
06837
06838 if (nStr > 0)
06839 {
06840 ANSI_String_In_Init(&aic, aStr, ANSI_ENDGOAL_NORMAL);
06841 ANSI_String_Copy(&aoc, &aic, LBUF_SIZE-1);
06842 }
06843
06844
06845
06846 if (vwTrailPartial0 > 0)
06847 {
06848 ANSI_String_In_Init(&aic, aPad, ANSI_ENDGOAL_NORMAL);
06849 ANSI_String_Skip(&aic, vwTrailSkip0, &vwDone);
06850 ANSI_String_Copy(&aoc, &aic, vwTrailPartial0);
06851 }
06852
06853
06854
06855 for (i = 0; i < nTrailFull; i++)
06856 {
06857 ANSI_String_In_Init(&aic, aPad, ANSI_ENDGOAL_NORMAL);
06858 ANSI_String_Copy(&aoc, &aic, vwPad);
06859 }
06860
06861
06862
06863 if (vwTrailPartial1 > 0)
06864 {
06865 ANSI_String_In_Init(&aic, aPad, ANSI_ENDGOAL_NORMAL);
06866 ANSI_String_Copy(&aoc, &aic, vwTrailPartial1);
06867 }
06868
06869 n = ANSI_String_Finalize(&aoc, &vwDone);
06870 *bufc += n;
06871 }
06872
06873 static FUNCTION(fun_ljust)
06874 {
06875 UNUSED_PARAMETER(executor);
06876 UNUSED_PARAMETER(caller);
06877 UNUSED_PARAMETER(enactor);
06878 UNUSED_PARAMETER(cargs);
06879 UNUSED_PARAMETER(ncargs);
06880
06881 centerjustcombo(CJC_LJUST, buff, bufc, fargs, nfargs);
06882 }
06883
06884 static FUNCTION(fun_rjust)
06885 {
06886 UNUSED_PARAMETER(executor);
06887 UNUSED_PARAMETER(caller);
06888 UNUSED_PARAMETER(enactor);
06889 UNUSED_PARAMETER(cargs);
06890 UNUSED_PARAMETER(ncargs);
06891
06892 centerjustcombo(CJC_RJUST, buff, bufc, fargs, nfargs);
06893 }
06894
06895 static FUNCTION(fun_center)
06896 {
06897 UNUSED_PARAMETER(executor);
06898 UNUSED_PARAMETER(caller);
06899 UNUSED_PARAMETER(enactor);
06900 UNUSED_PARAMETER(cargs);
06901 UNUSED_PARAMETER(ncargs);
06902
06903 centerjustcombo(CJC_CENTER, buff, bufc, fargs, nfargs);
06904 }
06905
06906
06907
06908
06909
06910 static FUNCTION(fun_setq)
06911 {
06912 UNUSED_PARAMETER(executor);
06913 UNUSED_PARAMETER(caller);
06914 UNUSED_PARAMETER(enactor);
06915 UNUSED_PARAMETER(nfargs);
06916 UNUSED_PARAMETER(cargs);
06917 UNUSED_PARAMETER(ncargs);
06918
06919 int regnum = mux_RegisterSet[(unsigned char)fargs[0][0]];
06920 if ( regnum < 0
06921 || regnum >= MAX_GLOBAL_REGS
06922 || fargs[0][1] != '\0')
06923 {
06924 safe_str("#-1 INVALID GLOBAL REGISTER", buff, bufc);
06925 }
06926 else
06927 {
06928 if (!mudstate.global_regs[regnum])
06929 {
06930 mudstate.global_regs[regnum] = alloc_lbuf("fun_setq");
06931 }
06932 int n = strlen(fargs[1]);
06933 memcpy(mudstate.global_regs[regnum], fargs[1], n+1);
06934 mudstate.glob_reg_len[regnum] = n;
06935 }
06936 }
06937
06938 static FUNCTION(fun_setr)
06939 {
06940 UNUSED_PARAMETER(executor);
06941 UNUSED_PARAMETER(caller);
06942 UNUSED_PARAMETER(enactor);
06943 UNUSED_PARAMETER(nfargs);
06944 UNUSED_PARAMETER(cargs);
06945 UNUSED_PARAMETER(ncargs);
06946
06947 int regnum = mux_RegisterSet[(unsigned char)fargs[0][0]];
06948 if ( regnum < 0
06949 || regnum >= MAX_GLOBAL_REGS
06950 || fargs[0][1] != '\0')
06951 {
06952 safe_str("#-1 INVALID GLOBAL REGISTER", buff, bufc);
06953 }
06954 else
06955 {
06956 if (!mudstate.global_regs[regnum])
06957 {
06958 mudstate.global_regs[regnum] = alloc_lbuf("fun_setq");
06959 }
06960 int n = strlen(fargs[1]);
06961 memcpy(mudstate.global_regs[regnum], fargs[1], n+1);
06962 mudstate.glob_reg_len[regnum] = n;
06963 safe_copy_buf(fargs[1], n, buff, bufc);
06964 }
06965 }
06966
06967 static FUNCTION(fun_r)
06968 {
06969 UNUSED_PARAMETER(executor);
06970 UNUSED_PARAMETER(caller);
06971 UNUSED_PARAMETER(enactor);
06972 UNUSED_PARAMETER(nfargs);
06973 UNUSED_PARAMETER(cargs);
06974 UNUSED_PARAMETER(ncargs);
06975
06976 int regnum = mux_RegisterSet[(unsigned char)fargs[0][0]];
06977 if ( regnum < 0
06978 || regnum >= MAX_GLOBAL_REGS
06979 || fargs[0][1] != '\0')
06980 {
06981 safe_str("#-1 INVALID GLOBAL REGISTER", buff, bufc);
06982 }
06983 else if (mudstate.global_regs[regnum])
06984 {
06985 safe_copy_buf(mudstate.global_regs[regnum],
06986 mudstate.glob_reg_len[regnum], buff, bufc);
06987 }
06988 }
06989
06990
06991
06992
06993
06994 static FUNCTION(fun_isdbref)
06995 {
06996 UNUSED_PARAMETER(executor);
06997 UNUSED_PARAMETER(caller);
06998 UNUSED_PARAMETER(enactor);
06999 UNUSED_PARAMETER(nfargs);
07000 UNUSED_PARAMETER(cargs);
07001 UNUSED_PARAMETER(ncargs);
07002
07003 bool bResult = false;
07004
07005 char *p = fargs[0];
07006 if (NUMBER_TOKEN == p[0])
07007 {
07008 p++;
07009 dbref dbitem = parse_dbref(p);
07010 bResult = Good_obj(dbitem);
07011 }
07012 safe_bool(bResult, buff, bufc);
07013 }
07014
07015
07016
07017
07018
07019 static char* trim_fast_left(char* str, char delim)
07020 {
07021
07022
07023 while (*str == delim)
07024 {
07025 str++;
07026 }
07027 return str;
07028 }
07029
07030 static void trim_fast_right(char* str, char delim)
07031 {
07032
07033
07034 char* last = NULL;
07035 while (*str)
07036 {
07037 if (*str != delim)
07038 {
07039 last = str;
07040 }
07041 str++;
07042 }
07043
07044 if (last == NULL)
07045 {
07046 return;
07047 }
07048
07049 *(last+1) = '\0';
07050 }
07051
07052 static char* trim_left(char* str, SEP* sep)
07053 {
07054 if (1 == sep->n)
07055 {
07056 return trim_fast_left(str, sep->str[0]);
07057 }
07058 int cycle = 0;
07059 int max = sep->n;
07060 char* base = str-1;
07061 for ( ; *str == sep->str[cycle]; str++)
07062 {
07063 if (max <= ++cycle)
07064 {
07065 cycle = 0;
07066 base = str;
07067 }
07068 }
07069 return base+1;
07070 }
07071
07072 static void trim_right(char* str, SEP* sep)
07073 {
07074 if (1 == sep->n)
07075 {
07076 trim_fast_right(str,sep->str[0]);
07077 return;
07078 }
07079
07080 int cycle = sep->n - 1;
07081 int max = sep->n - 1;
07082 int n = strlen(str);
07083 int base = n;
07084 n--;
07085 for ( ; n >= 0 && str[n] == sep->str[cycle]; n--)
07086 {
07087 if (--cycle < 0)
07088 {
07089 cycle = max;
07090 base = n;
07091 }
07092 }
07093 *(str+base) = '\0';
07094 }
07095
07096 static FUNCTION(fun_trim)
07097 {
07098 SEP sep;
07099 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
07100 {
07101 return;
07102 }
07103
07104 #define TRIM_LEFT 1
07105 #define TRIM_RIGHT 2
07106
07107 int trim;
07108 if (nfargs >= 2)
07109 {
07110 switch (mux_tolower(*fargs[1]))
07111 {
07112 case 'l':
07113 trim = TRIM_LEFT;
07114 break;
07115
07116 case 'r':
07117 trim = TRIM_RIGHT;
07118 break;
07119
07120 default:
07121 trim = TRIM_LEFT|TRIM_RIGHT;
07122 break;
07123 }
07124 }
07125 else
07126 {
07127 trim = TRIM_LEFT|TRIM_RIGHT;
07128 }
07129
07130 char* str;
07131 if (trim & TRIM_LEFT)
07132 {
07133 str = trim_left(fargs[0],&sep);
07134 }
07135 else
07136 {
07137 str = fargs[0];
07138 }
07139
07140 if (trim & TRIM_RIGHT)
07141 {
07142 trim_right(str,&sep);
07143 }
07144 safe_str(str,buff,bufc);
07145 }
07146
07147 static FUNCTION(fun_config)
07148 {
07149 UNUSED_PARAMETER(caller);
07150 UNUSED_PARAMETER(enactor);
07151 UNUSED_PARAMETER(cargs);
07152 UNUSED_PARAMETER(ncargs);
07153
07154 if (nfargs == 1)
07155 {
07156 cf_display(executor, fargs[0], buff, bufc);
07157 }
07158 else
07159 {
07160 cf_list(executor, buff, bufc);
07161 }
07162 }
07163
07164
07165
07166
07167 static int return_bit(dbref player)
07168 {
07169 if (God(player))
07170 return 7;
07171
07172 if (Wizard(player))
07173 return 5;
07174 if (Royalty(player))
07175 return 4;
07176 if (Staff(player) || Builder(player))
07177 return 3;
07178 if (Head(player) || Immortal(player))
07179 return 2;
07180 if (!(Uninspected(player) || Guest(player)))
07181 return 1;
07182 return 0;
07183 }
07184
07185 static FUNCTION(fun_bittype)
07186 {
07187 UNUSED_PARAMETER(caller);
07188 UNUSED_PARAMETER(enactor);
07189 UNUSED_PARAMETER(cargs);
07190 UNUSED_PARAMETER(ncargs);
07191
07192 dbref target;
07193 if (nfargs == 1)
07194 {
07195 target = match_thing(executor, fargs[0]);
07196 }
07197 else
07198 {
07199 target = executor;
07200 }
07201 if (!Good_obj(target))
07202 {
07203 return;
07204 }
07205 safe_ltoa(return_bit(target), buff, bufc);
07206 }
07207
07208 static FUNCTION(fun_error)
07209 {
07210 UNUSED_PARAMETER(executor);
07211 UNUSED_PARAMETER(cargs);
07212 UNUSED_PARAMETER(ncargs);
07213
07214 if ( Good_obj(mudconf.global_error_obj)
07215 && !Going(mudconf.global_error_obj))
07216 {
07217 dbref aowner;
07218 int aflags;
07219 char *errtext = atr_get(mudconf.global_error_obj, A_VA, &aowner, &aflags);
07220 char *errbuff = alloc_lbuf("process_command.error_msg");
07221 char *errbufc = errbuff;
07222 char *str = errtext;
07223 if (nfargs == 1)
07224 {
07225 char *arg = fargs[0];
07226 mux_exec(errbuff, &errbufc, mudconf.global_error_obj, caller, enactor,
07227 EV_TOP | EV_EVAL | EV_FCHECK | EV_STRIP_CURLY, &str, &arg, 1);
07228 *errbufc = '\0';
07229 }
07230 else
07231 {
07232 mux_exec(errbuff, &errbufc, mudconf.global_error_obj, caller, enactor,
07233 EV_TOP | EV_EVAL | EV_FCHECK | EV_STRIP_CURLY, &str, (char **)NULL, 0);
07234 *errbufc = '\0';
07235 }
07236 safe_str(errbuff, buff, bufc);
07237 free_lbuf(errtext);
07238 free_lbuf(errbuff);
07239 }
07240 else
07241 {
07242 safe_str("Huh? (Type \"help\" for help.)", buff, bufc);
07243 }
07244 }
07245
07246 static FUNCTION(fun_strip)
07247 {
07248 UNUSED_PARAMETER(executor);
07249 UNUSED_PARAMETER(caller);
07250 UNUSED_PARAMETER(enactor);
07251 UNUSED_PARAMETER(cargs);
07252 UNUSED_PARAMETER(ncargs);
07253
07254 if (fargs[0][0] == '\0')
07255 {
07256 return;
07257 }
07258 size_t n;
07259 char *p = strip_ansi(fargs[0], &n);
07260 if ( nfargs < 2
07261 || fargs[1][0] == '\0')
07262 {
07263 safe_copy_buf(p, n, buff, bufc);
07264 return;
07265 }
07266 char *pInput = alloc_lbuf("fun_strip.1");
07267 memcpy(pInput, p, n+1);
07268 p = strip_ansi(fargs[1], &n);
07269 safe_str(RemoveSetOfCharacters(pInput, p), buff, bufc);
07270 free_lbuf(pInput);
07271 }
07272
07273 #define DEFAULT_WIDTH 78
07274 static char *expand_tabs(const char *str)
07275 {
07276 static char tbuf1[LBUF_SIZE];
07277 char *bp = tbuf1;
07278
07279 if (str)
07280 {
07281 unsigned int n = 0;
07282 bool ansi = false;
07283
07284 for (unsigned int i = 0; str[i]; i++)
07285 {
07286 switch (str[i])
07287 {
07288 case '\t':
07289 safe_fill(tbuf1, &bp, ' ', 8 - n % 8);
07290 continue;
07291 case '\r':
07292
07293 case '\n':
07294 n = 0;
07295 break;
07296 case ESC_CHAR:
07297 ansi = true;
07298 break;
07299 case ANSI_ATTR_CMD:
07300 if (ansi)
07301 {
07302 ansi = false;
07303 }
07304 else
07305 {
07306 n++;
07307 }
07308 break;
07309 case BEEP_CHAR:
07310 break;
07311 default:
07312 if (!ansi)
07313 {
07314 n++;
07315 }
07316 }
07317 safe_chr(str[i], tbuf1, &bp);
07318 }
07319 }
07320 *bp = '\0';
07321 return tbuf1;
07322 }
07323
07324 static int wraplen(char *str, const int nWidth, bool &newline)
07325 {
07326 const int length = strlen(str);
07327 newline = false;
07328 if (length <= nWidth)
07329 {
07330
07331
07332
07333
07334 for (int i = 0; i < length; i++)
07335 {
07336 if ( str[i] == '\n'
07337 || str[i] == '\r')
07338 {
07339 newline = true;
07340 return i+2;
07341 }
07342 }
07343 return length;
07344 }
07345
07346
07347
07348
07349
07350 for (int i = 0; i < nWidth; i++)
07351 {
07352 if ( str[i] == '\n'
07353 || str[i] == '\r')
07354 {
07355 newline = true;
07356 return i+2;
07357 }
07358 }
07359
07360
07361
07362
07363 int maxlen = nWidth;
07364 while (str[maxlen] != ' ' && maxlen > 0)
07365 {
07366 maxlen--;
07367 }
07368 if (str[maxlen] != ' ')
07369 {
07370 maxlen = nWidth;
07371 }
07372 return (maxlen ? maxlen : -1);
07373 }
07374
07375 static FUNCTION(fun_wrap)
07376 {
07377 UNUSED_PARAMETER(executor);
07378 UNUSED_PARAMETER(caller);
07379 UNUSED_PARAMETER(enactor);
07380 UNUSED_PARAMETER(cargs);
07381 UNUSED_PARAMETER(ncargs);
07382
07383
07384
07385 int nWidth = DEFAULT_WIDTH;
07386 if ( nfargs >= 2
07387 && fargs[1][0])
07388 {
07389 nWidth = mux_atol(fargs[1]);
07390 if ( nWidth < 1
07391 || nWidth >= LBUF_SIZE)
07392 {
07393 safe_range(buff, bufc);
07394 return;
07395 }
07396 }
07397
07398
07399
07400 int iJustKey = CJC_LJUST;
07401 if ( nfargs >= 3
07402 && fargs[2][0])
07403 {
07404 char cJust = mux_toupper(fargs[2][0]);
07405 switch (cJust)
07406 {
07407 case 'L':
07408 iJustKey = CJC_LJUST;
07409 break;
07410 case 'R':
07411 iJustKey = CJC_RJUST;
07412 break;
07413 case 'C':
07414 iJustKey = CJC_CENTER;
07415 break;
07416 default:
07417 safe_str("#-1 INVALID JUSTIFICATION SPECIFIED", buff, bufc);
07418 return;
07419 }
07420 }
07421
07422
07423
07424 char *pLeft = NULL;
07425 if ( nfargs >= 4
07426 && fargs[3][0])
07427 {
07428 pLeft = fargs[3];
07429 }
07430
07431
07432
07433 char *pRight = NULL;
07434 if ( nfargs >= 5
07435 && fargs[4][0])
07436 {
07437 pRight = fargs[4];
07438 }
07439
07440
07441
07442 int nHanging = 0;
07443 if ( nfargs >= 6
07444 && fargs[5][0])
07445 {
07446 nHanging = mux_atol(fargs[5]);
07447 }
07448
07449
07450
07451 char *pOSep = "\r\n";
07452 if ( nfargs >= 7
07453 && fargs[6][0])
07454 {
07455 if (!strcmp(fargs[6], "@@"))
07456 {
07457 pOSep = NULL;
07458 }
07459 else
07460 {
07461 pOSep = fargs[6];
07462 }
07463 }
07464
07465
07466 int nFirstWidth = nWidth;
07467 if ( nfargs >= 8
07468 && fargs[7][0])
07469 {
07470 nFirstWidth = mux_atol(fargs[7]);
07471 if ( nFirstWidth < 1
07472 || nFirstWidth >= LBUF_SIZE)
07473 {
07474 safe_range(buff, bufc);
07475 return;
07476 }
07477 }
07478
07479 char *str = alloc_lbuf("fun_mywrap.str");
07480 char *tstr = alloc_lbuf("fun_mywrap.str2");
07481 strcpy(tstr, expand_tabs(fargs[0]));
07482 strcpy(str,strip_ansi(tstr));
07483 int nLength = 0;
07484 bool newline = false;
07485 char *jargs[2];
07486 struct ANSI_In_Context aic;
07487 struct ANSI_Out_Context aoc;
07488 char *mbufc;
07489 char *mbuf = mbufc = alloc_lbuf("fun_mywrap.out");
07490 int nBufferAvailable, nSize;
07491 int nDone;
07492 int i = 0;
07493
07494 while (str[i])
07495 {
07496 nLength = wraplen(str + i, i == 0 ? nFirstWidth : nWidth, newline);
07497 mbufc = mbuf;
07498
07499 ANSI_String_In_Init(&aic, tstr, ANSI_ENDGOAL_NORMAL);
07500 ANSI_String_Skip(&aic, i, &nDone);
07501 if (nDone < i || nLength <= 0)
07502 {
07503 break;
07504 }
07505 if (i > 0)
07506 {
07507 safe_str(pOSep, buff, bufc);
07508 if (nHanging > 0)
07509 {
07510 safe_fill(buff, bufc, ' ', nHanging);
07511 }
07512 }
07513 nBufferAvailable = LBUF_SIZE - (mbufc - mbuf) - 1;
07514 ANSI_String_Out_Init(&aoc, mbufc, nBufferAvailable, nLength-(newline ? 2 : 0), ANSI_ENDGOAL_NORMAL);
07515 ANSI_String_Copy(&aoc, &aic, nLength-(newline ? 2 : 0));
07516 nSize = ANSI_String_Finalize(&aoc, &nDone);
07517 mbufc += nSize;
07518
07519 jargs[0] = mbuf;
07520 jargs[1] = mux_ltoa_t(i == 0 ? nFirstWidth : nWidth);
07521 safe_str(pLeft,buff,bufc);
07522 centerjustcombo(iJustKey, buff, bufc, jargs, 2);
07523 safe_str(pRight, buff, bufc);
07524
07525 i += nLength;
07526 if (str[i] == ' ' && str[i+1] != ' ')
07527 {
07528 i++;
07529 }
07530 }
07531 free_lbuf(mbuf);
07532 free_lbuf(str);
07533 free_lbuf(tstr);
07534 }
07535
07536 typedef struct
07537 {
07538 int iBase;
07539 char chLetter;
07540 int nName;
07541 char *pName;
07542
07543 } RADIX_ENTRY;
07544
07545 #define N_RADIX_ENTRIES 7
07546 static const RADIX_ENTRY reTable[N_RADIX_ENTRIES] =
07547 {
07548 { 31556926, 'y', 4, "year" },
07549 { 2629743, 'M', 5, "month" },
07550 { 604800, 'w', 4, "week" },
07551 { 86400, 'd', 3, "day" },
07552 { 3600, 'h', 4, "hour" },
07553 { 60, 'm', 6, "minute" },
07554 { 1, 's', 6, "second" }
07555 };
07556
07557 #define IYEARS 0
07558 #define IMONTHS 1
07559 #define IWEEKS 2
07560 #define IDAYS 3
07561 #define IHOURS 4
07562 #define IMINUTES 5
07563 #define ISECONDS 6
07564
07565
07566
07567
07568 static void GeneralTimeConversion
07569 (
07570 char *Buffer,
07571 long Seconds,
07572 int iStartBase,
07573 int iEndBase,
07574 bool bSingleTerm,
07575 bool bNames
07576 )
07577 {
07578 if (Seconds < 0)
07579 {
07580 Seconds = 0;
07581 }
07582
07583 char *p = Buffer;
07584 int iValue;
07585
07586 for (int i = iStartBase; i <= iEndBase; i++)
07587 {
07588 if (reTable[i].iBase <= Seconds || i == iEndBase)
07589 {
07590
07591
07592
07593 iValue = Seconds/reTable[i].iBase;
07594 Seconds -= iValue * reTable[i].iBase;
07595
07596 if (iValue != 0 || i == iEndBase)
07597 {
07598 if (p != Buffer)
07599 {
07600 *p++ = ' ';
07601 }
07602 p += mux_ltoa(iValue, p);
07603 if (bNames)
07604 {
07605
07606
07607 *p++ = ' ';
07608 memcpy(p, reTable[i].pName, reTable[i].nName);
07609 p += reTable[i].nName;
07610 if (iValue != 1)
07611 {
07612
07613
07614 *p++ = 's';
07615 }
07616 }
07617 else
07618 {
07619 *p++ = reTable[i].chLetter;
07620 }
07621 }
07622 if (bSingleTerm)
07623 {
07624 break;
07625 }
07626 }
07627 }
07628 *p++ = '\0';
07629 }
07630
07631
07632
07633
07634
07635
07636
07637
07638
07639
07640
07641
07642
07643
07644 static char TimeBuffer64[64];
07645 static char TimeBuffer80[80];
07646
07647
07648
07649
07650
07651
07652 static const char *digit_format(int Seconds)
07653 {
07654 if (Seconds < 0)
07655 {
07656 Seconds = 0;
07657 }
07658
07659
07660
07661
07662
07663
07664 int Days = Seconds / 86400;
07665 Seconds -= Days * 86400;
07666
07667 int Hours = Seconds / 3600;
07668 Seconds -= Hours * 3600;
07669
07670 int Minutes = Seconds / 60;
07671
07672 if (Days > 0)
07673 {
07674 sprintf(TimeBuffer80, "%dd %02d:%02d", Days, Hours, Minutes);
07675 }
07676 else
07677 {
07678 sprintf(TimeBuffer80, "%02d:%02d", Hours, Minutes);
07679 }
07680 return TimeBuffer80;
07681 }
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692
07693
07694
07695
07696
07697
07698
07699
07700
07701
07702
07703
07704
07705
07706
07707
07708 static int tf1_width_table[4][3] =
07709 {
07710 { 86399, 863999, 86396459, },
07711 { 86399, 8639999, 863996459, },
07712 { 86399, 86399999, INT_MAX, },
07713 { 86399, 863999999, INT_MAX, }
07714 };
07715
07716 static struct
07717 {
07718 char *specs[4];
07719 int div[3];
07720 } tf1_case_table[4] =
07721 {
07722 {
07723 { " %2d:%02d", " %2d:%02d", " %2d:%02d", " %2d:%02d" },
07724 { 3600, 60, 1 }
07725 },
07726 {
07727 { "%dd %02d:%02d", "%2dd %02d:%02d", "%3dd %02d:%02d", "%4dd %02d:%02d" },
07728 { 86400, 3600, 60 }
07729 },
07730 {
07731 { "%3dd %02dh", "%4dd %02dh", "%5dd %02dh", "%6dd %02dh" },
07732 { 86400, 3600, 1 }
07733 },
07734 {
07735 { "%4dw %d", "%4dw %d", "", "" },
07736 { 604800, 86400, 1 }
07737 }
07738 };
07739
07740 const char *time_format_1(int Seconds, size_t maxWidth)
07741 {
07742 if (Seconds < 0)
07743 {
07744 Seconds = 0;
07745 }
07746
07747 if ( maxWidth < 8
07748 || 12 < maxWidth)
07749 {
07750 strcpy(TimeBuffer80, "???");
07751 return TimeBuffer80;
07752 }
07753 int iWidth = maxWidth - 8;
07754
07755 int iCase = 0;
07756 while ( iCase < 3
07757 && tf1_width_table[iWidth][iCase] < Seconds)
07758 {
07759 iCase++;
07760 }
07761
07762 int i, n[3];
07763 for (i = 0; i < 3; i++)
07764 {
07765 n[i] = Seconds / tf1_case_table[iCase].div[i];
07766 Seconds -= n[i] *tf1_case_table[iCase].div[i];
07767 }
07768 sprintf(TimeBuffer80, tf1_case_table[iCase].specs[iWidth], n[0], n[1], n[2]);
07769 return TimeBuffer80;
07770 }
07771
07772
07773
07774 const char *time_format_2(int Seconds)
07775 {
07776
07777
07778
07779 GeneralTimeConversion(TimeBuffer64, Seconds, IYEARS, ISECONDS, true, false);
07780 return TimeBuffer64;
07781 }
07782
07783
07784
07785
07786
07787
07788
07789 static const char *expand_time(int Seconds)
07790 {
07791
07792
07793
07794 GeneralTimeConversion(TimeBuffer64, Seconds, IMONTHS, ISECONDS, false, false);
07795 return TimeBuffer64;
07796 }
07797
07798
07799
07800 static const char *write_time(int Seconds)
07801 {
07802
07803
07804
07805
07806 GeneralTimeConversion(TimeBuffer80, Seconds, IMONTHS, ISECONDS, false, true);
07807 return TimeBuffer80;
07808 }
07809
07810
07811
07812
07813 static FUNCTION(fun_digittime)
07814 {
07815 UNUSED_PARAMETER(executor);
07816 UNUSED_PARAMETER(caller);
07817 UNUSED_PARAMETER(enactor);
07818 UNUSED_PARAMETER(nfargs);
07819 UNUSED_PARAMETER(cargs);
07820 UNUSED_PARAMETER(ncargs);
07821
07822 int tt = mux_atol(fargs[0]);
07823 safe_str(digit_format(tt), buff, bufc);
07824 }
07825
07826
07827
07828
07829 static FUNCTION(fun_singletime)
07830 {
07831 UNUSED_PARAMETER(executor);
07832 UNUSED_PARAMETER(caller);
07833 UNUSED_PARAMETER(enactor);
07834 UNUSED_PARAMETER(nfargs);
07835 UNUSED_PARAMETER(cargs);
07836 UNUSED_PARAMETER(ncargs);
07837
07838 int tt = mux_atol(fargs[0]);
07839 safe_str(time_format_2(tt), buff, bufc);
07840 }
07841
07842
07843
07844
07845 static FUNCTION(fun_exptime)
07846 {
07847 UNUSED_PARAMETER(executor);
07848 UNUSED_PARAMETER(caller);
07849 UNUSED_PARAMETER(enactor);
07850 UNUSED_PARAMETER(nfargs);
07851 UNUSED_PARAMETER(cargs);
07852 UNUSED_PARAMETER(ncargs);
07853
07854 int tt = mux_atol(fargs[0]);
07855 safe_str(expand_time(tt), buff, bufc);
07856 }
07857
07858
07859
07860
07861 static FUNCTION(fun_writetime)
07862 {
07863 UNUSED_PARAMETER(executor);
07864 UNUSED_PARAMETER(caller);
07865 UNUSED_PARAMETER(enactor);
07866 UNUSED_PARAMETER(nfargs);
07867 UNUSED_PARAMETER(cargs);
07868 UNUSED_PARAMETER(ncargs);
07869
07870 int tt = mux_atol(fargs[0]);
07871 safe_str(write_time(tt), buff, bufc);
07872 }
07873
07874
07875
07876
07877 static FUNCTION(fun_cmds)
07878 {
07879 UNUSED_PARAMETER(caller);
07880 UNUSED_PARAMETER(enactor);
07881 UNUSED_PARAMETER(nfargs);
07882 UNUSED_PARAMETER(cargs);
07883 UNUSED_PARAMETER(ncargs);
07884
07885 long nCmds = -1;
07886 if (is_rational(fargs[0]))
07887 {
07888 SOCKET s = mux_atol(fargs[0]);
07889 bool bFound = false;
07890 DESC *d;
07891 DESC_ITER_CONN(d)
07892 {
07893 if (d->descriptor == s)
07894 {
07895 bFound = true;
07896 break;
07897 }
07898 }
07899 if ( bFound
07900 && ( d->player == executor
07901 || Wizard_Who(executor)))
07902 {
07903 nCmds = d->command_count;
07904 }
07905 }
07906 else
07907 {
07908 dbref target = lookup_player(executor, fargs[0], true);
07909 if ( Good_obj(target)
07910 && Connected(target)
07911 && ( Wizard_Who(executor)
07912 || Controls(executor, target)))
07913 {
07914 nCmds = fetch_cmds(target);
07915 }
07916 }
07917 safe_ltoa(nCmds, buff, bufc);
07918 }
07919
07920
07921
07922
07923 static FUNCTION(fun_startsecs)
07924 {
07925 UNUSED_PARAMETER(executor);
07926 UNUSED_PARAMETER(caller);
07927 UNUSED_PARAMETER(enactor);
07928 UNUSED_PARAMETER(fargs);
07929 UNUSED_PARAMETER(nfargs);
07930 UNUSED_PARAMETER(cargs);
07931 UNUSED_PARAMETER(ncargs);
07932
07933 CLinearTimeAbsolute lta;
07934 lta = mudstate.start_time;
07935 lta.Local2UTC();
07936 safe_str(lta.ReturnSecondsString(), buff, bufc);
07937 }
07938
07939
07940
07941
07942 static FUNCTION(fun_conntotal)
07943 {
07944 UNUSED_PARAMETER(caller);
07945 UNUSED_PARAMETER(enactor);
07946 UNUSED_PARAMETER(nfargs);
07947 UNUSED_PARAMETER(cargs);
07948 UNUSED_PARAMETER(ncargs);
07949
07950 dbref target = lookup_player(executor, fargs[0], true);
07951 if (Good_obj(target))
07952 {
07953 long TotalTime = fetch_totaltime(target);
07954 if (Connected(target))
07955 {
07956 TotalTime += fetch_connect(target);
07957 }
07958 safe_ltoa(TotalTime, buff, bufc);
07959 }
07960 else
07961 {
07962 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
07963 }
07964 }
07965
07966
07967
07968
07969 static FUNCTION(fun_connmax)
07970 {
07971 UNUSED_PARAMETER(caller);
07972 UNUSED_PARAMETER(enactor);
07973 UNUSED_PARAMETER(nfargs);
07974 UNUSED_PARAMETER(cargs);
07975 UNUSED_PARAMETER(ncargs);
07976
07977 dbref target = lookup_player(executor, fargs[0], true);
07978 if (Good_obj(target))
07979 {
07980 long Longest = fetch_longestconnect(target);
07981 long Current = fetch_connect(target);
07982 if (Longest < Current)
07983 {
07984 Longest = Current;
07985 }
07986 safe_ltoa(Longest, buff, bufc);
07987 }
07988 else
07989 {
07990 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
07991 }
07992 }
07993
07994
07995
07996
07997 static FUNCTION(fun_connlast)
07998 {
07999 UNUSED_PARAMETER(caller);
08000 UNUSED_PARAMETER(enactor);
08001 UNUSED_PARAMETER(nfargs);
08002 UNUSED_PARAMETER(cargs);
08003 UNUSED_PARAMETER(ncargs);
08004
08005 dbref target = lookup_player(executor, fargs[0], true);
08006 if (Good_obj(target))
08007 {
08008 safe_ltoa(fetch_lastconnect(target), buff, bufc);
08009 }
08010 else
08011 {
08012 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
08013 }
08014 }
08015
08016
08017
08018
08019 static FUNCTION(fun_connnum)
08020 {
08021 UNUSED_PARAMETER(caller);
08022 UNUSED_PARAMETER(enactor);
08023 UNUSED_PARAMETER(nfargs);
08024 UNUSED_PARAMETER(cargs);
08025 UNUSED_PARAMETER(ncargs);
08026
08027 dbref target = lookup_player(executor, fargs[0], true);
08028 if (Good_obj(target))
08029 {
08030 long NumConnections = fetch_numconnections(target);
08031 if (Connected(target))
08032 {
08033 NumConnections += fetch_session(target);
08034 }
08035 safe_ltoa(NumConnections, buff, bufc);
08036 }
08037 else
08038 {
08039 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
08040 }
08041 }
08042
08043
08044
08045
08046 static FUNCTION(fun_connleft)
08047 {
08048 UNUSED_PARAMETER(caller);
08049 UNUSED_PARAMETER(enactor);
08050 UNUSED_PARAMETER(nfargs);
08051 UNUSED_PARAMETER(cargs);
08052 UNUSED_PARAMETER(ncargs);
08053
08054 dbref target = lookup_player(executor, fargs[0], true);
08055 if (Good_obj(target))
08056 {
08057 CLinearTimeAbsolute cl = fetch_logouttime(target);
08058 safe_str(cl.ReturnSecondsString(7), buff, bufc);
08059 }
08060 else
08061 {
08062 safe_str("#-1 PLAYER NOT FOUND", buff, bufc);
08063 }
08064 }
08065
08066
08067
08068
08069 static FUNCTION(fun_lattrcmds)
08070 {
08071 UNUSED_PARAMETER(caller);
08072 UNUSED_PARAMETER(enactor);
08073 UNUSED_PARAMETER(nfargs);
08074 UNUSED_PARAMETER(cargs);
08075 UNUSED_PARAMETER(ncargs);
08076
08077
08078
08079
08080
08081 olist_push();
08082 dbref thing;
08083 if (parse_attrib_wild(executor, fargs[0], &thing, false, false, true))
08084 {
08085 bool isFirst = true;
08086 char *buf = alloc_lbuf("fun_lattrcmds");
08087 for (int ca = olist_first(); ca != NOTHING; ca = olist_next())
08088 {
08089 ATTR *pattr = atr_num(ca);
08090 if (pattr)
08091 {
08092 dbref aowner;
08093 int aflags;
08094 atr_get_str(buf, thing, pattr->number, &aowner, &aflags);
08095 if (buf[0] == '$')
08096 {
08097 if (!isFirst)
08098 {
08099 safe_chr(' ', buff, bufc);
08100 }
08101 isFirst = false;
08102 safe_str(pattr->name, buff, bufc);
08103 }
08104 }
08105 }
08106 free_lbuf(buf);
08107 }
08108 else
08109 {
08110 safe_nomatch(buff, bufc);
08111 }
08112 olist_pop();
08113 }
08114
08115
08116
08117
08118
08119
08120 static FUNCTION(fun_lcmds)
08121 {
08122 SEP sep;
08123 if (!OPTIONAL_DELIM(2, sep, DELIM_NULL|DELIM_CRLF|DELIM_STRING))
08124 {
08125 return;
08126 }
08127
08128
08129
08130
08131 char cmd_type = '$';
08132 if ( nfargs == 3
08133 && ( *fargs[2] == '$'
08134 || *fargs[2] == '^'))
08135 {
08136 cmd_type = *fargs[2];
08137 }
08138
08139
08140
08141
08142
08143 olist_push();
08144 dbref thing;
08145 if (parse_attrib_wild(executor, fargs[0], &thing, false, false, true))
08146 {
08147 bool isFirst = true;
08148 char *buf = alloc_lbuf("fun_lattrcmds");
08149 dbref aowner;
08150 int aflags;
08151 for (int ca = olist_first(); ca != NOTHING; ca = olist_next())
08152 {
08153 ATTR *pattr = atr_num(ca);
08154 if (pattr)
08155 {
08156 atr_get_str(buf, thing, pattr->number, &aowner, &aflags);
08157 if (buf[0] == cmd_type)
08158 {
08159 bool isFound = false;
08160 char *c_ptr = buf+1;
08161
08162
08163
08164
08165 if (*c_ptr != ':')
08166 {
08167 int isEscaped = false;
08168 while (*c_ptr && !isFound)
08169 {
08170
08171
08172
08173 if (*c_ptr == '\\')
08174 {
08175 isEscaped = !isEscaped;
08176 }
08177 else if (*c_ptr == ':' && !isEscaped)
08178 {
08179 isFound = true;
08180 *c_ptr = '\0';
08181 }
08182 else if (*c_ptr != '\\' && isEscaped)
08183 {
08184 isEscaped = false;
08185 }
08186 c_ptr++;
08187 }
08188 }
08189
08190
08191
08192
08193
08194 if (isFound)
08195 {
08196 if (!isFirst)
08197 {
08198 print_sep(&sep, buff, bufc);
08199 }
08200
08201 mux_strlwr(buf);
08202 safe_str(buf+1, buff, bufc);
08203
08204 isFirst = false;
08205 }
08206 }
08207 }
08208 }
08209 free_lbuf(buf);
08210 }
08211 else
08212 {
08213 safe_nomatch(buff, bufc);
08214 }
08215 olist_pop();
08216 }
08217
08218
08219
08220
08221 static FUNCTION(fun_lflags)
08222 {
08223 UNUSED_PARAMETER(caller);
08224 UNUSED_PARAMETER(enactor);
08225 UNUSED_PARAMETER(nfargs);
08226 UNUSED_PARAMETER(cargs);
08227 UNUSED_PARAMETER(ncargs);
08228
08229 dbref target = match_thing_quiet(executor, fargs[0]);
08230 if (!Good_obj(target))
08231 {
08232 safe_match_result(target, buff, bufc);
08233 return;
08234 }
08235 bool bFirst = true;
08236 if ( mudconf.pub_flags
08237 || Examinable(executor, target))
08238 {
08239 FLAGNAMEENT *fp;
08240 for (fp = gen_flag_names; fp->flagname; fp++)
08241 {
08242 if (!fp->bPositive)
08243 {
08244 continue;
08245 }
08246 FLAGBITENT *fbe = fp->fbe;
08247 if (db[target].fs.word[fbe->flagflag] & fbe->flagvalue)
08248 {
08249 if ( ( (fbe->listperm & CA_STAFF)
08250 && !Staff(executor))
08251 || ( (fbe->listperm & CA_ADMIN)
08252 && !WizRoy(executor))
08253 || ( (fbe->listperm & CA_WIZARD)
08254 && !Wizard(executor))
08255 || ( (fbe->listperm & CA_GOD)
08256 && !God(executor)))
08257 {
08258 continue;
08259 }
08260 if ( isPlayer(target)
08261 && (fbe->flagvalue == CONNECTED)
08262 && (fbe->flagflag == FLAG_WORD2)
08263 && Hidden(target)
08264 && !See_Hidden(executor))
08265 {
08266 continue;
08267 }
08268
08269 if (!bFirst)
08270 {
08271 safe_chr(' ', buff, bufc);
08272 }
08273 bFirst = false;
08274
08275 safe_str(fp->flagname, buff, bufc);
08276 }
08277 }
08278 }
08279 else
08280 {
08281 safe_noperm(buff, bufc);
08282 }
08283 }
08284
08285
08286
08287
08288
08289
08290
08291
08292
08293
08294
08295
08296
08297
08298 static FUNCTION(fun_art)
08299 {
08300 UNUSED_PARAMETER(executor);
08301 UNUSED_PARAMETER(caller);
08302 UNUSED_PARAMETER(enactor);
08303 UNUSED_PARAMETER(nfargs);
08304 UNUSED_PARAMETER(cargs);
08305 UNUSED_PARAMETER(ncargs);
08306
08307 const int ovecsize = 33;
08308 int ovec[ovecsize];
08309
08310
08311
08312 mux_strlwr(fargs[0]);
08313
08314
08315
08316 ArtRuleset *arRule = mudconf.art_rules;
08317
08318 while (arRule != NULL)
08319 {
08320 pcre* reRuleRegexp = (pcre *) arRule->m_pRegexp;
08321 pcre_extra* reRuleStudy = (pcre_extra *) arRule->m_pRegexpStudy;
08322
08323 if ( !MuxAlarm.bAlarmed
08324 && pcre_exec(reRuleRegexp, reRuleStudy, fargs[0], strlen(fargs[0]),
08325 0, 0, ovec, ovecsize) > 0)
08326 {
08327 safe_str(arRule->m_bUseAn ? "an" : "a", buff, bufc);
08328 return;
08329 }
08330
08331 arRule = arRule->m_pNextRule;
08332 }
08333
08334
08335
08336 safe_str( "a", buff, bufc);
08337 }
08338
08339
08340
08341
08342
08343
08344
08345 static FUNCTION(fun_ord)
08346 {
08347 UNUSED_PARAMETER(executor);
08348 UNUSED_PARAMETER(caller);
08349 UNUSED_PARAMETER(enactor);
08350 UNUSED_PARAMETER(nfargs);
08351 UNUSED_PARAMETER(cargs);
08352 UNUSED_PARAMETER(ncargs);
08353
08354 size_t n;
08355 char *p = strip_ansi(fargs[0], &n);
08356 if (n == 1)
08357 {
08358 unsigned char ch = p[0];
08359 safe_ltoa(ch, buff, bufc);
08360 }
08361 else
08362 {
08363 safe_str("#-1 FUNCTION EXPECTS ONE CHARACTER", buff, bufc);
08364 }
08365 }
08366
08367
08368
08369
08370
08371
08372
08373 static FUNCTION(fun_chr)
08374 {
08375 UNUSED_PARAMETER(executor);
08376 UNUSED_PARAMETER(caller);
08377 UNUSED_PARAMETER(enactor);
08378 UNUSED_PARAMETER(nfargs);
08379 UNUSED_PARAMETER(cargs);
08380 UNUSED_PARAMETER(ncargs);
08381
08382 if (!is_integer(fargs[0], NULL))
08383 {
08384 safe_str("#-1 ARGUMENT MUST BE A NUMBER", buff, bufc);
08385 return;
08386 }
08387 int ch = mux_atol(fargs[0]);
08388 if ( ch < 0
08389 || (int) UCHAR_MAX < ch)
08390 {
08391 safe_str("#-1 THIS ISN'T UNICODE", buff, bufc);
08392 }
08393 else if (mux_isprint(ch))
08394 {
08395 safe_chr(ch, buff, bufc);
08396 }
08397 else
08398 {
08399 safe_str("#-1 UNPRINTABLE CHARACTER", buff, bufc);
08400 }
08401 }
08402
08403
08404
08405
08406 static FUNCTION(fun_stripaccents)
08407 {
08408 UNUSED_PARAMETER(executor);
08409 UNUSED_PARAMETER(caller);
08410 UNUSED_PARAMETER(enactor);
08411 UNUSED_PARAMETER(nfargs);
08412 UNUSED_PARAMETER(cargs);
08413 UNUSED_PARAMETER(ncargs);
08414
08415 size_t nLen;
08416 char *p = strip_accents(fargs[0], &nLen);
08417 safe_copy_buf(p, nLen, buff, bufc);
08418 }
08419
08420
08421
08422 static const unsigned char AccentCombo1[256] =
08423 {
08424
08425
08426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08427 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08428 0,18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08429 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,19, 0,20,17,
08430 0, 1, 0, 3,24, 5, 0, 0, 0, 7, 0, 0, 0, 0, 9,11,
08431 22, 0, 0, 0, 0,13, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
08432 0, 2, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0, 0,10,12,
08433 23, 0, 0,21, 0,14, 0, 0, 0,16, 0, 0, 0, 0, 0, 0,
08434
08435 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08436 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08437 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08440 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08441 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08442 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
08443 };
08444
08445
08446
08447 static const unsigned char AccentCombo2[256] =
08448 {
08449
08450
08451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08453 0, 0, 9, 0, 0, 0,13, 2, 0, 0, 0, 0, 7,12, 0, 0,
08454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
08455 0, 0,10, 0, 0,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08456 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
08457 1, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
08458 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,11, 0, 4, 0,
08459
08460 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08462 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08463 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08465 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08466 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
08467 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
08468 };
08469
08470 static const unsigned char AccentCombo3[24][16] =
08471 {
08472
08473
08474
08475 { 0x00, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x00 },
08476 { 0x00, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6 },
08477 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08478 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08479 { 0x00, 0xC8, 0xC9, 0xCA, 0x00, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08480 { 0x00, 0xE8, 0xE9, 0xEA, 0x00, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08481 { 0x00, 0xCC, 0xCD, 0xCE, 0x00, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08482 { 0x00, 0xEC, 0xED, 0xEE, 0x00, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08483
08484 { 0x00, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08485 { 0x00, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08486 { 0x00, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08487 { 0x00, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00 },
08488 { 0x00, 0xD9, 0xDA, 0xDB, 0x00, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08489 { 0x00, 0xF9, 0xFA, 0xFB, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08490 { 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08491 { 0x00, 0x00, 0xFD, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08492
08493 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08494 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08495 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08496 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
08497 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00 },
08498 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00 },
08499 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00 },
08500 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00 }
08501 };
08502
08503
08504
08505
08506 static FUNCTION(fun_accent)
08507 {
08508 UNUSED_PARAMETER(executor);
08509 UNUSED_PARAMETER(caller);
08510 UNUSED_PARAMETER(enactor);
08511 UNUSED_PARAMETER(nfargs);
08512 UNUSED_PARAMETER(cargs);
08513 UNUSED_PARAMETER(ncargs);
08514
08515 size_t n = strlen(fargs[0]);
08516 if (n != strlen(fargs[1]))
08517 {
08518 safe_str("#-1 STRING LENGTHS MUST BE EQUAL", buff, bufc);
08519 return;
08520 }
08521
08522 const unsigned char *p = (unsigned char *)fargs[0];
08523 const unsigned char *q = (unsigned char *)fargs[1];
08524
08525 while (*p)
08526 {
08527 unsigned char ch = '\0';
08528 unsigned char ch0 = AccentCombo1[*p];
08529 if (ch0)
08530 {
08531 unsigned char ch1 = AccentCombo2[*q];
08532 if (ch1)
08533 {
08534 ch = AccentCombo3[ch0-1][ch1];
08535 }
08536 }
08537 if (!mux_isprint(ch))
08538 {
08539 ch = *p;
08540 }
08541 safe_chr(ch, buff, bufc);
08542
08543 p++;
08544 q++;
08545 }
08546 }
08547
08548
08549
08550
08551
08552
08553
08554 static FUN builtin_function_list[] =
08555 {
08556 {"@@", fun_null, 1, 1, 1, FN_NOEVAL, CA_PUBLIC},
08557 {"ABS", fun_abs, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08558 {"ACCENT", fun_accent, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08559 {"ACOS", fun_acos, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08560 {"ADD", fun_add, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08561 {"AFTER", fun_after, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08562 {"ALPHAMAX", fun_alphamax, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08563 {"ALPHAMIN", fun_alphamin, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08564 {"AND", fun_and, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08565 {"ANDBOOL", fun_andbool, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08566 {"ANDFLAGS", fun_andflags, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08567 {"ANSI", fun_ansi, MAX_ARG, 2, MAX_ARG, 0, CA_PUBLIC},
08568 {"APOSS", fun_aposs, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08569 {"ART", fun_art, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08570 {"ASIN", fun_asin, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08571 {"ATAN", fun_atan, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08572 {"ATTRCNT", fun_attrcnt, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08573 {"BAND", fun_band, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08574 {"BEEP", fun_beep, MAX_ARG, 0, 0, 0, CA_WIZARD},
08575 {"BEFORE", fun_before, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08576 {"BITTYPE", fun_bittype, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08577 {"BNAND", fun_bnand, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08578 {"BOR", fun_bor, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08579 {"BXOR", fun_bxor, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08580 {"CAND", fun_cand, MAX_ARG, 0, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08581 {"CANDBOOL", fun_candbool, MAX_ARG, 0, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08582 #if defined(WOD_REALMS) || defined(REALITY_LVLS)
08583 {"CANSEE", fun_cansee, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08584 #endif
08585 {"CAPSTR", fun_capstr, 1, 1, 1, 0, CA_PUBLIC},
08586 {"CASE", fun_case, MAX_ARG, 2, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08587 {"CAT", fun_cat, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08588 {"CEIL", fun_ceil, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08589 {"CEMIT", fun_cemit, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08590 {"CENTER", fun_center, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08591 {"CHANNELS", fun_channels, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08592 {"CHILDREN", fun_children, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08593 {"CHOOSE", fun_choose, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08594 {"CHR", fun_chr, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08595 {"CMDS", fun_cmds, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08596 {"COLUMNS", fun_columns, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08597 {"COMALIAS", fun_comalias, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08598 {"COMP", fun_comp, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08599 {"COMTITLE", fun_comtitle, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08600 {"CON", fun_con, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08601 {"CONFIG", fun_config, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08602 {"CONN", fun_conn, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08603 {"CONNLAST", fun_connlast, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08604 {"CONNLEFT", fun_connleft, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08605 {"CONNMAX", fun_connmax, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08606 {"CONNNUM", fun_connnum, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08607 {"CONNRECORD", fun_connrecord, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08608 {"CONNTOTAL", fun_conntotal, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08609 {"CONTROLS", fun_controls, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08610 {"CONVSECS", fun_convsecs, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08611 {"CONVTIME", fun_convtime, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08612 {"COR", fun_cor, MAX_ARG, 0, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08613 {"CORBOOL", fun_corbool, MAX_ARG, 0, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08614 {"COS", fun_cos, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08615 {"CRC32", fun_crc32, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08616 {"CREATE", fun_create, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08617 {"CTIME", fun_ctime, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08618 {"CTU", fun_ctu, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08619 {"CWHO", fun_cwho, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08620 {"DEC", fun_dec, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08621 {"DECRYPT", fun_decrypt, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08622 {"DEFAULT", fun_default, MAX_ARG, 2, 2, FN_NOEVAL, CA_PUBLIC},
08623 {"DELETE", fun_delete, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08624 {"DIE", fun_die, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08625 {"DIGITTIME", fun_digittime, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08626 {"DIST2D", fun_dist2d, MAX_ARG, 4, 4, 0, CA_PUBLIC},
08627 {"DIST3D", fun_dist3d, MAX_ARG, 6, 6, 0, CA_PUBLIC},
08628 {"DOING", fun_doing, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08629 {"DUMPING", fun_dumping, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08630 {"E", fun_e, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08631 {"EDEFAULT", fun_edefault, MAX_ARG, 2, 2, FN_NOEVAL, CA_PUBLIC},
08632 {"EDIT", fun_edit, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08633 {"ELEMENTS", fun_elements, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08634 {"ELOCK", fun_elock, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08635 {"EMIT", fun_emit, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08636 {"EMPTY", fun_empty, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08637 {"ENCRYPT", fun_encrypt, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08638 {"ENTRANCES", fun_entrances, MAX_ARG, 0, 4, 0, CA_PUBLIC},
08639 {"EQ", fun_eq, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08640 {"ERROR", fun_error, 1, 0, 1, 0, CA_PUBLIC},
08641 {"ESCAPE", fun_escape, 1, 1, 1, 0, CA_PUBLIC},
08642 {"EVAL", fun_eval, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08643 {"EXIT", fun_exit, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08644 {"EXP", fun_exp, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08645 {"EXPTIME", fun_exptime, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08646 {"EXTRACT", fun_extract, MAX_ARG, 3, 5, 0, CA_PUBLIC},
08647 {"FCOUNT", fun_fcount, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08648 {"FDEPTH", fun_fdepth, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08649 {"FDIV", fun_fdiv, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08650 {"FILTER", fun_filter, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08651 {"FILTERBOOL", fun_filterbool, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08652 {"FINDABLE", fun_findable, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08653 {"FIRST", fun_first, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08654 {"FLAGS", fun_flags, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08655 {"FLOOR", fun_floor, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08656 {"FLOORDIV", fun_floordiv, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08657 {"FMOD", fun_fmod, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08658 {"FOLD", fun_fold, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08659 {"FOREACH", fun_foreach, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08660 {"FULLNAME", fun_fullname, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08661 {"GET", fun_get, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08662 {"GET_EVAL", fun_get_eval, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08663 {"GRAB", fun_grab, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08664 {"GRABALL", fun_graball, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08665 {"GREP", fun_grep, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08666 {"GREPI", fun_grepi, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08667 {"GT", fun_gt, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08668 {"GTE", fun_gte, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08669 {"HASATTR", fun_hasattr, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08670 {"HASATTRP", fun_hasattrp, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08671 {"HASFLAG", fun_hasflag, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08672 {"HASPOWER", fun_haspower, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08673 {"HASQUOTA", fun_hasquota, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08674 #ifdef REALITY_LVLS
08675 {"HASRXLEVEL", fun_hasrxlevel, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08676 {"HASTXLEVEL", fun_hastxlevel, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08677 #endif
08678 {"HASTYPE", fun_hastype, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08679 {"HEIGHT", fun_height, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08680 {"HOME", fun_home, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08681 {"HOST", fun_host, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08682 {"IABS", fun_iabs, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08683 {"IADD", fun_iadd, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08684 {"IDIV", fun_idiv, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08685 {"IDLE", fun_idle, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08686 {"IF", fun_ifelse, MAX_ARG, 2, 3, FN_NOEVAL, CA_PUBLIC},
08687 {"IFELSE", fun_ifelse, MAX_ARG, 3, 3, FN_NOEVAL, CA_PUBLIC},
08688 {"ILEV", fun_ilev, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08689 {"IMUL", fun_imul, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08690 {"INC", fun_inc, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08691 {"INDEX", fun_index, MAX_ARG, 4, 4, 0, CA_PUBLIC},
08692 {"INSERT", fun_insert, MAX_ARG, 3, 4, 0, CA_PUBLIC},
08693 {"INUM", fun_inum, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08694 {"INZONE", fun_inzone, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08695 {"ISDBREF", fun_isdbref, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08696 {"ISIGN", fun_isign, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08697 {"ISINT", fun_isint, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08698 {"ISNUM", fun_isnum, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08699 {"ISRAT", fun_israt, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08700 {"ISUB", fun_isub, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08701 {"ISWORD", fun_isword, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08702 {"ITEMIZE", fun_itemize, MAX_ARG, 1, 4, 0, CA_PUBLIC},
08703 {"ITEMS", fun_items, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08704 {"ITER", fun_iter, MAX_ARG, 2, 4, FN_NOEVAL, CA_PUBLIC},
08705 {"ITEXT", fun_itext, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08706 {"LADD", fun_ladd, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08707 {"LAND", fun_land, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08708 {"LAST", fun_last, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08709 {"LATTR", fun_lattr, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08710 {"LATTRCMDS", fun_lattrcmds, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08711 {"LATTRP", fun_lattrp, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08712 #ifdef REALITY_LVLS
08713 {"LISTRLEVELS", fun_listrlevels, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08714 #endif
08715 {"LCMDS", fun_lcmds, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08716 {"LCON", fun_lcon, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08717 {"LCSTR", fun_lcstr, 1, 1, 1, 0, CA_PUBLIC},
08718 {"LDELETE", fun_ldelete, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08719 {"LEXITS", fun_lexits, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08720 {"LFLAGS", fun_lflags, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08721 {"LINK", fun_link, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08722 {"LIST", fun_list, MAX_ARG, 2, 3, FN_NOEVAL, CA_PUBLIC},
08723 {"LIT", fun_lit, 1, 1, 1, FN_NOEVAL, CA_PUBLIC},
08724 {"LJUST", fun_ljust, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08725 {"LN", fun_ln, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08726 {"LNUM", fun_lnum, MAX_ARG, 0, 3, 0, CA_PUBLIC},
08727 {"LOC", fun_loc, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08728 {"LOCALIZE", fun_localize, MAX_ARG, 1, 1, FN_NOEVAL, CA_PUBLIC},
08729 {"LOCATE", fun_locate, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08730 {"LOCK", fun_lock, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08731 {"LOG", fun_log, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08732 {"LOR", fun_lor, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08733 {"LPARENT", fun_lparent, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08734 {"LPORTS", fun_lports, MAX_ARG, 0, 0, 0, CA_WIZARD},
08735 {"LPOS", fun_lpos, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08736 {"LRAND", fun_lrand, MAX_ARG, 3, 4, 0, CA_PUBLIC},
08737 {"LROOMS", fun_lrooms, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08738 {"LSTACK", fun_lstack, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08739 {"LT", fun_lt, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08740 {"LTE", fun_lte, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08741 {"LWHO", fun_lwho, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08742 {"MAIL", fun_mail, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08743 {"MAILFROM", fun_mailfrom, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08744 {"MAP", fun_map, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08745 {"MATCH", fun_match, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08746 {"MATCHALL", fun_matchall, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08747 {"MAX", fun_max, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08748 {"MEMBER", fun_member, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08749 {"MERGE", fun_merge, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08750 {"MID", fun_mid, MAX_ARG, 3, 3, 0, CA_PUBLIC},
08751 {"MIN", fun_min, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08752 {"MIX", fun_mix, MAX_ARG, 3, 12, 0, CA_PUBLIC},
08753 {"MOD", fun_mod, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08754 {"MONEY", fun_money, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08755 {"MONIKER", fun_moniker, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08756 {"MOTD", fun_motd, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08757 {"MTIME", fun_mtime, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08758 {"MUDNAME", fun_mudname, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08759 {"MUL", fun_mul, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08760 {"MUNGE", fun_munge, MAX_ARG, 3, 4, 0, CA_PUBLIC},
08761 {"NAME", fun_name, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08762 {"NEARBY", fun_nearby, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08763 {"NEQ", fun_neq, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08764 {"NEXT", fun_next, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08765 {"NOT", fun_not, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08766 {"NULL", fun_null, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08767 {"NUM", fun_num, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08768 {"OBJ", fun_obj, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08769 {"OBJEVAL", fun_objeval, MAX_ARG, 2, 2, FN_NOEVAL, CA_PUBLIC},
08770 {"OBJMEM", fun_objmem, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08771 {"OEMIT", fun_oemit, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08772 {"OR", fun_or, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08773 {"ORBOOL", fun_orbool, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08774 {"ORD", fun_ord, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08775 {"ORFLAGS", fun_orflags, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08776 {"OWNER", fun_owner, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08777 {"PACK", fun_pack, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08778 {"PARENT", fun_parent, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08779 {"PARSE", fun_iter, MAX_ARG, 2, 4, FN_NOEVAL, CA_PUBLIC},
08780 {"PEEK", fun_peek, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08781 {"PEMIT", fun_pemit, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08782 {"PFIND", fun_pfind, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08783 {"PI", fun_pi, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08784 {"PICKRAND", fun_pickrand, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08785 {"PLAYMEM", fun_playmem, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08786 {"PMATCH", fun_pmatch, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08787 {"POLL", fun_poll, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08788 {"POP", fun_pop, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08789 {"PORTS", fun_ports, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08790 {"POS", fun_pos, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08791 {"POSS", fun_poss, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08792 {"POWER", fun_power, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08793 {"POWERS", fun_powers, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08794 {"PUSH", fun_push, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08795 {"R", fun_r, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08796 {"RAND", fun_rand, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08797 {"REGMATCH", fun_regmatch, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08798 {"REGMATCHI", fun_regmatchi, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08799 {"REGRAB", fun_regrab, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08800 {"REGRABALL", fun_regraball, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08801 {"REGRABALLI", fun_regraballi, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08802 {"REGRABI", fun_regrabi, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08803 {"REMAINDER", fun_remainder, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08804 {"REMIT", fun_remit, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08805 {"REMOVE", fun_remove, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08806 {"REPEAT", fun_repeat, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08807 {"REPLACE", fun_replace, MAX_ARG, 3, 4, 0, CA_PUBLIC},
08808 {"REST", fun_rest, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08809 {"REVERSE", fun_reverse, 1, 1, 1, 0, CA_PUBLIC},
08810 {"REVWORDS", fun_revwords, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08811 {"RIGHT", fun_right, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08812 {"RJUST", fun_rjust, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08813 {"RLOC", fun_rloc, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08814 {"ROMAN", fun_roman, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08815 {"ROOM", fun_room, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08816 {"ROUND", fun_round, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08817 #ifdef REALITY_LVLS
08818 {"RXLEVEL", fun_rxlevel, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08819 #endif
08820 {"S", fun_s, 1, 1, 1, 0, CA_PUBLIC},
08821 {"SCRAMBLE", fun_scramble, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08822 {"SEARCH", fun_search, 1, 0, 1, 0, CA_PUBLIC},
08823 {"SECS", fun_secs, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08824 {"SECURE", fun_secure, 1, 1, 1, 0, CA_PUBLIC},
08825 {"SET", fun_set, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08826 {"SETDIFF", fun_setdiff, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08827 {"SETINTER", fun_setinter, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08828 {"SETQ", fun_setq, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08829 {"SETR", fun_setr, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08830 {"SETUNION", fun_setunion, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08831 {"SHA1", fun_sha1, 1, 0, 1, 0, CA_PUBLIC},
08832 {"SHL", fun_shl, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08833 {"SHR", fun_shr, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08834 {"SHUFFLE", fun_shuffle, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08835 {"SIGN", fun_sign, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08836 {"SIN", fun_sin, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08837 {"SINGLETIME", fun_singletime, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08838 {"SORT", fun_sort, MAX_ARG, 1, 4, 0, CA_PUBLIC},
08839 {"SORTBY", fun_sortby, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08840 {"SPACE", fun_space, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08841 {"SPELLNUM", fun_spellnum, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08842 {"SPLICE", fun_splice, MAX_ARG, 3, 5, 0, CA_PUBLIC},
08843 {"SQRT", fun_sqrt, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08844 {"SQUISH", fun_squish, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08845 {"STARTSECS", fun_startsecs, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08846 {"STARTTIME", fun_starttime, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08847 {"STATS", fun_stats, MAX_ARG, 0, 1, 0, CA_PUBLIC},
08848 {"STRCAT", fun_strcat, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08849 {"STRIP", fun_strip, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08850 {"STRIPACCENTS",fun_stripaccents, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08851 {"STRIPANSI", fun_stripansi, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08852 {"STRLEN", fun_strlen, 1, 0, 1, 0, CA_PUBLIC},
08853 {"STRMATCH", fun_strmatch, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08854 {"STRMEM", fun_strmem, 1, 0, 1, 0, CA_PUBLIC},
08855 {"STRTRUNC", fun_strtrunc, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08856 {"SUB", fun_sub, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08857 {"SUBEVAL", fun_subeval, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08858 {"SUBJ", fun_subj, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08859 {"SWITCH", fun_switch, MAX_ARG, 2, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08860 {"T", fun_t, 1, 0, 1, 0, CA_PUBLIC},
08861 {"TABLE", fun_table, MAX_ARG, 1, 6, 0, CA_PUBLIC},
08862 {"TAN", fun_tan, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08863 {"TEL", fun_tel, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08864 {"TEXTFILE", fun_textfile, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08865 {"TIME", fun_time, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08866 {"TIMEFMT", fun_timefmt, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08867 {"TRANSLATE", fun_translate, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08868 {"TRIM", fun_trim, MAX_ARG, 1, 3, 0, CA_PUBLIC},
08869 {"TRUNC", fun_trunc, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08870 #ifdef REALITY_LVLS
08871 {"TXLEVEL", fun_txlevel, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08872 #endif
08873 {"TYPE", fun_type, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08874 {"U", fun_u, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08875 {"UCSTR", fun_ucstr, 1, 1, 1, 0, CA_PUBLIC},
08876 {"UDEFAULT", fun_udefault, MAX_ARG, 2, MAX_ARG, FN_NOEVAL, CA_PUBLIC},
08877 {"ULOCAL", fun_ulocal, MAX_ARG, 1, MAX_ARG, 0, CA_PUBLIC},
08878 {"UNPACK", fun_unpack, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08879 {"V", fun_v, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08880 {"VADD", fun_vadd, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08881 {"VALID", fun_valid, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08882 {"VCROSS", fun_vcross, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08883 {"VDIM", fun_words, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08884 {"VDOT", fun_vdot, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08885 {"VERSION", fun_version, MAX_ARG, 0, 0, 0, CA_PUBLIC},
08886 {"VISIBLE", fun_visible, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08887 {"VMAG", fun_vmag, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08888 {"VMUL", fun_vmul, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08889 {"VSUB", fun_vsub, MAX_ARG, 2, 4, 0, CA_PUBLIC},
08890 {"VUNIT", fun_vunit, MAX_ARG, 1, 2, 0, CA_PUBLIC},
08891 {"WHERE", fun_where, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08892 {"WIDTH", fun_width, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08893 {"WORDPOS", fun_wordpos, MAX_ARG, 2, 3, 0, CA_PUBLIC},
08894 {"WORDS", fun_words, MAX_ARG, 0, 2, 0, CA_PUBLIC},
08895 {"WRAP", fun_wrap, MAX_ARG, 1, 8, 0, CA_PUBLIC},
08896 {"WRITETIME", fun_writetime, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08897 {"XGET", fun_xget, MAX_ARG, 2, 2, 0, CA_PUBLIC},
08898 {"XOR", fun_xor, MAX_ARG, 0, MAX_ARG, 0, CA_PUBLIC},
08899 {"ZFUN", fun_zfun, MAX_ARG, 2, 11, 0, CA_PUBLIC},
08900 {"ZONE", fun_zone, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08901 {"ZWHO", fun_zwho, MAX_ARG, 1, 1, 0, CA_PUBLIC},
08902 {NULL, NULL, MAX_ARG, 0, 0, 0, 0}
08903 };
08904
08905 void function_add(FUN *fp)
08906 {
08907 char *buff = alloc_sbuf("init_functab");
08908 char *bp = buff;
08909 safe_sb_str(fp->name, buff, &bp);
08910 *bp = '\0';
08911 mux_strlwr(buff);
08912 hashaddLEN(buff, strlen(buff), fp, &mudstate.func_htab);
08913 free_sbuf(buff);
08914 }
08915
08916 void functions_add(FUN funlist[])
08917 {
08918 char *buff = alloc_sbuf("init_functab");
08919 for (FUN *fp = funlist; fp->name; fp++)
08920 {
08921 char *bp = buff;
08922 safe_sb_str(fp->name, buff, &bp);
08923 *bp = '\0';
08924 mux_strlwr(buff);
08925 hashaddLEN(buff, strlen(buff), fp, &mudstate.func_htab);
08926 }
08927 free_sbuf(buff);
08928 }
08929
08930 void init_functab(void)
08931 {
08932 functions_add(builtin_function_list);
08933 ufun_head = NULL;
08934 }
08935
08936 void do_function
08937 (
08938 dbref executor,
08939 dbref caller,
08940 dbref enactor,
08941 int key,
08942 int nargs,
08943 char *fname,
08944 char *target
08945 )
08946 {
08947 UNUSED_PARAMETER(caller);
08948 UNUSED_PARAMETER(enactor);
08949 UNUSED_PARAMETER(nargs);
08950
08951 UFUN *ufp, *ufp2;
08952 ATTR *ap;
08953
08954 if ((key & FN_LIST) || !fname || *fname == '\0')
08955 {
08956 notify(executor, tprintf("%-28s %-8s %-30s Flgs",
08957 "Function Name", "DBref#", "Attribute"));
08958 notify(executor, tprintf("%28s %8s %30s %4s",
08959 "----------------------------", "--------",
08960 "------------------------------", " -- "));
08961
08962 int count = 0;
08963 for (ufp2 = ufun_head; ufp2; ufp2 = ufp2->next)
08964 {
08965 const char *pName = "(WARNING: Bad Attribute Number)";
08966 ap = atr_num(ufp2->atr);
08967 if (ap)
08968 {
08969 pName = ap->name;
08970 }
08971 notify(executor, tprintf("%-28.28s #%-7d %-30.30s %c%c",
08972 ufp2->name, ufp2->obj, pName, ((ufp2->flags & FN_PRIV) ? 'W' : '-'),
08973 ((ufp2->flags & FN_PRES) ? 'p' : '-')));
08974 count++;
08975 }
08976
08977 notify(executor, tprintf("%28s %8s %30s %4s",
08978 "----------------------------", "--------",
08979 "------------------------------", " -- "));
08980
08981 notify(executor, tprintf("Total User-Defined Functions: %d", count));
08982 return;
08983 }
08984
08985 char *np, *bp;
08986 ATTR *pattr;
08987 dbref obj;
08988
08989
08990
08991 bp = np = alloc_sbuf("add_user_func");
08992 safe_sb_str(fname, np, &bp);
08993 *bp = '\0';
08994 mux_strlwr(np);
08995
08996
08997
08998 if (hashfindLEN(np, strlen(np), &mudstate.func_htab) != NULL)
08999 {
09000 notify_quiet(executor, "Function already defined in builtin function table.");
09001 free_sbuf(np);
09002 return;
09003 }
09004
09005
09006
09007 if (!parse_attrib(executor, target, &obj, &pattr))
09008 {
09009 notify_quiet(executor, NOMATCH_MESSAGE);
09010 free_sbuf(np);
09011 return;
09012 }
09013
09014
09015
09016
09017 if (!pattr)
09018 {
09019 notify_quiet(executor, "No such attribute.");
09020 free_sbuf(np);
09021 return;
09022 }
09023
09024
09025
09026 if (!See_attr(executor, obj, pattr))
09027 {
09028 notify_quiet(executor, NOPERM_MESSAGE);
09029 free_sbuf(np);
09030 return;
09031 }
09032
09033
09034
09035 if ((key & FN_PRIV) && !Controls(executor, obj))
09036 {
09037 notify_quiet(executor, NOPERM_MESSAGE);
09038 free_sbuf(np);
09039 return;
09040 }
09041
09042
09043
09044 ufp = (UFUN *) hashfindLEN(np, strlen(np), &mudstate.ufunc_htab);
09045
09046 if (!ufp)
09047 {
09048 ufp = (UFUN *) MEMALLOC(sizeof(UFUN));
09049 ISOUTOFMEMORY(ufp);
09050 ufp->name = StringClone(np);
09051 mux_strupr(ufp->name);
09052 ufp->obj = obj;
09053 ufp->atr = pattr->number;
09054 ufp->perms = CA_PUBLIC;
09055 ufp->next = NULL;
09056 if (!ufun_head)
09057 {
09058 ufun_head = ufp;
09059 }
09060 else
09061 {
09062 for (ufp2 = ufun_head; ufp2->next; ufp2 = ufp2->next)
09063 {
09064
09065 ;
09066 }
09067 ufp2->next = ufp;
09068 }
09069 hashaddLEN(np, strlen(np), ufp, &mudstate.ufunc_htab);
09070 }
09071 ufp->obj = obj;
09072 ufp->atr = pattr->number;
09073 ufp->flags = key;
09074 free_sbuf(np);
09075 if (!Quiet(executor))
09076 {
09077 notify_quiet(executor, tprintf("Function %s defined.", fname));
09078 }
09079 }
09080
09081
09082
09083
09084 void list_functable(dbref player)
09085 {
09086 char *buff = alloc_lbuf("list_functable");
09087 char *bp = buff;
09088
09089 safe_str("Functions:", buff, &bp);
09090
09091 FUN *fp;
09092 for (fp = builtin_function_list; fp->name && bp < buff + (LBUF_SIZE-1); fp++)
09093 {
09094 if (check_access(player, fp->perms))
09095 {
09096 safe_chr(' ', buff, &bp);
09097 safe_str(fp->name, buff, &bp);
09098 }
09099 }
09100 *bp = '\0';
09101 notify(player, buff);
09102
09103 bp = buff;
09104 safe_str("User-Functions:", buff, &bp);
09105
09106 UFUN *ufp;
09107 for (ufp = ufun_head; ufp && bp < buff + (LBUF_SIZE-1); ufp = ufp->next)
09108 {
09109 if (check_access(player, ufp->perms))
09110 {
09111 safe_chr(' ', buff, &bp);
09112 safe_str(ufp->name, buff, &bp);
09113 }
09114 }
09115 *bp = '\0';
09116 notify(player, buff);
09117 free_lbuf(buff);
09118 }
09119
09120
09121
09122
09123
09124
09125 CF_HAND(cf_func_access)
09126 {
09127 UNUSED_PARAMETER(vp);
09128
09129 char *ap;
09130 for (ap = str; *ap && !mux_isspace(*ap); ap++)
09131 {
09132 *ap = mux_tolower(*ap);
09133 }
09134 int nstr = ap - str;
09135
09136 if (*ap)
09137 {
09138 *ap++ = '\0';
09139 }
09140
09141 FUN *fp = (FUN *)hashfindLEN(str, nstr, &mudstate.func_htab);
09142 if (fp)
09143 {
09144 return cf_modify_bits(&fp->perms, ap, pExtra, nExtra, player, cmd);
09145 }
09146 UFUN *ufp = (UFUN *)hashfindLEN(str, nstr, &mudstate.ufunc_htab);
09147 if (ufp)
09148 {
09149 return cf_modify_bits(&ufp->perms, ap, pExtra, nExtra, player, cmd);
09150 }
09151 cf_log_notfound(player, cmd, "Function", str);
09152 return -1;
09153 }