#include "copyright.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "db.h"
struct object *db = 0;
dbref db_top = 0;
//extern void *malloc(unsigned long);
//extern void *realloc(void *, unsigned long);
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 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 (void)
{
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;
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;
}
}
}