AC_CHECK_LIB(crypt, crypt)
LIB_SOCKET_NSL
AC_CHECK_LIB(fam, FAMOpen)
-AC_CHECK_LIB(z, gzungetc)
+
+
+AC_ARG_ENABLE(zlib, AS_HELP_STRING([--disable-zlib], [Don't use zlib for database compression.]),
+ enable_zlib=$enableval, enable_zlib=yes)
+if test "$enable_zlib" = "yes"; then
+ AC_CHECK_LIB(z, gzungetc)
+fi
# with_ssl=set
CHECK_SSL
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#include <inttypes.h>
#elif defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned int uint32_t;
-typedef unsigned __int64 uint64_t;
#define inline __inline
#else
#include <inttypes.h>
void list_locks(char *buff, char **bp, const char *name);
const char *lock_flags(lock_list *ll);
const char *lock_flags_long(lock_list *ll);
+void list_lock_flags(char *buff, char **bp);
+void list_lock_flags_long(char *buff, char **bp);
+lock_list *getlockstruct(dbref thing, lock_type type);
void check_zone_lock(dbref player, dbref zone, int noisy);
void define_lock(lock_type name, privbits flags);
#define L_FLAGS(lock) ((lock)->flags)
#define DBF_DIVISIONS 0x40000
#define DBF_LABELS 0x100000
#define DBF_SPIFFY_AF_ANSI 0x200000
-
+#define DBF_HEAR_CONNECT 0x400000
/* CobraMUSH Specific DBF Flags */
#define DBF_NEW_ATR_LOCK 0x200000
bool is_integer(char const *str);
bool is_uinteger(char const *str);
+bool is_strict_uinteger(const char *str);
bool is_boolean(char const *str);
/* Split a sep-delimited string into individual elements */
int nptrs = 0, i;
ap = (ATTR *) ptab_firstentry(&ptab_attrib);
+ ptrs[0] = "";
while (ap) {
ptrs[nptrs++] = AL_NAME(ap);
ap = (ATTR *) ptab_nextentry(&ptab_attrib);
parent_depth = GoodObject(Parent(thing));
} else {
flag_mask = AF_LISTEN;
- if (ThingInhearit(thing) || RoomInhearit(thing)) {
+ if (has_flag_by_name
+ (thing, "LISTEN_PARENT", TYPE_PLAYER | TYPE_THING | TYPE_ROOM)) {
parent_depth = GoodObject(Parent(thing));
} else {
parent_depth = 0;
shutdown_checkpoint();
#endif
WSACleanup(); /* clean up */
-#else
- exit(0);
#endif
+ exit(0);
}
#endif /* BOOLEXP_DEBUGGING */
}
}
+#ifdef WIN32
+#pragma warning( disable : 4761) /* Disable bogus conversion warning */
+#endif
+/* ARGSUSED */
+FUNCTION(fun_hidden)
+{
+ dbref it = match_thing(executor, args[0]);
+ if (CanSee(executor, it) && ((Admin(executor) ||
+ Location(executor) == Location(it) || Location(it) == executor))) {
+ if ((it == NOTHING) || (!IsPlayer(it))) {
+ notify(executor, T("Couldn't find that player."));
+ safe_str("#-1", buff, bp);
+ return;
+ }
+ safe_boolean(hidden(it), buff, bp);
+ return;
+ } else {
+ notify(executor, T("Permission denied."));
+ safe_str("#-1", buff, bp);
+ return;
+ }
+}
+
+#ifdef WIN32
+#pragma warning( default : 4761) /* Re-enable conversion warning */
+#endif
/** Look up a DESC by character name or file descriptor.
* \param executor the dbref of the object calling the function calling this.
}
COMMAND (cmd_attribute) {
- if (SW_ISSET(sw, SWITCH_ACCESS))
+ if(SW_ISSET(sw, SWITCH_INFO) || !has_power(player, "GFUNCS")) {
+ do_attribute_info(player, arg_left);
+ } else if (SW_ISSET(sw, SWITCH_ACCESS))
do_attribute_access(player, arg_left, arg_right,
SW_ISSET(sw, SWITCH_RETROACTIVE));
else if(SW_ISSET(sw, SWITCH_LOCK)) {
}
else if (SW_ISSET(sw, SWITCH_DELETE))
do_attribute_delete(player, arg_left, SW_ISSET(sw, SWITCH_DEFAULTS));
- else if (SW_ISSET(sw, SWITCH_RENAME))
- do_attribute_rename(player, arg_left, arg_right);
- else
- do_attribute_info(player, arg_left);
+ else if (SW_ISSET(sw, SWITCH_RENAME)) {
+ do_attribute_rename(player, arg_left, arg_right);
+ } else notify(player, "You lost me...");
}
COMMAND(cmd_atrchown)
{
int source = SW_ISSET(sw, SWITCH_SAVE) ? 2 : 1;
if (source == 2) {
- if (!God(player)) {
- /* Only god can alter the original config file. */
- notify(player, T("You can't remake the world in your image."));
- return;
- }
+ if (!God(player)) {
+ /* Only god can alter the original config file. */
+ notify(player, T("You can't remake the world in your image."));
+ return;
+ }
}
if (!config_set(arg_left, arg_right, source, 0)
&& !config_set(arg_left, arg_right, source, 1))
{"@ATRLOCK", "READ WRITE", cmd_atrlock, CMD_T_ANY | CMD_T_EQSPLIT, NULL},
{"@ATRCHOWN", NULL, cmd_atrchown, CMD_T_EQSPLIT, NULL},
{"@ATTRIBUTE", "ACCESS DEFAULTS LOCK WRITE READ DELETE RENAME RETROACTIVE", cmd_attribute,
- CMD_T_ANY | CMD_T_EQSPLIT, "POWER^GFUNCS"},
+ CMD_T_ANY | CMD_T_EQSPLIT, NULL},
{"@BOOT", "PORT ME", cmd_boot, CMD_T_ANY, NULL},
{"@BREAK", NULL, cmd_break, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE, NULL},
#ifdef CHAT_SYSTEM
noevtoken = 1;
p = string + 1;
string = p;
- memmove(global_eval_context.ccom, (char *) global_eval_context.ccom + 1, BUFFER_LEN - 1);
+ memmove(global_eval_context.ccom, (char *) global_eval_context.ccom + 1,
+ BUFFER_LEN - 1);
}
if (*p == '[') {
if ((cmd = command_find("WARN_ON_MISSING"))) {
command_parse_free_args;
return commandraw;
}
-
+
/* Parse out any switches */
sw = SW_ALLOC();
swp = switches;
}
- /* Finish setting up commandraw, if we may need it for hooks */
- if (has_hook(&cmd->hooks.ignore) || has_hook(&cmd->hooks.override)) {
- p = command2;
- if (*p && (*p == ' ')) {
- safe_chr(' ', commandraw, &c2);
- p++;
- }
- if (cmd->type & CMD_T_ARGS) {
- int lsa_index;
- if (lsa[1]) {
- safe_str(lsa[1], commandraw, &c2);
- for (lsa_index = 2; lsa[lsa_index]; lsa_index++) {
- safe_chr(',', commandraw, &c2);
- safe_str(lsa[lsa_index], commandraw, &c2);
- }
- }
- } else {
- safe_str(ls, commandraw, &c2);
+ /* Finish setting up commandraw, for hooks and %u */
+ p = command2;
+ if (attrib) {
+ safe_chr('/', commandraw, &c2);
+ safe_str(swp, commandraw, &c2);
+ }
+ if (*p && (*p == ' ')) {
+ safe_chr(' ', commandraw, &c2);
+ p++;
+ }
+ if (cmd->type & CMD_T_ARGS) {
+ int lsa_index;
+ if (lsa[1]) {
+ safe_str(lsa[1], commandraw, &c2);
+ for (lsa_index = 2; lsa[lsa_index]; lsa_index++) {
+ safe_chr(',', commandraw, &c2);
+ safe_str(lsa[lsa_index], commandraw, &c2);
+ }
}
- if (cmd->type & CMD_T_EQSPLIT) {
- 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);
- }
- }
+ } else {
+ safe_str(ls, commandraw, &c2);
+ }
+ if (cmd->type & CMD_T_EQSPLIT) {
+ 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);
+ }
+ } } else {
+ safe_str(rs, commandraw, &c2);
}
- } else {
- safe_str(rs, commandraw, &c2);
}
+ }
#ifdef NEVER
- /* We used to do this, but we're not sure why */
- process_expression(commandraw, &c2, (const char **) &p, player, realcause,
- cause, noevtoken ? PE_NOTHING :
- ((PE_DEFAULT & ~PE_FUNCTION_CHECK) |
- PE_COMMAND_BRACES), PT_DEFAULT, NULL);
+ /* We used to do this, but we're not sure why */
+ process_expression(commandraw, &c2, (const char **) &p, player, cause,
+ cause, noevtoken ? PE_NOTHING :
+ ((PE_DEFAULT & ~PE_EVALUATE) |
+ PE_COMMAND_BRACES), PT_DEFAULT, NULL);
#endif
- }
- *c2 = '\0';
- }
-
+ *c2 = '\0';
+ mush_strncpy(global_eval_context.ucom, commandraw, BUFFER_LEN);
+
retval = NULL;
if (cmd->func == NULL) {
do_rawlog(LT_ERR, T("No command vector on command %s."), cmd->name);
#include "game.h"
#include "attrib.h"
#include "flags.h"
+#include "function.h"
+#include "case.h"
#include "dbdefs.h"
#include "log.h"
#include "intmap.h"
notify_format(player, T("Queue entry with qid %u updated."), pid);
}
+FUNCTION(fun_pidinfo)
+{
+ char *r, *s;
+ char *osep, osepd[2] = { ' ', '\0' };
+ char *fields, field[80] = "queue player time object attribute command";
+ uint32_t pid;
+ BQUE *q;
+ bool first = true;
+
+ if (!is_uinteger(args[0])) {
+ safe_str(T(e_num), buff, bp);
+ return;
+ }
+
+ pid = parse_uint32(args[0], NULL, 10);
+ q = im_find(queue_map, pid);
+
+ if (!q) {
+ safe_str(T("#-1 INVALID PID"), buff, bp);
+ return;
+ }
+
+ if (!controls(executor, q->player) && !LookQueue(executor)) {
+ safe_str(T(e_perm), buff, bp);
+ return;
+ }
+
+ if ((nargs > 1) && args[1] && *args[1]) {
+ fields = args[1];
+ } else {
+ fields = field;
+ }
+
+ if (nargs == 3)
+ osep = args[2];
+ else {
+ osep = osepd;
+ }
+
+ s = trim_space_sep(fields, ' ');
+ do {
+ r = split_token(&s, ' ');
+ if (string_prefix("queue", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ if (GoodObject(q->sem))
+ safe_str("semaphore", buff, bp);
+ else
+ safe_str("wait", buff, bp);
+ } else if (string_prefix("player", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ safe_dbref(q->player, buff, bp);
+ } else if (string_prefix("time", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ if (q->left == 0)
+ safe_integer(-1, buff, bp);
+ else
+ safe_integer(difftime(q->left, mudtime), buff, bp);
+ } else if (string_prefix("object", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ safe_dbref(q->sem, buff, bp);
+ } else if (string_prefix("attribute", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ if (GoodObject(q->sem)) {
+ safe_str(q->semattr, buff, bp);
+ } else {
+ safe_dbref(NOTHING, buff, bp);
+ }
+ } else if (string_prefix("command", r)) {
+ if (!first)
+ safe_str(osep, buff, bp);
+ first = false;
+ safe_str(q->comm, buff, bp);
+ }
+ } while (s);
+}
+
+FUNCTION(fun_lpids)
+{
+ /* Can be called as LPIDS or GETPIDS */
+ BQUE *tmp;
+ int qmask = 3;
+ dbref thing = -1;
+ dbref player = -1;
+ char *attr = NULL;
+ bool first = true;
+ if (string_prefix(called_as, "LPIDS")) {
+ /* lpids(player[,type]) */
+ if (args[0] && *args[0]) {
+ player = match_thing(executor, args[0]);
+ if (!GoodObject(player)) {
+ safe_str(T(e_notvis), buff, bp);
+ return;
+ }
+ if (!(LookQueue(executor) || (Owner(player) == executor))) {
+ safe_str(T(e_perm), buff, bp);
+ return;
+ }
+ } else if (!LookQueue(executor)) {
+ player = executor;
+ }
+ if ((nargs == 2) && args[1] && *args[1]) {
+ if (*args[1] == 'W' || *args[1] == 'w')
+ qmask = 1;
+ else if (*args[1] == 'S' || *args[1] == 's')
+ qmask = 2;
+ }
+ } else {
+ /* getpids(obj[/attrib]) */
+ qmask = 2; /* semaphores only */
+ attr = strchr(args[0], '/');
+ if (attr)
+ *attr++ = '\0';
+ thing = match_thing(executor, args[0]);
+ if (!GoodObject(thing)) {
+ safe_str(T(e_notvis), buff, bp);
+ return;
+ }
+ if (!(LookQueue(executor) || (controls(executor, thing)))) {
+ safe_str(T(e_perm), buff, bp);
+ return;
+ }
+ }
+
+ if (qmask & 1) {
+ for (tmp = qwait; tmp; tmp = tmp->next) {
+ if (GoodObject(player) && (!Owns(tmp->player, player)))
+ continue;
+ if (!first)
+ safe_chr(' ', buff, bp);
+ safe_integer(tmp->qid, buff, bp);
+ first = false;
+ }
+ }
+ if (qmask & 2) {
+ for (tmp = qsemfirst; tmp; tmp = tmp->next) {
+ if (GoodObject(player) && (!Owns(tmp->player, player)))
+ continue;
+ if (GoodObject(thing) && (tmp->sem != thing))
+ continue;
+ if (attr && *attr && strcasecmp(tmp->semattr, attr))
+ continue;
+ if (!first)
+ safe_chr(' ', buff, bp);
+ safe_integer(tmp->qid, buff, bp);
+ first = false;
+ }
+ }
+}
+
+
static void
show_queue(dbref player, dbref victim, int q_type, int q_quiet, int q_all,
BQUE * q_ptr, int *tot, int *self, int *del)
}
add_to(QUEUE_PER_OWNER ? Owner(player) : player, num);
-
if (ncom && *ncom) {
int j;
for (j = 0; j < 10; j++)
turn comes up (Or show it in @ps, etc.). Exception is for
semaphores, which otherwise might wait forever. */
q->player = NOTHING;
-
if (q->semattr) {
BQUE *last = NULL, *tmp;
-
for (tmp = qsemfirst; tmp; last = tmp, tmp = tmp->next) {
if (tmp == q) {
if (last)
last->next = tmp->next;
else
qsemfirst = tmp->next;
-
if (qsemlast == tmp)
qsemlast = last;
-
break;
}
}
}
-
/** Halt all objects in the database.
* \param player the enactor.
*/
do_allrestart(dbref player)
{
dbref thing;
-
if (!HaltAny(player)) {
notify(player, T("You do not have the power to restart the world."));
return;
}
if (IsPlayer(thing)) {
notify_format(thing,
- T("Your objects are being globally restarted by %s"),
+ T
+ ("Your objects are being globally restarted by %s"),
Name(player));
}
}
dbref victim;
{
dbref thing;
-
if (IsPlayer(victim)) {
for (thing = 0; thing < db_top; thing++) {
if ((Owner(thing) == victim) && !IsGarbage(thing)
dbref loc =
(pseudo !=
- NOTHING) ? pseudo : (IsExit(player) ? Source(player) : Location(player));
+ NOTHING) ? pseudo : (IsExit(player) ? Source(player) : (IsRoom(player) ?
+ player :
+ Location(player)));
dbref new_exit;
if (!command_check_byname(player, "@dig")) {
notify(player, "Permission denied.");
clone = new_object();
+ /* Need to figure out why this is here. */
memcpy(REFDB(clone), REFDB(thing), sizeof(struct object));
Owner(clone) = Owner(player);
+ Name(clone) = NULL;
if (newname && *newname)
set_name(clone, newname);
else
dbflag += DBF_DIVISIONS;
dbflag += DBF_LABELS;
dbflag += DBF_SPIFFY_AF_ANSI;
+ dbflag += DBF_HEAR_CONNECT;
do_rawlog(LT_CHECK, "PARANOID WRITE BEGINNING...\n");
if (IsPlayer(i)) {
add_player(i);
clear_flag_internal(i, "CONNECTED");
+ /* If it has the MONITOR flag and the db predates HEAR_CONNECT, swap them over */
+ if (!(globals.indb_flags & DBF_HEAR_CONNECT) &&
+ has_flag_by_name(i, "MONITOR", NOTYPE)) {
+ clear_flag_internal(i, "MONITOR");
+ set_flag_internal(i, "HEAR_CONNECT");
+ }
}
break;
if (IsPlayer(i)) {
add_player(i);
clear_flag_internal(i, "CONNECTED");
+ /* If it has the MONITOR flag and the db predates HEAR_CONNECT, swap them over */
+ if (!(globals.indb_flags & DBF_HEAR_CONNECT) &&
+ has_flag_by_name(i, "MONITOR", NOTYPE)) {
+ clear_flag_internal(i, "MONITOR");
+ set_flag_internal(i, "HEAR_CONNECT");
+ }
}
}
break;
{"LIST", fun_list, 1, 1, FN_REG},
{"LIT", fun_lit, 1, -1, FN_LITERAL},
{"LJUST", fun_ljust, 2, 3, FN_REG},
+ {"LLOCKFLAGS", fun_lockflags, 0, 1, FN_REG},
+ {"LLOCKS", fun_locks, 1, 1, FN_REG},
{"LMATH", fun_lmath, 2, 3, FN_REG},
{"LNUM", fun_lnum, 1, 3, FN_REG},
{"LOC", fun_loc, 1, 1, FN_REG},
{"LOCALIZE", fun_localize, 1, 1, FN_NOPARSE},
{"LOCATE", fun_locate, 3, 3, FN_REG},
{"LOCK", fun_lock, 1, 2, FN_REG},
+ {"LOCKFLAGS", fun_lockflags, 0, 1, FN_REG},
+ {"LOCKOWNER", fun_lockowner, 1, 1, FN_REG},
+ {"LOCKS", fun_locks, 1, 1, FN_REG},
{"LPARENT", fun_lparent, 1, 1, FN_REG},
{"LPLAYERS", fun_dbwalker, 1, 1, FN_REG},
{"LPORTS", fun_lports, 0, 1, FN_REG},
return;
}
safe_str(privs_to_letters(attr_privs_view, AL_FLAGS(a)), buff, bp);
- if (atr_sub_branch(a))
- safe_chr('`', buff, bp);
} else {
/* Object flags, visible to all */
safe_str(unparse_flags(thing, executor), buff, bp);
return upcasestr(str);
}
+/* ARGSUSED */
+FUNCTION(fun_locks)
+{
+ dbref thing = match_thing(executor, args[0]);
+ lock_list *ll;
+ const lock_list *p;
+ int first = 1;
+
+ if (!GoodObject(thing)) {
+ safe_str(T(e_notvis), buff, bp);
+ return;
+ }
+
+ for (ll = Locks(thing); ll; ll = ll->next) {
+ p = get_lockproto(L_TYPE(ll));
+ if (!first) {
+ safe_chr(' ', buff, bp);
+ }
+ first = 0;
+ if (!p)
+ safe_str("USER:", buff, bp);
+ safe_str(L_TYPE(ll), buff, bp);
+ }
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lockflags)
+{
+ dbref it;
+ char *p;
+ int fullname = 0;
+ lock_list *ll;
+ lock_type ltype;
+
+ if (called_as[1] == 'L') /* LLOCKFLAGS */
+ fullname = 1;
+
+ if (nargs == 0) {
+ if (fullname)
+ list_lock_flags_long(buff, bp);
+ else
+ list_lock_flags(buff, bp);
+ return;
+ }
+
+ if ((p = strchr(args[0], '/')))
+ *(p++) = '\0';
+
+ it = match_thing(executor, args[0]);
+ if (!GoodObject(it)) {
+ safe_str(T(e_notvis), buff, bp);
+ return;
+ }
+ ltype = get_locktype(p);
+
+ if (GoodObject(it) && (ltype !=NULL)
+ &&Can_Read_Lock(executor, it, ltype)) {
+ ll = getlockstruct(it, ltype);
+ if (ll) {
+ if (fullname)
+ safe_str(lock_flags_long(ll), buff, bp);
+ else
+ safe_str(lock_flags(ll), buff, bp);
+ return;
+ } else {
+ safe_str("#-1 NO SUCH LOCK", buff, bp);
+ return;
+ }
+ }
+ safe_str("#-1 NO SUCH LOCK", buff, bp);
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lockowner)
+{
+ dbref it;
+ char *p;
+ lock_type ltype;
+ lock_list *ll;
+
+ if ((p = strchr(args[0], '/')))
+ *(p++) = '\0';
+
+ it = match_thing(executor, args[0]);
+ if (!GoodObject(it)) {
+ safe_str(T(e_notvis), buff, bp);
+ return;
+ }
+ ltype = get_locktype(p);
+ if (ltype == NULL || !Can_Read_Lock(executor, it, ltype)) {
+ safe_str(T("#-1 NO SUCH LOCK"), buff, bp);
+ return;
+ }
+ ll = getlockstruct(it, ltype);
+ if (ll)
+ safe_dbref(L_CREATOR(ll), buff, bp);
+ else
+ safe_str(T("#-1 NO SUCH LOCK"), buff, bp);
+
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lset)
+{
+ if (!FUNCTION_SIDE_EFFECTS) {
+ safe_str(T(e_disabled), buff, bp);
+ return;
+ }
+ if (!command_check_byname(executor, "@lset") || fun->flags & FN_NOSIDEFX) {
+ safe_str(T(e_perm), buff, bp);
+ return;
+ }
+ do_lset(executor, args[0], args[1]);
+}
+
/* ARGSUSED */
FUNCTION(fun_lock)
{
s = trim_space_sep(args[0], sep);
word_count = do_wordcount(s, sep);
+
+ if (word_count == 0)
+ return;
+ else if (word_count == 1) {
+ safe_strl(args[0], arglens[0], buff, bp);
+ return;
+ }
+
word_index = get_random32(0, word_count - 1);
/* Go to the start of the token we're interested in. */
char *s, *t;
char sep;
int el;
+ char needle[BUFFER_LEN], haystack[BUFFER_LEN];
if (!delim_check(buff, bp, nargs, args, 3, &sep))
return;
safe_str(T("#-1 CAN ONLY TEST ONE ELEMENT"), buff, bp);
return;
}
- s = trim_space_sep(args[0], sep);
+
+ strncpy(haystack, remove_markup(args[0], NULL), BUFFER_LEN);
+ strncpy(needle, remove_markup(args[1], NULL), BUFFER_LEN);
+
+ s = trim_space_sep(haystack, sep);
el = 1;
do {
t = split_token(&s, sep);
- if (!strcmp(args[1], t)) {
+ if (!strcmp(needle, t)) {
safe_integer(el, buff, bp);
return;
}
while (ptr && *ptr) {
if (*ptr == '-') {
isnegative = 1;
+ ptr++;
continue;
}
n *= from;
/* ARGSUSED */
FUNCTION(fun_rand)
{
- /*
- * Uses Sh'dow's random number generator, found in utils.c. Better
- * distribution than original, w/ minimal speed losses.
- */
- int low, high;
- if (!is_integer(args[0])) {
- safe_str(T(e_int), buff, bp);
+ uint32_t low, high;
+ if (!is_strict_uinteger(args[0])) {
+ safe_str(T(e_uint), buff, bp);
return;
}
if (nargs == 1) {
low = 0;
- high = parse_integer(args[0]) - 1;
+ high = parse_uinteger(args[0]);
+ if (high == 0) {
+ safe_str(T(e_range), buff, bp);
+ return;
+ }
+ high -= 1;
} else {
- if (!is_integer(args[1])) {
- safe_str(T(e_ints), buff, bp);
+ if (!is_strict_uinteger(args[1])) {
+ safe_str(T(e_uints), buff, bp);
return;
}
- low = parse_integer(args[0]);
- high = parse_integer(args[1]);
+ low = parse_uinteger(args[0]);
+ high = parse_uinteger(args[1]);
}
if (low > high) {
return;
}
- safe_integer(get_random32(low, high), buff, bp);
+ safe_uinteger(get_random32(low, high), buff, bp);
}
/* ARGSUSED */
return 1;
}
-
FUNCTION(fun_align)
{
int nline;
safe_str(T("#-1 TOO MANY COLUMNS FOR ALIGN"), buff, bp);
return;
}
- if (nargs < (ncols + 1) || nargs > (ncols + 4)) {
- safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
- return;
- }
- if (nargs >= (ncols + 2)) {
- if (!args[ncols + 1] || strlen(args[ncols + 1]) > 1) {
- safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+ if (strcmp(called_as, "LALIGN")) {
+ /* each column is a separate arg */
+ if (nargs < (ncols + 1) || nargs > (ncols + 4)) {
+ safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
return;
}
- if (*args[ncols + 1]) {
- filler = *(args[ncols + 1]);
+ if (nargs >= (ncols + 2)) {
+ if (!args[ncols + 1] || strlen(args[ncols + 1]) > 1) {
+ safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+ return;
+ }
+ if (*args[ncols + 1]) {
+ filler = *(args[ncols + 1]);
+ }
+ }
+ if (nargs >= (ncols + 3)) {
+ fieldsep = args[ncols + 2];
+ }
+ if (nargs >= (ncols + 4)) {
+ linesep = args[ncols + 3];
}
- }
- if (nargs >= (ncols + 3)) {
- fieldsep = args[ncols + 2];
- }
- if (nargs >= (ncols + 4)) {
- linesep = args[ncols + 3];
- }
- fslen = strlen(fieldsep);
- lslen = strlen(linesep);
+ fslen = strlen(fieldsep);
+ lslen = strlen(linesep);
- for (i = 0; i < MAX_COLS; i++) {
- as[i] = NULL;
- }
- for (i = 0; i < ncols; i++) {
- as[i] = parse_ansi_string(args[i + 1]);
- ptrs[i] = as[i]->text;
+ for (i = 0; i < MAX_COLS; i++) {
+ as[i] = NULL;
+ }
+ for (i = 0; i < ncols; i++) {
+ as[i] = parse_ansi_string(args[i + 1]);
+ ptrs[i] = as[i]->text;
+ }
+ } else {
+ /* columns are in args[1] as an args[2]-separated list */
+ char delim, *s;
+ if (!delim_check(buff, bp, nargs, args, 3, &delim))
+ return;
+ if (do_wordcount(args[1], delim) != ncols) {
+ safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
+ return;
+ }
+ if (nargs > 3) {
+ if (!args[3] || strlen(args[3]) > 1) {
+ safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+ return;
+ }
+ if (*args[3])
+ filler = *(args[3]);
+ }
+ if (nargs > 4)
+ fieldsep = args[4];
+ if (nargs > 5)
+ linesep = args[5];
+
+ fslen = strlen(fieldsep);
+ lslen = strlen(linesep);
+
+ for (i = 0; i < MAX_COLS; i++) {
+ as[i] = NULL;
+ }
+ s = trim_space_sep(args[1], delim);
+ for (i = 0; i < ncols; i++) {
+ as[i] = parse_ansi_string(split_token(&s, delim));
+ ptrs[i] = as[i]->text;
+ }
}
nline = 0;
strcpy(unp, command);
cptr = command_parse(player, cause, realcause, command, from_port);
- strcpy(global_eval_context.ucom, (cptr ? cptr : ""));
if (cptr) {
+ mush_strncpy(global_eval_context.ucom, cptr, BUFFER_LEN);
a = 0;
if (!Gagged(player)) {
if (Mobile(player)) {
/* If a monitor flag is set on a room or thing, it's a listener.
* Otherwise not (even if ^patterns are present)
*/
- return (ThingListen(thing) || RoomListen(thing));
+ return has_flag_by_name(thing, "MONITOR", NOTYPE);
}
/** Reset all players' money.
pf->type = PFT_GZFILE;
pf->handle.g = gzopen(filename, "rb");
if (!pf->handle.g) {
- do_rawlog(LT_ERR, "Unable to open %s with libz: %s\n", filename, strerror(errno));
+ do_rawlog(LT_ERR, "Unable to open %s with libz: %s\n", filename,
+ strerror(errno));
mush_free(pf, "pennfile");
longjmp(db_err, 1);
}
static lock_type check_lock_type(dbref player, dbref thing, lock_type name);
static int delete_lock(dbref player, dbref thing, lock_type type);
static int can_write_lock(dbref player, dbref thing, lock_list *lock);
-static lock_list *getlockstruct(dbref thing, lock_type type);
static lock_list *getlockstruct_noparent(dbref thing, lock_type type);
slab *lock_slab = NULL;
extern int unparsing_boolexp;
+lock_list *getlockstruct(dbref thing, lock_type type);
+
/** Return a list of all available locks
* \param buff the buffer
* \param bp a pointer to the current position in the buffer
return privs_to_letters(lock_privs, L_FLAGS(ll));
}
+/** List all lock flag characters on a buffer
+ * \param buff The buffer
+ * \param bp Pointer to a position in the buffer.
+ */
+
+void
+list_lock_flags(char *buff, char **bp)
+{
+ int i;
+ for (i = 0; lock_privs[i].name; i++) {
+ if (lock_privs[i].letter)
+ safe_chr(lock_privs[i].letter, buff, bp);
+ }
+}
+
+/** List all lock flag names on a buffer
+ * \param buff The buffer
+ * \param bp Pointer to a position in the buffer.
+ */
+
+void
+list_lock_flags_long(char *buff, char **bp)
+{
+ int i;
+ int first = 1;
+ for (i = 0; lock_privs[i].name; i++) {
+ if (!first)
+ safe_chr(' ', buff, bp);
+ first = 0;
+ safe_str(lock_privs[i].name, buff, bp);
+ }
+}
+
/** Return a list of lock flag names.
* \param ll pointer to a lock.
* \return string of lock flag names, space-separated.
return L_KEY(ll);
}
-static lock_list *
+lock_list *
getlockstruct(dbref thing, lock_type type)
{
lock_list *ll;
* \param ovector the offset vectors
* \param stringcount the number of subpatterns
* \param stringnumber the number of the desired subpattern
+ * \param nonempty if true, copy empty registers as well.
* \param buff buffer to copy the subpattern to
* \param bp pointer to the end of buffer
* \return size of subpattern, or -1 if unknown pattern
* \param ovector the offset vectors
* \param stringcount the number of subpatterns
* \param stringname the name of the desired subpattern
+ * \param nonempty if true, copy empty registers as well.
* \param buff buffer to copy the subpattern to
* \param bp pointer to the end of buffer
* \return size of subpattern, or -1 if unknown pattern
if (bind(s, server->ai_addr, server->ai_addrlen) == 0)
break; /* Success */
+#ifdef WIN32
+ if (WSAGetLastError() == WSAEADDRINUSE) {
+#else
+ if (errno == EADDRINUSE) {
+#endif
+ fprintf(stderr,
+ "Another process (Possibly another copy of this mush?) appears to be using port %hu. Aborting.\n",
+ port);
+ exit(1);
+ }
+
penn_perror("binding stream socket (Possibly ignorable)");
closesocket(s);
} while ((server = server->ai_next) != NULL);
* * unlike normal @listen, don't pass the message on.
* */
- if ((ThingListen(target) || RoomListen(target))
+ if ((has_flag_by_name(target, "MONITOR", NOTYPE))
&& eval_lock(speaker, target, Listen_Lock)
)
atr_comm_match(target, speaker, '^', ':',
return 1;
}
+/** Is string really an unsigned integer?
+ * \param str string to check.
+ * \retval 1 string is an uinteger.
+ * \retval 0 string is not an uinteger.
+ */
+bool
+is_strict_uinteger(const char *str)
+{
+ char *end;
+
+ if (!str)
+ return 0;
+ /* strtoul() accepts negative numbers, so we still have to do this check */
+ while (isspace((unsigned char) *str))
+ str++;
+ if (*str == '\0')
+ return 0;
+ if (!(isdigit((unsigned char) *str) || *str == '+'))
+ return 0;
+ errno = 0;
+ parse_uint(str, &end, 10);
+ if (errno == ERANGE || *end != '\0')
+ return 0;
+ return 1;
+}
+
/** Is string a number by the strict definition?
* A strict number is a non-null string that passes strtod.
* \param str string to check.
+
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
const char ***listptr);
+
pcre_get_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, const char **stringptr);
+
pcre_get_named_substring(const pcre * code, const char *subject, int *ovector,
int stringcount, const char *stringname,
const char **stringptr);
+
compile_regex(int, int, int *, uschar **, const uschar **, int *, BOOL, int,
int *, int *, branch_chain *, compile_data *);
ok_password(const char *password)
{
const unsigned char *scan;
+ if (password == NULL)
+ return 0;
+
if (*password == '\0')
return 0;
* \param newname new name for object.
*/
void
-do_name(dbref player, const char *name, char *newname)
+do_name(dbref player, const char *name, char *newname_)
{
dbref thing;
char *eon; /* End Of Name */
+ char *bon; /* Beginning of name*/
char *myenv[10];
int i;
-
- newname = trim_space_sep(newname, ' ');
+ char *newname;
if ((thing = match_controlled(player, name)) != NOTHING) {
+ newname = mush_strdup(trim_space_sep(newname_, ' '), "name.newname");
+ bon = newname;
+
/* check for bad name */
if ((*newname == '\0') || strchr(newname, '[')) {
notify(player, T("Give it what new name?"));
+ mush_free(newname, "name.newname");
return;
}
/* check for renaming a player */
if (IsPlayer(thing)) {
- if (*newname == '"') {
- for (; *newname && ((*newname == '"')
- || isspace((unsigned char) *newname)); newname++) ;
- eon = newname;
- while (*eon && (*eon != '"')) {
- while (*eon && (*eon != '"'))
- eon++;
- if (*eon == '"') {
- *eon++ = '\0';
- while (*eon && isspace((unsigned char) *eon))
- eon++;
- break;
- }
+ // If it has "s, it's surrounding a spaced name, likely. So bon
+ // is beginning of name.
+ // I'm going to cheat here and make it so
+ // @name me="foo"bar names somebody foo, since " is an invalid name.
+ if (*bon == '"') {
+ bon++;
+ eon = bon;
+ while (*eon && *eon != '"') {
+ eon++;
+ }
+ if (*eon) {
+ *eon = '\0';
}
} else {
- eon = newname;
+ eon = bon;
while (*eon && !isspace((unsigned char) *eon))
eon++;
if (*eon)
- *eon++ = '\0';
+ *(eon++) = '\0';
}
- if (!ok_player_name(newname, player, thing)) {
+ if (!ok_player_name(bon, player, thing)) {
notify(player, T("You can't give a player that name."));
+ mush_free(newname, "name.newname");
return;
}
/* everything ok, notify */
do_log(LT_CONN, 0, 0, T("Name change by %s(#%d) to %s"),
- Name(thing), thing, newname);
+ Name(thing), thing, bon);
/* everything ok, we can fall through to change the name */
} else {
+ bon = newname;
if (!ok_name(newname)) {
notify(player, T("That is not a reasonable name."));
+ mush_free(newname, "name.newname");
return;
}
}
myenv[0] = (char *) mush_malloc(BUFFER_LEN, "string");
myenv[1] = (char *) mush_malloc(BUFFER_LEN, "string");
mush_strncpy(myenv[0], Name(thing), BUFFER_LEN);
- strcpy(myenv[1], newname);
+ strcpy(myenv[1], bon);
for (i = 2; i < 10; i++)
myenv[i] = NULL;
if (IsPlayer(thing))
- reset_player_list(thing, Name(thing), NULL, newname, NULL);
- set_name(thing, newname);
+ reset_player_list(thing, Name(thing), NULL, bon, NULL);
+ set_name(thing, bon);
if(!IsPlayer(thing)) {
char lmbuf[1024];
ModTime(thing) = mudtime;
notify(player, T("Name set."));
real_did_it(player, thing, NULL, NULL, "ONAME", NULL, "ANAME", NOTHING,
myenv, NA_INTER_PRESENCE);
+ mush_free(newname, "name.newname");
mush_free(myenv[0], "string");
mush_free(myenv[1], "string");
}
if ((thing =
noisy_match_result(player, what, TYPE_THING,
- MAT_NEAR_THINGS)) != NOTHING) {
+ MAT_NEAR_THINGS | MAT_ENGLISH)) != NOTHING) {
if (!eval_lock(player, thing, Use_Lock)) {
fail_lock(player, thing, Use_Lock, T("Permission denied."), NOTHING);
return;
pcre_extra *extra;
size_t i;
const char *errptr;
+ ansi_string *as;
const char *d;
size_t delenn;
int erroffset;
int offsets[99];
int subpatterns;
+ int totallen = 0;
for (i = 0; i < nmatches; i++)
matches[i] = NULL;
return 0;
}
add_check("pcre");
- d = remove_markup(val, &delenn);
+
+ /* The ansi string */
+ as = parse_ansi_string(val);
+ delenn = as->len;
+ d = as->text;
+
extra = default_match_limit();
/*
* Now we try to match the pattern. The relevant fields will
* automatically be filled in by this.
*/
- if ((subpatterns = pcre_exec(re, extra, d, delenn - 1, 0, 0, offsets, 99))
+ if ((subpatterns = pcre_exec(re, extra, d, delenn, 0, 0, offsets, 99))
< 0) {
+ free_ansi_string(as);
mush_free(re, "pcre");
return 0;
}
* go from 1 to 9. We DO PRESERVE THIS PARADIGM, for consistency
* with other languages.
*/
-
- for (i = 0; i < nmatches && (int) i < subpatterns && (size_t) len > i; i++) {
- ssize_t sublen;
-
- sublen = pcre_copy_substring(d, offsets, subpatterns, (int) i, data, len);
-
- if (sublen < 0)
- break;
-
- matches[i] = data;
- data += sublen + 2;
- len -= sublen + 2;
+ for (i = 0; i < nmatches && (int) i < subpatterns && totallen < len; i++) {
+ // Current data match.
+ /* This is more annoying than a jumping flea up the nose. Since
+ * ansi_pcre_copy_substring() uses buff, bp instead of char *, len,
+ * we have to mangle bp and 'buff' by hand. Sound easy? We also
+ * have to make sure that 'buff' + len < BUFFER_LEN. Particularly since
+ * matchspace is 2*BUFFER_LEN
+ */
+ char *buff = data + totallen;
+ char *bp = buff;
+ matches[i] = bp;
+ if ((len - totallen) < BUFFER_LEN) {
+ buff = data + len - BUFFER_LEN;
+ }
+ ansi_pcre_copy_substring(as, offsets, subpatterns, (int) i, 1, buff, &bp);
+ *(bp++) = '\0';
+ totallen = bp - data;
}
+ free_ansi_string(as);
mush_free(re, "pcre");
return 1;
}
mush_free(results, "search_results");
}
-
-#ifdef WIN32
-#pragma warning( disable : 4761) /* Disable bogus conversion warning */
-#endif
-/* ARGSUSED */
-FUNCTION(fun_hidden)
-{
- dbref it = match_thing(executor, args[0]);
- if (CanSee(executor, it) && ((Admin(executor) ||
- Location(executor) == Location(it) || Location(it) == executor))) {
- if ((it == NOTHING) || (!IsPlayer(it))) {
- notify(executor, T("Couldn't find that player."));
- safe_str("#-1", buff, bp);
- return;
- }
- safe_boolean(hidden(it), buff, bp);
- return;
- } else {
- notify(executor, T("Permission denied."));
- safe_str("#-1", buff, bp);
- return;
- }
-}
-
-#ifdef WIN32
-#pragma warning( default : 4761) /* Re-enable conversion warning */
-#endif
-
/* ARGSUSED */
FUNCTION(fun_quota)
{
ATTR *a;
char lbuff[BUFFER_LEN];
- /* make sure player has money to do the search */
- if (!payfor(player, FIND_COST)) {
- notify_format(player, T("Searches cost %d %s."), FIND_COST,
- ((FIND_COST == 1) ? MONEY : MONIES));
- return -1;
- }
-
if (fill_search_spec(player, owner, nargs, args, &spec) < 0) {
giveto(player, FIND_COST);
if (spec.lock != TRUE_BOOLEXP)
return -1;
}
+ /* make sure player has money to do the search -
+ * But only if this does an eval or lock search. */
+ if ((spec.lock != TRUE_BOOLEXP) ||
+ spec.cmdstring[0] || spec.listenstring[0] || spec.eval[0]) {
+ if (!payfor(player, FIND_COST)) {
+ notify_format(player, T("Searches cost %d %s."), FIND_COST,
+ ((FIND_COST == 1) ? MONEY : MONIES));
+ return -1;
+ }
+ }
+
if ((spec.owner != ANY_OWNER &&
spec.owner != Owner(player) &&
(!(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER))
test('rand.6', $god, 'think rand(1,1)', '1');
test('rand.7', $god, 'think rand(2,1)', '#-1');
test('rand.8', $god, 'think rand(0,9)', '^\d\s*$');
+test('rand.9', $god, 'think rand(-5, 10)', '#-1');
+test('rand.10', $god, 'think rand(-5, -10)', '#-1');
+test('randword.1', $god, 'think randword(%b%b%b)', '^$');
+test('randword.2', $god, 'think randword(foo)', 'foo');
+test('randword.3', $god, 'think randword(foo bar)', '(?:foo|bar)');