void do_shutdown(dbref player) { if (Wizard(player)) { log_status("SHUTDOWN: by %s", unparse_object(player, player)); shutdown_flag = 1; restart_flag = 0; } else { notify(player, "Your delusions of grandeur have been duly noted."); log_status("ILLEGAL SHUTDOWN: tried by %s", unparse_object(player, player)); } }
void prim_frm(PRIM_PROTOTYPE) { char *filename; CHECKOP(1); oper1 = 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_STRING) abort_interp("Argument 1 is not a string."); if(!oper1->data.string) abort_interp("Argument 1 is a null string."); filename = oper1->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 result = unlink(filename); if(tp_log_files) log2filetime("logs/files", "#%d by %s FRM: %s \n", program, unparse_object(player, player), oper1->data.string->data); CLEAR(oper1); PushInt(result); }
/** Issue a warning about an object. * \param player player to receive the warning notification. * \param i object the warning is about. * \param name name of the warnings. * \param desc a formatting string for the warning message. */ void complain(dbref player, dbref i, const char *name, const char *desc, ...) { #ifdef HAS_VSNPRINTF char buff[BUFFER_LEN]; #else char buff[BUFFER_LEN * 3]; /* safety margin */ #endif va_list args; va_start(args, desc); #ifdef HAS_VSNPRINTF vsnprintf(buff, sizeof buff, desc, args); #else vsprintf(buff, desc, args); #endif buff[BUFFER_LEN - 1] = '\0'; va_end(args); notify_format(player, T("Warning '%s' for %s:"), name, unparse_object(player, i)); notify(player, buff); }
void prim_fsize(PRIM_PROTOTYPE) { FILE *fh; char *filename; int result; long offset; CHECKOP(1); oper1 = 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_STRING) abort_interp("Arguement 1 is not a string."); if (!oper1->data.string) abort_interp("Arguement 1 is a null string."); filename = oper1->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) { offset = -1; } else { fseek(fh, 0, SEEK_END); offset = ftell(fh); if(tp_log_files) log2filetime("logs/files", "#%d by %s FSIZE: %s \n", program, unparse_object(player, player), oper1->data.string->data); } fclose(fh); CLEAR(oper1); PushInt(offset); }
void log_program_text(struct line *first, dbref player, dbref i) { FILE *f; char fname[BUFFER_LEN]; time_t lt = time(NULL); strcpyn(fname, sizeof(fname), PROGRAM_LOG); f = fopen(fname, "ab"); if (!f) { log_status("Couldn't open file %s!", fname); return; } fputs("#######################################", f); fputs("#######################################\n", f); fprintf(f, "PROGRAM %s, SAVED AT %s BY %s(%d)\n", unparse_object(player, i), ctime(<), NAME(player), player); fputs("#######################################", f); fputs("#######################################\n\n", f); while (first) { if (!first->this_line) continue; fputs(first->this_line, f); fputc('\n', f); first = first->next; } fputs("\n\n\n", f); fclose(f); }
static void unparse_boolexp1(dbref player, struct boolexp * b, boolexp_type outer_type, int fullname) { if ((buftop - boolexp_buf) > (BUFFER_LEN / 2)) return; if (b == TRUE_BOOLEXP) { strcpy(buftop, "*UNLOCKED*"); buftop += strlen(buftop); } else { switch (b->type) { case BOOLEXP_AND: if (outer_type == BOOLEXP_NOT) { *buftop++ = '('; } unparse_boolexp1(player, b->sub1, b->type, fullname); *buftop++ = AND_TOKEN; unparse_boolexp1(player, b->sub2, b->type, fullname); if (outer_type == BOOLEXP_NOT) { *buftop++ = ')'; } break; case BOOLEXP_OR: if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) { *buftop++ = '('; } unparse_boolexp1(player, b->sub1, b->type, fullname); *buftop++ = OR_TOKEN; unparse_boolexp1(player, b->sub2, b->type, fullname); if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) { *buftop++ = ')'; } break; case BOOLEXP_NOT: *buftop++ = '!'; unparse_boolexp1(player, b->sub1, b->type, fullname); break; case BOOLEXP_CONST: if (fullname) { #ifndef SANITY strcpy(buftop, unparse_object(player, b->thing)); #endif } else { sprintf(buftop, "#%d", b->thing); } buftop += strlen(buftop); break; case BOOLEXP_PROP: strcpy(buftop, PropName(b->prop_check)); strcat(buftop, ":"); if (PropType(b->prop_check) == PROP_STRTYP) strcat(buftop, PropDataStr(b->prop_check)); buftop += strlen(buftop); break; default: abort(); /* bad type */ break; } } }
/* Use this to create a program. First, find a program that matches that name. If there's one, then we put him into edit mode and do it. Otherwise, we create a new object for him, and call it a program. */ void do_prog(int descr, dbref player, const char *name) { dbref i; struct match_data md; if (Typeof(player) != TYPE_PLAYER) { anotify_nolisten2(player, CFAIL "Only players can edit programs."); return; } else if (!Mucker(player)) { anotify_nolisten2(player, CFAIL NOMBIT_MESG); return; } else if (!tp_building || tp_db_readonly) { anotify_nolisten2(player, CFAIL NOBUILD_MESG); return; } else if (!*name) { anotify_nolisten2(player, CINFO "No program name given."); return; } init_match(descr, player, name, TYPE_PROGRAM, &md); match_possession(&md); match_neighbor(&md); match_registered(&md); match_absolute(&md); if ((i = match_result(&md)) == NOTHING) { i = new_program(OWNER(player), name); FLAGS(i) |= INTERNAL; DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CSUCC "Program %s created with number %d.", name, i); anotify_nolisten2(player, CINFO "Entering editor."); } else if (i == AMBIGUOUS) { anotify_nolisten2(player, CINFO "I don't know which one you mean!"); return; } else { if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } else if (FLAGS(i) & INTERNAL) { anotify_nolisten2(player, CFAIL NOEDIT_MESG); return; } DBFETCH(i)->sp.program.first = read_program(i); FLAGS(i) |= INTERNAL; DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CINFO "Entering editor for %s.", unparse_object(player, i)); /* list current line */ do_list(player, i, 0, 0, 0); DBDIRTY(i); } FLAGS(player) |= INTERACTIVE; DBDIRTY(player); }
void do_restart(dbref player, const char *msg) { if (Arch(player)) { if( *msg == '\0' || strcmp(msg, tp_muckname)) { notify(player, "Usage: @restart muckname" ); return; } log_status("REST: by %s\n", unparse_object(player, player)); shutdown_flag = 1; restart_flag = 1; } else { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); log_status("SHAM: Restart by %s\n", unparse_object(player, player)); } }
void check_exit(dbref obj) { int i, j; printf("Dest#: %d\n", j = DBFETCH(obj)->sp.exit.ndest); for (i = 0; i < j; i++) { printf("Link #%d: %s\n", i + 1, unparse_object(me, DBFETCH(obj)->sp.exit.dest[i])); } }
static void ShowPsLine(BQUE *tmp) { char *bufp = unparse_object(Show_Player, tmp->executor, false); if (tmp->IsTimed && (Good_obj(tmp->sem))) { CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow; notify(Show_Player, tprintf("[#%d/%d]%s:%s", tmp->sem, ltd.ReturnSeconds(), bufp, tmp->comm)); } else if (tmp->IsTimed) { CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow; notify(Show_Player, tprintf("[%d]%s:%s", ltd.ReturnSeconds(), bufp, tmp->comm)); } else if (Good_obj(tmp->sem)) { notify(Show_Player, tprintf("[#%d]%s:%s", tmp->sem, bufp, tmp->comm)); } else { notify(Show_Player, tprintf("%s:%s", bufp, tmp->comm)); } char *bp = bufp; if (Show_Key == PS_LONG) { for (int i = 0; i < tmp->nargs; i++) { if (tmp->env[i] != NULL) { safe_str("; Arg", bufp, &bp); safe_chr((char)(i + '0'), bufp, &bp); safe_str("='", bufp, &bp); safe_str(tmp->env[i], bufp, &bp); safe_chr('\'', bufp, &bp); } } *bp = '\0'; bp = unparse_object(Show_Player, tmp->enactor, false); notify(Show_Player, tprintf(" Enactor: %s%s", bp, bufp)); free_lbuf(bp); } free_lbuf(bufp); }
/* * do_attach() * * This routine attaches a previously existing action to a source object. * The action will not do anything unless it is LINKed. * */ void do_attach(int descr, dbref player, const char *action_name, const char *source_name) { dbref action, source; dbref loc; /* player's current location */ struct match_data md; char buf[BUFFER_LEN]; if ((loc = DBFETCH(player)->location) == NOTHING) return; if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } if (!*action_name || !*source_name) { anotify_nolisten2(player, CINFO "You must specify an action name and a source object."); return; } init_match(descr, player, action_name, TYPE_EXIT, &md); match_all_exits(&md); match_registered(&md); match_absolute(&md); if ((action = noisy_match_result(&md)) == NOTHING) return; if (Typeof(action) != TYPE_EXIT) { anotify_nolisten2(player, CINFO "That's not an action."); return; } else if (!controls(player, action)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } if (((source = parse_source(descr, player, source_name)) == NOTHING) || Typeof(source) == TYPE_PROGRAM) return; if (!unset_source(player, loc, action)) { return; } set_source(player, action, source); sprintf(buf, CSUCC "Action %s re-attached to %s.", unparse_object(player, action), NAME(source)); anotify_nolisten2(player, buf); if (MLevel(action)) { SetMLevel(action, 0); anotify_nolisten2(player, CINFO "Action priority Level reset to zero."); } }
static dbref parse_linkable_dest(int descr, dbref player, dbref exit, const char *dest_name) { dbref dobj; /* destination room/player/thing/link */ char buf[BUFFER_LEN]; struct match_data md; init_match(descr, player, dest_name, NOTYPE, &md); match_absolute(&md); match_everything(&md); match_home(&md); match_null(&md); if ((dobj = match_result(&md)) == NOTHING || dobj == AMBIGUOUS) { sprintf(buf, CINFO "I couldn't find '%s'.", dest_name); anotify_nolisten2(player, buf); return NOTHING; } if (!tp_teleport_to_player && Typeof(dobj) == TYPE_PLAYER) { sprintf(buf, CFAIL "You can't link to players. Destination %s ignored.", unparse_object(player, dobj)); anotify_nolisten2(player, buf); return NOTHING; } if (!can_link(player, exit)) { anotify_nolisten2(player, CFAIL "You can't link that."); return NOTHING; } if (!can_link_to(player, Typeof(exit), dobj)) { sprintf(buf, CFAIL "You can't link to %s.", unparse_object(player, dobj)); anotify_nolisten2(player, buf); return NOTHING; } else return dobj; }
void prim_curid(PRIM_PROTOTYPE) { int curuid = getuid(); int curgid = getgid(); if (getuid() == 0 ) abort_interp("Muck is running under root privs, file prims disabled."); if (mlev < LBOY) abort_interp("BOY primitive only."); if(tp_log_files) log2filetime("logs/files", "#%d by %s CURID \n", program, unparse_object(player, player)); PushInt(curgid); PushInt(curuid); }
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; }
/** Issue a warning about an object. * \param player player to receive the warning notification. * \param i object the warning is about. * \param name name of the warnings. * \param desc a formatting string for the warning message. */ void complain(dbref player, dbref i, const char *name, const char *desc, ...) { char buff[BUFFER_LEN]; va_list args; va_start(args, desc); mush_vsnprintf(buff, sizeof buff, desc, args); va_end(args); notify_format(player, T("Warning '%s' for %s:"), name, unparse_object(player, i)); notify(player, buff); }
void do_edit(int descr, dbref player, const char *name) { dbref i; struct match_data md; if (Typeof(player) != TYPE_PLAYER) { anotify_nolisten2(player, CFAIL "Only players can edit programs."); return; } else if (!Mucker(player)) { anotify_nolisten2(player, CFAIL NOMBIT_MESG); return; } else if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } else if (!*name) { anotify_nolisten2(player, CINFO "No program name given."); return; } init_match(descr, player, name, TYPE_PROGRAM, &md); match_possession(&md); match_neighbor(&md); match_registered(&md); match_absolute(&md); if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS) return; if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } else if (FLAGS(i) & INTERNAL) { anotify_nolisten2(player, CFAIL NOEDIT_MESG); return; } FLAGS(i) |= INTERNAL; DBFETCH(i)->sp.program.first = read_program(i); DBFETCH(player)->sp.player.curr_prog = i; anotify_fmt(player, CINFO "Entering editor for %s.", unparse_object(player, i)); /* list current line */ do_list(player, i, 0, 0, 0); FLAGS(player) |= INTERACTIVE; DBDIRTY(i); DBDIRTY(player); }
void prim_bwrite(PRIM_PROTOTYPE) { FILE *fh; char *filename; int result, tempdat; double offset; CHECKOP(3); oper1 = POP(); oper2 = POP(); oper3 = 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("Arguement 2 is a null string."); if (oper3->type != PROG_INTEGER) abort_interp("Arguement 3 is not an integer."); if (oper3->data.number < 0 ) abort_interp("Arguement 3 is a negative number."); offset = oper1->data.number; filename = oper2->data.string->data; tempdat = (int) oper3->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, "w"); if (fh == NULL) { result = 0; } else { fseek(fh, offset, SEEK_SET); fputc(tempdat - 8, fh); fclose(fh); result = 1; if(tp_log_files) log2filetime("logs/files", "#%d by %s BWRITE : %s \n", program, unparse_object(player, player), oper2->data.string->data); } CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); PushInt(result); }
/* quit from edit mode. Put player back into the regular game mode */ void do_quit(dbref player, dbref program) { log_status("PROGRAM SAVED: %s by %s(%d)", unparse_object(player, program), NAME(player), player); write_program(PROGRAM_FIRST(program), program); if (tp_log_programs) log_program_text(PROGRAM_FIRST(program), player, program); free_prog_text(PROGRAM_FIRST(program)); PROGRAM_SET_FIRST(program, NULL); FLAGS(program) &= ~INTERNAL; FLAGS(player) &= ~INTERACTIVE; PLAYER_SET_CURR_PROG(player, NOTHING); DBDIRTY(player); DBDIRTY(program); }
void prim_bread(PRIM_PROTOTYPE) { FILE *fh; /* Should return -1 for file open error. */ char *filename; /* -2 for EOF. */ double offset; 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 = -1; } else { fseek(fh, offset, SEEK_SET); result = fgetc(fh); if(tp_log_files) log2filetime("logs/files", "#%d by %s BREAD: %s \n", program, unparse_object(player, player), oper2->data.string->data); if (result == EOF) { result = -2; } fclose(fh); } CLEAR(oper1); CLEAR(oper2); PushInt(result); }
void prim_fren(PRIM_PROTOTYPE) { char *oldname, *newname; char tempB[BUFFER_LEN] = ""; 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_STRING) abort_interp("Argument 1 is not a string."); if(!oper1->data.string) abort_interp("Argument 1 is a null string."); if(oper2->type != PROG_STRING) abort_interp("Argument 2 is not a string."); if(!oper2->data.string) abort_interp("Argument 2 is a null string."); newname = oper1->data.string->data; oldname = oper2->data.string->data; /* ( s<old> s<new> -- i ) */ #ifdef SECURE_FILE_PRIMS if (!(valid_name( newname ))) abort_interp( "Invalid file name. (2)"); if ( strchr( newname, '$' ) == NULL ) newname = set_directory(newname); else newname = parse_token( newname ); if ( newname == NULL ) abort_interp( "Invalid shortcut used. (2)" ); strcpy( tempB, newname ); if (!(valid_name(oldname))) abort_interp( "Invalid file name. (1)"); if ( strchr( oldname, '$' ) == NULL ) oldname = set_directory(oldname); else oldname = parse_token( oldname ); if ( oldname == NULL ) abort_interp( "Invalid shortcut used. (1)" ); newname = tempB; #endif result = rename(oldname, newname); if(tp_log_files) log2filetime("logs/files", "#%d by %s FREN: %s -> %s \n", program, unparse_object(player, player), oper2->data.string->data, oper1->data.string->data); CLEAR(oper1); CLEAR(oper2); PushInt(result); }
void prim_descr_setuser(PRIM_PROTOTYPE) { char *ptr; CHECKOP(3); oper3 = POP(); oper2 = POP(); oper1 = POP(); if (mlev < (tp_compatible_muf ? LMAGE : LARCH)) abort_interp(tp_compatible_muf ? "Mage prim" : "Arch prim"); if (oper1->type != PROG_INTEGER) abort_interp("Integer descriptor number expected (1)"); if (oper2->type != PROG_OBJECT) abort_interp("Player dbref expected (2)"); ref = oper2->data.objref; if (ref != NOTHING && !valid_player(oper2)) abort_interp("Player dbref expected (2)"); if (oper3->type != PROG_STRING) abort_interp("Password string expected"); ptr = oper3->data.string? oper3->data.string->data : ""; if ((ref != NOTHING) && DBFETCH(ref)->sp.player.password && (*DBFETCH(ref)->sp.player.password) && strcmp(ptr, DBFETCH(ref)->sp.player.password) ) abort_interp("Incorrect password"); if (ref != NOTHING) { log_status("SUID: %d %s to %s(%d)\n", oper1->data.number, unparse_object(MAN, player), NAME(ref), ref); } tmp = oper1->data.number; CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); result = pset_user(tmp, ref); PushInt(result); }
void prim_fsinfo(PRIM_PROTOTYPE) { struct statfs fs; if (getuid() == 0 ) abort_interp("Muck is running under root privs, file prims disabled."); if (mlev < LBOY) abort_interp("BOY primitive only."); /* Returns: */ /* Magic Number, Total Blocks, Free Blocks, Available Blocks, Total Files, */ /* Free Files, Block Size (bytes), and Max Name Length. */ statfs("/", &fs); if(tp_log_files) log2filetime("logs/files", "#%d by %s FSINFO \n", program, unparse_object(player, player)); PushInt(fs.f_type); PushInt(fs.f_blocks); PushInt(fs.f_bfree); PushInt(fs.f_bavail); PushInt(fs.f_files); PushInt(fs.f_ffree); PushInt(fs.f_bsize); PushInt(fs.f_namelen); }
void prim_fappend(PRIM_PROTOTYPE) { FILE *fh; char *filename; char *writestring; 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_STRING) abort_interp("Argument 1 is not a string."); if(!oper1->data.string) abort_interp("Argument 1 is a null string."); if(oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string."); if(!oper2->data.string) abort_interp("Arguement 2 is a null string."); filename = oper1->data.string->data; writestring = 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, "a"); if (fh == NULL) { result = 0; } else { fputs(writestring, fh); fclose(fh); result = 1; if(tp_log_files) log2filetime("logs/files", "#%d by %s FAPPEND: %s \n", program, unparse_object(player, player), oper1->data.string->data); } CLEAR(oper1); CLEAR(oper2); PushInt(result); }
/** Unlink an exit or room. * \verbatim * This is the top-level function for @unlink, which can unlink an exit * or remove a drop-to from a room. * \endverbatim * \param player the enactor. * \param name name of the object to unlink. */ void do_unlink(dbref player, const char *name) { dbref exit_l, old_loc; long match_flags = MAT_EXIT | MAT_HERE | MAT_ABSOLUTE; if (!Wizard(player)) { match_flags |= MAT_CONTROL; } switch (exit_l = match_result(player, name, TYPE_EXIT, match_flags)) { case NOTHING: notify(player, T("Unlink what?")); break; case AMBIGUOUS: notify(player, T("I don't know which one you mean!")); break; default: if (!controls(player, exit_l)) { notify(player, T("Permission denied.")); } else { switch (Typeof(exit_l)) { case TYPE_EXIT: old_loc = Location(exit_l); Location(exit_l) = NOTHING; notify_format(player, T("Unlinked exit #%d (Used to lead to %s)."), exit_l, unparse_object(player, old_loc)); break; case TYPE_ROOM: Location(exit_l) = NOTHING; notify(player, T("Dropto removed.")); break; default: notify(player, T("You can't unlink that!")); break; } } } }
/* do_link * * Use this to link to a room that you own. It also sets home for * objects and things, and drop-to's for rooms. * It seizes ownership of an unlinked exit, and costs 1 penny * plus a penny transferred to the exit owner if they aren't you * * All destinations must either be owned by you, or be LINK_OK. */ void do_link(int descr, dbref player, const char *thing_name, const char *dest_name) { dbref good_dest[MAX_LINKS]; int ndest, i; struct match_data md; char buf[BUFFER_LEN]; dbref thing, dest; if (tp_db_readonly) { anotify_nolisten2(player, CFAIL DBRO_MESG); return; } if (Guest(player)) { anotify_fmt(player, CFAIL "%s", tp_noguest_mesg); return; } init_match(descr, player, thing_name, TYPE_EXIT, &md); match_all_exits(&md); match_neighbor(&md); match_possession(&md); match_me(&md); match_here(&md); match_absolute(&md); match_registered(&md); if (Mage(OWNER(player))) match_player(&md); if ((thing = noisy_match_result(&md)) == NOTHING) return; switch (Typeof(thing)) { case TYPE_EXIT: /* we're ok, check the usual stuff */ if (DBFETCH(thing)->sp.exit.ndest != 0) { if (controls(player, thing)) { if ((DBFETCH(thing)->sp.exit.dest)[0] != NIL) { anotify_nolisten2(player, CINFO "That exit is already linked."); return; } } else { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } } /* handle costs */ if (OWNER(thing) == OWNER(player)) { if (!payfor(player, tp_link_cost)) { anotify_fmt(player, CFAIL "It costs %d %s to link this exit.", tp_link_cost, (tp_link_cost == 1) ? tp_penny : tp_pennies); return; } } else { if (!payfor(player, tp_link_cost + tp_exit_cost)) { anotify_fmt(player, CFAIL "It costs %d %s to link this exit.", (tp_link_cost + tp_exit_cost), (tp_link_cost + tp_exit_cost == 1) ? tp_penny : tp_pennies); return; } else if (!Builder(player)) { anotify_nolisten2(player, CFAIL NOBBIT_MESG); return; } else { /* pay the owner for his loss */ dbref owner = OWNER(thing); DBFETCH(owner)->sp.player.pennies += tp_exit_cost; DBDIRTY(owner); } } /* link has been validated and paid for; do it */ OWNER(thing) = OWNER(player); if (! (ndest = link_exit(descr, player, thing, (char *) dest_name, good_dest))) { anotify_nolisten2(player, CFAIL "No destinations linked."); DBFETCH(player)->sp.player.pennies += tp_link_cost; /* Refund! */ DBDIRTY(player); break; } DBFETCH(thing)->sp.exit.ndest = ndest; if (DBFETCH(thing)->sp.exit.dest) free(DBFETCH(thing)->sp.exit.dest); DBFETCH(thing)->sp.exit.dest = (dbref *) malloc(sizeof(dbref) * ndest); for (i = 0; i < ndest; i++) (DBFETCH(thing)->sp.exit.dest)[i] = good_dest[i]; break; case TYPE_THING: case TYPE_PLAYER: init_match(descr, player, dest_name, TYPE_ROOM, &md); match_neighbor(&md); match_absolute(&md); match_registered(&md); match_me(&md); match_here(&md); match_null(&md); if (Typeof(thing) == TYPE_THING) match_possession(&md); if ((dest = noisy_match_result(&md)) == NOTHING) return; if (Typeof(thing) == TYPE_THING && dest == NIL) { anotify_fmt(player, CFAIL "%s", "You cannot HOME a THING to NIL."); return; } if (!controls(player, thing) || !can_link_to(player, Typeof(thing), dest)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); return; } if (parent_loop_check(thing, dest)) { anotify_nolisten2(player, CFAIL "That would cause a parent paradox."); return; } /* do the link */ if (Typeof(thing) == TYPE_THING) { DBFETCH(thing)->sp.thing.home = dest; } else DBFETCH(thing)->sp.player.home = dest; sprintf(buf, CSUCC "%s's home set to %s.", NAME(thing), unparse_object(player, dest)); anotify_nolisten2(player, buf); break; case TYPE_ROOM: /* room dropto's */ init_match(descr, player, dest_name, TYPE_ROOM, &md); match_neighbor(&md); match_possession(&md); match_registered(&md); match_absolute(&md); match_home(&md); match_null(&md); if ((dest = noisy_match_result(&md)) == NOTHING) break; if (!controls(player, thing) || !can_link_to(player, Typeof(thing), dest) || (thing == dest)) { anotify_fmt(player, CFAIL "%s", tp_noperm_mesg); } else { DBFETCH(thing)->sp.room.dropto = dest; /* dropto */ sprintf(buf, CSUCC "%s's dropto set to %s.", NAME(thing), unparse_object(player, dest)); anotify_nolisten2(player, buf); } break; case TYPE_PROGRAM: anotify_nolisten2(player, CFAIL "You can't link programs to things!"); break; default: anotify_nolisten2(player, CFAIL "Weird object type."); log_status("*BUG: weird object: Typeof(%d) = %d\n", thing, Typeof(thing)); break; } DBDIRTY(thing); return; }
void check_room(dbref obj) { printf("Dropto: %s\n", unparse_object(me, DBFETCH(obj)->sp.room.dropto)); printf("First exit: %s\n", unparse_object(me, DBFETCH(obj)->exits)); }
/** Link an exit, room, player, or thing. * \verbatim * This is the top-level function for @link, which is used to link an * exit to a destination, set a player or thing's home, or set a * drop-to on a room. * * Linking an exit usually seizes ownership of the exit and costs 1 penny. * 1 penny is also transferred to the former owner. * \endverbatim * \param player the enactor. * \param name the name of the object to link. * \param room_name the name of the link destination. * \param preserve if 1, preserve ownership and zone data on exit relink. */ void do_link(dbref player, const char *name, const char *room_name, int preserve) { /* Use this to link to a room that you own. * It usually seizes ownership of the exit and costs 1 penny, * plus a penny transferred to the exit owner if they aren't you. * You must own the linked-to room AND specify it by room number. */ dbref thing; dbref room; if (!room_name || !*room_name) { do_unlink(player, name); return; } if (!IsRoom(player) && GoodObject(Location(player)) && IsExit(Location(player))) { notify(player, T("You somehow wound up in a exit. No biscuit.")); return; } if ((thing = noisy_match_result(player, name, TYPE_EXIT, MAT_EVERYTHING)) != NOTHING) { switch (Typeof(thing)) { case TYPE_EXIT: if ((room = check_var_link(room_name)) == NOTHING) room = parse_linkable_room(player, room_name); if (room == NOTHING) return; if (GoodObject(room) && !can_link_to(player, room)) { notify(player, T("Permission denied.")); break; } /* We may link an exit if it's unlinked and we pass the link-lock * or if we control it. */ if (!(controls(player, thing) || ((Location(thing) == NOTHING) && eval_lock(player, thing, Link_Lock)))) { notify(player, T("Permission denied.")); return; } if (preserve && !Wizard(player)) { notify(player, T("Permission denied.")); return; } /* handle costs */ if (Owner(thing) == Owner(player)) { if (!payfor(player, LINK_COST)) { notify_format(player, T("It costs %d %s to link this exit."), LINK_COST, ((LINK_COST == 1) ? MONEY : MONIES)); return; } } else { if (!payfor(player, LINK_COST + EXIT_COST)) { int a = LINK_COST + EXIT_COST; notify_format(player, T("It costs %d %s to link this exit."), a, ((a == 1) ? MONEY : MONIES)); return; } else if (!preserve) { /* pay the owner for his loss */ giveto(Owner(thing), EXIT_COST); chown_object(player, thing, player, 0); } } /* link has been validated and paid for; do it */ if (!preserve) { Owner(thing) = Owner(player); Zone(thing) = Zone(player); } Location(thing) = room; /* notify the player */ notify_format(player, T("Linked exit #%d to %s"), thing, unparse_object(player, room)); break; case TYPE_PLAYER: case TYPE_THING: if ((room = noisy_match_result(player, room_name, NOTYPE, MAT_EVERYTHING)) == NOTHING) { notify(player, T("No match.")); return; } if (IsExit(room)) { notify(player, T("That is an exit.")); return; } if (thing == room) { notify(player, T("You may not link something to itself.")); return; } /* abode */ if (!controls(player, room) && !Abode(room)) { notify(player, T("Permission denied.")); break; } if (!controls(player, thing)) { notify(player, T("Permission denied.")); } else if (room == HOME) { notify(player, T("Can't set home to home.")); } else { /* do the link */ Home(thing) = room; /* home */ if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player))) notify(player, T("Home set.")); } break; case TYPE_ROOM: if ((room = parse_linkable_room(player, room_name)) == NOTHING) return; if ((room != HOME) && (!IsRoom(room))) { notify(player, T("That is not a room!")); return; } if (!controls(player, thing)) { notify(player, T("Permission denied.")); } else { /* do the link, in location */ Location(thing) = room; /* dropto */ notify(player, T("Dropto set.")); } break; default: notify(player, T("Internal error: weird object type.")); do_log(LT_ERR, NOTHING, NOTHING, "Weird object! Type of #%d is %d", thing, Typeof(thing)); break; } } }
static void unparse_boolexp1( dbref player, BOOLEXP *b, char outer_type, int format ) { ATTR *ap; char sep_ch; char *buff; if( b == TRUE_BOOLEXP ) { if( format == F_EXAMINE ) { safe_str( ( char * ) "*UNLOCKED*", boolexp_buf, &buftop ); } return; } switch( b->type ) { case BOOLEXP_AND: if( outer_type == BOOLEXP_NOT ) { safe_chr( '(', boolexp_buf, &buftop ); } unparse_boolexp1( player, b->sub1, b->type, format ); safe_chr( AND_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub2, b->type, format ); if( outer_type == BOOLEXP_NOT ) { safe_chr( ')', boolexp_buf, &buftop ); } break; case BOOLEXP_OR: if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) { safe_chr( '(', boolexp_buf, &buftop ); } unparse_boolexp1( player, b->sub1, b->type, format ); safe_chr( OR_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub2, b->type, format ); if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) { safe_chr( ')', boolexp_buf, &buftop ); } break; case BOOLEXP_NOT: safe_chr( '!', boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub1, b->type, format ); break; case BOOLEXP_INDIR: safe_chr( INDIR_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub1, b->type, format ); break; case BOOLEXP_IS: safe_chr( IS_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub1, b->type, format ); break; case BOOLEXP_CARRY: safe_chr( CARRY_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub1, b->type, format ); break; case BOOLEXP_OWNER: safe_chr( OWNER_TOKEN, boolexp_buf, &buftop ); unparse_boolexp1( player, b->sub1, b->type, format ); break; case BOOLEXP_CONST: if( !mudstate.standalone ) { switch( format ) { case F_QUIET: /* * Quiet output - for dumps and internal use. * Always #Num */ safe_str( ( char * ) unparse_object_quiet( player, b->thing ), boolexp_buf, &buftop ); break; case F_EXAMINE: /* * Examine output - informative. * * Name(#Num) or Name */ buff = unparse_object( player, b->thing, 0 ); safe_str( buff, boolexp_buf, &buftop ); free_lbuf( buff ); break; case F_DECOMPILE: /* * Decompile output - should be usable on * other MUSHes. *Name if player, Name if * thing, else #Num */ switch( Typeof( b->thing ) ) { case TYPE_PLAYER: safe_chr( '*', boolexp_buf, &buftop ); case TYPE_THING: safe_name( b->thing, boolexp_buf, &buftop ); break; default: safe_dbref( boolexp_buf, &buftop, b->thing ); break; } break; case F_FUNCTION: /* * Function output - must be usable by @lock * cmd. *Name if player, else #Num */ switch( Typeof( b->thing ) ) { case TYPE_PLAYER: safe_chr( '*', boolexp_buf, &buftop ); safe_name( b->thing, boolexp_buf, &buftop ); break; default: safe_dbref( boolexp_buf, &buftop, b->thing ); break; } } } else { safe_str( ( char * ) unparse_object_quiet( player, b->thing ), boolexp_buf, &buftop ); } break; case BOOLEXP_ATR: case BOOLEXP_EVAL: if( b->type == BOOLEXP_EVAL ) { sep_ch = '/'; } else { sep_ch = ':'; } ap = atr_num( b->thing ); if( ap && ap->number ) { safe_str( ( char * ) ap->name, boolexp_buf, &buftop ); } else { safe_ltos( boolexp_buf, &buftop, b->thing ); } safe_chr( sep_ch, boolexp_buf, &buftop ); safe_str( ( char * ) b->sub1, boolexp_buf, &buftop ); break; default: log_write_raw( 1, "ABORT! unparse.c, bad boolexp type in unparse_boolexp1().\n" ); abort(); break; } }
/* * do_create * * Use this to create an object. */ void do_create(dbref player, char *name, char *acost) { dbref loc; dbref thing; int cost; static char buf[BUFFER_LEN]; char buf2[BUFFER_LEN]; char *rname, *qname; if (!Builder(player)) { anotify_nolisten2(player, CFAIL NOBBIT_MESG); return; } if (!tp_building || tp_db_readonly) { anotify_nolisten2(player, CFAIL NOBUILD_MESG); return; } strcpy(buf2, acost); for (rname = buf2; (*rname && (*rname != '=')); rname++) ; qname = rname; if (*rname) *(rname++) = '\0'; while ((qname > buf2) && (isspace(*qname))) *(qname--) = '\0'; qname = buf2; for (; *rname && isspace(*rname); rname++) ; cost = atoi(qname); if (*name == '\0') { anotify_nolisten2(player, CINFO "Create what?"); return; } else if (!ok_name(name)) { anotify_nolisten2(player, CINFO "That's a silly name for a thing!"); return; } else if (cost < 0) { anotify_nolisten2(player, CINFO "You can't create an object for less than nothing!"); return; } else if (cost < tp_object_cost) { cost = tp_object_cost; } if (!payfor(player, cost)) { anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies); return; } else { /* create the object */ thing = new_object(player); /* initialize everything */ NAME(thing) = alloc_string(name); DBFETCH(thing)->location = player; OWNER(thing) = OWNER(player); DBFETCH(thing)->sp.thing.value = OBJECT_ENDOWMENT(cost); DBFETCH(thing)->exits = NOTHING; FLAGS(thing) = TYPE_THING; /* endow the object */ if (DBFETCH(thing)->sp.thing.value > tp_max_object_endowment) { DBFETCH(thing)->sp.thing.value = tp_max_object_endowment; } if ((loc = DBFETCH(player)->location) != NOTHING && controls(player, loc)) { DBFETCH(thing)->sp.thing.home = loc; /* home */ } else { DBFETCH(thing)->sp.thing.home = player; /* set thing's home to player instead */ } /* link it in */ PUSH(thing, DBFETCH(player)->contents); DBDIRTY(player); /* and we're done */ sprintf(buf, CSUCC "Object %s created.", unparse_object(player, thing)); anotify_nolisten2(player, buf); DBDIRTY(thing); } if (*rname) { PData pdat; sprintf(buf, CINFO "Registered as $%s", rname); anotify_nolisten2(player, buf); sprintf(buf, "_reg/%s", rname); pdat.flags = PROP_REFTYP; pdat.data.ref = thing; set_property(player, buf, &pdat); } }
/* * do_dig * * Use this to create a room. */ void do_dig(int descr, dbref player, const char *name, const char *pname) { char *rname, *qname; dbref newparent; char rbuf[BUFFER_LEN]; char qbuf[BUFFER_LEN]; char buf[BUFFER_LEN]; dbref room; struct match_data md; dbref parent; if (!Builder(player) && !tp_all_can_build_rooms) { anotify_nolisten2(player, CFAIL NOBBIT_MESG); return; } if (!tp_building || tp_db_readonly) { anotify_nolisten2(player, CFAIL NOBUILD_MESG); return; } if (*name == '\0') { anotify_nolisten2(player, CINFO "You need name for the room."); return; } if (!ok_name(name)) { anotify_nolisten2(player, CINFO "That's a silly name for a room!"); return; } if (!payfor(player, tp_room_cost)) { anotify_fmt(player, CFAIL "You don't have enough %s to dig a room.", tp_pennies); return; } room = new_object(player); /* Initialize everything */ newparent = DBFETCH(DBFETCH(player)->location)->location; while ((OkObj(newparent)) && !(FLAGS(newparent) & ABODE) && !(FLAG2(newparent) & F2PARENT)) newparent = DBFETCH(newparent)->location; if (!OkObj(newparent)) { if (OkObj(tp_default_parent)) newparent = tp_default_parent; else newparent = GLOBAL_ENVIRONMENT; } NAME(room) = alloc_string(name); DBFETCH(room)->location = newparent; OWNER(room) = OWNER(player); DBFETCH(room)->exits = NOTHING; DBFETCH(room)->sp.room.dropto = NOTHING; FLAGS(room) = TYPE_ROOM | (FLAGS(player) & JUMP_OK); PUSH(room, DBFETCH(newparent)->contents); DBDIRTY(room); DBDIRTY(newparent); sprintf(buf, CSUCC "Room %s created.", unparse_object(player, room)); anotify_nolisten2(player, buf); strcpy(buf, pname); for (rname = buf; (*rname && (*rname != '=')); rname++) ; qname = rname; if (*rname) *(rname++) = '\0'; while ((qname > buf) && (isspace(*qname))) *(qname--) = '\0'; qname = buf; for (; *rname && isspace(*rname); rname++) ; rname = strcpy(rbuf, rname); qname = strcpy(qbuf, qname); if (*qname) { anotify_nolisten2(player, CNOTE "Trying to set parent..."); init_match(descr, player, qname, TYPE_ROOM, &md); match_absolute(&md); match_registered(&md); match_here(&md); if ((parent = noisy_match_result(&md)) == NOTHING || parent == AMBIGUOUS) { anotify_nolisten2(player, CINFO "Parent set to default."); } else { if ((!can_link_to(player, Typeof(room), parent) && !(FLAG2(parent) & F2PARENT)) || room == parent) { anotify_nolisten2(player, CFAIL "Permission denied. Parent set to default."); } else { moveto(room, parent); sprintf(buf, CSUCC "Parent set to %s.", unparse_object(player, parent)); anotify_nolisten2(player, buf); } } } if (*rname) { PData pdat; sprintf(buf, "_reg/%s", rname); pdat.flags = PROP_REFTYP; pdat.data.ref = room; set_property(player, buf, &pdat); sprintf(buf, CINFO "Room registered as $%s", rname); anotify_nolisten2(player, buf); } }