Returns a space-separated list of the attribute names on the object
that you are permitted to examine. To see the complete list, own the
object, have the See_All power over the object, or have the object set
- VISUAL in order to use this function on the object.
+ VISUAL and pass its examine lock in order to use this function on the
+ object.
If a wildcarded attribute pattern is provided, only attribute names
matching that pattern will be returned. lattr() uses the same
char **bp);
extern char *str_escaped_chr(const char *RESTRICT string, char escape_chr);
- extern char *replace_string
+ extern char *mush_strncpy(char *restrict, const char *, size_t);
+ extern char *replace_string
(const char *RESTRICT old, const char *RESTRICT newbit,
const char *RESTRICT string) __attribute_malloc__;
extern char *replace_string2(const char *old[2], const char *newbits[2],
extern int wildcard(const char *s);
extern int quick_wild_new(const char *RESTRICT tstr,
const char *RESTRICT dstr, int cs);
- extern int regexp_match_case(const char *RESTRICT s, const char *RESTRICT d,
- int cs);
+ extern int regexp_match_case_r(const char *RESTRICT s,
+ const char *RESTRICT d, int cs, char **, int,
+ char *, int);
extern int quick_regexp_match(const char *RESTRICT s,
const char *RESTRICT d, int cs);
- extern int wild_match_case(const char *RESTRICT s, const char *RESTRICT d,
- int cs);
+ extern int wild_match_case_r(const char *RESTRICT s, const char *RESTRICT d,
+ int cs, char **, int, char *, int);
extern int quick_wild(const char *RESTRICT tsr, const char *RESTRICT dstr);
extern int atr_wild(const char *RESTRICT tstr, const char *RESTRICT dstr);
-/** Default (case-sensitive) regex match */
-#define regexp_match(s,d) regexp_match_case(s,d,1)
-/** Default (case-insensitive) wildcard match */
-#define wild_match(s,d) wild_match_case(s,d,0)
/** Default (case-insensitive) local wildcard match */
#define local_wild_match(s,d) local_wild_match_case(s, d, 0)
extern pcre *pcre_compile(const char *, int, const char **,
int *, const unsigned char *);
extern int pcre_copy_substring(const char *, int *, int, int, char *, int);
+ int pcre_get_substring(const char *, int *, int, int, const char **);
extern int pcre_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int);
extern const unsigned char *pcre_maketables(void);
makedepend -fMakefile.SH -w10 -- -I../hdrs -I.. $(CFLAGS) -- $(C_FILES) $(H_FILES)
perl ../utils/fixdepend.pl Makefile.SH
-# Requires GNU indent!
+# Requires GNU indent 1.2 or better!
+
indent:
(set +e; for file in *.dst *.c ../hdrs/*.h ; do echo $$file; \
- /usr/bin/expand $$file > tmpfile; mv -f tmpfile $$file; \
- /usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 \
+ /usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 -nut \
-T atr_err -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \
-T NVAL -T i_rec -T f_rec -T USERFN_ENTRY -T PRIV -T FLAG \
-T FLAGENT -T FLAG_ALIAS -T tlist -T u -T stat -T tcheck -T ATTR \
for (ap = access_top; ap; ap = ap->next) {
if (!(ap->can & ACS_SITELOCK)
&& ((ap->can & ACS_REGEXP)
- ? (regexp_match_case(ap->host, hname, 0)
- || (p && regexp_match_case(ap->host, p, 0))
+ ? (quick_regexp_match(ap->host, hname, 0)
+ || (p && quick_regexp_match(ap->host, p, 0))
#ifdef FORCE_IPV4
- || regexp_match_case(ip4_to_ip6(ap->host), hname, 0)
- || (p && regexp_match_case(ip4_to_ip6(ap->host), p, 0))
+ || quick_regexp_match(ip4_to_ip6(ap->host), hname, 0)
+ || (p && quick_regexp_match(ip4_to_ip6(ap->host), p, 0))
#endif
)
: (quick_wild(ap->host, hname)
(*rulenum)++;
if (!(ap->can & ACS_SITELOCK)
&& ((ap->can & ACS_REGEXP)
- ? (regexp_match_case(ap->host, hname, 0)
- || (p && regexp_match_case(ap->host, p, 0))
+ ? (quick_regexp_match(ap->host, hname, 0)
+ || (p && quick_regexp_match(ap->host, p, 0))
#ifdef FORCE_IPV4
- || regexp_match_case(ip4_to_ip6(ap->host), hname, 0)
- || (p && regexp_match_case(ip4_to_ip6(ap->host), p, 0))
+ || quick_regexp_match(ip4_to_ip6(ap->host), hname, 0)
+ || (p && quick_regexp_match(ip4_to_ip6(ap->host), p, 0))
#endif
)
: (quick_wild(ap->host, hname)
free(t);
}
} else {
- if (!AL_FLAGS(root) & AF_ROOT) /* Upgrading old database */
- AL_FLAGS(root) |= AF_ROOT;
+ if (!AL_FLAGS(root) & AF_ROOT) /* Upgrading old database */
+ AL_FLAGS(root) |= AF_ROOT;
}
}
ATTR *skip[ATTRIBUTE_NAME_LIMIT / 2];
int skipcount;
int lock_checked = 0;
+ char match_space[BUFFER_LEN * 2];
+ int match_space_len = BUFFER_LEN * 2;
dbref local_ooref;
/* check for lots of easy ways out */
match_found = 0;
if (AF_Regexp(ptr)) {
- if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) {
+ if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len)) {
match_found = 1;
match++;
}
if (quick_wild_new(tbuf2 + 1, str, AF_Case(ptr))) {
match_found = 1;
match++;
- wild_match_case(tbuf2 + 1, str, AF_Case(ptr));
+ if (!just_match)
+ wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len);
}
}
if (match_found) {
match_found = 0;
if (AF_Regexp(ptr)) {
- if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) {
+ if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len)) {
match_found = 1;
match++;
}
if (quick_wild_new(tbuf2 + 1, str, AF_Case(ptr))) {
match_found = 1;
match++;
- wild_match_case(tbuf2 + 1, str, AF_Case(ptr));
+ if (!just_match)
+ wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len);
}
}
if (match_found) {
ATTR *skip[ATTRIBUTE_NAME_LIMIT / 2];
int skipcount;
int lock_checked = 0;
+ char match_space[BUFFER_LEN * 2];
+ int match_space_len = BUFFER_LEN * 2;
/* check for lots of easy ways out */
if ((type != '$' && type != '^') || !GoodObject(thing) || Halted(thing)
match_found = 0;
if (AF_Regexp(ptr)) {
- if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) {
+ if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len)) {
match_found = 1;
match++;
}
if (quick_wild_new(tbuf2 + 1, str, AF_Case(ptr))) {
match_found = 1;
match++;
- wild_match_case(tbuf2 + 1, str, AF_Case(ptr));
+ if(!just_match)
+ wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len);
}
}
if (match_found) {
match_found = 0;
if (AF_Regexp(ptr)) {
- if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) {
+ if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len)) {
match_found = 1;
match++;
}
if (quick_wild_new(tbuf2 + 1, str, AF_Case(ptr))) {
match_found = 1;
match++;
- wild_match_case(tbuf2 + 1, str, AF_Case(ptr));
- }
+ if(!just_match)
+ wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10,
+ match_space, match_space_len);
+ }
}
if (match_found) {
/* Since we're still checking the lock on the child, not the
char tbuf1[BUFFER_LEN];
char tbuf2[BUFFER_LEN];
char *s;
+ char match_space[BUFFER_LEN * 2];
+ int match_space_len = BUFFER_LEN * 2;
/* check for lots of easy ways out */
if (!GoodObject(thing) || Halted(thing) || NoCommand(thing))
strcpy(tbuf2, tbuf1);
if (AF_Regexp(ptr) ?
- regexp_match_case(tbuf2 + 1, str, AF_Case(ptr)) :
- wild_match_case(tbuf2 + 1, str, AF_Case(ptr))) {
+ regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr),
+ global_eval_context.wnxt, 10, match_space,
+ match_space_len) : wild_match_case_r(tbuf2 + 1, str,
+ AF_Case(ptr), global_eval_context. wnxt, 10, match_space,
+ match_space_len))
+ {
if (!eval_lock(player, thing, Command_Lock)
|| !eval_lock(player, thing, Use_Lock))
return 0;
void WIN32_CDECL signal_shutdown(int sig);
void WIN32_CDECL signal_dump(int sig);
void reaper(int sig);
+#ifndef WIN32
+sig_atomic_t dump_error = 0;
+WAIT_TYPE dump_status = 0;
+#endif
extern Pid_t forked_dump_pid; /**< Process id of forking dump process */
static void dump_users(DESC *call_by, char *match, int doing);
static const char *time_format_1(long int dt);
static void query_info_slave(int fd);
static void reap_info_slave(void);
void kill_info_slave(void);
+sig_atomic_t slave_error = 0;
#endif
#endif
void reopen_logs(void);
process_commands();
+ /* Check signal handler flags */
+
+#ifndef WIN32
+ if (dump_error) {
+ if (WIFSIGNALED(dump_status)) {
+ do_rawlog(LT_ERR, T("ERROR! forking dump exited with signal %d"),
+ WTERMSIG(dump_status));
+ flag_broadcast("ROYALTY WIZARD", 0,
+ T("GAME: ERROR! Forking database save failed!"));
+ } else if (WIFEXITED(dump_status) && WEXITSTATUS(dump_status) == 0) {
+ time(&globals.last_dump_time);
+ if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE)
+ flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE);
+ }
+ dump_error = 0;
+ dump_status = 0;
+ }
+#if defined(INFO_SLAVE) && !defined(COMPILE_CONSOLE)
+ if (slave_error) {
+ do_rawlog(LT_ERR, T("info_slave on pid %d exited unexpectedly!"),
+ slave_error);
+ slave_error = 0;
+ }
+#endif
+#endif /* !WIN32 */
+
if (signal_shutdown_flag) {
flag_broadcast(0, 0, T("GAME: Shutdown by external signal"));
do_rawlog(LT_ERR, T("SHUTDOWN by external signal"));
do_rawlog(LT_ERR, T("info_slave on pid %d exited!"), pid);
info_slave_state = 0;
info_slave_pid = -1;
+ slave_error = pid;
} else
#endif
#endif
if (forked_dump_pid > -1 && pid == forked_dump_pid) {
/* Most failures are handled by the forked mush already */
- if (WIFSIGNALED(my_stat)) {
- do_rawlog(LT_ERR, T("ERROR! forking dump exited with signal %d"),
- WTERMSIG(my_stat));
- } else if (WIFEXITED(my_stat) && WEXITSTATUS(my_stat) == 0) {
- time(&globals.last_dump_time);
- if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE)
- flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE);
-
- }
+ dump_error = forked_dump_pid;
+ dump_status = my_stat;
forked_dump_pid = -1;
}
}
/* do @listen stuff */
a = atr_get_noparent(target, "LISTEN");
if (a) {
+ char match_space[BUFFER_LEN * 2];
+ int match_space_len = BUFFER_LEN * 2;
if (!tbuf1)
tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string");
strcpy(tbuf1, atr_value(a));
if (AF_Regexp(a)
- ? regexp_match_case(tbuf1,
+ ? regexp_match_case_r(tbuf1,
+ (char *) notify_makestring(msgbuf, messages,
+ NA_ASCII),
+ AF_Case(a), global_eval_context.wnxt, 10,
+ match_space, match_space_len)
+ : wild_match_case_r(tbuf1,
(char *) notify_makestring(msgbuf, messages,
- NA_ASCII), AF_Case(a))
- : wild_match_case(tbuf1,
- (char *) notify_makestring(msgbuf, messages,
- NA_ASCII), AF_Case(a))) {
+ NA_ASCII),
+ AF_Case(a), global_eval_context.wnxt, 10,
+ match_space, match_space_len)) {
if (eval_lock(speaker, target, Listen_Lock))
if (PLAYER_AHEAR || (!IsPlayer(target))) {
if (speaker != target)
return buff;
}
+/** Safe version of strncpy() that always nul-terminates the
+ * destination string. The only reason it's not called
+ * safe_strncpy() is to avoid confusion with the unrelated
+ * safe_*() pennstr functions.
+ * \param dst the destination string to copy to
+ * \param src the source string to copy from
+ * \param len the maximum number of bytes to copy
+ * return dst
+ */
+char *
+mush_strncpy(char *RESTRICT dst, const char *RESTRICT src, size_t len)
+{
+ size_t n = 0;
+ char *start = dst;
+
+ if (!src || !dst || len == 0)
+ return dst;
+
+ len--;
+
+ while (*src && n < len) {
+ *dst++ = *src++;
+ n++;
+ }
+
+ *dst = '\0';
+ return start;
+}
+
/** Safely append an int to a string. Returns a true value on failure.
* This will someday take extra arguments for use with our version
#include "conf.h"
#include "case.h"
#include "externs.h"
+#include "ansi.h"
#include "mymalloc.h"
#include "parse.h"
#include "pcre.h"
const unsigned char *tables = NULL; /** Pointer to character tables */
-static char wspace[3 * BUFFER_LEN + NUMARGS]; /* argument return buffer */
- /* big to match tprintf */
-
static int wild1
(const char *RESTRICT tstr, const char *RESTRICT dstr, int arg,
- char **RESTRICT wbuf, int cs);
-static int wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs);
+ char **wbuf, int *len, int cs, char **ary, int max);
+static int wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs,
+ char **ary, int max, char *buffer, int len);
static int check_literals(const char *RESTRICT tstr, const char *RESTRICT dstr,
int cs);
static char *strip_backslashes(const char *str);
*/
static int
wild1(const char *RESTRICT tstr, const char *RESTRICT dstr, int arg,
- char **RESTRICT wbuf, int cs)
+ char **wbuf, int *len, int cs, char **ary, int max)
{
const char *datapos;
int argpos, numextra;
if (!*dstr)
return 0;
- global_eval_context.wnxt[arg++] = *wbuf;
- *(*wbuf)++ = *dstr;
- *(*wbuf)++ = '\0';
+ if (*len >= 2) {
+ ary[arg++] = *wbuf;
+ *(*wbuf)++ = *dstr;
+ *(*wbuf)++ = '\0';
+ *len -= 2;
+ }
/* Jump to the fast routine if we can. */
- if (arg >= NUMARGS)
+ if (arg >= (int) max || *len < 2)
return quick_wild_new(tstr + 1, dstr + 1, cs);
break;
case '\\':
/* If at end of pattern, slurp the rest, and leave. */
if (!tstr[1]) {
- global_eval_context.wnxt[arg] = *wbuf;
- strcpy(*wbuf, dstr);
- *wbuf += strlen(dstr) + 2;
+ int tlen;
+ tlen = strlen(dstr);
+ if (tlen < *len) {
+ ary[arg] = *wbuf;
+ strcpy(*wbuf, dstr);
+ *wbuf += tlen + 2;
+ *len -= tlen + 1;
+ }
return 1;
}
/* Remember current position for filling in the '*' return. */
/* Fill in arguments if someone put another '*'
* before a fixed string.
*/
- global_eval_context.wnxt[argpos++] = *wbuf;
- *(*wbuf)++ = '\0';
+ if (*len >= 1) {
+ ary[argpos++] = *wbuf;
+ *(*wbuf)++ = '\0';
+ *len -= 1;
+ }
/* Jump to the fast routine if we can. */
- if (argpos >= NUMARGS)
+ if (argpos >= (int) max || *len < 2)
return quick_wild_new(tstr, dstr, cs);
/* Fill in any intervening '?'s */
while (argpos < arg) {
- global_eval_context.wnxt[argpos++] = *wbuf;
- *(*wbuf)++ = *datapos++;
- *(*wbuf)++ = '\0';
+ if (*len >= 2) {
+ ary[argpos++] = *wbuf;
+ *(*wbuf)++ = *datapos++;
+ *(*wbuf)++ = '\0';
+ *len -= 2;
+ }
/* Jump to the fast routine if we can. */
- if (argpos >= NUMARGS)
+ if (argpos >= (int) max || *len < 1)
return quick_wild_new(tstr, dstr, cs);
}
}
else {
while (1) {
if (EQUAL(cs, *dstr, *tstr) &&
- ((arg < NUMARGS) ? wild1(tstr, dstr, arg, wbuf, cs)
+ ((arg < (int) max) ? wild1(tstr, dstr, arg, wbuf, len, cs, ary, max)
: quick_wild_new(tstr, dstr, cs)))
break;
if (!*dstr)
/* Found a match! Fill in all remaining arguments.
* First do the '*'...
*/
- global_eval_context.wnxt[argpos++] = *wbuf;
- strncpy(*wbuf, datapos, (dstr - datapos) - numextra);
- *wbuf += (dstr - datapos) - numextra;
- *(*wbuf)++ = '\0';
- datapos = dstr - numextra;
+ {
+ int datalen;
+ datalen = (dstr - datapos) - numextra;
+ if (datalen + 1 <= *len) {
+ ary[argpos++] = *wbuf;
+ strncpy(*wbuf, datapos, datalen);
+ *wbuf += datalen;
+ *(*wbuf)++ = '\0';
+ *len -= datalen + 1;
+ datapos = dstr - numextra;
+ }
+ }
/* Fill in any trailing '?'s that are left. */
while (numextra) {
- if (argpos >= NUMARGS)
+ if (argpos >= (int) max || *len < 2)
return 1;
- global_eval_context.wnxt[argpos++] = *wbuf;
- *(*wbuf)++ = *datapos++;
- *(*wbuf)++ = '\0';
- numextra--;
+ if (*len >= 2) {
+ ary[argpos++] = *wbuf;
+ *(*wbuf)++ = *datapos++;
+ *(*wbuf)++ = '\0';
+ *len -= 2;
+ numextra--;
+ }
}
/* It's done! */
* Side Effect: this routine modifies the 'global_eval_context.wnxt' global variable.
*/
static int
-wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs)
+wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs,
+ char **ary, int max, char *buffer, int len)
{
- char *buffer = wspace;
-
- /* Do fast match. */
+ /* Do fast match to see if pattern matches. If yes, do it again,
+ remembering this time.. */
while ((*s != '*') && (*s != '?')) {
if (*s == '\\')
s++;
return 0;
/* Do the match. */
- return wild1(s, d, p, &buffer, cs);
+ return wild1(s, d, p, &buffer, &len, cs, ary, max);
}
+
-/** Wildcard match, possibly case-sensitive, and remember the wild data.
- *
+/** Wildcard match, possibly case-sensitive, and remember the wild data
+ * in matches, storing them in data.
* This routine will cause crashes if fed NULLs instead of strings.
*
* \param s pattern to match against.
* \param d string to check.
* \param cs if 1, case-sensitive; if 0, case-insensitive.
+ * \param ary An array to store the grabs in
+ * \param max Number of elements ary can hold
+ * \param data Buffer used to hold the matches. The elements of ary
+ * are set to pointers into this buffer.
+ * \param len The number of bytes in data. Twice the length of d should
+ * be enough.
* \retval 1 d matches s.
* \retval 0 d doesn't match s.
*/
int
-wild_match_case(const char *RESTRICT s, const char *RESTRICT d, int cs)
+wild_match_case_r(const char *RESTRICT s, const char *RESTRICT d, int cs,
+ char **matches, int nmatches, char *data, int len)
{
- int j;
- /* Clear %0-%9 and r(0) - r(9) */
- for (j = 0; j < NUMARGS; j++)
- global_eval_context.wnxt[j] = (char *) NULL;
- for (j = 0; j < NUMQ; j++)
- global_eval_context.rnxt[j] = (char *) NULL;
- clear_namedregs(&global_eval_context.namedregsnxt);
- return wild(s, d, 0, cs);
+ int n;
+
+ for (n = 0; n < nmatches; n++)
+ matches[n] = NULL;
+
+ return wild(s, d, 0, cs, matches, nmatches, data, len);
}
/** Regexp match, possibly case-sensitive, and remember matched subexpressions.
*
* \param s regexp to match against.
* \param d string to check.
- * \param cs if 1, case-sensitive; if 0, case-insensitive.
- * \retval 1 d matches s.
- * \retval 0 d doesn't match s.
+ * \param cs if 1, case-sensitive; if 0, case-insensitive
+ * \param matches array to store matched subexpressions in
+ * \param nmatches the size of the matches array
+ * \param data buffer space to copy matches into. The elements of
+ * array point into here
+ * \param len The size of data
+ * \retval 1 d matches s
+ * \retval 0 d doesn't match s
*/
int
-regexp_match_case(const char *RESTRICT s, const char *RESTRICT d, int cs)
+regexp_match_case_r(const char *RESTRICT s, const char *RESTRICT val, int cs,
+ char **matches, int nmatches, char *data, int len)
{
- int j;
pcre *re;
int i;
- static char wtmp[NUMARGS][BUFFER_LEN];
const char *errptr;
+ const char *d;
+ size_t delenn;
int erroffset;
int offsets[99];
int subpatterns;
+ for (i = 0; i < nmatches; i++)
+ matches[i] = NULL;
+
if ((re = pcre_compile(s, (cs ? 0 : PCRE_CASELESS), &errptr, &erroffset,
tables)) == NULL) {
/*
return 0;
}
add_check("pcre");
+ d = remove_markup(val, &delenn);
/*
* Now we try to match the pattern. The relevant fields will
* automatically be filled in by this.
*/
- if ((subpatterns = pcre_exec(re, NULL, d, strlen(d), 0, 0, offsets, 99))
+ if ((subpatterns = pcre_exec(re, NULL, d, delenn - 1, 0, 0, offsets, 99))
< 0) {
mush_free(re, "pcre");
return 0;
* with other languages.
*/
- /* Clear %0-%9 and r(0) - r(9) */
- for (j = 0; j < NUMARGS; j++) {
- wtmp[j][0] = '\0';
- global_eval_context.wnxt[j] = (char *) NULL;
- }
- for (j = 0; j < NUMQ; j++)
- global_eval_context.rnxt[j] = (char *) NULL;
- clear_namedregs(&global_eval_context.namedregsnxt);
+ for (i = 0; i < nmatches && i < subpatterns && len > 1; i++) {
+ int sublen;
+ const char *submatch;
+
+ pcre_get_substring(d, offsets, subpatterns, (int) i, &submatch);
+ sublen = strlen(submatch);
+
+ if (sublen >= len)
+ break;
- for (i = 0; (i < 10) && (i < NUMARGS); i++) {
- pcre_copy_substring(d, offsets, subpatterns, i, wtmp[i], BUFFER_LEN);
- global_eval_context.wnxt[i] = wtmp[i];
+ strcpy(data, submatch);
+ matches[i] = data;
+ data += sublen + 1;
+ len -= sublen + 1;
}
mush_free(re, "pcre");
quick_regexp_match(const char *RESTRICT s, const char *RESTRICT d, int cs)
{
pcre *re;
+ const char *sptr;
+ size_t slen;
const char *errptr;
int erroffset;
int offsets[99];
return 0;
}
add_check("pcre");
+ sptr = remove_markup(d, &slen);
/*
* Now we try to match the pattern. The relevant fields will
* automatically be filled in by this.
*/
- r = pcre_exec(re, NULL, d, strlen(d), 0, 0, offsets, 99);
+ r = pcre_exec(re, NULL, sptr, slen - 1, 0, 0, offsets, 99);
mush_free(re, "pcre");
char dbuf1[BUFFER_LEN];
const char delims[] = "?*";
char *sp, *dp;
- strncpy(dbuf1, dstr, BUFFER_LEN - 1);
- dbuf1[BUFFER_LEN - 1] = '\0';
- strcpy(tbuf1, strip_backslashes(tstr));
+ mush_strncpy(dbuf1, dstr, BUFFER_LEN);
+ mush_strncpy(tbuf1, strip_backslashes(tstr), BUFFER_LEN);
if (!cs) {
upcasestr(tbuf1);
upcasestr(dbuf1);
restriction = args[n + 1];
/* A special old-timey kludge */
if (class && !*class && restriction && *restriction) {
- if (isdigit((unsigned char) *restriction)
- || ((*restriction == '#') && *(restriction + 1)
- && isdigit((unsigned char) *(restriction + 1)))) {
+ if (isdigit((unsigned char) *class) || ((*class == '#') && *(class + 1)
+ && isdigit((unsigned char)
+ *(class + 1)))) {
size_t offset = 0;
if (*restriction == '#')
offset = 1;