#include "copyright.h" #include <ctype.h> #include "db.h" struct object *db = 0; dbref db_top = 0; extern void *malloc(unsigned long); extern void *realloc(void *, unsigned long); const char *alloc_string(const char *string) { char *s; /* NULL, "" -> NULL */ if(string == 0 || *string == '\0') return 0; if((s = (char *) malloc(strlen(string)+1)) == 0) { abort(); } strcpy(s, string); return s; } static void db_grow(dbref newtop) { struct object *newdb; if(newtop > db_top) { db_top = newtop; if(db) { if((newdb = (struct object *) realloc((void *) db, db_top * sizeof(struct object))) == 0) { abort(); } db = newdb; } else { /* make the initial one */ if((db = (struct object *) malloc(db_top * sizeof(struct object))) == 0) { abort(); } } } } dbref new_object() { dbref newobj; struct object *o; newobj = db_top; db_grow(db_top + 1); /* clear it out */ o = db+newobj; o->name = 0; o->description = 0; o->location = NOTHING; o->contents = NOTHING; o->exits = NOTHING; o->next = NOTHING; o->key = NOTHING; o->fail_message = 0; o->succ_message = 0; o->ofail = 0; o->osuccess = 0; o->owner = NOTHING; o->pennies = 0; /* flags you must initialize yourself */ o->password = 0; return newobj; } #define DB_MSGLEN 512 static void putref(FILE *f, dbref ref) { fprintf(f, "%d\n", ref); } static void putstring(FILE *f, const char *s) { if(s) { fputs(s, f); } putc('\n', f); } int db_write_object(FILE *f, dbref i) { struct object *o; o = db + i; putstring(f, o->name); putstring(f, o->description); putref(f, o->location); putref(f, o->contents); putref(f, o->exits); putref(f, o->next); putref(f, o->key); putstring(f, o->fail_message); putstring(f, o->succ_message); putstring(f, o->ofail); putstring(f, o->osuccess); putref(f, o->owner); putref(f, o->pennies); putref(f, o->flags); putstring(f, o->password); return 0; } dbref db_write(FILE *f) { dbref i; for(i = 0; i < db_top; i++) { fprintf(f, "#%d\n", i); db_write_object(f, i); } fputs("***END OF DUMP***\n", f); fflush(f); return(db_top); } dbref parse_dbref(const char *s) { const char *p; long x; x = atol(s); if(x > 0) { return x; } else if(x == 0) { /* check for 0 */ for(p = s; *p; p++) { if(*p == '0') return 0; if(!isspace(*p)) break; } } /* else x < 0 or s != 0 */ return NOTHING; } static dbref getref(FILE *f) { static char buf[DB_MSGLEN]; fgets(buf, sizeof(buf), f); return(atol(buf)); } static const char *getstring(FILE *f) { static char buf[DB_MSGLEN]; char *p; fgets(buf, sizeof(buf), f); for(p = buf; *p; p++) { if(*p == '\n') { *p = '\0'; break; } } if(!*buf) { return(0); } else { return(alloc_string(buf)); } } void db_free() { dbref i; struct object *o; if(db) { for(i = 0; i < db_top; i++) { o = &db[i]; if(o->name) free(o->name); if(o->description) free(o->description); if(o->succ_message) free(o->succ_message); if(o->fail_message) free(o->fail_message); if(o->ofail) free(o->ofail); if(o->osuccess) free(o->osuccess); if(o->password) free(o->password); } free(db); db = 0; db_top = 0; } } dbref db_read(FILE *f) { dbref i; struct object *o; const char *end; db_free(); for(i = 0;; i++) { switch(getc(f)) { case '#': /* another entry, yawn */ if(i != getref(f)) { /* we blew it */ return -1; } /* make space */ db_grow(i+1); /* read it in */ o = db+i; o->name = getstring(f); o->description = getstring(f); o->location = getref(f); o->contents = getref(f); o->exits = getref(f); o->next = getref(f); o->key = getref(f); o->fail_message = getstring(f); o->succ_message = getstring(f); o->ofail = getstring(f); o->osuccess = getstring(f); o->owner = getref(f); o->pennies = getref(f); o->flags = getref(f); o->password = getstring(f); break; case '*': end = getstring(f); if(strcmp(end, "**END OF DUMP***")) { free(end); return -1; } else { free(end); return db_top; } default: return -1; break; } } }