/* db.h */ #include "copyright.h" #ifndef __DB_H #define __DB_H #include "config.h" #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/file.h> #include <string.h> #ifdef WANT_ANSI #ifdef __STDC__ #include <stdlib.h> #endif /* __STDC__ */ #endif /* WANT_ANSI */ #define KEY_SIZE 17 #define STORE(key,con) (dbp->put)(dbp,&(key),&(con),R_PUT) #define DELETE(key) (dbp->del)(dbp, &(key), O_RDWR) #define FETCH(key,res) (dbp->get)(dbp, &(key), &(res), O_RDWR) #define SYNC (dbp->sync)(dbp) #define CLOSE (dbp->close)(dbp) #include "udb.h" extern DB *dbp; extern int depth; typedef int dbref; /* offset into db */ typedef int FLAG; /* flags */ #define TYPE_ROOM 0x0 #define TYPE_THING 0x1 #define TYPE_EXIT 0x2 #define TYPE_PLAYER 0x3 #define TYPE_LOST 0x4 /* unused for now... */ #define TYPE_FREE 0x5 /* unused for now... */ #define NOTYPE 0x7 /* no particular type */ #define TYPE_MASK 0x7 /* room for expansion */ #define WIZARD 0x00000010 /* gets automatic control */ #define LINK_OK 0x00000020 /* anybody can link to this room */ #define DARK 0x00000040 /* Don't show contents or presence */ #define STICKY 0x00000100 /* Object goes home when dropped */ #define HAVEN 0x00000400 /* No killing here, or no pages */ #define QUIET 0x00000800 /* Prevent 'feelgood' messages */ #define HALT 0x00001000 /* object cannot perform actions */ #define GOING 0x00004000 /* object is available for recycling */ #define MONITOR 0x00008000 /* Process ^x:action listens on obj? */ /* #define MARKED 0x00010000 */ /* flag used for db checking */ #define PUPPET 0x00020000 /* Relays ALL messages to owner */ #define CHOWN_OK 0x00040000 /* Object may be @chowned freely */ #define ENTER_OK 0x00080000 /* Object may be ENTERed */ #define VISUAL 0x00100000 /* Everyone can see properties */ #define IMMORTAL 0x00200000 /* Object can't be killed */ #define STARTUP 0x00400000 /* Object has a startup field */ #define OPAQUE 0x00800000 /* Can't see inside */ #define VERBOSE 0x01000000 /* Tells owner everything it does. */ #define INHERIT 0x02000000 /* Gets owner's privs. (i.e. Wiz) */ #define NOSPOOF 0x04000000 /* Report originator of all actions. */ #define HEARTHRU 0x40000000 /* Can hear out of this object or exit */ /* object specific flags */ /* Exit flags */ #define EXIT_SEETHRU 0x00000008 /* Show dest @desc also */ #define EXIT_KEY 0x00000080 /* Divest of KEY objs when used */ #define EXIT_ROBOT 0x08000000 /* Robots may not use */ #define EXIT_SAFE 0x10000000 /* Prevents accidental @destroy */ /* Object flags */ #define THING_KEY 0x00000008 /* cannot be picked up by puppets */ #define THING_DEST_OK 0x00000200 /* Destroyable by others */ #define THING_ROBOT 0x08000000 /* Robots cannot use */ #define THING_SAFE 0x10000000 /* Prevents accidental @destroy */ /* Player flags */ #define PLAYER_BUILD 0x00000008 /* Player can build. */ #define PLAYER_GAGGED 0x00000080 /* Player can't speak, etc */ #define PLAYER_CONNECT 0x00000200 /* Player is connected */ #define PLAYER_UNFIND 0x00002000 /* Hidden from @whereis */ #define PLAYER_ROBOT 0x08000000 /* Allowed to use robot commands */ #define PLAYER_SLAVE 0x10000000 /* Prevents player from modifying db */ #define PLAYER_SUSPECT 0x20000000 /* Report logins/logouts to wizards */ /* Room flags */ #define ROOM_FLOATING 0x00000008 /* Don't blather about disconnected */ #define ROOM_TEMPLE 0x00000080 /* Get sac value for dropped objs */ #define ROOM_ABODE 0x00000200 /* May set home here */ #define ROOM_JUMP_OK 0x00002000 /* May @tel here */ #define ROOM_SAFE 0x10000000 /* Prevents accidental @destroy */ #define GOD ((dbref) 1) /* ---------------------- Object Permission/Attribute Macros */ /* IS(X,T,F) - Is X of type T and have flag F set? */ /* Typeof(X) - What object type is X */ /* God(X) - Is X player #1 */ /* Guest(X) - Is X the GUEST player */ /* Robot(X) - Is X a robot player */ /* Wizard(X) - Does X have wizard privs */ /* Immortal(X) - Is X unkillable */ /* Alive(X) - Is X a player or a puppet */ /* Dark(X) - Is X dark */ /* Builder(X) - Is X allowed to add on to the db */ /* Floating(X) - Prevent 'disconnected room' msgs for room X */ /* Quiet(X) - Should 'Set.' messages et al from X be disabled */ /* Gagged(X) - Should X be prevented from yakking */ /* Player_haven(X) - Is the owner of X no-page */ /* Haven(X) - Is X no-kill(rooms) or no-page(players) */ /* Halted(X) - Is X halted (not allowed to run commands)? */ /* Suspect(X) - Is X someone the wizzes should keep an eye on */ /* Slave(X) - Should X be prevented from db-changing commands */ /* Safe(X,P) - Does P need the /OVERRIDE switch to @destroy X? */ /* Monnitor(X) - Should we check for ^xxx:xxx listens on player? */ /* Unfindable(X) - Is @whereis blocked for X */ /* Findable(X) - Can @whereis find X */ /* No_robots(X) - Does X disallow robot players from using */ /* Has_location(X) - Is X something with a location (ie plyr or obj) */ /* Has_home(X) - Is X something with a home (ie plyr or obj) */ /* Has_contents(X) - Is X something with contents (ie plyr/obj/room) */ /* Good_obj(X) - Is X inside the DB and have a valid type? */ /* Good_owner(X) - Is X a good owner value? */ /* Going(X) - Is X marked GOING? */ /* Inherits(X) - Does X inherit the privs of its owner */ /* Examinable(P,X) - Can P look at attribs of X */ /* Controls(P,X) - Can P force X to do something */ /* Affects(P,X) - (Controls in MUSH V1) Is P wiz or same owner as X */ /* Abode(X) - Is X an ABODE room */ /* Link_exit(P,X) - Can P link from exit X */ /* Linkable(P,X) - Can P link to X */ /* Mark(x) - Set marked flag on X */ /* Unmark(x) - Clear marked flag on X */ /* Marked(x) - Check marked flag on X */ /* See_attr(P,X.A,O) - Can P see text attr A on X if attr has owner O */ /* Set_attr(P,X,A,F) - Can P set/change text attr A (with flags F) on X */ /* Read_attr(P,X.A,O) - Can P see attr A on X if attr has owner O */ /* Write_attr(P,X,A,F) - Can P set/change attr A (with flags F) on X */ #define IS(thing,type,flag) ((Typeof(thing)==(type)) && (Flags(thing) & (flag))) #define Typeof(x) (Flags(x) & TYPE_MASK) #define God(x) ((x) == GOD) #define Guest(x) (Owner(x) == mudconf.guest_char) #define Robot(x) IS((x),TYPE_PLAYER,PLAYER_ROBOT) #define Wizard(x) ((Flags(x) & WIZARD) || \ ((Flags(Owner(x)) & WIZARD) && Inherits(x))) #define Immortal(x) ((Flags(x) & IMMORTAL) || \ ((Flags(Owner(x)) & IMMORTAL) && Inherits(x))) #define Alive(x) ((Typeof(x)==TYPE_PLAYER) || \ ((Typeof(x)==TYPE_THING) && (Flags(x) & PUPPET))) #define Dark(x) (((Flags(x) & DARK) != 0) && \ (Wizard(x) || !Alive(x))) #define Builder(x) ((Flags(Owner(x)) & PLAYER_BUILD) || Wizard(x)) #define Floating(x) IS((x),TYPE_ROOM,ROOM_FLOATING) #define Quiet(x) (((Flags(x) & QUIET) !=0) || \ ((Flags(Owner(x)) & QUIET) != 0)) #define Gagged(x) ((Flags(Owner(x)) & PLAYER_GAGGED) != 0) #define Player_haven(x) ((Flags(Owner(x)) & HAVEN) != 0) #define Haven(x) ((Flags(x) & HAVEN) != 0) #define Halted(x) ((Flags(x) & HALT) != 0) #define Suspect(x) ((Flags(Owner(x)) & PLAYER_SUSPECT) != 0) #define Slave(x) (Flags(Owner(x)) & PLAYER_SLAVE) #define Safe(x,p) ((Typeof(x) == TYPE_PLAYER) || \ (Flags(x) & THING_SAFE)) #define Monitor(x) (Flags(x) & MONITOR) #define Audible(x) (Flags(x) & HEARTHRU) #define Unfindable(x) ((Typeof(x) == TYPE_PLAYER) && \ ((Flags(x) & PLAYER_UNFIND) != 0)) #define Findable(x) ((Typeof(x) == TYPE_PLAYER) && \ ((Flags(x) & PLAYER_UNFIND) == 0)) #define No_robots(x) (IS((x),TYPE_EXIT,EXIT_ROBOT) || \ IS((x),TYPE_THING,THING_ROBOT)) #define Has_location(x) ((Typeof(x) == TYPE_PLAYER) || \ (Typeof(x) == TYPE_THING)) #define Has_home(x) ((Typeof(x) == TYPE_PLAYER) || \ (Typeof(x) == TYPE_THING)) #define Has_contents(x) ((Typeof(x) == TYPE_PLAYER) || \ (Typeof(x) == TYPE_THING) || \ (Typeof(x) == TYPE_ROOM)) #define Has_exits(x) ((Typeof(x) == TYPE_PLAYER) || \ (Typeof(x) == TYPE_THING) || \ (Typeof(x) == TYPE_ROOM)) #define Good_obj(x) ((((x) >= 0) && ((x) < mudstate.db_top)) && \ (Typeof(x) <= TYPE_PLAYER)) #define Good_owner(x) (Good_obj(x) && (Typeof(x) == TYPE_PLAYER)) #define Going(x) ((Flags(x) & GOING) != 0) #define Inherits(x) (((Flags(x) & INHERIT) != 0) || \ ((Flags(Owner(x)) & INHERIT) != 0) || \ ((x) == Owner(x))) #define Examinable(p,x) (((Flags(x) & VISUAL) != 0) || \ (Wizard(p)) || \ (Owner(p) == Owner(x))) #define Controls(p,x) (Good_obj(x) && \ (!(God(x) && !God(p))) && \ (Wizard(p) || \ ((Owner(p) == Owner(x)) && \ (Inherits(p) || !Inherits(x))))) #define Affects(p,x) (Good_obj(x) && \ (!(God(x) && !God(p))) && \ (Wizard(p) || \ (Owner(p) == Owner(x)))) #define Abode(x) (IS((x),TYPE_ROOM,ROOM_ABODE)) #define Mark(x) (mudstate.markbits->chunk[(x)>>3] |= \ mudconf.markdata[(x)&7]) #define Unmark(x) (mudstate.markbits->chunk[(x)>>3] &= \ ~mudconf.markdata[(x)&7]) #define Marked(x) (mudstate.markbits->chunk[(x)>>3] & \ mudconf.markdata[(x)&7]) #define Mark_all(i) for ((i)=0; (i)<((mudstate.db_top+7)>>3); (i)++) \ mudstate.markbits->chunk[i]=0xff #define Unmark_all(i) for ((i)=0; (i)<((mudstate.db_top+7)>>3); (i)++) \ mudstate.markbits->chunk[i]=0x0 #define Link_exit(p,x) ((Typeof(x) == TYPE_EXIT) && \ ((Location(x) == NOTHING) || Controls(p,x))) #define Linkable(p,x) (Good_obj(x) && \ (((Flags(x) & LINK_OK) != 0) || \ Controls(p,x))) #define See_attr(p,x,a,o) \ (!((a)->flags & (AF_INTERNAL|AF_IS_LOCK)) && \ (God(p) || \ ((Examinable(p,x) || (Owner(p) == o)) && \ !((a)->flags & (AF_DARK|AF_MDARK))) || \ (Wizard(p) && !((a)->flags & AF_DARK)) || \ !((a)->flags & (AF_DARK|AF_MDARK|AF_ODARK)))) #define Set_attr(p,x,a,f) \ (!((a)->flags & (AF_INTERNAL|AF_IS_LOCK)) && \ (God(p) || \ (!God(x) && !(f & AF_LOCK) && \ ((Controls(p,x) && \ !((a)->flags & (AF_WIZARD|AF_GOD))) || \ (Wizard(p) && \ !((a)->flags & AF_GOD)))))) #define Read_attr(p,x,a,o) \ (!((a)->flags & AF_INTERNAL) && \ (God(p) || \ ((Examinable(p,x) || (Owner(p) == o)) && \ !((a)->flags & (AF_DARK|AF_MDARK))) || \ (Wizard(p) && !((a)->flags & AF_DARK)) || \ !((a)->flags & (AF_DARK|AF_MDARK|AF_ODARK)))) #define Write_attr(p,x,a,f) \ (!((a)->flags & AF_INTERNAL) && \ (God(p) || \ (!God(x) && !(f & AF_LOCK) && \ ((Controls(p,x) && \ !((a)->flags & (AF_WIZARD|AF_GOD))) || \ (Wizard(p) && \ !((a)->flags & AF_GOD)))))) #define Has_power(p,x) (check_access((p),powers_nametab[x].flag)) /* Player classes and pseudo-classes for determining access to commands */ #define CLASS_SLAVE 0 #define CLASS_GUEST 1 #define CLASS_VISITOR 2 #define CLASS_PLAYER 4 #define CLASS_ARCHITECT 8 #define CLASS_MAGE 12 #define CLASS_WIZARD 14 #define CLASS_MAINT 15 #define CLASS_GOD 16 /* Cannot assign players to this class */ #define CLASS_DISABLED 17 /* Cannot assign players to this class */ typedef struct attr ATTR; struct attr { const char *name; /* This has to be first. braindeath. */ int number; /* attr number */ int flags; int (*check) (int key, dbref player, dbref thing, int anum, char *atext); }; extern ATTR *atr_num(int anum); extern ATTR *atr_str(char *s); extern ATTR attr[]; /* Attribute flags */ #define AF_ODARK 0x0001 /* players other than owner can't see it */ #define AF_DARK 0x0002 /* No one can see it */ #define AF_WIZARD 0x0004 /* only wizards can change it */ #define AF_MDARK 0x0008 /* Only wizards can see it. Dark to mortals */ #define AF_INTERNAL 0x0010 /* Don't show even to #1 */ #define AF_NOCMD 0x0020 /* Don't create a @ command for it */ #define AF_LOCK 0x0040 /* Attribute is locked */ #define AF_DELETED 0x0080 /* Attribute should be ignored */ #define AF_NOPROG 0x0100 /* Don't process $-commands from this attr */ #define AF_GOD 0x0200 /* Only #1 can change it */ #define AF_IS_LOCK 0x0400 /* Attribute is a lock */ #define ATR_INFO_CHAR '\1' /* Leadin char for attr control data */ #define A_OSUCC 1 /* Others success message */ #define A_OFAIL 2 /* Others fail message */ #define A_FAIL 3 /* Invoker fail message */ #define A_SUCC 4 /* Invoker success message */ #define A_PASS 5 /* Password (only meaningful for players) */ #define A_DESC 6 /* Description */ #define A_SEX 7 /* Sex */ #define A_ODROP 8 /* Others drop message */ #define A_DROP 9 /* Invoker drop message */ #define A_OKILL 10 /* Others kill message */ #define A_KILL 11 /* Invoker kill message */ #define A_ASUCC 12 /* Success action list */ #define A_AFAIL 13 /* Failure action list */ #define A_ADROP 14 /* Drop action list */ #define A_AKILL 15 /* Kill action list */ #define A_AUSE 16 /* Use action list */ #define A_CHARGES 17 /* Number of charges remaining */ #define A_RUNOUT 18 /* Actions done when no more charges */ #define A_STARTUP 19 /* Actions run when game started up */ #define A_ACLONE 20 /* Actions run when obj is cloned */ #define A_APAY 21 /* Actions run when given COST pennies */ #define A_OPAY 22 /* Others pay message */ #define A_PAY 23 /* Invoker pay message */ #define A_COST 24 /* Number of pennies needed to invoke xPAY */ #define A_RAND 25 /* Unused */ #define A_LISTEN 26 /* (Wildcarded) string to listen for */ #define A_AAHEAR 27 /* Actions to do when anyone says LISTEN str */ #define A_AMHEAR 28 /* Actions to do when I say LISTEN str */ #define A_AHEAR 29 /* Actions to do when others say LISTEN str */ #define A_LAST 30 /* Date/time of last login (players only) */ #define A_QUEUE 31 /* Number of entries obj has in the queue */ #define A_IDESC 32 /* Inside description (ENTER to get inside) */ #define A_ENTER 33 /* Invoker enter message */ #define A_OXENTER 34 /* Others enter message in dest */ #define A_AENTER 35 /* Enter action list */ #define A_ADESC 36 /* Describe action list */ #define A_ODESC 37 /* Others describe message */ #define A_RQUOTA 38 /* Relative object quota */ #define A_ACONNECT 39 /* Actions run when player connects */ #define A_ADISCONNECT 40 /* Actions run when player disconnectes */ #define A_ALLOWANCE 41 /* Daily allowance, if diff from default */ #define A_LOCK 42 /* Object lock */ #ifdef ATR_NAME #define A_NAME 43 /* Object name */ #endif #define A_COMMENT 44 /* Wizard-accessable comments */ #define A_USE 45 /* Invoker use message */ #define A_OUSE 46 /* Others use message */ #define A_SEMAPHORE 47 /* Semaphore control info */ #define A_TIMEOUT 48 /* Per-user disconnect timeout */ #define A_QUOTA 49 /* Absolute quota (to speed up @quota) */ #define A_LEAVE 50 /* Invoker leave message */ #define A_OLEAVE 51 /* Others leave message in src */ #define A_ALEAVE 52 /* Leave action list */ #define A_OENTER 53 /* Others enter message in src */ #define A_OXLEAVE 54 /* Others leave message in dest */ #define A_MOVE 55 /* Invoker move message */ #define A_OMOVE 56 /* Others move message */ #define A_AMOVE 57 /* Move action list */ #define A_ALIAS 58 /* Alias for player names */ #define A_LENTER 59 /* ENTER lock */ #define A_LLEAVE 60 /* LEAVE lock */ #define A_LPAGE 61 /* PAGE lock */ #define A_LUSE 62 /* USE lock */ #define A_LGIVE 63 /* Give lock (who may give me away?) */ #define A_EALIAS 64 /* Alternate names for ENTER */ #define A_LALIAS 65 /* Alternate names for LEAVE */ #define A_EFAIL 66 /* Invoker entry fail message */ #define A_OEFAIL 67 /* Others entry fail message */ #define A_AEFAIL 68 /* Entry fail action list */ #define A_LFAIL 69 /* Invoker leave fail message */ #define A_OLFAIL 70 /* Others leave fail message */ #define A_ALFAIL 71 /* Leave fail action list */ #define A_REJECT 72 /* Rejected page return message */ #define A_AWAY 73 /* Not_connected page return message */ #define A_IDLE 74 /* Success page return message */ #define A_UFAIL 75 /* Invoker use fail message */ #define A_OUFAIL 76 /* Others use fail message */ #define A_AUFAIL 77 /* Use fail action list */ #define A_PFAIL 78 /* Invoker page fail message */ #define A_TPORT 79 /* Invoker teleport message */ #define A_OTPORT 80 /* Others teleport message in src */ #define A_OXTPORT 81 /* Others teleport message in dst */ #define A_ATPORT 82 /* Teleport action list */ #define A_PRIVS 83 /* Individual permissions */ #define A_LOGINDATA 84 /* Recent login information */ #define A_LTPORT 85 /* Teleport lock (can others @tel to me?) */ #define A_LDROP 86 /* Drop lock (can I be dropped or @tel'ed) */ #define A_LRECEIVE 87 /* Receive lock (who may give me things?) */ #define A_LASTSITE 88 /* Last site logged in from, in cleartext */ #define A_INPREFIX 89 /* Prefix on incoming messages into objects */ #define A_PREFIX 90 /* Prefix used by exits/objects when audible */ #define A_INFILTER 91 /* Filter to zap incoming text into objects */ #define A_FILTER 92 /* Filter to zap text forwarded by audible. */ #define A_LLINK 93 /* Who may link to here */ #define A_LTELOUT 94 /* Who may teleport out from here */ #define A_FORWARDLIST 95 /* Recipients of AUDIBLE output */ #define A_VA 100 /* VA attribute (VB-VZ follow) */ #define A_VLIST 252 #define A_LIST 253 #define A_STRUCT 254 #define A_TEMP 255 #define A_USER_START 256 /* Start of user-named attributes */ #define ATR_BUF_CHUNK 100 /* Min size to allocate for attribute buffer */ #define ATR_BUF_INCR 6 /* Max size of one attribute */ /* Attribute handler keys */ #define AH_READ 0 /* Read the attribute from the hash db */ #define AH_WRITE 1 /* Write the attribute to the hash db */ #define AH_RWMASK 1 /* Mask for read/write bit */ #define AH_RAW 2 /* Don't encode/decode tag info */ #define AH_NOCHECK 4 /* Don't check permissions */ #define AH_NOSPECIAL 8 /* Ignore special processing */ /* Boolean expressions, for locks */ typedef char boolexp_type; #define BOOLEXP_AND 0 #define BOOLEXP_OR 1 #define BOOLEXP_NOT 2 #define BOOLEXP_CONST 3 #define BOOLEXP_ATR 4 #define BOOLEXP_INDIR 5 #define BOOLEXP_CARRY 6 #define BOOLEXP_IS 7 #define BOOLEXP_OWNER 8 struct boolexp { boolexp_type type; struct boolexp *sub1; struct boolexp *sub2; dbref thing; /* thing refers to an object */ }; #define TRUE_BOOLEXP ((struct boolexp *) 0) #define Astr(alist) ((unsigned char *)(&((alist)[1]))) /* Database format information */ #define F_UNKNOWN 0 /* Unknown database format */ #define F_MUSH 1 /* MUSH format (many variants) */ #define F_MUSE 2 /* MUSE format */ #define F_MUD 3 /* Old TinyMUD format */ #define F_MUCK 4 /* TinyMUCK format */ #define V_MASK 0x00ff /* Database version */ #define V_ZONE 0x0100 /* db has a ZONE/DOMAIN field */ #define V_LINK 0x0200 /* db has the LINK field (exits from objs) */ #define V_GDBM 0x0400 /* attributes are in a gdbm db, not here */ #define V_ATRNAME 0x0800 /* NAME is an attribute, not in the header */ #define V_ATRKEY 0x1000 /* KEY is an attribute, not in the header */ #define V_PERNKEY 0x1000 /* Extra locks in object header */ #define V_PARENT 0x2000 /* db has the PARENT field (inherit attrs) */ #define V_COMM 0x4000 /* Comm status in header */ /* special dbref's */ #define NOTHING (-1) /* null dbref */ #define AMBIGUOUS (-2) /* multiple possibilities, for matchers */ #define HOME (-3) /* virtual room, represents mover's home */ typedef struct object OBJ; struct object { #ifndef ATR_NAME char *name; /* PLAYER, THING, ROOM: Name of the object */ /* EXIT: Set of commands to use the exit */ #endif dbref location; /* PLAYER, THING: where it is */ /* ROOM: dropto: */ /* EXIT: where it goes to */ dbref contents; /* PLAYER, THING, ROOM: head of contentslist */ /* EXIT: unused */ dbref exits; /* PLAYER, THING, ROOM: head of exitslist */ /* EXIT: where it is */ dbref next; /* PLAYER, THING: next in contentslist */ /* EXIT: next in exitslist */ /* ROOM: unused */ dbref link; /* PLAYER, THING: home location */ /* ROOM, EXIT: unused */ dbref parent; /* ALL: defaults for attrs, exits, $cmds, */ dbref owner; /* PLAYER: domain number */ /* THING, ROOM, EXIT: owning player number */ int penn; /* PLAYER: wealth */ /* THING: sacrifice value */ /* ROOM, EXIT: ignored */ FLAG flags; /* ALL: Flags set on the object */ }; extern dbref getref(); extern void putref(); extern struct boolexp *dup_bool(); extern void free_boolexp(); extern dbref parse_dbref(); extern int mkattr(char *buff); extern void al_add (dbref thing, int attrnum); extern void al_delete (dbref thing, int attrnum); extern void al_destroy (dbref thing); extern void al_store (void); extern void db_grow(dbref newtop); extern void db_free(void); extern void db_make_minimal(void); extern dbref db_read(FILE * f, int *db_format, int *db_version, int *db_flags); extern dbref db_write(FILE * f, int format, int version); #define DOLIST(thing,list) \ for ((thing)=(list); \ ((thing)!=NOTHING) && (Next(thing)!=(thing)); \ (thing)=Next(thing)) #define SAFE_DOLIST(thing,next,list) \ for ((thing)=(list),(next)=((thing)==NOTHING ? NOTHING: Next(thing)); \ (thing)!=NOTHING && (Next(thing)!=(thing)); \ (thing)=(next), (next)=Next(next)) #define DO_WHOLE_DB(thing) \ for ((thing)=0; (thing)<mudstate.db_top; (thing)++) #define Dropper(thing) \ (Hearer(thing) && (Flags(Owner(thing)) & PLAYER_CONNECT)) #endif /* __DB_H */