/* Primitives package */ #include "copyright.h" #include "config.h" #include <sys/types.h> #include <stdio.h> #include <time.h> #include "db.h" #include "inst.h" #include "externs.h" #include "match.h" #include "interface.h" #include "params.h" #include "tune.h" #include "fbstrings.h" #include "interp.h" #include "inst.h" static struct inst *oper1, *oper2, *oper3, *oper4; static int result; static dbref ref; static char buf[BUFFER_LEN]; struct tm *time_tm; void prim_time(PRIM_PROTOTYPE) { CHECKOP(0); CHECKOFLOW(3); { time_t lt; struct tm *tm; lt = time(NULL); tm = localtime(<); result = tm->tm_sec; PushInt(result); result = tm->tm_min; PushInt(result); result = tm->tm_hour; PushInt(result); } } void prim_date(PRIM_PROTOTYPE) { CHECKOP(0); CHECKOFLOW(3); { time_t lt; struct tm *tm; lt = time(NULL); tm = localtime(<); result = tm->tm_mday; PushInt(result); result = tm->tm_mon + 1; PushInt(result); result = tm->tm_year + 1900; PushInt(result); } } void prim_gmtoffset(PRIM_PROTOTYPE) { CHECKOP(0); CHECKOFLOW(1); result = get_tz_offset(); PushInt(result); } void prim_systime(PRIM_PROTOTYPE) { CHECKOP(0); result = time(NULL); CHECKOFLOW(1); PushInt(result); } void prim_systime_precise(PRIM_PROTOTYPE) { struct timeval fulltime; double dbltime; CHECKOP(0); gettimeofday(&fulltime, (struct timezone *) 0); CHECKOFLOW(2); dbltime = fulltime.tv_sec + (((double)fulltime.tv_usec) / 1.0e6); PushFloat(dbltime); } void prim_timesplit(PRIM_PROTOTYPE) { time_t lt = 0; CHECKOP(1); oper1 = POP(); /* integer: time */ if (oper1->type != PROG_INTEGER) abort_interp("Invalid argument"); lt = (time_t) oper1->data.number; time_tm = localtime(<); CHECKOFLOW(8); CLEAR(oper1); result = time_tm->tm_sec; PushInt(result); result = time_tm->tm_min; PushInt(result); result = time_tm->tm_hour; PushInt(result); result = time_tm->tm_mday; PushInt(result); result = time_tm->tm_mon + 1; PushInt(result); result = time_tm->tm_year + 1900; PushInt(result); result = time_tm->tm_wday + 1; PushInt(result); result = time_tm->tm_yday + 1; PushInt(result); } void prim_timefmt(PRIM_PROTOTYPE) { time_t lt = 0; CHECKOP(2); oper2 = POP(); /* integer: time */ oper1 = POP(); /* string: format */ if (oper1->type != PROG_STRING) abort_interp("Invalid argument (1)"); if (!oper1->data.string) abort_interp("Illegal NULL string (1)"); if (oper2->type != PROG_INTEGER) abort_interp("Invalid argument (2)"); lt = (time_t) oper2->data.number; time_tm = localtime(<); if (!format_time(buf, BUFFER_LEN, oper1->data.string->data, time_tm)) abort_interp("Operation would result in overflow."); CHECKOFLOW(1); CLEAR(oper1); CLEAR(oper2); PushString(buf); } void prim_userlog(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Non-string argument."); if (mlev < tp_userlog_mlev) abort_interp("Permission Denied (mlev < tp_userlog_mlev)"); if(oper1->data.string) { snprintf(buf,BUFFER_LEN,"%s",oper1->data.string->data); } else { *buf='\0'; } log_user(player, program, buf); CLEAR(oper1); return; } void prim_queue(PRIM_PROTOTYPE) { dbref temproom; /* int dbref string -- */ CHECKOP(3); oper1 = POP(); oper2 = POP(); oper3 = POP(); if (mlev < 3) abort_interp("Requires Mucker level 3 or better."); if (oper3->type != PROG_INTEGER) abort_interp("Non-integer argument (1)."); if (oper2->type != PROG_OBJECT) abort_interp("Argument must be a dbref (2)"); if (!valid_object(oper2)) abort_interp("Invalid dbref (2)"); if (Typeof(oper2->data.objref) != TYPE_PROGRAM) abort_interp("Object must be a program. (2)"); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (3)."); if ((oper4 = fr->variables + 1)->type != PROG_OBJECT) temproom = DBFETCH(player)->location; else temproom = oper4->data.objref; result = add_muf_delayq_event(oper3->data.number, fr->descr, player, temproom, NOTHING, oper2->data.objref, DoNullInd(oper1->data.string), "Queued Event.", 0); CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); PushInt(result); } void prim_kill(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) { do_abort_silent(); } else { if (mlev < 3) { if (!control_process(ProgUID, oper1->data.number)) { abort_interp("Permission Denied."); } } result = dequeue_process(oper1->data.number); } CLEAR(oper1); PushInt(result); } void prim_force(PRIM_PROTOTYPE) { struct inst *oper1 = NULL; /* prevents re-entrancy issues! */ struct inst *oper2 = NULL; /* prevents re-entrancy issues! */ int i; /* d s -- */ CHECKOP(2); oper1 = POP(); /* string to @force */ oper2 = POP(); /* player dbref */ if (mlev < 4) abort_interp("Wizbit only primitive."); if (fr->level > 8) abort_interp("Interp call loops not allowed."); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (2)."); if (oper2->type != PROG_OBJECT) abort_interp("Non-object argument (1)."); ref = oper2->data.objref; if (ref < 0 || ref >= db_top) abort_interp("Invalid object to force. (1)"); if (Typeof(ref) != TYPE_PLAYER && Typeof(ref) != TYPE_THING) abort_interp("Object to force not a thing or player. (1)"); if (!oper1->data.string) abort_interp("Null string argument (2)."); if (index(oper1->data.string->data, '\r')) abort_interp("Carriage returns not allowed in command string. (2)."); #ifdef GOD_PRIV if (God(oper2->data.objref) && !God(OWNER(program))) abort_interp("Cannot force god (1)."); #endif force_prog = program; force_level++; process_command(dbref_first_descr(oper2->data.objref), oper2->data.objref, oper1->data.string->data); force_level--; force_prog = NOTHING; for (i = 1; i <= fr->caller.top; i++) { if (Typeof(fr->caller.st[i]) != TYPE_PROGRAM) { do_abort_silent(); } } CLEAR(oper1); CLEAR(oper2); } void prim_timestamps(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_OBJECT) abort_interp("Non-object argument (1)."); if (!valid_object(oper1)) abort_interp("Invalid object."); CHECKREMOTE(oper1->data.objref); CHECKOFLOW(4); ref = oper1->data.objref; CLEAR(oper1); result = DBFETCH(ref)->ts.created; PushInt(result); result = DBFETCH(ref)->ts.modified; PushInt(result); result = DBFETCH(ref)->ts.lastused; PushInt(result); result = DBFETCH(ref)->ts.usecount; PushInt(result); } extern int top_pid; struct forvars *copy_fors(struct forvars *); struct tryvars *copy_trys(struct tryvars *); void prim_fork(PRIM_PROTOTYPE) { int i; struct frame *tmpfr; CHECKOP(0); CHECKOFLOW(1); if (mlev < 3) abort_interp("Permission Denied."); fr->pc = pc; tmpfr = (struct frame *) calloc(1, sizeof(struct frame)); tmpfr->next = NULL; tmpfr->system.top = fr->system.top; for (i = 0; i < fr->system.top; i++) tmpfr->system.st[i] = fr->system.st[i]; tmpfr->argument.top = fr->argument.top; for (i = 0; i < fr->argument.top; i++) copyinst(&fr->argument.st[i], &tmpfr->argument.st[i]); tmpfr->caller.top = fr->caller.top; for (i = 0; i <= fr->caller.top; i++) { tmpfr->caller.st[i] = fr->caller.st[i]; if (i > 0) PROGRAM_INC_INSTANCES(fr->caller.st[i]); } tmpfr->trys.top = fr->trys.top; tmpfr->trys.st = copy_trys(fr->trys.st); tmpfr->fors.top = fr->fors.top; tmpfr->fors.st = copy_fors(fr->fors.st); for (i = 0; i < MAX_VAR; i++) copyinst(&fr->variables[i], &tmpfr->variables[i]); localvar_dupall(tmpfr, fr); scopedvar_dupall(tmpfr, fr); tmpfr->error.is_flags = fr->error.is_flags; if (fr->rndbuf) { tmpfr->rndbuf = (void *) malloc(sizeof(unsigned long) * 4); if (tmpfr->rndbuf) { memcpy(tmpfr->rndbuf, fr->rndbuf, 16); } } else { tmpfr->rndbuf = NULL; } tmpfr->pc = pc; tmpfr->pc++; tmpfr->level = fr->level; tmpfr->already_created = fr->already_created; tmpfr->trig = fr->trig; tmpfr->brkpt.debugging = 0; tmpfr->brkpt.bypass = 0; tmpfr->brkpt.isread = 0; tmpfr->brkpt.showstack = 0; tmpfr->brkpt.lastline = 0; tmpfr->brkpt.lastpc = 0; tmpfr->brkpt.lastlisted = 0; tmpfr->brkpt.lastcmd = NULL; tmpfr->brkpt.breaknum = -1; tmpfr->brkpt.lastproglisted = NOTHING; tmpfr->brkpt.proglines = NULL; tmpfr->brkpt.count = 1; tmpfr->brkpt.temp[0] = 1; tmpfr->brkpt.level[0] = -1; tmpfr->brkpt.line[0] = -1; tmpfr->brkpt.linecount[0] = -2; tmpfr->brkpt.pc[0] = NULL; tmpfr->brkpt.pccount[0] = -2; tmpfr->brkpt.prog[0] = program; tmpfr->proftime.tv_sec = 0; tmpfr->proftime.tv_usec = 0; tmpfr->totaltime.tv_sec = 0; tmpfr->totaltime.tv_usec = 0; tmpfr->pid = top_pid++; tmpfr->multitask = BACKGROUND; tmpfr->been_background = 1; tmpfr->writeonly = 1; tmpfr->started = time(NULL); tmpfr->instcnt = 0; tmpfr->skip_declare = fr->skip_declare; tmpfr->wantsblanks = fr->wantsblanks; tmpfr->perms = fr->perms; tmpfr->descr = fr->descr; tmpfr->events = NULL; tmpfr->waiters = NULL; tmpfr->waitees = NULL; tmpfr->dlogids = NULL; tmpfr->timercount = 0; /* child process gets a 0 returned on the stack */ result = 0; push(tmpfr->argument.st, &(tmpfr->argument.top), PROG_INTEGER, MIPSCAST & result); result = add_muf_delay_event(0, fr->descr, player, NOTHING, NOTHING, program, tmpfr, "BACKGROUND"); /* parent process gets the child's pid returned on the stack */ if (!result) result = -1; PushInt(result); } void prim_pid(PRIM_PROTOTYPE) { CHECKOP(0); CHECKOFLOW(1); result = fr->pid; PushInt(result); } void prim_stats(PRIM_PROTOTYPE) { /* A WhiteFire special. :) */ CHECKOP(1); oper1 = POP(); if (mlev < 3) abort_interp("Requires Mucker Level 3."); if (!valid_player(oper1) && (oper1->data.objref != NOTHING)) abort_interp("non-player argument (1)"); ref = oper1->data.objref; CLEAR(oper1); { dbref i; int rooms, exits, things, players, programs, garbage; /* tmp, ref */ rooms = exits = things = players = programs = garbage = 0; for (i = 0; i < db_top; i++) { if (ref == NOTHING || OWNER(i) == ref) { switch (Typeof(i)) { case TYPE_ROOM: rooms++; break; case TYPE_EXIT: exits++; break; case TYPE_THING: things++; break; case TYPE_PLAYER: players++; break; case TYPE_PROGRAM: programs++; break; case TYPE_GARBAGE: garbage++; break; } } } ref = rooms + exits + things + players + programs + garbage; PushInt(ref); PushInt(rooms); PushInt(exits); PushInt(things); PushInt(programs); PushInt(players); PushInt(garbage); /* push results */ } } void prim_abort(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Invalid argument"); strcpy(buf, DoNullInd(oper1->data.string)); abort_interp(buf); } 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_parselock(PRIM_PROTOTYPE) { struct boolexp *lok; CHECKOP(1); oper1 = POP(); /* string: lock string */ CHECKOFLOW(1); if (oper1->type != PROG_STRING) abort_interp("Invalid argument."); if (oper1->data.string != (struct shared_string *) NULL) { lok = parse_boolexp(fr->descr, ProgUID, oper1->data.string->data, 0); } else { lok = TRUE_BOOLEXP; } CLEAR(oper1); PushLock(lok); free_boolexp(lok); } void prim_unparselock(PRIM_PROTOTYPE) { const char *ptr; CHECKOP(1); oper1 = POP(); /* lock: lock */ if (oper1->type != PROG_LOCK) abort_interp("Invalid argument."); if (oper1->data.lock != (struct boolexp *) TRUE_BOOLEXP) { ptr = unparse_boolexp(ProgUID, oper1->data.lock, 0); } else { ptr = NULL; } CHECKOFLOW(1); CLEAR(oper1); if (ptr) { PushString(ptr); } else { PushNullStr; } } 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_testlock(PRIM_PROTOTYPE) { struct inst *oper1 = NULL; /* prevents re-entrancy issues! */ struct inst *oper2 = NULL; /* prevents re-entrancy issues! */ /* d d - i */ CHECKOP(2); oper1 = POP(); /* boolexp lock */ oper2 = POP(); /* player dbref */ if (fr->level > 8) abort_interp("Interp call loops not allowed."); if (!valid_object(oper2)) abort_interp("Invalid argument (1)."); if (Typeof(oper2->data.objref) != TYPE_PLAYER && Typeof(oper2->data.objref) != TYPE_THING) { abort_interp("Invalid object type (1)."); } CHECKREMOTE(oper2->data.objref); if (oper1->type != PROG_LOCK) abort_interp("Invalid argument (2)."); result = eval_boolexp(fr->descr, oper2->data.objref, oper1->data.lock, player); CLEAR(oper1); CLEAR(oper2); PushInt(result); } void prim_sysparm(PRIM_PROTOTYPE) { const char *ptr; const char *tune_get_parmstring(const char *name, int mlev); CHECKOP(1); oper1 = POP(); /* string: system parm name */ if (oper1->type != PROG_STRING) abort_interp("Invalid argument."); if (oper1->data.string) { ptr = tune_get_parmstring(oper1->data.string->data, mlev); } else { ptr = ""; } CHECKOFLOW(1); CLEAR(oper1); PushString(ptr); } 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 (!string_compare(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_setsysparm(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); /* string: new parameter value */ oper2 = POP(); /* string: parameter to tune */ if (mlev < 4) abort_interp("Wizbit only primitive."); 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)"); if (!oper1->data.string) abort_interp("Null string argument. (2)"); result = tune_setparm(oper2->data.string->data, oper1->data.string->data); switch (result) { case 0: /* TUNESET_SUCCESS */ log_status("TUNED (MUF): %s(%d) tuned %s to %s\n", NAME(player), player, oper2->data.string->data, oper1->data.string->data); break; case 1: /* TUNESET_UNKNOWN */ abort_interp("Unknown parameter. (1)"); break; case 2: /* TUNESET_SYNTAX */ abort_interp("Bad parameter syntax. (2)"); break; case 3: /* TUNESET_BADVAL */ abort_interp("Bad parameter value. (2)"); break; } CLEAR(oper1); CLEAR(oper2); } void prim_sysparm_array(PRIM_PROTOTYPE) { stk_array *nu; 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), mlev); CLEAR(oper1); PushArrayRaw(nu); } void prim_timer_start(PRIM_PROTOTYPE) { CHECKOP(2); oper2 = POP(); /* string: timer id */ oper1 = POP(); /* int: delay length in seconds */ if (fr->timercount > tp_process_timer_limit) abort_interp("Too many timers!"); if (oper1->type != PROG_INTEGER) abort_interp("Expected an integer delay time. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected a string timer id. (2)"); dequeue_timers(fr->pid, DoNullInd(oper2->data.string)); add_muf_timer_event(fr->descr, player, program, fr, oper1->data.number, DoNullInd(oper2->data.string)); CLEAR(oper1); CLEAR(oper2); } void prim_timer_stop(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); /* string: timer id */ if (oper1->type != PROG_STRING) abort_interp("Expected a string timer id. (2)"); dequeue_timers(fr->pid, DoNullInd(oper1->data.string)); CLEAR(oper1); } 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_event_count(PRIM_PROTOTYPE) { CHECKOP(0); CHECKOFLOW(1); result = muf_event_count(fr); PushInt(result); } 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_pname_okp(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Player name string expected."); if (!oper1->data.string) abort_interp("Cannot be an empty string."); result = ok_player_name(oper1->data.string->data); CLEAR(oper1); PushInt(result); } void prim_name_okp(PRIM_PROTOTYPE) { CHECKOP(1); oper1 = POP(); if (oper1->type != PROG_STRING) abort_interp("Object name string expected."); if (!oper1->data.string) abort_interp("Cannot be an empty string."); result = ok_name(oper1->data.string->data); CLEAR(oper1); PushInt(result); } void prim_force_level(PRIM_PROTOTYPE) { CHECKOFLOW(1); PushInt(force_level); } void prim_watchpid(PRIM_PROTOTYPE) { struct frame *frame; CHECKOP(1); oper1 = POP(); if (mlev < 3) { abort_interp("Mucker level 3 required."); } if (oper1->type != PROG_INTEGER) { abort_interp("Process PID expected."); } /* Lets see if the batbat catches this one. */ /* Heh. - Revar */ if (oper1->data.number == fr->pid) { abort_interp("Narcissistic processes not allowed."); } frame = timequeue_pid_frame (oper1->data.number); if (frame) { struct mufwatchpidlist **cur; struct mufwatchpidlist *waitee; for (cur = &frame->waiters; *cur; cur = &(*cur)->next) { if ((*cur)->pid == oper1->data.number) { break; } } if (!*cur) { *cur = (struct mufwatchpidlist*) malloc (sizeof (**cur)); if (!*cur) { abort_interp ("Internal memory error.\n"); } (*cur)->next = 0; (*cur)->pid = fr->pid; waitee = (struct mufwatchpidlist*) malloc (sizeof (*waitee)); if (!waitee) { abort_interp ("Internal memory error.\n"); } waitee->next = fr->waitees; waitee->pid = oper1->data.number; fr->waitees = waitee; } } else { char buf[64]; snprintf (buf, sizeof(buf), "PROC.EXIT.%d", oper1->data.number); muf_event_add(fr, buf, oper1, 0); } CLEAR (oper1); } void prim_read_wants_blanks(PRIM_PROTOTYPE) { fr->wantsblanks = 1; } void prim_debugger_break(PRIM_PROTOTYPE) { int i = 0; if (fr->brkpt.count >= MAX_BREAKS) abort_interp("Too many breakpoints set."); fr->brkpt.force_debugging = 1; if (fr->brkpt.count != 1 || fr->brkpt.temp[0] != 1 || fr->brkpt.level[0] != -1 || fr->brkpt.line[0] != -1 || fr->brkpt.linecount[0] != -2 || fr->brkpt.pc[0] != NULL || fr->brkpt.pccount[0] != -2 || fr->brkpt.prog[0] != program ) { /* No initial breakpoint. Lets make one. */ i = fr->brkpt.count++; fr->brkpt.temp[i] = 1; fr->brkpt.level[i] = -1; fr->brkpt.line[i] = -1; fr->brkpt.linecount[i] = -2; fr->brkpt.pc[i] = NULL; fr->brkpt.pccount[i] = 0; fr->brkpt.prog[i] = NOTHING; } } 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); } void prim_ignore_add(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_add_player(oper2->data.objref, oper1->data.objref); CLEAR(oper1); CLEAR(oper2); } 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_debug_on(PRIM_PROTOTYPE) { FLAGS(program) |= DARK; DBDIRTY(program); } void prim_debug_off(PRIM_PROTOTYPE) { FLAGS(program) &= ~DARK; DBDIRTY(program); } void prim_debug_line(PRIM_PROTOTYPE) { if (((FLAGS(program) & DARK) == 0) && controls(player, program)) { char* msg = debug_inst(fr, 0, pc, fr->pid, arg, buf, sizeof(buf), *top, program); notify_nolisten(player, msg, 1); } }