From d544bd0007c04214021b308592688de877c99923 Mon Sep 17 00:00:00 2001 From: Rick Bird Date: Fri, 25 Mar 2011 04:28:04 -0400 Subject: [PATCH] PennMUSH patch 1.8.1-patch08 applied. untested --- hdrs/copyrite.h | 2 +- hdrs/lock.h | 2 + src/attrib.c | 5 +++ src/bsd.c | 23 +++++++----- src/command.c | 30 +++++++-------- src/funlist.c | 27 ++++++++------ src/funtime.c | 87 ++++++++++++++++++++++++++++++++----------- src/game.c | 10 ++++- src/lock.c | 41 ++++++++++++++++++++ src/look.c | 6 ++- src/move.c | 3 +- src/notify.c | 5 +-- src/parse.c | 99 +++++++++++++++++++------------------------------ src/wiz.c | 9 +++-- 14 files changed, 219 insertions(+), 130 deletions(-) diff --git a/hdrs/copyrite.h b/hdrs/copyrite.h index 982503d..5c623fc 100644 --- a/hdrs/copyrite.h +++ b/hdrs/copyrite.h @@ -170,7 +170,7 @@ * * Past and present PennMUSH development team members: * T. Alexander Popiel, Ralph Melton, Thorvald Natvig, Luuk de Waard, - * Shawn Wagner, Ervin Hearn III, Alan "Javelin" Schwartz + * Shawn Wagner, Ervin Hearn III, Alan "Javelin" Schwartz, Greg Millam * Past and present PennMUSH porters: * Nick Gammon, Sylvia, Dan Williams, Ervin Hearn III * TinyMUSH 2.2, TinyMUSH 3.0, TinyMUX 2, and RhostMUSH developers diff --git a/hdrs/lock.h b/hdrs/lock.h index 16d82a3..b055aee 100644 --- a/hdrs/lock.h +++ b/hdrs/lock.h @@ -60,6 +60,8 @@ int add_lock_raw(dbref player, dbref thing, lock_type type, boolexp key, int flags); void free_locks(lock_list *ll); int eval_lock(dbref player, dbref thing, lock_type ltype); +int eval_lock_with(dbref player, dbref thing, lock_type ltype, dbref env0, + dbref env1); int fail_lock(dbref player, dbref thing, lock_type ltype, const char *def, dbref loc); void do_unlock(dbref player, const char *name, lock_type type); diff --git a/src/attrib.c b/src/attrib.c index e7f2f77..3381846 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1448,6 +1448,11 @@ atr_comm_divmatch(dbref thing, dbref player, int type, int end, if (!s) continue; *s++ = '\0'; + if (type == '^' && !AF_Ahear(ptr)) { + if ((thing == player && !AF_Mhear(ptr)) + || (thing != player && AF_Mhear(ptr))) + continue; + } if (AF_Regexp(ptr)) { /* Turn \: into : */ diff --git a/src/bsd.c b/src/bsd.c index ab169c0..934399b 100644 --- a/src/bsd.c +++ b/src/bsd.c @@ -4143,7 +4143,7 @@ FUNCTION(fun_lwho) int start, count; int powered = !(strchr(called_as, 'M') != NULL) && Priv_Who(executor); int xwho = *called_as == 'X'; - int objid = strchr(called_as, 'D') != NULL; + int objid = (index(called_as, 'D') != NULL); first = 1; if(!xwho && nargs && args[0] && *args[0]) { @@ -4385,6 +4385,7 @@ FUNCTION(fun_zwho) dbref zone, victim; int first; int powered = (strcmp(called_as, "ZMWHO") && Priv_Who(executor)); + int objid = (index(called_as, 'D') != NULL); first = 1; zone = match_thing(executor, args[0]); @@ -4401,7 +4402,7 @@ FUNCTION(fun_zwho) return; } - if (!GoodObject(zone) || !(eval_lock(victim, zone, Zone_Lock) || CanSee(victim,zone))) { + if (!GoodObject(zone) || (!Priv_Who(executor) && !(eval_lock(victim, zone, Zone_Lock) || CanSee(victim,zone)))) { safe_str(T(e_perm), buff, bp); return; } @@ -4417,13 +4418,17 @@ FUNCTION(fun_zwho) DESC_ITER_CONN(d) { if (Zone(Location(d->player)) == zone && - (!Hidden(d) || (powered && CanSee(victim, d->player))) ) { - if (first) { - first = 0; - } else { - safe_chr(' ', buff, bp); - } - safe_dbref(d->player, buff, bp); + (!Hidden(d) || (powered && CanSee(victim, d->player))) ) { + if (first) { + first = 0; + } else { + safe_chr(' ', buff, bp); + } + safe_dbref(d->player, buff, bp); + if (objid) { + safe_chr(':', buff, bp); + safe_integer(CreTime(d->player), buff, bp); + } } } } diff --git a/src/command.c b/src/command.c index a86f473..cb74d13 100644 --- a/src/command.c +++ b/src/command.c @@ -1159,20 +1159,20 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from safe_str(ls, commandraw, &c2); } if (cmd->type & CMD_T_EQSPLIT) { - safe_chr('=', commandraw, &c2); - if (cmd->type & CMD_T_RS_ARGS) { - int rsa_index; - /* This is counterintuitive, but rsa[] - * starts at 1. */ - if (rsa[1]) { - safe_str(rsa[1], commandraw, &c2); - for (rsa_index = 2; rsa[rsa_index]; rsa_index++) { - safe_chr(',', commandraw, &c2); - safe_str(rsa[rsa_index], commandraw, &c2); - } - } - } else { - safe_str(rs, commandraw, &c2); + if(rhs_present) { + safe_chr('=', commandraw, &c2); + if (cmd->type & CMD_T_RS_ARGS) { + int rsa_index; + /* This is counterintuitive, but rsa[] + * starts at 1. */ + if (rsa[1]) { + safe_str(rsa[1], commandraw, &c2); + for (rsa_index = 2; rsa[rsa_index]; rsa_index++) { + safe_chr(',', commandraw, &c2); + safe_str(rsa[rsa_index], commandraw, &c2); + } + } + } } #ifdef NEVER /* We used to do this, but we're not sure why */ @@ -1371,7 +1371,7 @@ int command_lock(const char *name, const char *lock) { * This does nothing more than notify the player * with "This command has not been implemented" */ -COMMAND (cmd_unimplemented) { +COMMAND(cmd_unimplemented) { char *saveregs[NUMQ]; if (strcmp(cmd->name, "UNIMPLEMENTED_COMMAND") != 0 && diff --git a/src/funlist.c b/src/funlist.c index b42af23..9e63d22 100644 --- a/src/funlist.c +++ b/src/funlist.c @@ -42,8 +42,9 @@ static int regrep_helper(dbref who, dbref what, dbref parent, /** Type definition for a qsort comparison function */ typedef int (*comp_func) (const void *, const void *); static void sane_qsort(void **array, int left, int right, comp_func compare); +enum itemfun_op { IF_DELETE, IF_REPLACE, IF_INSERT }; static void do_itemfuns(char *buff, char **bp, char *str, char *num, - char *word, char *sep, int flag); + char *word, char *sep, enum itemfun_op flag); char *iter_rep[MAX_ITERS]; /**< itext values */ int iter_place[MAX_ITERS]; /**< inum numbers */ @@ -2335,11 +2336,11 @@ FUNCTION(fun_index) * \param num string containing the element number to operate on. * \param word string to insert/delete/replace. * \param sep separator string. - * \param flag operation to perform: 0 - delete, 1 - replace, 2 - insert + * \param flag operation to perform: IF_DELETE, IF_REPLACE, IF_INSERT */ static void do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, - char *sep, int flag) + char *sep, enum itemfun_op flag) { char c; int el, count, len = -1; @@ -2358,7 +2359,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, c = ' '; /* we can't remove anything before the first position */ - if ((el < 1 && flag != 2) || el == 0) { + if ((el < 1 && flag != IF_INSERT) || el == 0) { safe_str(str, buff, bp); return; } @@ -2408,7 +2409,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, sptr[-1] = '\0'; switch (flag) { - case 0: + case IF_DELETE: /* deletion */ if (!eptr) { /* last element in the string */ if (el != 1) @@ -2421,7 +2422,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, safe_str(eptr, buff, bp); } break; - case 1: + case IF_REPLACE: /* replacing */ if (!eptr) { /* last element in string */ if (el != 1) { @@ -2439,7 +2440,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, safe_str(eptr, buff, bp); } break; - case 2: + case IF_INSERT: /* insertion */ if (sptr == str) { /* first element in string */ safe_str(word, buff, bp); @@ -2449,8 +2450,10 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word, safe_str(str, buff, bp); safe_chr(c, buff, bp); safe_str(word, buff, bp); - safe_chr(c, buff, bp); - safe_str(sptr, buff, bp); + if (sptr && *sptr) { /* Don't add an osep to the end of the list */ + safe_chr(c, buff, bp); + safe_str(sptr, buff, bp); + } } break; } @@ -2462,7 +2465,7 @@ FUNCTION(fun_ldelete) { /* delete a word at position X of a list */ - do_itemfuns(buff, bp, args[0], args[1], NULL, args[2], 0); + do_itemfuns(buff, bp, args[0], args[1], NULL, args[2], IF_DELETE); } /* ARGSUSED */ @@ -2470,7 +2473,7 @@ FUNCTION(fun_replace) { /* replace a word at position X of a list */ - do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], 1); + do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], IF_REPLACE); } /* ARGSUSED */ @@ -2478,7 +2481,7 @@ FUNCTION(fun_insert) { /* insert a word at position X of a list */ - do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], 2); + do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], IF_INSERT); } /* ARGSUSED */ diff --git a/src/funtime.c b/src/funtime.c index 049c3ca..82dee0e 100644 --- a/src/funtime.c +++ b/src/funtime.c @@ -127,17 +127,17 @@ FUNCTION(fun_time) } else { /* Always make time(player) return a time, * even if player's TZ is unset or wonky */ - a = atr_get(thing, "TZ"); - if (a) { - ptr = atr_value(a); - if(is_strict_number(ptr)) { - utc = 1; - tz = strtod(ptr, NULL); - if (tz >= -24.0 || tz <= 24.0) { - mytime += (int) (tz * 3600); - } - } else setenv("TZ", ptr, 1); - } + a = atr_get(thing, "TZ"); + if (a) { + ptr = atr_value(a); + if(is_strict_number(ptr)) { + utc = 1; + tz = strtod(ptr, NULL); + if (tz >= -24.0 && tz <= 24.0) { + mytime += (int) (tz * 3600); + } + } else setenv("TZ", ptr, 1); + } } } } else if (!strcmp("UTCTIME", called_as)) { @@ -205,16 +205,6 @@ FUNCTION(fun_etimefmt) } -/* ARGSUSED */ -FUNCTION(fun_stringsecs) -{ - int secs; - if (etime_to_secs(args[0], &secs)) - safe_integer(secs, buff, bp); - else - safe_str(T("#-1 INVALID TIMESTRING"), buff, bp); -} - /** Convert an elapsed time string (3d 2h 1m 10s) to seconds. * \param str1 a time string. * \param secs pointer to an int to fill with number of seconds. @@ -273,6 +263,61 @@ etime_to_secs(char *str1, int *secs) } +/* ARGSUSED */ +FUNCTION(fun_stringsecs) +{ + /* parse the result from timestring() back into a number of seconds */ + + int secs = 0; + char *str1 = args[0]; + char str2[BUFFER_LEN]; + int i; + + while (str1 && *str1) { + while (*str1 == ' ') + str1++; + i = 0; + while (isdigit((unsigned char) *str1)) { + str2[i] = *str1; + str1++; + i++; + } + if (i == 0) { + safe_str(T("#-1 INVALID TIMESTRING"), buff, bp); // no numbers + return; + } + str2[i] = '\0'; + if (!*str1) { + secs += parse_integer(str2); // no more chars, just add seconds and stop + break; + } + switch (*str1) { + case 'd': + case 'D': + secs += (parse_integer(str2) * 86400); // days + break; + case 'h': + case 'H': + secs += (parse_integer(str2) * 3600); // hours + break; + case 'm': + case 'M': + secs += (parse_integer(str2) * 60); // minutes + break; + case 's': + case 'S': + case ' ': + secs += parse_integer(str2); // seconds + break; + default: + safe_str(T("#-1 INVALID TIMESTRING"), buff, bp); + return; + } + str1++; // move past the time char + } + safe_integer(secs, buff, bp); +} + /* ARGSUSED */ FUNCTION(fun_timestring) { diff --git a/src/game.c b/src/game.c index f87656e..6f27b77 100644 --- a/src/game.c +++ b/src/game.c @@ -1994,7 +1994,7 @@ linux_uptime(dbref player __attribute__ ((__unused__))) { struct tm *t; t = localtime(&mudtime); - strftime(tbuf1, sizeof tbuf1, "%I:%M%p ", t); + strftime(tbuf1, sizeof tbuf1, "Server uptime: %I:%M%p ", t); nl = tbuf1 + strlen(tbuf1); } /* System uptime */ @@ -2252,6 +2252,14 @@ do_uptime(dbref player, int mortal) (options.warn_counter - mudtime) % 60, tbuf1); } + notify_format(player, + T + ("PennMUSH Uptime: %ld days %ld hours %ld minutes %ld seconds"), + (mudtime - globals.first_start_time) / 86400, + ((mudtime - globals.first_start_time) % 86400) / 3600, + (((mudtime - globals.first_start_time) % 86400) % 3600) / 60, + (((mudtime - globals.first_start_time) % 86400) % 3600) % 60); + /* Mortals, go no further! */ if (!Site(player) || mortal) return; diff --git a/src/lock.c b/src/lock.c index abe946c..90df30a 100644 --- a/src/lock.c +++ b/src/lock.c @@ -806,6 +806,47 @@ eval_lock(dbref player, dbref thing, lock_type ltype) return eval_boolexp(player, getlock(thing, ltype), thing, NULL); } +/** Evaluate a lock. + * Evaluate lock ltype on thing for player, passing dbrefs for %0/%1. + * \param player dbref attempting to pass the lock. + * \param thing object containing the lock. + * \param ltype type of lock to check. + * \retval 1 player passes the lock. + * \retval 0 player does not pass the lock. + */ +int +eval_lock_with(dbref player, dbref thing, lock_type ltype, dbref env0, + dbref env1) +{ + char *myenv[10] = { NULL }; + char e0[SBUF_LEN], e1[SBUF_LEN], *ep; + char *preserves[10]; + int result; + + if (env0 != NOTHING) { + ep = e0; + safe_dbref(env0, e0, &ep); + *ep = '\0'; + myenv[0] = e0; + } + + if (env1 != NOTHING) { + ep = e1; + safe_dbref(env1, e1, &ep); + *ep = '\0'; + myenv[1] = e1; + } + + save_global_env("eval_lock_save", preserves); + restore_global_env("eval_lock", myenv); + + boolexp b = getlock(thing, ltype); + log_activity(LA_LOCK, thing, unparse_boolexp(player, b, UB_DBREF)); + result = eval_boolexp(player, b, thing, NULL); + restore_global_env("eval_lock_save", preserves); + return result; +} + /** Active a lock's failure attributes. * \param player dbref failing to pass the lock. * \param thing object containing the lock. diff --git a/src/look.c b/src/look.c index 1dc79e4..9ccf057 100644 --- a/src/look.c +++ b/src/look.c @@ -79,13 +79,14 @@ look_exits(dbref player, dbref loc, const char *exit_name) a = atr_get(loc, "EXITFORMAT"); if (a) { char *wsave[10], *rsave[NUMQ]; - char *arg, *buff, *bp, *save; + char *arg, *arg2, *buff, *bp, *save; char const *sp; int j; arg = (char *) mush_malloc(BUFFER_LEN, "string"); + arg2 = (char *) mush_malloc(BUFFER_LEN, "string"); buff = (char *) mush_malloc(BUFFER_LEN, "string"); - if (!arg || !buff) + if (!arg || !buff || !arg2) mush_panic("Unable to allocate memory in look_exits"); save_global_regs("look_exits", rsave); for (j = 0; j < 10; j++) { @@ -126,6 +127,7 @@ look_exits(dbref player, dbref loc, const char *exit_name) mush_free((Malloc_t) tbuf2, "string"); mush_free((Malloc_t) nbuf, "string"); mush_free((Malloc_t) arg, "string"); + mush_free((Malloc_t) arg2, "string"); mush_free((Malloc_t) buff, "string"); return; } diff --git a/src/move.c b/src/move.c index 75b9079..7f89693 100644 --- a/src/move.c +++ b/src/move.c @@ -303,8 +303,7 @@ can_move(dbref player, const char *direction) { int ok; if (!strcasecmp(direction, "home")) { - ok = !Fixed(player); - ok = ok && command_check_byname(player, "HOME"); + ok = command_check_byname(player, "HOME"); } else { /* otherwise match on exits - don't use GoodObject here! */ ok = (match_result(player, direction, TYPE_EXIT, MAT_ENGLISH | MAT_EXIT) != diff --git a/src/notify.c b/src/notify.c index ee9097d..a260e8e 100644 --- a/src/notify.c +++ b/src/notify.c @@ -972,12 +972,11 @@ notify_anything_loc(dbref speaker, na_lookup func, } } /* if object is flagged LISTENER, check for ^ listen patterns - * * these are like AHEAR - object cannot trigger itself. * * unlike normal @listen, don't pass the message on. * */ - if ((speaker != target) && (ThingListen(target) || RoomListen(target)) - && eval_lock(speaker, target, Listen_Lock) + if ((ThingListen(target) || RoomListen(target)) + && eval_lock(speaker, target, Listen_Lock) ) atr_comm_match(target, speaker, '^', ':', (char *) notify_makestring(msgbuf, messages, NA_ASCII), 0, diff --git a/src/parse.c b/src/parse.c index 4d755fd..3f8e217 100644 --- a/src/parse.c +++ b/src/parse.c @@ -653,71 +653,50 @@ process_expression(char *buff, char **bp, char const **str, break; case '$': /* Dollar subs for regedit() */ if ((eflags & (PE_DOLLAR | PE_EVALUATE)) == (PE_DOLLAR | PE_EVALUATE) && - global_eval_context.re_subpatterns >= 0) { - char obuf[BUFFER_LEN]; - int p = 0; + global_eval_context.re_subpatterns >= 0 && + global_eval_context.re_offsets != NULL && + global_eval_context.re_from != NULL) { + char obuf[BUFFER_LEN]; + int p = -1; char subspace[BUFFER_LEN]; char *named_substring = NULL; obuf[0] = '\0'; - (*str)++; - /* Check the first two characters after the $ for a number */ - if (isdigit((unsigned char) **str)) { - p = **str - '0'; - (*str)++; - if (isdigit((unsigned char) **str)) { - p *= 10; - p += **str - '0'; - (*str)++; - if (isdigit((unsigned char) **str)) { - /* More than 100. Treat this as literal. */ - safe_chr('$', buff, bp); - safe_number(p, buff, bp); - } - } - /* Look for a named subexpression */ - } else if (**str == '<') { - char *nbuf = subspace; - (*str)++; - for (; *str && **str != '>'; (*str)++) - safe_chr(**str, subspace, &nbuf); - *nbuf = '\0'; - if (*str) - (*str)++; - if (is_strict_integer(subspace)) - p = abs(parse_integer(subspace)); - else - named_substring = subspace; - } else { - safe_chr('$', buff, bp); - break; - } - - if ((!named_substring && p >= global_eval_context.re_subpatterns) || - global_eval_context.re_offsets == NULL || - global_eval_context.re_from == NULL) { - /* It's out of bounds, return */ - safe_chr('$', buff, bp); - if (named_substring) - safe_format(buff, bp, "<%s>", named_substring); - else - safe_integer(p, buff, bp); - break; - } + (*str)++; + /* Check the first two characters after the $ for a number */ + if (isdigit((unsigned char) **str)) { + p = **str - '0'; + (*str)++; + } else if (**str == '<') { + char *nbuf = subspace; + (*str)++; + for (; *str && **str && **str != '>'; (*str)++) + safe_chr(**str, subspace, &nbuf); + *nbuf = '\0'; + if (*str && **str) + (*str)++; + if (is_strict_integer(subspace)) + p = abs(parse_integer(subspace)); + else + named_substring = subspace; + } else { + safe_chr('$', buff, bp); + break; + } - if (named_substring) { - pcre_copy_named_substring(global_eval_context.re_code, - global_eval_context.re_from, - global_eval_context.re_offsets, - global_eval_context.re_subpatterns, - named_substring, obuf, BUFFER_LEN); - } else { - pcre_copy_substring(global_eval_context.re_from, - global_eval_context.re_offsets, - global_eval_context.re_subpatterns, - p, obuf, BUFFER_LEN); - } - safe_str(obuf, buff, bp); + if (named_substring) { + pcre_copy_named_substring(global_eval_context.re_code, + global_eval_context.re_from, + global_eval_context.re_offsets, + global_eval_context.re_subpatterns, + named_substring, obuf, BUFFER_LEN); + } else { + pcre_copy_substring(global_eval_context.re_from, + global_eval_context.re_offsets, + global_eval_context.re_subpatterns, + p, obuf, BUFFER_LEN); + } + safe_str(obuf, buff, bp); } else { safe_chr('$', buff, bp); (*str)++; diff --git a/src/wiz.c b/src/wiz.c index 3673375..1efd2dc 100644 --- a/src/wiz.c +++ b/src/wiz.c @@ -399,9 +399,9 @@ do_teleport(dbref player, const char *arg1, const char *arg2, int silent, */ if (player == victim) { if (Fixed(victim) || RPMODE(victim)) - notify(player, T("You can't do that IC!")); - else - safe_tel(victim, HOME, silent); + notify(player, T("You can't do that IC!")); + else if(command_check_byname(victim, "HOME")) + safe_tel(victim, HOME, silent); return; } else destination = Home(victim); @@ -1995,7 +1995,8 @@ raw_search(dbref player, const char *owner, int nargs, const char **args, } if ((spec.owner != ANY_OWNER && spec.owner != Owner(player) - && !(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER)))) { + && !(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER)) || + (ZMaster(spec.owner) && eval_lock(player, spec.owner, Zone_Lock)))) { giveto(player, FIND_COST); notify(player, T("You need a search warrant to do that.")); return -1; -- 2.30.2