/* textout.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> #include <netinet/in.h> #ifdef HAVE_STRING_H #include <string.h> #else #include <strings.h> #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ #include <ctype.h> #include "conf.h" #include "teeny.h" #include "teenydb.h" #include "textdb.h" #include "externs.h" static void putarray _ANSI_ARGS_((FILE *, int *)); static void putbool_sub _ANSI_ARGS_((FILE *, struct boolexp *)); static void putbool _ANSI_ARGS_((FILE *, struct boolexp *)); INLINE static void gfilter_init _ANSI_ARGS_((void)); static void gfilter_free _ANSI_ARGS_((void)); static int gfilter _ANSI_ARGS_((int)); static int *gfilt = (int *)NULL; static int gcount = 0; static void gfilter_init() { register int indx, findx; gcount = mudstat.total_objects - mudstat.actual_objects; if(gcount > 0) { if(gfilt != (int *)NULL) ty_free((VOID *)gfilt); gfilt = (int *)ty_malloc((gcount * sizeof(int)), "gfilt"); for(indx = 0, findx = 0; indx < mudstat.total_objects; indx++) { if(!_exists_object(indx)) gfilt[findx++] = indx; } } } static void gfilter_free() { if(gfilt != (int *)NULL) { ty_free((VOID *)gfilt); gfilt = (int *)NULL; gcount = 0; } } INLINE static int gfilter(objnum) int objnum; { register int indx; if((gfilt != (int *)NULL) && (objnum >= 0)) { for(indx = 0; indx < gcount; indx++) { if(gfilt[indx] > objnum) break; } indx--; return(objnum - indx); } else return(objnum); } static void putarray(out, array) FILE *out; int *array; { register int i; if(array != (int *)NULL) { for(i = 0; i < array[0]; i++) fprintf(out, "%d ", gfilter(array[i])); fprintf(out, "%d\n", gfilter(array[i])); } else fputs("-1\n", out); } static void putbool_sub(out, lock) FILE *out; struct boolexp *lock; { switch(lock->type) { case BOOLEXP_AND: fputc('(', out); putbool_sub(out, lock->sub1); fputc('&', out); putbool_sub(out, lock->sub2); fputc(')', out); break; case BOOLEXP_OR: fputc('(', out); putbool_sub(out, lock->sub1); fputc('|', out); putbool_sub(out, lock->sub2); fputc(')', out); break; case BOOLEXP_NOT: fputc('(', out); fputc('!', out); putbool_sub(out, lock->sub1); fputc(')', out); break; case BOOLEXP_CONST: fprintf(out, "#%d", gfilter((lock->dat).thing)); break; case BOOLEXP_FLAG: fprintf(out, "~%d/%d", ((lock->dat).flags)[0], ((lock->dat).flags)[1]); break; case BOOLEXP_ATTR: fputc('{', out); fputs(((lock->dat).atr)[0], out); fputc(':', out); fputs(((lock->dat).atr)[1], out); fputc('}', out); break; } } static void putbool(out, lock) FILE *out; struct boolexp *lock; { if(lock != (struct boolexp *)NULL) putbool_sub(out, lock); } extern const char teenymud_version[]; void text_dump(out, write_version, write_flags) FILE *out; int write_version, write_flags; { register int obj, idx; struct obj_data *theobj; struct attr *attrs; if(write_flags & DB_GFILTER) gfilter_init(); fprintf(out, "!\n! TeenyMUD %s textdump.\n! Actual objects: %d\n!\n", teenymud_version, mudstat.actual_objects); fprintf(out, "$%d %d %d\n", write_version, (write_flags & ~DB_GFILTER), ((write_flags & DB_GFILTER) ? mudstat.actual_objects : mudstat.total_objects)); for(obj = 0; obj < mudstat.total_objects; obj++) { if((obj >= 1000) && ((obj % 1000) == 0)) { fputc('o', stderr); fflush(stderr); } else if((obj % 100) == 0) { fputc('.', stderr); fflush(stderr); } if(_exists_object(obj)) { if((theobj = lookup_obj(obj)) == (struct obj_data *)NULL) { fprintf(stderr, "Warning: couldn't load object #%d! Writing it out as garbage.\n", obj); fprintf(out, "@%d\n", obj); } else { fprintf(out, "#%d\n%d/%d\n", gfilter(obj), DSC_FLAG1(main_index[obj]), DSC_FLAG2(main_index[obj])); fprintf(out, "%d\n%d\n", theobj->quota, gfilter(theobj->loc)); if(DSC_TYPE(main_index[obj]) != TYP_EXIT) { fprintf(out, "%d\n", gfilter(DSC_HOME(main_index[obj]))); } else { putarray(out, DSC_DESTS(main_index[obj])); } fprintf(out, "%d\n", gfilter(DSC_OWNER(main_index[obj]))); fprintf(out, "%d\n%d\n", gfilter(theobj->contents), gfilter(theobj->exits)); fprintf(out, "%d\n%d\n", gfilter(theobj->rooms), gfilter(DSC_NEXT(main_index[obj]))); fprintf(out, "%d\n%d\n", theobj->timestamp, theobj->created); fprintf(out, "%d\n%d\n", theobj->usecnt, gfilter(DSC_PARENT(main_index[obj]))); fprintf(out, "%d\n%d\n", theobj->charges, theobj->semaphores); fprintf(out, "%d\n%d\n", theobj->cost, theobj->queue); if(theobj->name != (char *)NULL) fputs(theobj->name, out); fputc('\n', out); for (idx = 0; idx < ATTR_WIDTH; idx++) { for (attrs = theobj->attributes[idx]; attrs != (struct attr *)NULL; attrs = attrs->next) { if(attrs->name != (char *)NULL) fputs(attrs->name, out); fputc('\n', out); fprintf(out, "%d %d\n", attrs->flags, attrs->type); switch(attrs->type) { case ATTR_STRING: if((attrs->dat).str != (char *)NULL) fputs((attrs->dat).str, out); break; case ATTR_LOCK: putbool(out, (attrs->dat).lock); break; } fputc('\n', out); } } fputs(">\n", out); } } else if(!(write_flags & DB_GFILTER)) { fprintf(out, "@%d\n", obj); } } fputs("**** END OF DUMP ****\n", out); fputc('\n', stderr); fflush(stderr); if(write_flags & DB_GFILTER) gfilter_free(); }