src/db_rw.c

Go to the documentation of this file.
00001 /*
00002  * db_rw.c 
00003  */
00004 
00005 #include "copyright.h"
00006 #include "config.h"
00007 
00008 #include <sys/file.h>
00009 
00010 #include "mudconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013 #include "db.h"
00014 #include "vattr.h"
00015 #include "attrs.h"
00016 #include "alloc.h"
00017 #include "powers.h"
00018 
00019 extern const char *getstring_noalloc(FILE *, int);
00020 extern void putstring(FILE *, const char *);
00021 extern void db_grow(dbref);
00022 
00023 extern struct object *db;
00024 
00025 static int g_version;
00026 static int g_format;
00027 static int g_flags;
00028 
00029 /*
00030  * ---------------------------------------------------------------------------
00031  * * getboolexp1: Get boolean subexpression from file.
00032  */
00033 
00034 static BOOLEXP *getboolexp1(FILE * f)
00035 {
00036         BOOLEXP *b;
00037         char *buff, *s;
00038         int c, d, anum;
00039 
00040         c = getc(f);
00041         switch (c) {
00042         case '\n':
00043                 ungetc(c, f);
00044                 return TRUE_BOOLEXP;
00045                 /*
00046                  * break; 
00047                  */
00048         case EOF:
00049                 abort();                                /*
00050                                                                  * unexpected EOF in boolexp 
00051                                                                  */
00052                 break;
00053         case '(':
00054                 b = alloc_bool("getboolexp1.openparen");
00055                 switch (c = getc(f)) {
00056                 case NOT_TOKEN:
00057                         b->type = BOOLEXP_NOT;
00058                         b->sub1 = getboolexp1(f);
00059                         if((d = getc(f)) == '\n')
00060                                 d = getc(f);
00061                         if(d != ')')
00062                                 goto error;
00063                         return b;
00064                 case INDIR_TOKEN:
00065                         b->type = BOOLEXP_INDIR;
00066                         b->sub1 = getboolexp1(f);
00067                         if((d = getc(f)) == '\n')
00068                                 d = getc(f);
00069                         if(d != ')')
00070                                 goto error;
00071                         return b;
00072                 case IS_TOKEN:
00073                         b->type = BOOLEXP_IS;
00074                         b->sub1 = getboolexp1(f);
00075                         if((d = getc(f)) == '\n')
00076                                 d = getc(f);
00077                         if(d != ')')
00078                                 goto error;
00079                         return b;
00080                 case CARRY_TOKEN:
00081                         b->type = BOOLEXP_CARRY;
00082                         b->sub1 = getboolexp1(f);
00083                         if((d = getc(f)) == '\n')
00084                                 d = getc(f);
00085                         if(d != ')')
00086                                 goto error;
00087                         return b;
00088                 case OWNER_TOKEN:
00089                         b->type = BOOLEXP_OWNER;
00090                         b->sub1 = getboolexp1(f);
00091                         if((d = getc(f)) == '\n')
00092                                 d = getc(f);
00093                         if(d != ')')
00094                                 goto error;
00095                         return b;
00096                 default:
00097                         ungetc(c, f);
00098                         b->sub1 = getboolexp1(f);
00099                         if((c = getc(f)) == '\n')
00100                                 c = getc(f);
00101                         switch (c) {
00102                         case AND_TOKEN:
00103                                 b->type = BOOLEXP_AND;
00104                                 break;
00105                         case OR_TOKEN:
00106                                 b->type = BOOLEXP_OR;
00107                                 break;
00108                         default:
00109                                 goto error;
00110                         }
00111                         b->sub2 = getboolexp1(f);
00112                         if((d = getc(f)) == '\n')
00113                                 d = getc(f);
00114                         if(d != ')')
00115                                 goto error;
00116                         return b;
00117                 }
00118         case '-':                                       /*
00119                                                                  * obsolete NOTHING key, eat it 
00120                                                                  */
00121                 while ((c = getc(f)) != '\n')
00122                         if(c == EOF)
00123                                 abort();                /*
00124                                                                  * unexp EOF 
00125                                                                  */
00126                 ungetc(c, f);
00127                 return TRUE_BOOLEXP;
00128                 break;
00129         case '"':
00130                 ungetc(c, f);
00131                 buff = alloc_lbuf("getboolexp_quoted");
00132                 StringCopy(buff, getstring_noalloc(f, 1));
00133                 c = fgetc(f);
00134                 if(c == EOF) {
00135                         free_lbuf(buff);
00136                         return TRUE_BOOLEXP;
00137                 }
00138 
00139                 b = alloc_bool("getboolexp1_quoted");
00140                 anum = mkattr(buff);
00141                 if(anum <= 0) {
00142                         free_bool(b);
00143                         free_lbuf(buff);
00144                         goto error;
00145                 }
00146                 free_lbuf(buff);
00147                 b->thing = anum;
00148 
00149                 /*
00150                  * if last character is : then this is an attribute lock. A 
00151                  * last character of / means an eval lock 
00152                  */
00153 
00154                 if((c == ':') || (c == '/')) {
00155                         if(c == '/')
00156                                 b->type = BOOLEXP_EVAL;
00157                         else
00158                                 b->type = BOOLEXP_ATR;
00159                         buff = alloc_lbuf("getboolexp1.attr_lock");
00160                         StringCopy(buff, getstring_noalloc(f, 1));
00161                         b->sub1 = (BOOLEXP *) strsave(buff);
00162                         free_lbuf(buff);
00163                 }
00164                 return b;
00165         default:                                        /*
00166                                                                  * dbref or attribute 
00167                                                                  */
00168                 ungetc(c, f);
00169                 b = alloc_bool("getboolexp1.default");
00170                 b->type = BOOLEXP_CONST;
00171                 b->thing = 0;
00172 
00173                 /*
00174                  * This is either an attribute, eval, or constant lock.
00175                  * Constant locks are of the form <num>, while
00176                  * attribute * and * * * * eval locks are of the form
00177                  * <anam-or-anum>:<string> or
00178                  * <aname-or-anum>/<string> respectively. The
00179                  * characters <nl>, |, and & terminate the string. 
00180                  */
00181 
00182                 if(isdigit(c)) {
00183                         while (isdigit(c = getc(f))) {
00184                                 b->thing = b->thing * 10 + c - '0';
00185                         }
00186                 } else if(isalpha(c)) {
00187                         buff = alloc_lbuf("getboolexp1.atr_name");
00188                         for(s = buff;
00189                                 ((c = getc(f)) != EOF) && (c != '\n') && (c != ':') &&
00190                                 (c != '/'); *s++ = c);
00191                         if(c == EOF) {
00192                                 free_lbuf(buff);
00193                                 free_bool(b);
00194                                 goto error;
00195                         }
00196                         *s = '\0';
00197 
00198                         /*
00199                          * Look the name up as an attribute.  If not found,
00200                          * create a new attribute. 
00201                          */
00202 
00203                         anum = mkattr(buff);
00204                         if(anum <= 0) {
00205                                 free_bool(b);
00206                                 free_lbuf(buff);
00207                                 goto error;
00208                         }
00209                         free_lbuf(buff);
00210                         b->thing = anum;
00211                 } else {
00212                         free_bool(b);
00213                         goto error;
00214                 }
00215 
00216                 /*
00217                  * if last character is : then this is an attribute lock. A 
00218                  * last character of / means an eval lock 
00219                  */
00220 
00221                 if((c == ':') || (c == '/')) {
00222                         if(c == '/')
00223                                 b->type = BOOLEXP_EVAL;
00224                         else
00225                                 b->type = BOOLEXP_ATR;
00226                         buff = alloc_lbuf("getboolexp1.attr_lock");
00227                         for(s = buff;
00228                                 ((c = getc(f)) != EOF) && (c != '\n') && (c != ')') &&
00229                                 (c != OR_TOKEN) && (c != AND_TOKEN); *s++ = c);
00230                         if(c == EOF)
00231                                 goto error;
00232                         *s++ = 0;
00233                         b->sub1 = (BOOLEXP *) strsave(buff);
00234                         free_lbuf(buff);
00235                 }
00236                 ungetc(c, f);
00237                 return b;
00238         }
00239 
00240   error:
00241         abort();                                        /*
00242                                                                  * bomb out 
00243                                                                  */
00244         return TRUE_BOOLEXP;
00245 }
00246 
00247 /*
00248  * ---------------------------------------------------------------------------
00249  * * getboolexp: Read a boolean expression from the flat file.
00250  */
00251 
00252 static BOOLEXP *getboolexp(FILE * f)
00253 {
00254         BOOLEXP *b;
00255         char c;
00256 
00257         b = getboolexp1(f);
00258         if(getc(f) != '\n')
00259                 abort();                                /*
00260                                                                  * parse error, we lose 
00261                                                                  */
00262 
00263         /*
00264          * MUSH (except for PernMUSH) and MUSE can have an extra CR, * MUD *
00265          * * * * * does not. 
00266          */
00267 
00268         if(((g_format == F_MUSH) && (g_version != 2)) || (g_format == F_MUSE)
00269            || (g_format == F_MUX)) {
00270                 if((c = getc(f)) != '\n')
00271                         ungetc(c, f);
00272         }
00273         return b;
00274 }
00275 
00276 /*
00277  * ---------------------------------------------------------------------------
00278  * * get_list: Read attribute list from flat file.
00279  */
00280 
00281 static int get_list(FILE * f, dbref i, int new_strings)
00282 {
00283         dbref atr;
00284         int c;
00285         char *buff;
00286 
00287         buff = alloc_lbuf("get_list");
00288         while (1) {
00289                 switch (c = getc(f)) {
00290                 case '>':                               /*
00291                                                                  * read # then string 
00292                                                                  */
00293                         atr = getref(f);
00294                         if(atr > 0) {
00295                                 /*
00296                                  * Store the attr 
00297                                  */
00298 
00299                                 atr_add_raw(i, atr, (char *) getstring_noalloc(f,
00300                                                                                                                            new_strings));
00301                         } else {
00302                                 /*
00303                                  * Silently discard 
00304                                  */
00305 
00306                                 getstring_noalloc(f, new_strings);
00307                         }
00308                         break;
00309                 case '\n':                              /*
00310                                                                  * ignore newlines. They're due to v(r). 
00311                                                                  */
00312                         break;
00313                 case '<':                               /*
00314                                                                  * end of list 
00315                                                                  */
00316                         free_lbuf(buff);
00317                         c = getc(f);
00318                         if(c != '\n') {
00319                                 ungetc(c, f);
00320                                 fprintf(stderr, "No line feed on object %d\n", i);
00321                                 return 1;
00322                         }
00323                         return 1;
00324                 default:
00325                         fprintf(stderr,
00326                                         "Bad character '%c' when getting attributes on object %d\n",
00327                                         c, i);
00328                         /*
00329                          * We've found a bad spot.  I hope things aren't * *
00330                          * * * * * too bad. 
00331                          */
00332 
00333                         (void) getstring_noalloc(f, new_strings);
00334                 }
00335         }
00336 }
00337 
00338 /*
00339  * ---------------------------------------------------------------------------
00340  * * putbool_subexp: Write a boolean sub-expression to the flat file.
00341  */
00342 static void putbool_subexp(FILE * f, BOOLEXP * b)
00343 {
00344         ATTR *va;
00345 
00346         switch (b->type) {
00347         case BOOLEXP_IS:
00348                 putc('(', f);
00349                 putc(IS_TOKEN, f);
00350                 putbool_subexp(f, b->sub1);
00351                 putc(')', f);
00352                 break;
00353         case BOOLEXP_CARRY:
00354                 putc('(', f);
00355                 putc(CARRY_TOKEN, f);
00356                 putbool_subexp(f, b->sub1);
00357                 putc(')', f);
00358                 break;
00359         case BOOLEXP_INDIR:
00360                 putc('(', f);
00361                 putc(INDIR_TOKEN, f);
00362                 putbool_subexp(f, b->sub1);
00363                 putc(')', f);
00364                 break;
00365         case BOOLEXP_OWNER:
00366                 putc('(', f);
00367                 putc(OWNER_TOKEN, f);
00368                 putbool_subexp(f, b->sub1);
00369                 putc(')', f);
00370                 break;
00371         case BOOLEXP_AND:
00372                 putc('(', f);
00373                 putbool_subexp(f, b->sub1);
00374                 putc(AND_TOKEN, f);
00375                 putbool_subexp(f, b->sub2);
00376                 putc(')', f);
00377                 break;
00378         case BOOLEXP_OR:
00379                 putc('(', f);
00380                 putbool_subexp(f, b->sub1);
00381                 putc(OR_TOKEN, f);
00382                 putbool_subexp(f, b->sub2);
00383                 putc(')', f);
00384                 break;
00385         case BOOLEXP_NOT:
00386                 putc('(', f);
00387                 putc(NOT_TOKEN, f);
00388                 putbool_subexp(f, b->sub1);
00389                 putc(')', f);
00390                 break;
00391         case BOOLEXP_CONST:
00392                 fprintf(f, "%d", b->thing);
00393                 break;
00394         case BOOLEXP_ATR:
00395                 va = atr_num(b->thing);
00396                 if(va) {
00397                         fprintf(f, "%s:%s", va->name, (char *) b->sub1);
00398                 } else {
00399                         fprintf(f, "%d:%s\n", b->thing, (char *) b->sub1);
00400                 }
00401                 break;
00402         case BOOLEXP_EVAL:
00403                 va = atr_num(b->thing);
00404                 if(va) {
00405                         fprintf(f, "%s/%s\n", va->name, (char *) b->sub1);
00406                 } else {
00407                         fprintf(f, "%d/%s\n", b->thing, (char *) b->sub1);
00408                 }
00409                 break;
00410         default:
00411                 fprintf(stderr, "Unknown boolean type in putbool_subexp: %d\n",
00412                                 b->type);
00413         }
00414 }
00415 
00416 /*
00417  * ---------------------------------------------------------------------------
00418  * * putboolexp: Write boolean expression to the flat file.
00419  */
00420 
00421 static void putboolexp(FILE * f, BOOLEXP * b)
00422 {
00423         if(b != TRUE_BOOLEXP) {
00424                 putbool_subexp(f, b);
00425         }
00426         putc('\n', f);
00427 }
00428 
00429 dbref db_read(FILE * f, int *db_format, int *db_version, int *db_flags)
00430 {
00431         dbref i, anum;
00432         char ch;
00433         const char *tstr;
00434         int header_gotten, size_gotten, nextattr_gotten;
00435         int read_attribs, read_name, read_zone, read_link, read_key, read_parent;
00436         int read_extflags, read_3flags, read_money, read_timestamps,
00437                 read_new_strings;
00438         int read_powers, read_powers_player, read_powers_any;
00439         int deduce_version, deduce_name, deduce_zone, deduce_timestamps;
00440         int aflags, f1, f2, f3;
00441         BOOLEXP *tempbool;
00442 
00443         header_gotten = 0;
00444         size_gotten = 0;
00445         nextattr_gotten = 0;
00446         g_format = F_UNKNOWN;
00447         g_version = 0;
00448         g_flags = 0;
00449         read_attribs = 1;
00450         read_name = 1;
00451         read_zone = 0;
00452         read_link = 0;
00453         read_key = 1;
00454         read_parent = 0;
00455         read_money = 1;
00456         read_extflags = 0;
00457         read_3flags = 0;
00458         read_timestamps = 0;
00459         read_new_strings = 0;
00460         read_powers = 0;
00461         read_powers_player = 0;
00462         read_powers_any = 0;
00463         deduce_version = 1;
00464         deduce_zone = 1;
00465         deduce_name = 1;
00466         deduce_timestamps = 1;
00467         db_free();
00468         for(i = 0;; i++) {
00469 
00470                 switch (ch = getc(f)) {
00471                 case '-':                               /* Misc tag */
00472                         switch (ch = getc(f)) {
00473                         case 'R':                       /* Record number of players */
00474                                 mudstate.record_players = getref(f);
00475                                 break;
00476                         default:
00477                                 (void) getstring_noalloc(f, 0);
00478                         }
00479                         break;
00480                 case '+':                               /*
00481                                                                  * MUX and MUSH header 
00482                                                                  */
00483                         switch (ch = getc(f)) { /*
00484                                                                          * 2nd char selects 
00485                                                                          * type 
00486                                                                          */
00487                         case 'X':                       /*
00488                                                                  * MUX VERSION 
00489                                                                  */
00490                                 if(header_gotten) {
00491                                         fprintf(stderr,
00492                                                         "\nDuplicate MUX version header entry at object %d, ignored.\n",
00493                                                         i);
00494                                         tstr = getstring_noalloc(f, 0);
00495                                         break;
00496                                 }
00497                                 header_gotten = 1;
00498                                 deduce_version = 0;
00499                                 g_format = F_MUX;
00500                                 g_version = getref(f);
00501 
00502                                 /*
00503                                  * Otherwise extract feature flags 
00504                                  */
00505 
00506                                 if(g_version & V_GDBM) {
00507                                         read_attribs = 0;
00508                                         read_name = !(g_version & V_ATRNAME);
00509                                 }
00510                                 read_zone = (g_version & V_ZONE);
00511                                 read_link = (g_version & V_LINK);
00512                                 read_key = !(g_version & V_ATRKEY);
00513                                 read_parent = (g_version & V_PARENT);
00514                                 read_money = !(g_version & V_ATRMONEY);
00515                                 read_extflags = (g_version & V_XFLAGS);
00516                                 read_3flags = (g_version & V_3FLAGS);
00517                                 read_powers = (g_version & V_POWERS);
00518                                 read_new_strings = (g_version & V_QUOTED);
00519                                 g_flags = g_version & ~V_MASK;
00520 
00521                                 g_version &= V_MASK;
00522                                 deduce_name = 0;
00523                                 deduce_version = 0;
00524                                 deduce_zone = 0;
00525                                 break;
00526                         case 'S':                       /*
00527                                                                  * SIZE 
00528                                                                  */
00529                                 if(size_gotten) {
00530                                         fprintf(stderr,
00531                                                         "\nDuplicate size entry at object %d, ignored.\n",
00532                                                         i);
00533                                         tstr = getstring_noalloc(f, 0);
00534                                 } else {
00535                                         mudstate.min_size = getref(f);
00536                                 }
00537                                 size_gotten = 1;
00538                                 break;
00539                         case 'A':                       /*
00540                                                                  * USER-NAMED ATTRIBUTE 
00541                                                                  */
00542                                 anum = getref(f);
00543                                 tstr = getstring_noalloc(f, read_new_strings);
00544                                 if(isdigit(*tstr)) {
00545                                         aflags = 0;
00546                                         while (isdigit(*tstr))
00547                                                 aflags = (aflags * 10) + (*tstr++ - '0');
00548                                         tstr++;         /*
00549                                                                  * skip ':' 
00550                                                                  */
00551                                 } else {
00552                                         aflags = mudconf.vattr_flags;
00553                                 }
00554                                 vattr_define((char *) tstr, anum, aflags);
00555                                 break;
00556                         case 'F':                       /*
00557                                                                  * OPEN USER ATTRIBUTE SLOT 
00558                                                                  */
00559                                 anum = getref(f);
00560                                 break;
00561                         case 'N':                       /*
00562                                                                  * NEXT ATTR TO ALLOC WHEN NO
00563                                                                  * FREELIST 
00564                                                                  */
00565                                 if(nextattr_gotten) {
00566                                         fprintf(stderr,
00567                                                         "\nDuplicate next free vattr entry at object %d, ignored.\n",
00568                                                         i);
00569                                         tstr = getstring_noalloc(f, 0);
00570                                 } else {
00571                                         mudstate.attr_next = getref(f);
00572                                         nextattr_gotten = 1;
00573                                 }
00574                                 break;
00575                         default:
00576                                 fprintf(stderr,
00577                                                 "\nUnexpected character '%c' in MUX header near object #%d, ignored.\n",
00578                                                 ch, i);
00579                                 tstr = getstring_noalloc(f, 0);
00580                         }
00581                         break;
00582                 case '!':                               /*
00583                                                                  * MUX entry/MUSH entry/MUSE non-zoned entry 
00584                                                                  */
00585                         if(deduce_version) {
00586                                 g_format = F_MUX;
00587                                 g_version = 1;
00588                                 deduce_name = 0;
00589                                 deduce_zone = 0;
00590                                 deduce_version = 0;
00591                         } else if(deduce_zone) {
00592                                 deduce_zone = 0;
00593                                 read_zone = 0;
00594                         }
00595                         i = getref(f);
00596                         db_grow(i + 1);
00597 
00598                         if(read_name) {
00599                                 tstr = getstring_noalloc(f, read_new_strings);
00600                                 if(deduce_name) {
00601                                         if(isdigit(*tstr)) {
00602                                                 read_name = 0;
00603                                                 s_Location(i, atoi(tstr));
00604                                         } else {
00605                                                 s_Name(i, (char *) tstr);
00606                                                 s_Location(i, getref(f));
00607                                         }
00608                                         deduce_name = 0;
00609                                 } else {
00610                                         s_Name(i, (char *) tstr);
00611                                         s_Location(i, getref(f));
00612                                 }
00613                         } else {
00614                                 s_Location(i, getref(f));
00615                         }
00616 
00617                         /*
00618                          * ZONE on MUSE databases and some others 
00619                          */
00620 
00621                         if(read_zone)
00622                                 s_Zone(i, getref(f));
00623 
00624                         /*
00625                          * else
00626                          * * s_Zone(i, NOTHING); 
00627                          */
00628 
00629                         /*
00630                          * CONTENTS and EXITS 
00631                          */
00632 
00633                         s_Contents(i, getref(f));
00634                         s_Exits(i, getref(f));
00635 
00636                         /*
00637                          * LINK 
00638                          */
00639 
00640                         if(read_link)
00641                                 s_Link(i, getref(f));
00642                         else
00643                                 s_Link(i, NOTHING);
00644 
00645                         /*
00646                          * NEXT 
00647                          */
00648 
00649                         s_Next(i, getref(f));
00650 
00651                         /*
00652                          * LOCK
00653                          */
00654 
00655                         if(read_key) {
00656                                 tempbool = getboolexp(f);
00657                                 atr_add_raw(i, A_LOCK, unparse_boolexp_quiet(1, tempbool));
00658                                 free_boolexp(tempbool);
00659                         }
00660                         /*
00661                          * OWNER 
00662                          */
00663 
00664                         s_Owner(i, getref(f));
00665 
00666                         /*
00667                          * PARENT: PennMUSH uses this field for ZONE
00668                          * (which we  use as PARENT if we
00669                          * didn't already read in a  
00670                          * non-NOTHING parent. 
00671                          */
00672 
00673                         if(read_parent) {
00674                                 s_Parent(i, getref(f));
00675                         } else {
00676                                 s_Parent(i, NOTHING);
00677                         }
00678 
00679                         /*
00680                          * PENNIES 
00681                          */
00682 
00683                         if(read_money)          /*
00684                                                                  *  if not fix in
00685                                                                  * unscraw_foreign  
00686                                                                  */
00687                                 s_Pennies(i, getref(f));
00688 
00689                         /*
00690                          * FLAGS 
00691                          */
00692 
00693                         f1 = getref(f);
00694                         if(read_extflags)
00695                                 f2 = getref(f);
00696                         else
00697                                 f2 = 0;
00698 
00699                         if(read_3flags)
00700                                 f3 = getref(f);
00701                         else
00702                                 f3 = 0;
00703 
00704                         s_Flags(i, f1);
00705                         s_Flags2(i, f2);
00706                         s_Flags3(i, f3);
00707 
00708                         if(read_powers) {
00709                                 f1 = getref(f);
00710                                 f2 = getref(f);
00711                                 s_Powers(i, f1);
00712                                 s_Powers2(i, f2);
00713                         }
00714 
00715                         /*
00716                          * ATTRIBUTES 
00717                          */
00718 
00719                         if(read_attribs) {
00720                                 if(!get_list(f, i, read_new_strings)) {
00721                                         fprintf(stderr,
00722                                                         "\nError reading attrs for object #%d\n", i);
00723                                         return -1;
00724                                 }
00725                         }
00726                         /*
00727                          * check to see if it's a player 
00728                          */
00729 
00730                         if(Typeof(i) == TYPE_PLAYER) {
00731                                 c_Connected(i);
00732                         }
00733                         break;
00734                 case '*':                               /*
00735                                                                  * EOF marker 
00736                                                                  */
00737                         tstr = getstring_noalloc(f, 0);
00738                         if(strcmp(tstr, "**END OF DUMP***")) {
00739                                 fprintf(stderr, "\nBad EOF marker at object #%d\n", i);
00740                                 return -1;
00741                         } else {
00742                                 /*
00743                                  * Fix up bizarro foreign DBs 
00744                                  */
00745 
00746                                 *db_version = g_version;
00747                                 *db_format = g_format;
00748                                 *db_flags = g_flags;
00749                                 load_player_names();
00750                                 return mudstate.db_top;
00751                         }
00752                 default:
00753                         fprintf(stderr, "\nIllegal character '%c' near object #%d\n",
00754                                         ch, i);
00755                         return -1;
00756                 }
00757 
00758         }
00759 
00760 }
00761 
00762 static int db_write_object(FILE * f, dbref i, int db_format, int flags)
00763 {
00764         ATTR *a;
00765         char *got, *as;
00766         dbref aowner;
00767         int ca, aflags, save, j;
00768         BOOLEXP *tempbool;
00769 
00770         if(!(flags & V_ATRNAME))
00771                 putstring(f, Name(i));
00772         putref(f, Location(i));
00773         if(flags & V_ZONE)
00774                 putref(f, Zone(i));
00775         putref(f, Contents(i));
00776         putref(f, Exits(i));
00777         if(flags & V_LINK)
00778                 putref(f, Link(i));
00779         putref(f, Next(i));
00780         if(!(flags & V_ATRKEY)) {
00781                 got = atr_get(i, A_LOCK, &aowner, &aflags);
00782                 tempbool = parse_boolexp(GOD, got, 1);
00783                 free_lbuf(got);
00784                 putboolexp(f, tempbool);
00785                 if(tempbool)
00786                         free_bool(tempbool);
00787         }
00788         putref(f, Owner(i));
00789         if(flags & V_PARENT)
00790                 putref(f, Parent(i));
00791         if(!(flags & V_ATRMONEY))
00792                 putref(f, Pennies(i));
00793         putref(f, Flags(i));
00794         if(flags & V_XFLAGS)
00795                 putref(f, Flags2(i));
00796         if(flags & V_3FLAGS)
00797                 putref(f, Flags3(i));
00798         if(flags & V_POWERS) {
00799                 putref(f, Powers(i));
00800                 putref(f, Powers2(i));
00801         }
00802         /*
00803          * write the attribute list 
00804          */
00805 
00806         if((!(flags & V_GDBM)) || (mudstate.panicking == 1)) {
00807                 for(ca = atr_head(i, &as); ca; ca = atr_next(&as)) {
00808                         save = 0;
00809                         a = atr_num(ca);
00810                         if(a)
00811                                 j = a->number;
00812                         else
00813                                 j = -1;
00814 
00815                         if(j > 0) {
00816                                 switch (j) {
00817                                 case A_NAME:
00818                                         if(flags & V_ATRNAME)
00819                                                 save = 1;
00820                                         break;
00821                                 case A_LOCK:
00822                                         if(flags & V_ATRKEY)
00823                                                 save = 1;
00824                                         break;
00825                                 case A_LIST:
00826                                 case A_MONEY:
00827                                         break;
00828                                 default:
00829                                         save = 1;
00830                                 }
00831                         }
00832                         if(save) {
00833                                 got = atr_get_raw(i, j);
00834                                 fprintf(f, ">%d\n", j);
00835                                 putstring(f, got);
00836                         }
00837                 }
00838                 fprintf(f, "<\n");
00839         }
00840         return 0;
00841 }
00842 
00843 dbref db_write(FILE * f, int format, int version)
00844 {
00845         dbref i;
00846         int flags;
00847         VATTR *vp;
00848 
00849         switch (format) {
00850         case F_MUX:
00851                 flags = version;
00852                 break;
00853         default:
00854                 fprintf(stderr, "Can only write MUX format.\n");
00855                 return -1;
00856         }
00857         i = mudstate.attr_next;
00858         fprintf(f, "+X%d\n+S%d\n+N%d\n", flags, mudstate.db_top, i);
00859         fprintf(f, "-R%d\n", mudstate.record_players);
00860 
00861         /*
00862          * Dump user-named attribute info 
00863          */
00864 
00865         vp = vattr_first();
00866         while (vp != NULL) {
00867                 if(!(vp->flags & AF_DELETED))
00868                         fprintf(f, "+A%d\n\"%d:%s\"\n", vp->number, vp->flags, vp->name);
00869                 vp = vattr_next(vp);
00870         }
00871 
00872         DO_WHOLE_DB(i) {
00873 
00874                 if(!(Going(i))) {
00875                         fprintf(f, "!%d\n", i);
00876                         db_write_object(f, i, format, flags);
00877                 }
00878         }
00879         fputs("***END OF DUMP***\n", f);
00880         fflush(f);
00881         return (mudstate.db_top);
00882 }

Generated on Mon May 28 04:25:19 2007 for BattletechMUX by  doxygen 1.4.7