Ejemplo n.º 1
0
// do_flag: Rename flags or remove flag aliases.
// Based on RhostMUSH code.
//
static bool flag_rename(UTF8 *alias, UTF8 *newname)
{
    int nAlias;
    bool bValidAlias;
    UTF8 *pCheckedAlias = MakeCanonicalFlagName(alias, &nAlias, &bValidAlias);
    if (!bValidAlias)
    {
        return false;
    }
    UTF8 *pAlias = alloc_sbuf("flag_rename.old");
    memcpy(pAlias, pCheckedAlias, nAlias+1);

    int nNewName;
    bool bValidNewName;
    UTF8 *pCheckedNewName = MakeCanonicalFlagName(newname, &nNewName, &bValidNewName);
    if (!bValidNewName)
    {
        free_sbuf(pAlias);
        return false;
    }
    UTF8 *pNewName = alloc_sbuf("flag_rename.new");
    memcpy(pNewName, pCheckedNewName, nNewName+1);

    FLAGNAMEENT *flag1;
    flag1 = (FLAGNAMEENT *)hashfindLEN(pAlias, nAlias, &mudstate.flags_htab);
    if (flag1 != NULL)
    {
        FLAGNAMEENT *flag2;
        flag2 = (FLAGNAMEENT *)hashfindLEN(pNewName, nNewName, &mudstate.flags_htab);
        if (flag2 == NULL)
        {
            hashaddLEN(pNewName, nNewName, flag1, &mudstate.flags_htab);

            if (flag1->flagname != flag1->pOrigName)
            {
                MEMFREE(flag1->flagname);
            }
            flag1->flagname = StringCloneLen(pNewName, nNewName);

            free_sbuf(pAlias);
            free_sbuf(pNewName);
            return true;
        }
    }
    free_sbuf(pAlias);
    free_sbuf(pNewName);
    return false;
}
Ejemplo n.º 2
0
void local_mysql_init(void) {
  /* Setup our local command and function tables */
  static CMDENT mysql_cmd_table[] = {
    {(char *) "@sql", NULL, CA_WIZARD, 0, 0, CS_ONE_ARG, 0, do_sql},
    {(char *) "@sqlconnect", NULL, CA_WIZARD, 0, 0, CS_NO_ARGS, 0, do_sql_connect},
    {(char *) "@sqldisconnect", NULL, CA_WIZARD, 0, 0, CS_NO_ARGS, 0, do_sql_shutdown},
    {(char *) NULL, NULL, 0, 0, 0, 0, 0, NULL}

  };
  
  static FUN mysql_fun_table[] = {
    {"SQL", local_fun_sql, 0, FN_VARARGS, CA_WIZARD, 0},
    {"SQLESCAPE", local_fun_sql_escape, 1, 0, CA_WIZARD, 0},
    {"SQLON", local_fun_sql_connect, 0, 0, CA_WIZARD, 0},
    {"SQLOFF", local_fun_sql_disconnect, 0, 0, CA_WIZARD, 0},
    {NULL, NULL, 0, 0, 0, 0}
  };

  CMDENT *cmdp;
  FUN *fp;
  char *buff, *cp, *dp;

  /* Add the commands to the command table */
  for (cmdp = mysql_cmd_table; cmdp->cmdname; cmdp++) {
    cmdp->cmdtype = CMD_LOCAL_e;
    hashadd(cmdp->cmdname, (int *) cmdp, &mudstate.command_htab);
  }

  /* Register the functions */
  buff = alloc_sbuf("init_mysql_functab");
  for (fp = mysql_fun_table ; fp->name ; fp++) {
     cp = (char *) fp->name;
      dp = buff;
      while (*cp) {
	*dp = ToLower(*cp);
	cp++;
	dp++;
      }
      *dp = '\0';
    hashadd2(buff, (int *) fp, &mudstate.func_htab, 1);
  }

  sql_init(-1);
}
Ejemplo n.º 3
0
char *decode_flags( dbref player, FLAGSET flagset ) {
    char *buf, *bp, *s;

    FLAGENT *fp;

    int flagtype;

    FLAG fv;

    buf = bp = s = alloc_sbuf( "decode_flags" );
    *bp = '\0';

    flagtype = ( flagset.word1 & TYPE_MASK );
    if( object_types[flagtype].lett != ' ' ) {
        safe_sb_chr( object_types[flagtype].lett, buf, &bp );
    }

    for( fp = gen_flags; fp->flagname; fp++ ) {
        if( fp->flagflag & FLAG_WORD3 ) {
            fv = flagset.word3;
        } else if( fp->flagflag & FLAG_WORD2 ) {
            fv = flagset.word2;
        } else {
            fv = flagset.word1;
        }
        if( fv & fp->flagvalue ) {
            if( ( fp->listperm & CA_WIZARD ) && !Wizard( player ) ) {
                continue;
            }
            if( ( fp->listperm & CA_GOD ) && !God( player ) ) {
                continue;
            }

            safe_sb_chr( fp->flaglett, buf, &bp );
        }
    }

    *bp = '\0';
    return buf;
}
Ejemplo n.º 4
0
Archivo: eval.c Proyecto: gtaylor/btmux
static void tcache_add(char *orig, char *result)
{
	char *tp;
	TCENT *xp;

	if(strcmp(orig, result)) {
		tcache_count++;
		if(tcache_count <= mudconf.trace_limit) {
			xp = (TCENT *) alloc_sbuf("tcache_add.sbuf");
			tp = alloc_lbuf("tcache_add.lbuf");
			StringCopy(tp, result);
			xp->orig = orig;
			xp->result = tp;
			xp->next = tcache_head;
			tcache_head = xp;
		} else {
			free_lbuf(orig);
		}
	} else {
		free_lbuf(orig);
	}
}
Ejemplo n.º 5
0
/* ---------------------------------------------------------------------------
 * did_it_rlevel: Have player do something to/with thing, watching the
 * attributes. 'what' is actually ignored, the desclist match being used
 * instead.
 */
void did_it_rlevel
(
    dbref player,
    dbref thing,
    int   what,
    const UTF8 *def,
    int   owhat,
    const UTF8 *odef,
    int   awhat,
    int   ctrl_flags,
    const UTF8 *args[],
    int   nargs
)
{
    if (MuxAlarm.bAlarmed)
    {
        return;
    }

    UTF8 *d, *buff, *act, *charges, *bp;
    dbref aowner;
    int num, aflags;
    int i;
    bool found_a_desc;

    reg_ref **preserve = NULL;
    bool need_pres = false;

    // Message to player.
    //
    if (0 < what)
    {
        // Get description list.
        //
        DESC_INFO *desclist = desclist_match(player, thing);
        found_a_desc = false;
        for (i = 0; i < desclist->n; i++)
        {
            // Ok, if it's A_DESC, we need to check against A_IDESC.
            //
            if (  A_IDESC == what
               && A_DESC == desclist->descs[i])
            {
                d = atr_pget(thing, A_IDESC, &aowner, &aflags);
            }
            else
            {
                d = atr_pget(thing, desclist->descs[i], &aowner, &aflags);
            }

            if ('\0' != d[0])
            {
                // No need for the 'def' message.
                //
                found_a_desc = true;
                if (!need_pres)
                {
                    need_pres = true;
                    preserve = PushRegisters(MAX_GLOBAL_REGS);
                    save_global_regs(preserve);
                }
                buff = bp = alloc_lbuf("did_it.1");
                mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
                    AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
                    args, nargs);
                *bp = '\0';

                if (  A_HTDESC == desclist->descs[i]
                   && Html(player))
                {
                    safe_str(T("\r\n"), buff, &bp);
                    *bp = '\0';
                    notify_html(player, buff);
                }
                else
                {
                    notify(player, buff);
                }
                free_lbuf(buff);
            }
            free_lbuf(d);
        }

        if (!found_a_desc)
        {
            // No desc found... try the default desc (again).
            // A_DESC or A_HTDESC... the worst case we look for it twice.
            //
            d = atr_pget(thing, what, &aowner, &aflags);
            if ('\0' != d[0])
            {
                // No need for the 'def' message
                //
                found_a_desc = true;
                if (!need_pres)
                {
                    need_pres = true;
                    preserve = PushRegisters(MAX_GLOBAL_REGS);
                    save_global_regs(preserve);
                }
                buff = bp = alloc_lbuf("did_it.1");
                mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
                    AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
                    args, nargs);
                *bp = '\0';

                if (  A_HTDESC == what
                   && Html(player))
                {
                    safe_str(T("\r\n"), buff, &bp);
                    *bp = '\0';
                    notify_html(player, buff);
                }
                else
                {
                    notify(player, buff);
                }
                free_lbuf(buff);
            }
            else if (def)
            {
                notify(player, def);
            }
            free_lbuf(d);
        }
    }
    else if (  what < 0
            && def)
    {
        notify(player, def);
    }

    if (isPlayer(thing))
    {
       d = atr_pget(mudconf.master_room, get_atr(T("ASSET_DESC")), &aowner, &aflags);
       if (*d)
       {
          if (!need_pres)
          {
             need_pres = true;
             preserve = PushRegisters(MAX_GLOBAL_REGS);
             save_global_regs(preserve);
          }
          buff = bp = alloc_lbuf("did_it.1");
          mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
              AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
              args, nargs);
          *bp = '\0';
          notify(player, buff);
          free_lbuf(buff);
       }
       free_lbuf(d);
    }

    // Message to neighbors.
    //
    dbref loc;
    if (  0 < owhat
       && Has_location(player)
       && Good_obj(loc = Location(player)))
    {
        d = atr_pget(thing, owhat, &aowner, &aflags);
        if (*d)
        {
            if (!need_pres)
            {
                need_pres = true;
                preserve = PushRegisters(MAX_GLOBAL_REGS);
                save_global_regs(preserve);
            }
            buff = bp = alloc_lbuf("did_it.2");
            mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, thing, player,
                AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_TOP),
                args, nargs);
            *bp = '\0';

            if (*buff)
            {
                if (aflags & AF_NONAME)
                {
                    notify_except2_rlevel2(loc, player, player, thing, buff);
                }
                else
                {
                    notify_except2_rlevel2(loc, player, player, thing,
                        tprintf(T("%s %s"), Name(player), buff));
                }
            }
            free_lbuf(buff);
        }
        else if (odef)
        {
            if (ctrl_flags & VERB_NONAME)
            {
                notify_except2_rlevel2(loc, player, player, thing, odef);
            }
            else
            {
                notify_except2_rlevel2(loc, player, player, thing,
                    tprintf(T("%s %s"), Name(player), odef));
            }
        }
        free_lbuf(d);
    }
    else if (  owhat < 0
            && odef
            && Has_location(player)
            && Good_obj(loc = Location(player)))
    {
        if (ctrl_flags & VERB_NONAME)
        {
            notify_except2_rlevel2(loc, player, player, thing, odef);
        }
        else
        {
            notify_except2_rlevel2(loc, player, player, thing,
                tprintf(T("%s %s"), Name(player), odef));
        }
    }

    // If we preserved the state of the global registers, restore them.
    //
    if (need_pres)
    {
        restore_global_regs(preserve);
        PopRegisters(preserve, MAX_GLOBAL_REGS);
    }

    // Do the action attribute.
    //
    if (  awhat > 0
       && IsReal(thing, player))
    {
        act = atr_pget(thing, awhat, &aowner, &aflags);
        if (*act != '\0')
        {
            charges = atr_pget(thing, A_CHARGES, &aowner, &aflags);
            if (*charges)
            {
                num = mux_atol(charges);
                if (num > 0)
                {
                    buff = alloc_sbuf("did_it.charges");
                    mux_ltoa(num-1, buff);
                    atr_add_raw(thing, A_CHARGES, buff);
                    free_sbuf(buff);
                }
                else
                {
                    buff = atr_pget(thing, A_RUNOUT, &aowner, &aflags);
                    if (*buff != '\0')
                    {
                        free_lbuf(act);
                        act = buff;
                    }
                    else
                    {
                        free_lbuf(act);
                        free_lbuf(buff);
                        free_lbuf(charges);
                        return;
                    }
                }
            }
            free_lbuf(charges);

            CLinearTimeAbsolute lta;
            wait_que(thing, player, player, AttrTrace(aflags, 0), false, lta,
                NOTHING, 0,
                act,
                nargs, args,
                mudstate.global_regs);
        }
        free_lbuf(act);
    }
}
Ejemplo n.º 6
0
Archivo: eval.c Proyecto: gtaylor/btmux
void exec(char *buff, char **bufc, int tflags, dbref player, dbref cause,
		  int eval, char **dstr, char *cargs[], int ncargs)
{
#define	NFARGS	30
	char *fargs[NFARGS];
	char *preserve[MAX_GLOBAL_REGS];
	char *tstr, *tbuf, *tbufc, *savepos, *atr_gotten, *start, *oldp, *savestr;
	char savec, ch, *str;
	char *realbuff = NULL, *realbp = NULL;
	dbref aowner;
	int at_space, nfargs, gender, i, j, alldone, feval; long aflags;
	int is_trace, is_top, save_count;
	int ansi;
	FUN *fp;
	UFUN *ufp;

	static const char *subj[5] = { "", "it", "she", "he", "they" };
	static const char *poss[5] = { "", "its", "her", "his", "their" };
	static const char *obj[5] = { "", "it", "her", "him", "them" };
	static const char *absp[5] = { "", "its", "hers", "his", "theirs" };

	if(*dstr == NULL)
		return;

	// dprintk("%d/%s", player, *dstr);

	at_space = 1;
	gender = -1;
	alldone = 0;
	ansi = 0;

	is_trace = Trace(player) && !(eval & EV_NOTRACE);
	is_top = 0;

	/* Extend the buffer if we need to. */

	if(((*bufc) - buff) > (LBUF_SIZE - SBUF_SIZE)) {
		realbuff = buff;
		realbp = *bufc;
		buff = (char *) malloc(LBUF_SIZE);
		*bufc = buff;
	}

	oldp = start = *bufc;

	/*
	 * If we are tracing, save a copy of the starting buffer 
	 */

	savestr = NULL;
	if(is_trace) {
		is_top = tcache_empty();
		savestr = alloc_lbuf("exec.save");
		StringCopy(savestr, *dstr);
	}
	while (**dstr && !alldone) {
		switch (**dstr) {
		case ' ':
			/*
			 * A space.  Add a space if not compressing or if * * 
			 * 
			 * *  * * previous char was not a space 
			 */

			if(!(mudconf.space_compress && at_space) ||
			   (eval & EV_NO_COMPRESS)) {
				safe_chr(' ', buff, bufc);
				at_space = 1;
			}
			break;
		case '\\':
			/*
			 * General escape.  Add the following char without *
			 * * * * special processing 
			 */

			at_space = 0;
			(*dstr)++;
			if(**dstr)
				safe_chr(**dstr, buff, bufc);
			else
				(*dstr)--;
			break;
		case '[':
			/*
			 * Function start.  Evaluate the contents of the * *
			 * * * square brackets as a function.  If no closing
			 * * * * * bracket, insert the [ and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			if(eval & EV_NOFCHECK) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
				break;
			}
			tbuf = parse_to(dstr, ']', 0);
			if(*dstr == NULL) {
				safe_chr('[', buff, bufc);
				*dstr = tstr;
			} else {
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval | EV_FCHECK | EV_FMAND), &str, cargs, ncargs);
				(*dstr)--;
			}
			break;
		case '{':
			/*
			 * Literal start.  Insert everything up to the * * *
			 * * terminating } without parsing.  If no closing *
			 * * * * brace, insert the { and continue. 
			 */

			at_space = 0;
			tstr = (*dstr)++;
			tbuf = parse_to(dstr, '}', 0);
			if(*dstr == NULL) {
				safe_chr('{', buff, bufc);
				*dstr = tstr;
			} else {
				if(!(eval & EV_STRIP)) {
					safe_chr('{', buff, bufc);
				}
				/*
				 * Preserve leading spaces (Felan) 
				 */

				if(*tbuf == ' ') {
					safe_chr(' ', buff, bufc);
					tbuf++;
				}
				str = tbuf;
				exec(buff, bufc, 0, player, cause,
					 (eval & ~(EV_STRIP | EV_FCHECK)), &str, cargs, ncargs);
				if(!(eval & EV_STRIP)) {
					safe_chr('}', buff, bufc);
				}
				(*dstr)--;
			}
			break;
		case '%':
			/*
			 * Percent-replace start.  Evaluate the chars * * *
			 * following * and perform the appropriate * * *
			 * substitution. 
			 */

			at_space = 0;
			(*dstr)++;
			savec = **dstr;
			savepos = *bufc;
			switch (savec) {
			case '\0':			/*
								 * Null - all done 
								 */
				(*dstr)--;
				break;
			case '|':			/* piped command output */
				safe_str(mudstate.pout, buff, bufc);
				break;
			case '%':			/*
								 * Percent - a literal % 
								 */
				safe_chr('%', buff, bufc);
				break;
			case 'c':
			case 'C':
				(*dstr)++;
				if(!**dstr)
					(*dstr)--;
				ansi = 1;
				switch (**dstr) {
				case 'h':		/*
								 * hilite 
								 */
					safe_str(ANSI_HILITE, buff, bufc);
					break;
				case 'i':		/*
								 * inverse 
								 */
					safe_str(ANSI_INVERSE, buff, bufc);
					break;
				case 'f':		/*
								 * flash 
								 */
					safe_str(ANSI_BLINK, buff, bufc);
					break;
				case 'u':		/* underline */
					safe_str(ANSI_UNDER, buff, bufc);
					break;
				case 'n':		/*
								 * normal 
								 */
					safe_str(ANSI_NORMAL, buff, bufc);
					ansi = 0;
					break;
				case 'x':		/*
								 * black fg 
								 */
					safe_str(ANSI_BLACK, buff, bufc);
					break;
				case 'r':		/*
								 * red fg 
								 */
					safe_str(ANSI_RED, buff, bufc);
					break;
				case 'g':		/*
								 * green fg 
								 */
					safe_str(ANSI_GREEN, buff, bufc);
					break;
				case 'y':		/*
								 * yellow fg 
								 */
					safe_str(ANSI_YELLOW, buff, bufc);
					break;
				case 'b':		/*
								 * blue fg 
								 */
					safe_str(ANSI_BLUE, buff, bufc);
					break;
				case 'm':		/*
								 * magenta fg 
								 */
					safe_str(ANSI_MAGENTA, buff, bufc);
					break;
				case 'c':		/*
								 * cyan fg 
								 */
					safe_str(ANSI_CYAN, buff, bufc);
					break;
				case 'w':		/*
								 * white fg 
								 */
					safe_str(ANSI_WHITE, buff, bufc);
					break;
				case 'X':		/*
								 * black bg 
								 */
					safe_str(ANSI_BBLACK, buff, bufc);
					break;
				case 'R':		/*
								 * red bg 
								 */
					safe_str(ANSI_BRED, buff, bufc);
					break;
				case 'G':		/*
								 * green bg 
								 */
					safe_str(ANSI_BGREEN, buff, bufc);
					break;
				case 'Y':		/*
								 * yellow bg 
								 */
					safe_str(ANSI_BYELLOW, buff, bufc);
					break;
				case 'B':		/*
								 * blue bg 
								 */
					safe_str(ANSI_BBLUE, buff, bufc);
					break;
				case 'M':		/*
								 * magenta bg 
								 */
					safe_str(ANSI_BMAGENTA, buff, bufc);
					break;
				case 'C':		/*
								 * cyan bg 
								 */
					safe_str(ANSI_BCYAN, buff, bufc);
					break;
				case 'W':		/*
								 * white bg 
								 */
					safe_str(ANSI_BWHITE, buff, bufc);
					break;
				default:
					safe_chr(**dstr, buff, bufc);
				}
				break;
			case 'r':			/*
								 * Carriage return 
								 */
			case 'R':
				safe_str((char *) "\r\n", buff, bufc);
				break;
			case 't':			/*
								 * Tab 
								 */
			case 'T':
				safe_chr('\t', buff, bufc);
				break;
			case 'B':			/*
								 * Blank 
								 */
			case 'b':
				safe_chr(' ', buff, bufc);
				break;
			case '0':			/*
								 * Command argument number N 
								 */
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				i = (**dstr - '0');
				if((i < ncargs) && (cargs[i] != NULL))
					safe_str(cargs[i], buff, bufc);
				break;
			case 'V':			/*
								 * Variable attribute 
								 */
			case 'v':
				(*dstr)++;
				ch = ToUpper(**dstr);
				if(!**dstr)
					(*dstr)--;
				if((ch < 'A') || (ch > 'Z'))
					break;
				i = 100 + ch - 'A';
				atr_gotten = atr_pget(player, i, &aowner, &aflags);
				safe_str(atr_gotten, buff, bufc);
				free_lbuf(atr_gotten);
				break;
			case 'Q':
			case 'q':
				(*dstr)++;
				i = (**dstr - '0');
				if((i >= 0) && (i <= 9) && mudstate.global_regs[i]) {
					safe_str(mudstate.global_regs[i], buff, bufc);
				}
				if(!**dstr)
					(*dstr)--;
				break;
			case 'O':			/*
								 * Objective pronoun 
								 */
			case 'o':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) obj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'P':			/*
								 * Personal pronoun 
								 */
			case 'p':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) poss[gender], buff, bufc);
				}
				break;
			case 'S':			/*
								 * Subjective pronoun 
								 */
			case 's':
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender)
					tbuf = Name(cause);
				else
					tbuf = (char *) subj[gender];
				safe_str(tbuf, buff, bufc);
				break;
			case 'A':			/*
								 * Absolute posessive 
								 */
			case 'a':			/*
								 * idea from Empedocles 
								 */
				if(gender < 0)
					gender = get_gender(cause);
				if(!gender) {
					safe_str(Name(cause), buff, bufc);
					safe_chr('s', buff, bufc);
				} else {
					safe_str((char *) absp[gender], buff, bufc);
				}
				break;
			case '#':			/*
								 * Invoker DB number 
								 */
				tbuf = alloc_sbuf("exec.invoker");
				sprintf(tbuf, "#%ld", cause);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case '!':			/*
								 * Executor DB number 
								 */
				tbuf = alloc_sbuf("exec.executor");
				sprintf(tbuf, "#%ld", player);
				safe_str(tbuf, buff, bufc);
				free_sbuf(tbuf);
				break;
			case 'N':			/*
								 * Invoker name 
								 */
			case 'n':
				safe_str(Name(cause), buff, bufc);
				break;
			case 'L':			/*
								 * Invoker location db# 
								 */
			case 'l':
				if(!(eval & EV_NO_LOCATION)) {
					tbuf = alloc_sbuf("exec.exloc");
					sprintf(tbuf, "#%ld", where_is(cause));
					safe_str(tbuf, buff, bufc);
					free_sbuf(tbuf);
				}

				break;
			default:			/*
								 * Just copy 
								 */
				safe_chr(**dstr, buff, bufc);
			}
			if(isupper(savec))
				*savepos = ToUpper(*savepos);
			break;
		case '(':
			/*
			 * Arglist start.  See if what precedes is a function. If so,
			 * execute it if we should.
			 */

			at_space = 0;
			if(!(eval & EV_FCHECK)) {
				safe_chr('(', buff, bufc);
				break;
			}
			/*
			 * Load an sbuf with an uppercase version of the func name, and
			 * see if the func exists.  Trim trailing spaces from the name
			 * if configured.
			 */

			**bufc = '\0';
			tbufc = tbuf = alloc_sbuf("exec.tbuf");
			safe_sb_str(oldp, tbuf, &tbufc);
			*tbufc = '\0';
			if(mudconf.space_compress) {
				while ((--tbufc >= tbuf) && isspace(*tbufc));
				tbufc++;
				*tbufc = '\0';
			}
			for(tbufc = tbuf; *tbufc; tbufc++)
				*tbufc = ToLower(*tbufc);
			fp = (FUN *) hashfind(tbuf, &mudstate.func_htab);

			/*
			 * If not a builtin func, check for global func 
			 */

			ufp = NULL;
			if(fp == NULL) {
				ufp = (UFUN *) hashfind(tbuf, &mudstate.ufunc_htab);
			}
			/*
			 * Do the right thing if it doesn't exist 
			 */

			if(!fp && !ufp) {
				if(eval & EV_FMAND) {
					*bufc = oldp;
					safe_str((char *) "#-1 FUNCTION (", buff, bufc);
					safe_str(tbuf, buff, bufc);
					safe_str((char *) ") NOT FOUND", buff, bufc);
					alldone = 1;
				} else {
					safe_chr('(', buff, bufc);
				}
				free_sbuf(tbuf);
				eval &= ~EV_FCHECK;
				break;
			}
			free_sbuf(tbuf);

			/*
			 * Get the arglist and count the number of args * Neg 
			 * 
			 * *  * *  * * # of args means catenate subsequent
			 * args 
			 */

			if(ufp)
				nfargs = NFARGS;
			else if(fp->nargs < 0)
				nfargs = -fp->nargs;
			else
				nfargs = NFARGS;
			tstr = *dstr;
			if(fp && (fp->flags & FN_NO_EVAL))
				feval = (eval & ~EV_EVAL) | EV_STRIP_ESC;
			else
				feval = eval;
			*dstr =
				parse_arglist(player, cause, *dstr + 1, ')', feval, fargs,
							  nfargs, cargs, ncargs);

			/*
			 * If no closing delim, just insert the '(' and * * * 
			 * 
			 * * continue normally 
			 */

			if(!*dstr) {
				*dstr = tstr;
				safe_chr(**dstr, buff, bufc);
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * Count number of args returned 
			 */

			(*dstr)--;
			j = 0;
			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					j = i + 1;
			nfargs = j;

			/*
			 * If it's a user-defined function, perform it now. 
			 */

			if(ufp) {
				mudstate.func_nest_lev++;
				if(!check_access(player, ufp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else {
					tstr = atr_get(ufp->obj, ufp->atr, &aowner, &aflags);
					if(ufp->flags & FN_PRIV)
						i = ufp->obj;
					else
						i = player;
					str = tstr;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(!mudstate.global_regs[j])
								preserve[j] = NULL;
							else {
								preserve[j] = alloc_lbuf("eval_regs");
								StringCopy(preserve[j],
										   mudstate.global_regs[j]);
							}
						}
					}

					exec(buff, &oldp, 0, i, cause, feval, &str, fargs,
						 nfargs);
					*bufc = oldp;

					if(ufp->flags & FN_PRES) {
						for(j = 0; j < MAX_GLOBAL_REGS; j++) {
							if(preserve[j]) {
								if(!mudstate.global_regs[j])
									mudstate.global_regs[j] =
										alloc_lbuf("eval_regs");
								StringCopy(mudstate.global_regs[j],
										   preserve[j]);
								free_lbuf(preserve[j]);
							} else {
								if(mudstate.global_regs[j])
									*(mudstate.global_regs[i]) = '\0';
							}
						}
					}

					free_lbuf(tstr);
				}

				/*
				 * Return the space allocated for the args 
				 */

				mudstate.func_nest_lev--;
				for(i = 0; i < nfargs; i++)
					if(fargs[i] != NULL)
						free_lbuf(fargs[i]);
				eval &= ~EV_FCHECK;
				break;
			}
			/*
			 * If the number of args is right, perform the func.
			 * Otherwise return an error message.  Note
			 * that parse_arglist returns zero args as one
			 * null arg, so we have to handle that case
			 * specially. 
			 */

			if((fp->nargs == 0) && (nfargs == 1)) {
				if(!*fargs[0]) {
					free_lbuf(fargs[0]);
					fargs[0] = NULL;
					nfargs = 0;
				}
			}
			if((nfargs == fp->nargs) || (nfargs == -fp->nargs) ||
			   (fp->flags & FN_VARARGS)) {

				/*
				 * Check recursion limit 
				 */

				mudstate.func_nest_lev++;
				mudstate.func_invk_ctr++;
				if(mudstate.func_nest_lev >= mudconf.func_nest_lim) {
					safe_str("#-1 FUNCTION RECURSION LIMIT EXCEEDED", buff,
							 bufc);
				} else if(mudstate.func_invk_ctr == mudconf.func_invk_lim) {
					safe_str("#-1 FUNCTION INVOCATION LIMIT EXCEEDED",
							 buff, bufc);
				} else if(!check_access(player, fp->perms)) {
					safe_str("#-1 PERMISSION DENIED", buff, &oldp);
					*bufc = oldp;
				} else if(mudstate.func_invk_ctr < mudconf.func_invk_lim) {
					fp->fun(buff, &oldp, player, cause, fargs, nfargs,
							cargs, ncargs);
					*bufc = oldp;
				} else {
					**bufc = '\0';
				}
				mudstate.func_nest_lev--;
			} else {
				*bufc = oldp;
				tstr = alloc_sbuf("exec.funcargs");
				sprintf(tstr, "%d", fp->nargs);
				safe_str((char *) "#-1 FUNCTION (", buff, bufc);
				safe_str((char *) fp->name, buff, bufc);
				safe_str((char *) ") EXPECTS ", buff, bufc);
				safe_str(tstr, buff, bufc);
				safe_str((char *) " ARGUMENTS", buff, bufc);
				free_sbuf(tstr);
			}

			/*
			 * Return the space allocated for the arguments 
			 */

			for(i = 0; i < nfargs; i++)
				if(fargs[i] != NULL)
					free_lbuf(fargs[i]);
			eval &= ~EV_FCHECK;
			break;
		default:
			/*
			 * A mundane character.  Just copy it 
			 */

			at_space = 0;
			safe_chr(**dstr, buff, bufc);
		}
		(*dstr)++;
	}

	/*
	 * If we're eating spaces, and the last thing was a space, eat it
	 * up. Complicated by the fact that at_space is initially
	 * true. So check to see if we actually put something in the
	 * buffer, too. 
	 */

	if(mudconf.space_compress && at_space && !(eval & EV_NO_COMPRESS)
	   && (start != *bufc))
		(*bufc)--;

	/*
	 * The ansi() function knows how to take care of itself. However, 
	 * if the player used a %c sub in the string, and hasn't yet
	 * terminated the color with a %cn yet, we'll have to do it for 
	 * them. 
	 */

	if(ansi == 1)
		safe_str(ANSI_NORMAL, buff, bufc);

	**bufc = '\0';

	/*
	 * Report trace information 
	 */

	if(realbuff) {
		**bufc = '\0';
		*bufc = realbp;
		safe_str(buff, realbuff, bufc);
		free(buff);
		buff = realbuff;
	}

	if(is_trace) {
		tcache_add(savestr, start);
		save_count = tcache_count - mudconf.trace_limit;;
		if(is_top || !mudconf.trace_topdown)
			tcache_finish(player);
		if(is_top && (save_count > 0)) {
			tbuf = alloc_mbuf("exec.trace_diag");
			sprintf(tbuf, "%d lines of trace output discarded.", save_count);
			notify(player, tbuf);
			free_mbuf(tbuf);
		}
	}
}
Ejemplo n.º 7
0
UTF8 *decode_flags(dbref player, FLAGSET *fs)
{
    UTF8 *buf, *bp;
    buf = bp = alloc_sbuf("decode_flags");
    *bp = '\0';

    if (!Good_obj(player))
    {
        mux_strncpy(buf, T("#-2 ERROR"), SBUF_SIZE-1);
        return buf;
    }
    int flagtype = fs->word[FLAG_WORD1] & TYPE_MASK;
    bool bNeedColon = true;
    if (object_types[flagtype].lett != ' ')
    {
        safe_sb_chr(object_types[flagtype].lett, buf, &bp);
        bNeedColon = false;
    }

    FLAGNAMEENT *fp;
    for (fp = gen_flag_names; fp->flagname; fp++)
    {
        FLAGBITENT *fbe = fp->fbe;
        if (  !fp->bPositive
           || fbe->flaglett == ' ')
        {
            // Only look at positive-sense entries that have non-space flag
            // letters.
            //
            continue;
        }
        if (fs->word[fbe->flagflag] & fbe->flagvalue)
        {
            if (  (  (fbe->listperm & CA_STAFF)
                  && !Staff(player))
               || (  (fbe->listperm & CA_ADMIN)
                  && !WizRoy(player))
               || (  (fbe->listperm & CA_WIZARD)
                  && !Wizard(player))
               || (  (fbe->listperm & CA_GOD)
                  && !God(player)))
            {
                continue;
            }

            // Don't show CONNECT on dark wizards to mortals
            //
            if (  flagtype == TYPE_PLAYER
               && fbe->flagflag == FLAG_WORD2
               && fbe->flagvalue == CONNECTED
               && (fs->word[FLAG_WORD1] & (WIZARD | DARK)) == (WIZARD | DARK)
               && !See_Hidden(player))
            {
                continue;
            }

            if (  bNeedColon
               && mux_isdigit(fbe->flaglett))
            {
                // We can't allow numerical digits at the beginning.
                //
                safe_sb_chr(':', buf, &bp);
            }
            safe_sb_chr(fbe->flaglett, buf, &bp);
            bNeedColon = false;
        }
    }
    *bp = '\0';
    return buf;
}
Ejemplo n.º 8
0
char *unparse_flags( dbref player, dbref thing ) {
    char *buf, *bp, *s;

    FLAGENT *fp;

    int flagtype;

    FLAG fv, flagword, flag2word, flag3word;

    buf = bp = s = alloc_sbuf( "unparse_flags" );
    *bp = '\0';

    if( !Good_obj( player ) || !Good_obj( thing ) ) {
        strcpy( buf, "#-2 ERROR" );
        return buf;
    }
    flagword = Flags( thing );
    flag2word = Flags2( thing );
    flag3word = Flags3( thing );
    flagtype = ( flagword & TYPE_MASK );
    if( object_types[flagtype].lett != ' ' ) {
        safe_sb_chr( object_types[flagtype].lett, buf, &bp );
    }

    for( fp = gen_flags; fp->flagname; fp++ ) {
        if( fp->flagflag & FLAG_WORD3 ) {
            fv = flag3word;
        } else if( fp->flagflag & FLAG_WORD2 ) {
            fv = flag2word;
        } else {
            fv = flagword;
        }
        if( fv & fp->flagvalue ) {

            if( ( fp->listperm & CA_WIZARD ) && !Wizard( player ) ) {
                continue;
            }
            if( ( fp->listperm & CA_GOD ) && !God( player ) ) {
                continue;
            }

            /*
             * don't show CONNECT on dark wizards to mortals
             */

            if( ( flagtype == TYPE_PLAYER ) && isConnFlag( fp ) &&
                    Can_Hide( thing ) && Hidden( thing ) &&
                    !See_Hidden( player ) ) {
                continue;
            }

            /*
             * Check if this is a marker flag and we're at the
             * beginning of a buffer. If so, we need to insert a
             * separator character first so we don't end up
             * running the dbref number into the flags.
             */
            if( ( s == bp ) && isMarkerFlag( fp ) ) {
                safe_sb_chr( MARK_FLAG_SEP, buf, &bp );
            }

            safe_sb_chr( fp->flaglett, buf, &bp );
        }
    }

    *bp = '\0';
    return buf;
}