#include "prims.h" #include "params.h" /* private globals */ extern inst *p_oper1, *p_oper2, *p_oper3, *p_oper4; extern int p_result; static int tmp; extern int p_nargs; extern dbref p_ref; extern char p_buf[BUFFER_LEN]; void prims_addressp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = (p_oper1->type == PROG_ADD); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_numberp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_STRING || !p_oper1->data.string) p_result = 0; else p_result = number(p_oper1->data.string); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_playerp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) p_result = 0; else { p_ref = p_oper1->data.objref; p_result = (Typeof(p_ref) == TYPE_PLAYER); } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_thingp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) p_result = 0; else { p_ref = p_oper1->data.objref; p_result = (Typeof(p_ref) == TYPE_THING); } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_roomp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) p_result = 0; else { p_ref = p_oper1->data.objref; p_result = (Typeof(p_ref) == TYPE_ROOM); } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_programp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) p_result = 0; else { p_ref = p_oper1->data.objref; p_result = (Typeof(p_ref) == TYPE_PROGRAM); } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_exitp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) p_result = 0; else { p_ref = p_oper1->data.objref; p_result = (Typeof(p_ref) == TYPE_EXIT); } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_okp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = (valid_object(p_oper1)); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_flagp (__P_PROTO) { char *flag; FLAG *fst; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument type (2)"); if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)"); if (!valid_object(p_oper2)) abort_interp("Invalid object."); p_ref = p_oper2->data.objref; tmp = 0; p_result = 0; flag = p_oper1->data.string; if (p_result) flag++; if ((fst = flag_lookup(flag, p_ref)) != NULL) tmp = fst->flag; p_result = (tmp && ((FLAGS(p_ref) & tmp) != 0)); CLEAR(p_oper1); CLEAR(p_oper2); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_set (__P_PROTO) { char *flag; FLAG *fst; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument type (2)"); if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)"); if (!valid_object(p_oper2)) abort_interp("Invalid object."); p_ref = p_oper2->data.objref; tmp = 0; p_result = (*p_oper1->data.string == '!'); flag = p_oper1->data.string; if (p_result) flag++; if ((fst = flag_lookup(flag, p_ref)) != NULL) tmp = fst->flag; if (!tmp) abort_interp("Unrecognized flag."); if (!fr->wizard && !permissions(fr->euid, p_ref)) abort_interp("Permission denied."); if ((!fr->wizard & ((tmp & DARK) && Typeof(p_ref) != TYPE_ROOM) && (Typeof(p_ref) != TYPE_PROGRAM)) || (tmp & WIZARD) || (tmp & GOD) || (tmp & MUCKER)) abort_interp("Permission denied."); if (!p_result) { FLAGS(p_ref) |= tmp; DBDIRTY(p_ref); } else { FLAGS(p_ref) &= ~tmp; DBDIRTY(p_ref); } CLEAR(p_oper1); CLEAR(p_oper2); } void prims_stringp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = p_oper1->type; p_result = (p_result == PROG_STRING); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_dbrefp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = p_oper1->type; p_result = (p_result == PROG_OBJECT); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_intp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = p_oper1->type; p_result = (p_result == PROG_INTEGER); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_floatp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = p_oper1->type; p_result = (p_result == PROG_FLOAT); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_varp (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); p_result = p_oper1->type; p_result = (p_result == PROG_VAR); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } /**************************************** * getflags ( d -- i ) - get flags on an object ****************************************/ void prims_getflags (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1)) abort_interp("Invalid object."); if (!fr->wizard && (fr->euid != OWNER(p_oper1->data.objref))) abort_interp("Permission denied."); p_result = FLAGS(p_oper1->data.objref); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_locked (__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1) && !is_home(p_oper1)) abort_interp("Non-object argument."); if (DBFETCH(p_oper1->data.objref)->key == NULL) p_result = 0; else p_result = 1; CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } static int passlock_depth = 0; void prims_passlockp (__P_PROTO) { CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_OBJECT || p_oper2->type != PROG_OBJECT) abort_interp("Non-object argument."); passlock_depth++; if (passlock_depth < MAX_FRAMES_USER) p_result = eval_boolexp(p_oper2->data.objref, DBFETCH(p_oper1->data.objref)->key, p_oper1->data.objref); else p_result = 0; /* fail if too deep */ passlock_depth--; CLEAR(p_oper1); CLEAR(p_oper2); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_okplayer (__P_PROTO) { char *b; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (!valid_object(p_oper2)) abort_interp("Invalid object"); p_ref = p_oper2->data.objref; if (Typeof(p_ref) != TYPE_PLAYER) abort_interp("Non player object (1)"); if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)"); b = DoNullInd(p_oper1->data.string); p_result = 1; if (!ok_player_name(b, p_ref)) p_result = 0; if(o_taboonames) { if(!ok_taboo_name(p_ref, b, 1)) p_result = 0; } CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_controls (__P_PROTO) { CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_OBJECT || p_oper2->type != PROG_OBJECT) abort_interp("Non-object argument."); p_result = controls(p_oper2->data.objref, p_oper1->data.objref); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); CLEAR(p_oper1); CLEAR(p_oper2); } void prims_abort(__P_PROTO) { char p_buf[BUFFER_LEN]; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument"); if (!p_oper1->data.string) abort_interp("NULL argument"); strcpy(p_buf, DoNullInd(p_oper1->data.string)); abort_interp(p_buf); } #define ABORT_CHECKARGS(msg) { char zbuf[BUFFER_LEN]; if (*top == stackpos+1) sprintf(zbuf, "%s (top)", msg); else sprintf(zbuf, "%s (top-%d)", msg, ((*top)-stackpos-1)); abort_interp(zbuf); } #define MaxComplexity 18 /* A truly ridiculously high number! */ void prims_checkargs(__P_PROTO) { int currpos, stackpos; int rngstktop = 0; enum { itsarange, itsarepeat } rngstktyp[MaxComplexity]; int rngstkpos[MaxComplexity]; int rngstkcnt[MaxComplexity]; CHECKOP(1); p_oper1 = POP(); /* string argument */ if (p_oper1->type != PROG_STRING) abort_interp("Non string argument."); if (!p_oper1->data.string) { /* if null string, then no args expected. */ CLEAR(p_oper1); return; } strcpy(p_buf, p_oper1->data.string); /* copy into local buffer */ currpos = strlen(p_buf) - 1; stackpos = *top - 1; while (currpos >= 0) { if (isdigit(p_buf[currpos])) { if (rngstktop >= MaxComplexity) abort_interp("Argument expression ridiculously complex."); tmp = 1; p_result = 0; while ((currpos >= 0) && isdigit(p_buf[currpos])) { p_result = p_result + (tmp * (p_buf[currpos] - '0')); tmp = tmp * 10; currpos--; } if (p_result == 0) abort_interp("Bad multiplier '0' in argument expression."); if (p_result >= STACK_SIZE) abort_interp("Multiplier too large in argument expression."); rngstktyp[rngstktop] = itsarepeat; rngstkcnt[rngstktop] = p_result; rngstkpos[rngstktop] = currpos; rngstktop++; } else if (p_buf[currpos] == '}') { if (rngstktop >= MaxComplexity) abort_interp("Argument expression ridiculously complex."); if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_INTEGER) ABORT_CHECKARGS("Expected an integer range counter."); p_result = arg[stackpos].data.number; if (p_result < 0) ABORT_CHECKARGS("Range counter should be non-negative."); rngstkpos[rngstktop] = currpos - 1; rngstkcnt[rngstktop] = p_result; rngstktyp[rngstktop] = itsarange; rngstktop++; currpos--; if (p_result == 0) { while ((currpos > 0) && (p_buf[currpos] != '{')) currpos--; } stackpos--; } else if (p_buf[currpos] == '{') { if (rngstktop <= 0) abort_interp("Mismatched { in argument expression"); if (rngstktyp[rngstktop - 1] != itsarange) abort_interp("Misformed argument expression."); if (--rngstkcnt[rngstktop - 1] > 0) { currpos = rngstkpos[rngstktop - 1]; } else { rngstktop--; currpos--; if (rngstktop && (rngstktyp[rngstktop - 1] == itsarepeat)) { if (--rngstkcnt[rngstktop - 1] > 0) { currpos = rngstkpos[rngstktop - 1]; } else { rngstktop--; } } } } else { switch (p_buf[currpos]) { case 'i': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_INTEGER) ABORT_CHECKARGS("Expected an integer."); break; case 's': case 'S': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_STRING) ABORT_CHECKARGS("Expected a string."); if (p_buf[currpos] == 'S' && !arg[stackpos].data.string) ABORT_CHECKARGS("Expected a non-null string."); break; case 'd': case 'p': case 'r': case 't': case 'e': case 'f': case 'D': case 'P': case 'R': case 'T': case 'E': case 'F': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_OBJECT) ABORT_CHECKARGS("Expected a dbref."); p_ref = arg[stackpos].data.objref; if ((p_ref >= db_top) || (p_ref < HOME)) ABORT_CHECKARGS("Invalid dbref."); switch (p_buf[currpos]) { case 'D': if ((p_ref < 0) && (p_ref != HOME)) ABORT_CHECKARGS("Invalid dbref."); if (Typeof(p_ref) == TYPE_GARBAGE) ABORT_CHECKARGS("Invalid dbref."); case 'd': if (p_ref < HOME) ABORT_CHECKARGS("Invalid dbref."); break; case 'P': if (p_ref < 0) ABORT_CHECKARGS("Expected player dbref."); case 'p': if ((p_ref >= 0) && (Typeof(p_ref) != TYPE_PLAYER)) ABORT_CHECKARGS("Expected player dbref."); if (p_ref == HOME) ABORT_CHECKARGS("Expected player dbref."); break; case 'R': if ((p_ref < 0) && (p_ref != HOME)) ABORT_CHECKARGS("Expected room dbref."); case 'r': if ((p_ref >= 0) && (Typeof(p_ref) != TYPE_ROOM)) ABORT_CHECKARGS("Expected room dbref."); break; case 'T': if (p_ref < 0) ABORT_CHECKARGS("Expected thing dbref."); case 't': if ((p_ref >= 0) && (Typeof(p_ref) != TYPE_THING)) ABORT_CHECKARGS("Expected thing dbref."); if (p_ref == HOME) ABORT_CHECKARGS("Expected player dbref."); break; case 'E': if (p_ref < 0) ABORT_CHECKARGS("Expected exit dbref."); case 'e': if ((p_ref >= 0) && (Typeof(p_ref) != TYPE_EXIT)) ABORT_CHECKARGS("Expected exit dbref."); if (p_ref == HOME) ABORT_CHECKARGS("Expected player dbref."); break; case 'F': if (p_ref < 0) ABORT_CHECKARGS("Expected program dbref."); case 'f': if ((p_ref >= 0) && (Typeof(p_ref) != TYPE_PROGRAM)) ABORT_CHECKARGS("Expected program dbref."); if (p_ref == HOME) ABORT_CHECKARGS("Expected player dbref."); break; } break; case '?': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); break; case 'v': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_VAR) ABORT_CHECKARGS("Expected a variable."); break; case 'a': if (stackpos < 0) ABORT_CHECKARGS("Stack underflow."); if (arg[stackpos].type != PROG_ADD) ABORT_CHECKARGS("Expected a function address."); break; case ' ': /* this is meaningless space. Ignore it. */ stackpos++; break; default: abort_interp("Unkown argument type in expression."); break; } currpos--; /* decrement string index */ stackpos--; /* move on to next stack item down */ /* are we expecting a repeat of the last argument or range? */ if ((rngstktop > 0) && (rngstktyp[rngstktop - 1] == itsarepeat)) { /* is the repeat is done yet? */ if (--rngstkcnt[rngstktop - 1] > 0) { /* no, repeat last argument or range */ currpos = rngstkpos[rngstktop - 1]; } else { /* yes, we're done with this repeat */ rngstktop--; } } } } /* while loop */ if (rngstktop > 0) abort_interp("Badly formed argument expression."); /* Oops. still haven't finished a range or repeat expression. */ CLEAR(p_oper1); /* clear link to shared string */ } void prims_password (__P_PROTO) { char *pw; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (!valid_object(p_oper2)) abort_interp("Invalid argument type (1)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if(!(p_oper1->data.string)) abort_interp("Empty string argument (2)"); p_ref = p_oper2->data.objref; if (Typeof(p_ref) != TYPE_PLAYER) abort_interp("Non-player object type."); if (!fr->wizard && !permissions(fr->euid, p_ref)) abort_interp("Permission denied."); pw = DoNullInd(p_oper1->data.string); if(check_password(pw, p_ref)) p_result=0; else p_result=1; CLEAR(p_oper1); CLEAR(p_oper2); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); if (!p_result) { fr->status = STATUS_SLEEP; fr->sleeptime = time(NULL) + PWSLEEP; } }