#include "prims.h" #include "config.h" #include "mush.h" /* private globals */ extern inst *p_oper1, *p_oper2, *p_oper3, *p_oper4; extern int p_nargs; extern int p_result; extern frame *frame_list; extern dbref p_ref; extern char p_buf[BUFFER_LEN]; line *get_new_line(); void do_insert_quit(dbref player, dbref p_ref, int flag); void prims_notify (__P_PROTO) { CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (!valid_object(p_oper2)) abort_interp("Non-object argument (1)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (p_oper1->data.string) #ifdef HOWARD /* FIX ME! */ notify(player, p_oper2->data.objref, p_oper1->data.string); #else notify(player, p_oper2->data.objref, p_oper1->data.string); #endif CLEAR(p_oper1); CLEAR(p_oper2); } void prims_notify_nolisten (__P_PROTO) { CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (!valid_object(p_oper2)) abort_interp("Non-object argument (1)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (!p_oper1->data.string) abort_interp("Null string argument (2)"); if (!fr->wizard) abort_interp("Permission denied."); notify_nolisten(p_oper2->data.objref, p_oper1->data.string); CLEAR(p_oper1); CLEAR(p_oper2); } void prims_notify_except (__P_PROTO) { CHECKOP(3); p_oper1 = POP(); p_oper2 = POP(); p_oper3 = POP(); if (!valid_object(p_oper3)) abort_interp("Invalid argument (1)"); if (p_oper2->type != PROG_OBJECT) abort_interp("Invalid object argument (2)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (3)"); if (p_oper1->data.string) notify_except(player, p_oper3->data.objref, p_oper2->data.objref, p_oper1->data.string); CLEAR(p_oper1); CLEAR(p_oper2); CLEAR(p_oper3); } void prims_notify_except_nolisten (__P_PROTO) { CHECKOP(3); p_oper1 = POP(); p_oper2 = POP(); p_oper3 = POP(); if (!valid_object(p_oper3)) abort_interp("Invalid argument (1)"); if (p_oper2->type != PROG_OBJECT) abort_interp("Invalid object argument (2)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (3)"); if (!p_oper1->data.string) abort_interp("Null string argument (3)"); if (!fr->wizard) abort_interp("Permission denied."); notify_except_nolisten(player, p_oper3->data.objref, p_oper2->data.objref, p_oper1->data.string); CLEAR(p_oper1); CLEAR(p_oper2); CLEAR(p_oper3); } /* FORCE ( d s -- ) <- forces a dbref to do an action */ void prims_force (__P_PROTO) { char str[BUFFER_LEN]; dbref who; CHECKOP(2); p_oper2 = POP(); p_oper1 = POP(); if(!valid_object(p_oper1)) abort_interp("Invalid argument (1)"); if(p_oper2->type != PROG_STRING) abort_interp("Non-string argument (2)"); if(!p_oper2->data.string) abort_interp("Empty string argument (2)"); if(!controls(fr->euid, p_oper1->data.objref) && (!(FLAGS(program) & GOD) && !(FLAGS(OWNER(program)) & GOD))) abort_interp("Permission denied."); who=p_oper1->data.objref; if(FLAGS(who) & INTERACTIVE) abort_interp("Object is in interactive mode."); strcpy(str, p_oper2->data.string); #ifdef MUSH if((FLAGS(who) & HAVEN) && Typeof(who) != TYPE_PLAYER) abort_interp("Object is set HALT."); /* parse_que(who, str, who); */ process_command(who, str, who); #else process_command(who, str, who); #endif /* MUSH */ CLEAR(p_oper1); CLEAR(p_oper2); } /* From here on out are prims to control/get info on running MUF processes */ void prims_processes(__P_PROTO) { int frames; frame *fr1; for(fr1 = frame_list, frames = 0; fr1; fr1 = fr1->next) { if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); p_result = fr1->pid; push(arg, top, PROG_INTEGER, MIPSCAST &p_result); frames++; } if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); push(arg, top, PROG_INTEGER, MIPSCAST &frames); } void prims_pidkill(__P_PROTO) { frame *fr1; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_INTEGER) abort_interp("Operand not an integer."); switch(p_oper1->data.number) { case -2: if (fr->wizard) { for(fr1 = frame_list; fr1; fr1 = fr1->next) fr1->status = STATUS_DEAD; } else abort_interp("Permission denied."); return; case -1: for(fr1 = frame_list; fr1; fr1 = fr1->next) { if (fr1->player == player) fr1->status = STATUS_DEAD; } return; default: if((fr1 = find_frame(p_oper1->data.number))) { if (controls(player, fr1->euid)) { if((FLAGS(fr1->player) & INTERACTIVE) && (fr1->pid == DBFETCH(fr1->player)->sp.player.pid)) FLAGS(fr1->player) &= ~INTERACTIVE; free_frame(fr1); CLEAR(p_oper1); } else abort_interp("Permission denied."); } else abort_interp ("No such process."); } } void prims_go(__P_PROTO) { frame *fr1; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_INTEGER) abort_interp("Operand not an integer."); if((fr1 = find_frame(p_oper1->data.number))) { if ((fr->wizard) || (fr1->player == player)) { fr1->status = STATUS_RUN; } else abort_interp("Permission denied."); } else abort_interp ("No such process."); } void prims_sleeptime(__P_PROTO) { frame *fr1; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_INTEGER) abort_interp("Operand not an integer."); if((fr1 = find_frame(p_oper1->data.number))) { if (fr1->status == STATUS_SLEEP) p_result = (fr1->sleeptime - time(NULL)); else p_result = 0; push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } else abort_interp ("No such process."); } void prims_piddbref (__P_PROTO) { frame *fr1; CHECKOP(1); p_oper1 = POP(); if (!p_oper1->type == PROG_INTEGER) abort_interp("Operand not an integer."); if ((fr1 = find_frame(p_oper1->data.number))) p_ref=fr1->prog; else p_ref = (dbref)0; push(arg, top, PROG_OBJECT, MIPSCAST &p_ref); CLEAR(p_oper1); } void prims_pid(__P_PROTO) { p_result = fr->pid; push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_isapid(__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_INTEGER) abort_interp("Non-integer argument"); p_result = find_a_frame(p_oper1->data.number); CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_foreground(__P_PROTO) { if(fr->wizard) fr->endless = '1'; else abort_interp("Permission denied."); } void prims_compile(__P_PROTO) { CHECKOP(1); p_oper1 = POP(); if(!valid_object(p_oper1)) abort_interp("Invalid argument (1)"); p_ref =p_oper1->data.objref; if(Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Non-program argument"); if(!fr->wizard || !controls(player, p_ref)) abort_interp("Permission denied."); /* try to compile it... */ DBSTORE(p_ref, sp.program.first, read_program(p_ref)); do_compile(player, p_ref); free_prog_text(DBFETCH(p_ref)->sp.program.first); if (DBFETCH(p_ref)->sp.program.start == 0) p_result = 0; else p_result = DBFETCH(p_oper1->data.objref)->sp.program.siz; CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_uncompile(__P_PROTO) { char buf[200]; CHECKOP(1); p_oper1 = POP(); if(!valid_object(p_oper1)) abort_interp("Invalid argument (1)"); p_ref =p_oper1->data.objref; if(Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Non-program argument"); if(!fr->wizard || !controls(player, p_ref)) abort_interp("Permission denied."); sprintf (buf, "Program %s uncompiled by %s", unparse_name(p_ref), unparse_name(player)); bump_frames(buf, p_ref, player); free_prog(DBFETCH(p_ref)->sp.program.code, DBFETCH(p_ref)->sp.program.siz); /* cleanpubs(DBFETCH(p_ref)->sp.program.pubs); */ /* DBFETCH(p_ref)->sp.program.pubs = NULL; */ DBFETCH(p_ref)->sp.program.first = 0; DBFETCH(p_ref)->sp.program.curr_line = 0; DBFETCH(p_ref)->sp.program.siz = 0; DBFETCH(p_ref)->sp.program.code = 0; DBFETCH(p_ref)->sp.program.start = 0; CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_newprogram(__P_PROTO) { char buf[300]; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument."); if (!p_oper1->data.string) abort_interp("NULL argument"); if (!Wizard(fr->euid) || Typeof(fr->euid) != TYPE_PLAYER) abort_interp("Permission denied"); p_ref = new_object(); DBSTORE(p_ref, name, dup_string(p_oper1->data.string)); sprintf(buf, "A scroll containing a spell called %s", p_oper1->data.string); #ifndef USE_DBP_STR DBSTORE(p_ref, desc, dup_string(buf)); #else add_property(p_ref, "desc", buf, PERMS_COREAD | PERMS_COWRITE | PERMS_OTREAD, ACCESS_CO); #endif DBSTORE(p_ref, location, fr->euid); DBSTORE(p_ref, link, fr->euid); add_backlinks(p_ref); DBSTORE(p_ref, owner, fr->euid); add_ownerlist(p_ref); FLAGS(p_ref) = TYPE_PROGRAM; DBSTORE(p_ref, sp.program.first, 0); DBSTORE(p_ref, sp.program.curr_line, 0); DBSTORE(p_ref, sp.program.siz, 0); DBSTORE(p_ref, sp.program.code, 0); DBSTORE(p_ref, sp.program.start, 0); DBSTORE(p_ref, sp.program.editlocks, NULL); /* DBSTORE(fr->euid, curr_prog, p_ref); */ PUSH(p_ref, DBFETCH(fr->euid)->contents); DBDIRTY(p_ref); DBDIRTY(fr->euid); p_result = (int) p_ref; CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_prog_size(__P_PROTO) { if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); p_result = DBFETCH(p_oper1->data.objref)->sp.program.siz; push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_new_macro(__P_PROTO) { macrotable *newmacro; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_STRING || p_oper2->type != PROG_STRING) abort_interp("Non-string argument."); if (!p_oper1->data.string || !p_oper1->data.string) abort_interp("NULL argument."); newmacro = new_macro (p_oper2->data.string, p_oper1->data.string, fr->euid); if (!macrotop) macrotop = newmacro; else if (!grow_macro_tree(macrotop, newmacro)) p_result = 0; else p_result = 1; CLEAR(p_oper1); CLEAR(p_oper2); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_kill_macro(__P_PROTO) { char tmp[BUFFER_LEN]; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument."); if (!p_oper1->data.string) abort_interp("NULL argument."); if (!fr->wizard) abort_interp("Permission denied"); strcpy(tmp, p_oper1->data.string); if (!string_compare(tmp, macrotop->name)) { macrotable *macrotemp = macrotop; int whichway = (macrotop->left) ? 1 : 0; macrotop = whichway ? macrotop->left : macrotop->right; if (macrotop && (whichway ? macrotemp->right : macrotemp->left)) grow_macro_tree(macrotop, whichway ? macrotemp->right : macrotemp->left); free ((void *) macrotemp); p_result =1; } else if (erase_node(macrotop, macrotop, tmp)) p_result =1; else p_result =0; CLEAR(p_oper1); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_get_macro(__P_PROTO) { char *tmp; CHECKOP(1); p_oper1 = POP(); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument."); if (!p_oper1->data.string) abort_interp("NULL argument."); if (!(tmp = (char *)macro_expansion(macrotop, p_oper1->data.string))) strcpy(p_buf, ""); else strcpy(p_buf, tmp); CLEAR(p_oper1); push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf)); } void prims_delete(__P_PROTO) { line *curr, *temp; int i, one=0, two=0, flag=0; CHECKOP(2); p_oper1 = POP(); p_oper2 = POP(); if (p_oper1->type != PROG_INTEGER) abort_interp("Non-interger argument."); if (p_oper2->type == PROG_INTEGER) { CHECKOP(1); p_oper3 = POP(); if (!valid_object(p_oper3)) abort_interp("Non-object argument (3)"); one = p_oper2->data.number; if (one <= 0) abort_interp("Negative/zero line number.(2)"); flag++; } two = p_oper1->data.number; if (two <= 0) abort_interp("Negative/zero line number.(1)"); if(flag) p_ref = p_oper3->data.objref; else p_ref = p_oper2->data.objref; if (Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Invalid PROGRAM(2)"); if (!controls(player, p_ref)) abort_interp("Permission denied"); if (DBFETCH(p_ref)->sp.program.editlocks != NULL) abort_interp("That program is being edited."); if(!flag) one = two; if (one > two) abort_interp("Nonsensical arguments."); DBSTORE(p_ref, sp.program.first, read_program(p_ref)); DBSTORE(player, curr_prog, p_ref); DBSTORE(p_ref, sp.program.editlocks, dbreflist_add(DBFETCH(p_ref)->sp.program.editlocks, player)); DBDIRTY(player); DBDIRTY(p_ref); i = one - 1; for (curr = DBFETCH(p_ref)->sp.program.first; curr && i; i--) curr = curr->next; if (curr) { DBFETCH(p_ref)->sp.program.curr_line = one; i = two - one + 1; /* delete n lines */ while (i && curr) { temp = curr; if (curr->prev) curr->prev->next = curr->next; else DBFETCH(p_ref)->sp.program.first = curr->next; if (curr->next) curr->next->prev = curr->prev; curr = curr->next; free_line(temp); i--; } p_result = two - one - i + 1; } else p_result = 0; do_insert_quit(player, p_ref, flag); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } void prims_insert(__P_PROTO) { dbref edprog; int i; line *curr; line *new_line; CHECKOP(3); p_oper1 = POP(); p_oper2 = POP(); p_oper3 = POP(); if (!valid_object(p_oper3)) abort_interp("Non-object argument (1)"); if (p_oper2->type != PROG_INTEGER) abort_interp("Non-integer argument (2)"); if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument (3)"); p_result = p_oper2->data.number; if (p_result <= 0) abort_interp("Negative/zero line number.(1)"); p_ref = p_oper3->data.objref; if (Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Invalid PROGRAM(2)"); if (!controls(fr->euid, p_ref)) abort_interp("Permission denied"); if (DBFETCH(p_ref)->sp.program.editlocks != NULL) abort_interp("That program is being edited."); if(!p_oper1->data.string) abort_interp("NULL argument. (3)"); strcpy(p_buf, p_oper1->data.string); DBFETCH(player)->sp.player.insert_mode++; DBSTORE(p_ref, sp.program.first, read_program(p_ref)); DBSTORE(player, curr_prog, p_ref); DBSTORE(p_ref, sp.program.editlocks, dbreflist_add(DBFETCH(p_ref)->sp.program.editlocks, player)); DBDIRTY(player); DBDIRTY(p_ref); edprog = DBFETCH(player)->curr_prog; i = DBFETCH(edprog)->sp.program.curr_line - 1; for (curr = DBFETCH(edprog)->sp.program.first; curr && i && i + 1; i--, curr = curr->next); new_line = get_new_line(); /* initialize line */ new_line->this_line = dup_string(p_buf); if (!DBFETCH(edprog)->sp.program.first) /* nothing --- insert in front */ { DBFETCH(edprog)->sp.program.first = new_line; DBFETCH(edprog)->sp.program.curr_line = 2; /* insert at the end */ DBDIRTY(edprog); do_insert_quit(player, p_ref, 1); return; } if (!curr) /* insert at the end */ { i = 1; for (curr = DBFETCH(edprog)->sp.program.first; curr->next; curr = curr->next, i++); DBFETCH(edprog)->sp.program.curr_line = i + 2; new_line->prev = curr; curr->next = new_line; DBDIRTY(edprog); do_insert_quit(player, p_ref, 1); return; } if (!DBFETCH(edprog)->sp.program.curr_line) /* insert at the beginning */ { DBFETCH(edprog)->sp.program.curr_line = 1; /* insert after this new line */ new_line->next = DBFETCH(edprog)->sp.program.first; DBFETCH(edprog)->sp.program.first = new_line; DBDIRTY(edprog); do_insert_quit(player, p_ref, 1); return; } /* inserting in the middle */ DBFETCH(edprog)->sp.program.curr_line++; new_line->prev = curr; new_line->next = curr->next; if (new_line->next) new_line->next->prev = new_line; curr->next = new_line; DBDIRTY(edprog); do_insert_quit(player, p_ref, 1); } void do_insert_quit(dbref player, dbref p_ref, int flag) { write_program(DBFETCH(p_ref)->sp.program.first, p_ref); free_prog_text(DBFETCH(p_ref)->sp.program.first); DBSTORE(p_ref, sp.program.editlocks, dbreflist_remove(DBFETCH(p_ref)->sp.program.editlocks, player)); DBSTORE(player, curr_prog, NOTHING); DBFETCH(player)->sp.player.insert_mode =0; DBDIRTY(player); DBDIRTY(p_ref); CLEAR(p_oper1); CLEAR(p_oper2); if(flag) CLEAR(p_oper3); } void prims_getlines(__P_PROTO) { line *curr; int i, count, one, two; CHECKOP(3); p_oper1 = POP(); p_oper2 = POP(); p_oper3 = POP(); if (!valid_object(p_oper3)) abort_interp("Non-object argument (1)"); if (p_oper2->type != PROG_INTEGER || p_oper1->type != PROG_INTEGER) abort_interp("Non-integer arguments"); one = p_oper2->data.number; two = p_oper1->data.number; p_ref = p_oper3->data.objref; if (Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Non-program object"); if (!(controls(player, p_ref) || Linkable(p_ref))) abort_interp("Permission denied."); if (DBFETCH(p_ref)->sp.program.editlocks != NULL) abort_interp("That program is being edited."); if ((one > two) && (two != -1)) abort_interp("Arguments don't make sense!"); DBSTORE(p_ref, sp.program.first, read_program(p_ref)); DBDIRTY(p_ref); i = one - 1; for (curr = DBFETCH(p_ref)->sp.program.first; i && curr; i--, curr = curr->next); if (curr) { i = two - one + 1; /* display n lines */ for (count = one; curr && (i || (two == -1)); i--) { if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); sprintf(p_buf, "%s", DoNull(curr->this_line)); push(arg, top, PROG_STRING, MIPSCAST dup_string(p_buf)); count++; curr = curr->next; } if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); p_result = count - one; push(arg, top, PROG_INTEGER, MIPSCAST &p_result); } else abort_interp("Line not available."); if (!(FLAGS(p_ref) & INTERNAL)) free_prog_text(DBFETCH(p_ref)->sp.program.first); CLEAR(p_oper1); CLEAR(p_oper2); CLEAR(p_oper3); } void prims_prog_lines(__P_PROTO) { line *curr; CHECKOP(1); p_oper1 = POP(); if (!valid_object(p_oper1)) abort_interp("Non-object argument (1)"); p_ref = p_oper1->data.objref; if(Typeof(p_ref) != TYPE_PROGRAM) abort_interp("Non-program object"); if (DBFETCH(p_ref)->sp.program.editlocks != NULL) abort_interp("That program is being edited."); DBSTORE(p_ref, sp.program.first, read_program(p_ref)); DBDIRTY(p_ref); curr = DBFETCH(p_ref)->sp.program.first; if (curr) for(p_result = 0; curr; curr = curr->next) p_result++; else p_result=0; if (*top >= STACK_SIZE) abort_interp("Stack Overflow!"); push(arg, top, PROG_INTEGER, MIPSCAST &p_result); if (!(FLAGS(p_ref) & INTERNAL)) free_prog_text(DBFETCH(p_ref)->sp.program.first); CLEAR(p_oper1); }