void prim_event_exists(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); /* str: eventID to look for */ if (oper1->type != PROG_STRING || !oper1->data.string) abort_interp("Expected a non-null string eventid to search for."); result = muf_event_exists(fr, oper1->data.string->data); CLEAR(oper1); PushInt(result); }
void prim_prettylock(PRIM_PROTOTYPE) { const char *ptr; CHECKOP(1); oper1 = POP(); /* lock: lock */ if (oper1->type != PROG_LOCK) abort_interp("Invalid argument"); ptr = unparse_boolexp(ProgUID, oper1->data.lock, 1); CHECKOFLOW(1); CLEAR(oper1); PushString(ptr); }
void prim_lreverse(PRIM_PROTOTYPE) { int i; CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_INTEGER) abort_interp("Invalid argument type."); tmp = oper1->data.number; /* Depth on stack */ if (tmp < 0) abort_interp("Argument must be positive."); CHECKOP(tmp); if (tmp > 0) { for (i = 0; i < (tmp / 2); i++) { temp2 = arg[*top - (tmp - i)]; arg[*top - (tmp - i)] = arg[*top - (i + 1)]; arg[*top - (i + 1)] = temp2; } } CLEAR(oper1); PushInt(tmp); }
void prim_interp(PRIM_PROTOTYPE) { struct inst *oper1 = NULL; /* prevents re-entrancy issues! */ struct inst *oper2 = NULL; /* prevents re-entrancy issues! */ struct inst *oper3 = NULL; /* prevents re-entrancy issues! */ struct inst *rv=NULL; char buf[BUFFER_LEN]; struct frame *tmpfr; CHECKOP(3); oper3 = POP(); /* string -- top stack argument */ oper2 = POP(); /* dbref -- trigger */ oper1 = POP(); /* dbref -- Program to run */ if (!valid_object(oper1) || Typeof(oper1->data.objref) != TYPE_PROGRAM) abort_interp("Bad program reference. (1)"); if (!valid_object(oper2)) abort_interp("Bad object. (2)"); if ((mlev < 3) && !permissions(ProgUID, oper2->data.objref)) abort_interp("Permission denied."); if (fr->level > 8) abort_interp("Interp call loops not allowed."); CHECKREMOTE(oper2->data.objref); strcpyn(buf, sizeof(buf), match_args); strcpyn(match_args, sizeof(match_args), oper3->data.string ? oper3->data.string->data : ""); tmpfr = interp(fr->descr, player, DBFETCH(player)->location, oper1->data.objref, oper2->data.objref, PREEMPT, STD_HARDUID, 0); if (tmpfr) { rv = interp_loop(player, oper1->data.objref, tmpfr, 1); } strcpyn(match_args, sizeof(match_args), buf); CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); if (rv) { if (rv->type < PROG_STRING) { push(arg, top, rv->type, MIPSCAST(&rv->data.number)); } else { push(arg, top, rv->type, MIPSCAST(rv->data.string)); } } else { PushNullStr; } }
void prim_fread(PRIM_PROTOTYPE) { FILE *fh; char *filename; double offset; char tempchr[2]; int result; CHECKOP(2); oper1 = POP(); oper2 = POP(); if (getuid() == 0 ) abort_interp("Muck is running under root privs, file prims disabled."); if (mlev < LBOY) abort_interp("BOY primitive only."); if(oper1->type != PROG_INTEGER) abort_interp("Arguement 1 is not an integer."); if(oper1->data.number < 0 ) abort_interp("Arguement 1 is a negative number."); if(oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string."); if(!oper2->data.string) abort_interp("Argueemnt 2 is a null string."); offset = oper1->data.number; filename = oper2->data.string->data; #ifdef SECURE_FILE_PRIMS if (!(valid_name(filename))) abort_interp( "Invalid file name."); if ( strchr( filename, '$' ) == NULL ) filename = set_directory(filename); else filename = parse_token( filename ); if ( filename == NULL ) abort_interp( "Invalid shortcut used." ); #endif fh = fopen(filename, "r"); if (fh == NULL) { result = 0; } else { fseek(fh, offset, SEEK_SET); tempchr[0] = (char) fgetc(fh); tempchr[1] = '\0'; fclose(fh); sprintf(buf, "%s", tempchr); result = 1; if(tp_log_files) log2filetime("logs/files", "#%d by %s FREAD: %s \n", program, unparse_object(player, player), oper2->data.string->data); if ( tempchr[0] == EOF ) result = 0; } CLEAR(oper1); CLEAR(oper2); if( result ) PushString(buf); else PushNullStr; }
void prim_bitand(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if (!arith_type(oper2, oper1)) abort_interp("Invalid argument type"); result = oper2->data.number & oper1->data.number; tmp = oper2->type; CLEAR(oper1); CLEAR(oper2); push(arg, top, tmp, MIPSCAST & result); }
void prim_logstatus(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (mlev < LARCH) abort_interp("Archwizard primitive."); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (1)."); if (oper1->data.string) { strcpy(buf, oper1->data.string->data); log_status("%s\r\n", buf); } CLEAR(oper1); }
void prim_online(PRIM_PROTOTYPE) { CHECKOP(0); if (mlev < (tp_compatible_muf ? LM3 : LM2)) abort_interp(tp_compatible_muf ? "M3 prim" : "M2 prim"); result = pcount(); CHECKOFLOW(result + 1); while (result) { ref = pdbref(result--); PushObject(ref); } result = pcount(); PushInt(result); }
void prim_nextdescr(PRIM_PROTOTYPE) { /* int -- int */ CHECKOP(1); oper1 = POP(); if (mlev < LM3) abort_interp("M3 prim"); if (oper1->type != PROG_INTEGER) abort_interp("Argument not an integer (1)"); result = oper1->data.number; result = pnextdescr(result); CLEAR(oper1); PushInt(result); }
void prim_awakep(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (!valid_object(oper1)) abort_interp("invalid argument"); ref = oper1->data.objref; if (Typeof(ref) == TYPE_THING && (FLAGS(ref) & ZOMBIE)) ref = OWNER(ref); if (Typeof(ref) != TYPE_PLAYER) abort_interp("invalid argument"); result = online(ref); PushInt(result); }
void prim_atan(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); if (!no_good(oper1->data.fnumber)) { fresult = atan(oper1->data.fnumber); } else { fresult = H_PI; } CLEAR(oper1); PushFloat(fresult); }
void prim_atan2(PRIM_PROTOTYPE) { CHECKOP(2); oper2 = POP(); oper1 = POP(); if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); if (oper2->type != PROG_FLOAT) abort_interp("Non-float argument. (2)"); fresult = atan2(oper1->data.fnumber, oper2->data.fnumber); CLEAR(oper1); CLEAR(oper2); PushFloat(fresult); }
void prim_put(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if (oper1->type != PROG_INTEGER || oper1->data.number <= 0) abort_interp("Operand not a positive integer."); tmp = oper1->data.number; EXPECT_WRITE_STACK(tmp); CLEAR(&arg[*top - tmp]); copyinst(oper2, &arg[*top - tmp]); CLEAR(oper1); CLEAR(oper2); }
void prim_ftostr(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if ( oper1->type == PROG_INTEGER ) { oper1->type = PROG_FLOAT; oper1->data.fnumber = oper1->data.number; } if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); sprintf(buf, "%#g", oper1->data.fnumber); CLEAR(oper1); PushString(buf); }
void prim_cancallp(PRIM_PROTOTYPE) { CHECKOP(2); oper2 = POP(); /* string: public function name */ oper1 = POP(); /* dbref: Program dbref to check */ if (oper1->type != PROG_OBJECT) abort_interp("Expected dbref argument. (1)"); if (!valid_object(oper1)) abort_interp("Invalid dbref (1)"); if (Typeof(oper1->data.objref) != TYPE_PROGRAM) abort_interp("Object is not a MUF Program. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected string argument. (2)"); if (!oper2->data.string) abort_interp("Invalid Null string argument. (2)"); if (!(PROGRAM_CODE(oper1->data.objref))) { struct line *tmpline; tmpline = PROGRAM_FIRST(oper1->data.objref); PROGRAM_SET_FIRST(oper1->data.objref, (struct line *) read_program(oper1->data.objref)); do_compile(-1, OWNER(oper1->data.objref), oper1->data.objref, 0); free_prog_text(PROGRAM_FIRST(oper1->data.objref)); PROGRAM_SET_FIRST(oper1->data.objref, tmpline); } result = 0; if (ProgMLevel(oper1->data.objref) > 0 && (mlev >= 4 || OWNER(oper1->data.objref) == ProgUID || Linkable(oper1->data.objref)) ) { struct publics *pbs; pbs = PROGRAM_PUBS(oper1->data.objref); while (pbs) { if (!strcasecmp(oper2->data.string->data, pbs->subname)) break; pbs = pbs->next; } if (pbs && mlev >= pbs->mlev) result = 1; } CHECKOFLOW(1); CLEAR(oper1); CLEAR(oper2); PushInt(result); }
void prim_ispidp(PRIM_PROTOTYPE) { /* i -- i */ CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_INTEGER) abort_interp("Non-integer argument (1)"); if (oper1->data.number == fr->pid) { result = 1; } else { result = in_timequeue(oper1->data.number); } CLEAR(oper1); PushInt(result); }
void prim_at(PRIM_PROTOTYPE) { CHECKOP(1); temp1 = *(oper1 = POP()); if ((temp1.type != PROG_VAR) && (temp1.type != PROG_LVAR)) abort_interp("Non-variable argument."); if (temp1.data.number >= MAX_VAR || temp1.data.number < 0) abort_interp("Variable number out of range."); if (temp1.type == PROG_LVAR) { copyinst(&(CurrVar[temp1.data.number]), &arg[(*top)++]); } else { copyinst(&(fr->variables[temp1.data.number]), &arg[(*top)++]); } CLEAR(&temp1); }
void prim_floor(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); if (!no_good(oper1->data.fnumber)) { fresult = (float) floor((double) oper1->data.fnumber); } else { fresult = 0.0; fr->error.error_flags.f_bounds = 1; } CLEAR(oper1); PushFloat(fresult); }
void prim_acos(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); if ((oper1->data.fnumber >= -1.0) && (oper1->data.fnumber <= 1.0)) { fresult = acos(oper1->data.fnumber); } else { fresult = 0.0; fr->error.error_flags.nan = 1; } CLEAR(oper1); PushFloat(fresult); }
void prim_conboot(PRIM_PROTOTYPE) { /* int -- */ CHECKOP(1); if (mlev < (tp_compatible_muf ? LMAGE : LARCH)) abort_interp(tp_compatible_muf ? "Mage prim" : "Arch prim"); oper1 = POP(); if (oper1->type != PROG_INTEGER) abort_interp("Argument not an integer (1)"); result = oper1->data.number; if ((result < 1) || (result > pcount())) abort_interp("Invalid connection number (1)"); CLEAR(oper1); pboot(result); }
void prim_forpop(PRIM_PROTOTYPE) { CHECKOP(0); if (!(fr->fors.top)) abort_interp("Internal error; FOR stack underflow."); CLEAR(&fr->fors.st->cur); CLEAR(&fr->fors.st->end); if (fr->trys.st) fr->trys.st->for_count--; fr->fors.top--; fr->fors.st = pop_for(fr->fors.st); }
void prim_sysparm_array(PRIM_PROTOTYPE) { stk_array *nu; int security = TUNE_MLEV(player); CHECKOP(1); oper1 = POP(); /* string: match pattern */ if (oper1->type != PROG_STRING) abort_interp("Expected a string smatch pattern."); nu = tune_parms_array(DoNullInd(oper1->data.string), security, fr->pinning); CLEAR(oper1); PushArrayRaw(nu); }
void prim_ignore_del(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if (mlev < 3) abort_interp("Permission Denied."); if (!valid_object(oper1)) abort_interp("Invalid object. (2)"); if (!valid_object(oper2)) abort_interp("Invalid object. (1)"); ignore_remove_player(oper2->data.objref, oper1->data.objref); CLEAR(oper1); CLEAR(oper2); }
void prim_setsysparm(PRIM_PROTOTYPE) { const char *oldvalue, *newvalue; int security = TUNE_MLEV(player); CHECKOP(2); oper1 = POP(); /* string: new parameter value */ oper2 = POP(); /* string: parameter to tune */ if (mlev < 4) abort_interp("Wizbit only primitive."); if (force_level) abort_interp("Cannot be forced."); if (oper2->type != PROG_STRING) abort_interp("Invalid argument. (1)"); if (!oper2->data.string) abort_interp("Null string argument. (1)"); if (oper1->type != PROG_STRING) abort_interp("Invalid argument. (2)"); oldvalue = tune_get_parmstring(oper2->data.string->data, security); newvalue = oper1->data.string ? oper1->data.string->data : ""; result = tune_setparm(oper2->data.string->data, newvalue, security); switch (result) { case TUNESET_SUCCESS: log_status("TUNED (MUF): %s(%d) tuned %s from '%s' to '%s'", NAME(player), player, oper2->data.string->data, oldvalue, newvalue); break; case TUNESET_UNKNOWN: abort_interp("Unknown parameter. (1)"); break; case TUNESET_SYNTAX: abort_interp("Bad parameter syntax. (2)"); break; case TUNESET_BADVAL: abort_interp("Bad parameter value. (2)"); break; case TUNESET_DENIED: abort_interp("Permission denied. (1)"); break; } CLEAR(oper1); CLEAR(oper2); }
void prim_event_send(PRIM_PROTOTYPE) { struct frame* destfr; stk_array *arr; struct inst temp1; CHECKOP(3); oper3 = POP(); /* any: data to pass */ oper2 = POP(); /* string: event id */ oper1 = POP(); /* int: process id to send to */ if (mlev < 3) abort_interp("Requires Mucker level 3 or better."); if (oper1->type != PROG_INTEGER) abort_interp("Expected an integer process id. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected a string event id. (2)"); if (oper1->data.number == fr->pid) destfr = fr; else destfr = timequeue_pid_frame(oper1->data.number); if (destfr) { arr = new_array_dictionary(); array_set_strkey(&arr, "data", oper3); array_set_strkey_intval(&arr, "caller_pid", fr->pid); array_set_strkey_intval(&arr, "descr", fr->descr); array_set_strkey_refval(&arr, "caller_prog", program); array_set_strkey_refval(&arr, "trigger", fr->trig); array_set_strkey_refval(&arr, "prog_uid", ProgUID); array_set_strkey_refval(&arr, "player", player); temp1.type = PROG_ARRAY; temp1.data.array = arr; snprintf(buf, sizeof(buf), "USER.%.32s", DoNullInd(oper2->data.string)); muf_event_add(destfr, buf, &temp1, 0); CLEAR(&temp1); } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); }
void prim_strtof(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Non-string argument. (1)"); fresult = 0.0; if (!oper1->data.string || !ifloat(oper1->data.string->data)) { fresult = 0.0; fr->error.error_flags.nan = 1; } else { sscanf(oper1->data.string->data, "%g", &fresult); } CLEAR(oper1); PushFloat(fresult); }
void prim_mod(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if ((!arith_type(oper2, oper1)) || (oper1->type == PROG_FLOAT) || (oper2->type == PROG_FLOAT)) abort_interp("Invalid argument type."); if (oper1->data.number) result = oper2->data.number % oper1->data.number; else result = 0; tmp = oper2->type; CLEAR(oper1); CLEAR(oper2); push(arg, top, tmp, MIPSCAST & result); }
void prim_cos(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_FLOAT) abort_interp("Non-float argument. (1)"); if (!no_good(oper1->data.fnumber)) { fresult = cos(oper1->data.fnumber); } else { /* FIXME: This should be NaN. */ fresult = 0.0; fr->error.error_flags.f_bounds = 1; } CLEAR(oper1); PushFloat(fresult); }
void prim_sysparm_array(PRIM_PROTOTYPE) { stk_array *nu; /* string */ CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Expected a string smatch pattern. (1)"); nu = tune_parms_array(DoNullInd(oper1->data.string), mlev); CLEAR(oper1); PushArrayRaw(nu); }
void prim_ignoringp(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if (mlev < 3) abort_interp("Permission Denied."); if (!valid_object(oper1)) abort_interp("Invalid object. (2)"); if (!valid_object(oper2)) abort_interp("Invalid object. (1)"); result = ignore_is_ignoring(oper2->data.objref, oper1->data.objref); CLEAR(oper1); CLEAR(oper2); PushInt(result); }