/* dbcmds.c */ #include "config.h" /* * This file is part of TeenyMUD II. * Copyright(C) 1993, 1994, 1995 by Jason Downs. * All rights reserved. * * TeenyMUD II is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * TeenyMUD II is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file 'COPYING'); if not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. * */ #include <stdio.h> #include <sys/types.h> #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif /* HAVE_STRING_H */ #include <ctype.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDIB_H */ #include "conf.h" #include "teeny.h" #include "commands.h" #include "teenydb.h" #include "externs.h" /* * Database intensive commands. */ static char elist[] = "***End of list***"; VOID do_owned(player, cause, switches, argone, argtwo) int player, cause, switches; char *argone, *argtwo; { int matchfor, i, type, flags[FLAGS_LEN], not; char *p; if ((argone == (char *)NULL) || (argone[0] == '\0')) matchfor = player; else { matchfor = resolve_player(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if (matchfor == -1) return; } type = -1; not = 0; bzero((VOID *)flags, sizeof(flags)); if (argtwo && *argtwo) { if(*argtwo == '!') { not++; argtwo++; } for (p = argtwo; *p && *p != '/'; p++); if (*p == '/') { *p++ = '\0'; parse_flags(p, flags); if ((flags[0] == -1) && (flags[1] == -1)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Illegal flags.", NOT_QUIET); return; } } if (*argtwo) { parse_type(argtwo, &type); if (type == -1) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Illegal type.", 0); return; } } } for (i = 0; i < mudstat.total_objects; i++) { if (main_index[i] == NULL) continue; if (DSC_OWNER(main_index[i]) != DSC_OWNER(main_index[matchfor])) continue; /* they own this object */ if (not) { if ((type != -1) && (DSC_TYPE(main_index[i]) == type)) continue; if (((flags[0] != 0) && (DSC_FLAG1(main_index[i]) & flags[0])) || ((flags[1] != 0) && (DSC_FLAG2(main_index[i]) & flags[1]))) continue; } else { if ((type != -1) && (DSC_TYPE(main_index[i]) != type)) continue; if (((flags[0] != 0) && (!(DSC_FLAG1(main_index[i]) & flags[0]))) || ((flags[1] != 0) && (!(DSC_FLAG2(main_index[i]) & flags[1])))) continue; } notify_player(player, cause, player, display_name(player, cause, i), 0); cache_trim(); } notify_player(player, cause, player, elist, 0); } VOID do_entrances(player, cause, switches, argone) int player, cause, switches; char *argone; { register int indx; int search_for; int done, obj; char buf[MEDBUFFSIZ]; if ((argone == (char *)NULL) || (argone[0] == '\0')) { if (get_int_elt(player, LOC, &search_for) == -1) { notify_bad(player); return; } } else { search_for = resolve_object(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(search_for == -1) return; if (DSC_TYPE(main_index[search_for]) == TYP_EXIT) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "That won't have anything linked to it.", NOT_QUIET); return; } } if (!controls(player, cause, search_for)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Permission denied.", NOT_QUIET); return; } for (obj = 0; obj < mudstat.total_objects; obj++) { if (main_index[obj] == NULL) continue; if(DSC_TYPE(main_index[obj]) == TYP_EXIT) { if (DSC_DESTS(main_index[obj]) != (int *)NULL) { for(indx = 1, done = 0; !done && (indx <= (DSC_DESTS(main_index[obj]))[0]); indx++) { if((DSC_DESTS(main_index[obj]))[indx] == search_for) { strcpy(buf, "Exit: "); strcat(buf, display_name(player, cause, obj)); notify_player(player, cause, player, buf, 0); done++; } } } } else { if(DSC_HOME(main_index[obj]) != search_for) continue; if(DSC_TYPE(main_index[obj]) == TYP_ROOM) { strcpy(buf, "Drop to: "); } else { strcpy(buf, "Home: "); } strcat(buf, display_name(player, cause, obj)); notify_player(player, cause, player, buf, 0); } cache_trim(); } notify_player(player, cause, player, elist, 0); } VOID do_find(player, cause, switches, argone, argtwo) int player, cause, switches; char *argone, *argtwo; { char *p, *name; int type, flags[FLAGS_LEN], not; register int i; register int cost = mudconf.find_cost; type = -1; not = 0; bzero((VOID *)flags, sizeof(flags)); if (argtwo && *argtwo) { if (*argtwo == '!') { not++; argtwo++; } for (p = argtwo; *p && (*p != '/'); p++); if (*p == '/') { *p++ = '\0'; parse_flags(p, flags); if ((flags[0] == -1) && (flags[1] == -1)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Illegal flag.", NOT_QUIET); return; } } if (*argtwo) { parse_type(argtwo, &type); if (type == -1) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Illegal type.", NOT_QUIET); return; } } cost = mudconf.limfind_cost; } if (!can_afford(player, cause, cost, (switches & CMD_QUIET))) return; for (i = 0; i < mudstat.total_objects; i++) { if (main_index[i] == (struct dsc *)NULL) continue; if (not) { if ((type != -1) && (DSC_TYPE(main_index[i]) == type)) continue; if (((flags[0] != 0) && (DSC_FLAG1(main_index[i]) & flags[0])) || ((flags[1] != 0) && (DSC_FLAG2(main_index[i]) & flags[1]))) continue; } else { if ((type != -1) && (DSC_TYPE(main_index[i]) != type)) continue; if (((flags[0] != 0) && (!(DSC_FLAG1(main_index[i]) & flags[0]))) || ((flags[1] != 0) && (!(DSC_FLAG2(main_index[i]) & flags[1])))) continue; } if ((switches & FIND_OWNED) && (DSC_OWNER(main_index[i]) != player)) continue; if (!controls(player, cause, i)) continue; if ((get_str_elt(i, NAME, &name) == -1) || !name || !name[0]) { logfile(LOG_ERROR, "do_find: object #%d has a bad name.\n"); continue; } if ((argone == (char *)NULL) || (argone[0] == '\0') || quick_wild_prefix(argone, name)) notify_player(player, cause, player, display_name(player, cause, i), 0); cache_trim(); } notify_player(player, cause, player, elist, 0); } VOID do_trace(player, cause, switches, argone, argtwo) int player, cause, switches; char *argone, *argtwo; { int obj, max_depth, loc, depth; char *ptr; if ((get_int_elt(player, LOC, &loc) == -1) || !_exists_object(loc)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You have no location!", NOT_QUIET); return; } if ((argone == (char *)NULL) || (argone[0] == '\0')) { obj = loc; } else { obj = resolve_object(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(obj == -1) return; } if ((argtwo == (char *)NULL) || (argtwo[0] == '\0')) { max_depth = mudconf.max_list; } else { max_depth = (int)strtol(argtwo, &ptr, 10); if ((ptr == argtwo) || (max_depth < 1)){ if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "That's not a reasonable depth.", NOT_QUIET); return; } } depth = 0; do { notify_player(player, cause, player, display_name(player, cause, obj), 0); depth++; cache_trim(); } while ((depth < max_depth) && (obj != mudconf.root_location) && (get_int_elt(obj, LOC, &obj) != -1) && _exists_object(obj)); notify_player(player, cause, player, elist, 0); } VOID do_stats(player, cause, switches, argone) int player, cause, switches; char *argone; { int matchfor; char buf[MEDBUFFSIZ]; static const char stats_frmt[] = "%d object%s = %d room%s, %d exit%s, %d thing%s, %d player%s (%d garbage)."; if ((argone == (char *)NULL) || (argone[0] == '\0')) { matchfor = -2; } else { matchfor = resolve_player(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(matchfor == -1) return; if ((matchfor != player) && !isWIZARD(player)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You can't stat other players!", NOT_QUIET); return; } /* matchfor should now contain a valid player number */ } if (!isWIZARD(player) && (matchfor == -2) && !(switches & STATS_FULL)) { snprintf(buf, sizeof(buf), "The universe contains %d objects.", mudstat.actual_objects); notify_player(player, cause, player, buf, 0); } else { int totals[TYPE_TOTAL]; register int i, total = 0; float ratio = 0.0; if (!can_afford(player, cause, ((switches == STATS_FULL) ? mudconf.fullstat_cost : mudconf.stat_cost), (switches & CMD_QUIET))) return; bzero((VOID *)totals, sizeof(int) * TYPE_TOTAL); for (i = 0; i < mudstat.total_objects; i++) { if (main_index[i] == (struct dsc *)NULL) continue; if ((matchfor == -2) || (DSC_OWNER(main_index[i]) == matchfor)) { total++; totals[DSC_TYPE(main_index[i])]++; } } if(totals[TYP_ROOM] > 0) ratio = (float)totals[TYP_EXIT] / (float)totals[TYP_ROOM]; snprintf(buf, sizeof(buf), stats_frmt, total, (total == 1) ? "" : "s", totals[TYP_ROOM], (totals[TYP_ROOM] == 1) ? "" : "s", totals[TYP_EXIT], (totals[TYP_EXIT] == 1) ? "" : "s", totals[TYP_THING], (totals[TYP_THING] == 1) ? "" : "s", totals[TYP_PLAYER], (totals[TYP_PLAYER] == 1) ? "" : "s", (matchfor == -2) ? mudstat.garbage_count : 0); notify_player(player, cause, player, buf, 0); snprintf(buf, sizeof(buf), "Exit/Room Ratio: %.2f", ratio); notify_player(player, cause, player, buf, 0); if (isWIZARD(player) && (matchfor == -2)) { snprintf(buf, sizeof(buf), "Cache stats: %d bytes in use of %d max. %d cache hits with %d misses. %d database errors.", mudstat.cache_usage, mudconf.cache_size, mudstat.cache_hits, mudstat.cache_misses, mudstat.cache_errors); notify_player(player, cause, player, buf, 0); } } } VOID do_children(player, cause, switches, argone) int player, cause, switches; char *argone; { int obj; register int i; if ((argone == (char *)NULL) || (argone[0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "List the children of what?", NOT_QUIET); return; } obj = resolve_object(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY : RSLV_EXITS)); if(obj == -1) return; if (!controls(player, cause, obj) && !isPARENT_OK(obj)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Permission denied.", NOT_QUIET); return; } for (i = 0; i < mudstat.total_objects; i++) { if (main_index[i] == (struct dsc *)NULL) continue; if (DSC_PARENT(main_index[i]) == obj) { notify_player(player, cause, player, display_name(player, cause, i), 0); cache_trim(); } } notify_player(player, cause, player, elist, 0); } VOID do_wipe(player, cause, switches, argc, argv) int player, cause, switches, argc; char *argv[]; { int thing, count; struct attr *atptr; struct asearch srch; char buf[MEDBUFFSIZ]; if ((argc < 1) || (argc > 2)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Wipe what?", NOT_QUIET); return; } thing = resolve_object(player, cause, argv[0], (!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY : RSLV_EXITS)); if(thing == -1) return; count = 0; for (atptr = attr_first(thing, &srch); atptr != (struct attr *)NULL; atptr = attr_next(thing, &srch)) { if (((argc == 2) && !quick_wild(argv[1], atptr->name)) || ((atptr->dat).str == (char *)NULL) || (((atptr->dat).str)[0] == '\0')) continue; if (!can_see_attr(player, cause, thing, atptr->flags) || !can_set_attr(player, cause, thing, atptr->flags)) { if(!(switches & CMD_QUIET)) { snprintf(buf, sizeof(buf), "%s(#%d): Permission denied.", atptr->name, thing); notify_player(player, cause, player, buf, NOT_QUIET); } continue; } if(!(switches & CMD_QUIET)) { snprintf(buf, sizeof(buf), "Removing attribute %s.", atptr->name); notify_player(player, cause, player, buf, NOT_QUIET); } if(attr_delete(thing, atptr->name) == -1) { notify_bad(player); return; } count++; } if(!(switches & CMD_QUIET)) { if(count) { snprintf(buf, sizeof(buf), "Removed %d attributes.", count); notify_player(player, cause, player, buf, NOT_QUIET); } else notify_player(player, cause, player, "No matching attributes.", NOT_QUIET); } } VOID do_edit(player, cause, switches, argc, argv) int player, cause, switches, argc; char *argv[]; { int thing; int d, len, doneone = 0; char *r, *val, *s; struct attr *atptr; struct asearch srch; char dest[MEDBUFFSIZ], buf[MEDBUFFSIZ]; int (*mfunc) _ANSI_ARGS_((char *, char *)); if (argc == 0) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Edit what?", NOT_QUIET); return; } if ((argv[1] == (char *)NULL) || (argv[1][0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You must specify an attribute.", NOT_QUIET); return; } if ((argc < 3) || (argv[2] == (char *)NULL) || (argv[2][0] == '\0')) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Nothing to do.", NOT_QUIET); return; } thing = resolve_object(player, cause, argv[0], (!(switches & CMD_QUIET) ? RSLV_EXITS|RSLV_NOISY : RSLV_EXITS)); if(thing == -1) return; val = argv[2]; if(argv[3] == NULL) r = ""; else r = argv[3]; /* * Set the mfunc. If /all was given, use quick_wild(), otherwise use * quick_wild_prefix(). */ if (switches & EDIT_ALL) mfunc = quick_wild; else mfunc = quick_wild_prefix; for (atptr = attr_first(thing, &srch); atptr != (struct attr *)NULL; atptr = attr_next(thing, &srch)) { if (atptr->type != ATTR_STRING) continue; if (!(mfunc)(argv[1], atptr->name) || ((atptr->dat).str == (char *)NULL) || (((atptr->dat).str)[0] == '\0')) continue; if (!can_see_attr(player, cause, thing, atptr->flags) || !can_set_attr(player, cause, thing, atptr->flags)) { if(!(switches & CMD_QUIET)) { snprintf(buf, sizeof(buf), "%s(#%d): Permission denied.", atptr->name, thing); notify_player(player, cause, player, buf, NOT_QUIET); } continue; } /* * Decide what to do. */ if((val[0] == '$') && (val[1] == '\0')) { /* Append */ s = (atptr->dat).str; d = 0; while((d < sizeof(dest)-2) && *s) dest[d++] = *s++; if(!(switches & EDIT_NOSPACE)) dest[d++] = ' '; s = r; while((d < sizeof(dest)-1) && *s) dest[d++] = *s++; } else if((val[0] == '^') && (val[1] == '\0')) { /* Prepend */ s = r; d = 0; while((d < sizeof(dest)-2) && *s) dest[d++] = *s++; if(!(switches & EDIT_NOSPACE)) dest[d++] = ' '; s = (atptr->dat).str; while((d < sizeof(dest)-1) && *s) dest[d++] = *s++; } else { /* Replacement. */ len = strlen(val); s = (atptr->dat).str; d = 0; while((d < sizeof(dest)) && *s) { if (strncmp(val, s, len) == 0) { if ((d + strlen(r)) < sizeof(dest)-1) { strcpy(dest + d, r); d += strlen(r); s += len; } else if(d < (sizeof(dest)-1)) { dest[d++] = *s++; } } else dest[d++] = *s++; } } dest[d] = '\0'; if (!ok_attr_value(dest)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You can't set an attribute to that!", NOT_QUIET); return; } /* XXX - this only works because the attribute already exists! */ if (attr_add(thing, atptr->name, dest, atptr->flags) == -1) { notify_bad(player); return; } if(!(switches & CMD_QUIET)) { snprintf(buf, sizeof(buf), "%s set.", atptr->name); notify_player(player, cause, player, buf, NOT_QUIET); } doneone++; /* If /all wasn't given, we're done. */ if(!(switches & EDIT_ALL)) break; } if (doneone) { stamp(thing, STAMP_MODIFIED); } else { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "No matching attributes.", NOT_QUIET); } } VOID do_sweep(player, cause, switches, argone) int player, cause, switches; char *argone; { int here, list, obj, owner; char *name, buf[MEDBUFFSIZ]; if ((get_int_elt(player, LOC, &here) == -1) || !_exists_object(here)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "You have no location!", NOT_QUIET); return; } if (argone && *argone) { obj = resolve_object(player, cause, argone, (!(switches & CMD_QUIET) ? RSLV_NOISY : 0)); if(obj == -1) return; } else obj = here; if ((obj != here) && !controls(player, cause, obj)) { if(!(switches & CMD_QUIET)) notify_player(player, cause, player, "Permission denied.", NOT_QUIET); return; } if (get_int_elt(obj, CONTENTS, &list) != -1) { while (list != -1) { if((get_str_elt(list, NAME, &name) != -1) && (get_int_elt(list, OWNER, &owner) != -1)) { if (isALIVE(list) || (isPUPPET(list) && isALIVE(owner)) || isLISTENER(list)) { snprintf(buf, sizeof(buf), "%s is listening.", name); notify_player(player, cause, player, buf, 0); } if (isAUDIBLE(list)) { snprintf(buf, sizeof(buf), "%s will echo things.", name); notify_player(player, cause, player, buf, 0); } } if (get_int_elt(list, NEXT, &list) == -1) break; } } else { notify_bad(player); return; } if (get_int_elt(obj, EXITS, &list) != -1) { while (list != -1) { if (isAUDIBLE(list) && (get_str_elt(list, NAME, &name) != -1)) { snprintf(buf, sizeof(buf), "%s will echo things.", name); notify_player(player, cause, player, buf, 0); } if (get_int_elt(list, NEXT, &list) == -1) break; } } notify_player(player, cause, player, elist, 0); }