00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include <sys/file.h>
00009 #include <sys/stat.h>
00010
00011 #define __DB_C
00012 #include "mudconf.h"
00013 #include "config.h"
00014 #include "externs.h"
00015 #include "db.h"
00016 #include "attrs.h"
00017 #include "vattr.h"
00018 #include "match.h"
00019 #include "alloc.h"
00020 #include "powers.h"
00021 #include "interface.h"
00022 #include "flags.h"
00023 #include "p.comsys.h"
00024 #include "mmdb.h"
00025
00026 #ifndef O_ACCMODE
00027 #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
00028 #endif
00029
00030
00031
00032
00033 #define RS_CONCENTRATE 0x00000002
00034 #define RS_RECORD_PLAYERS 0x00000004
00035 #define RS_NEW_STRINGS 0x00000008
00036 #define RS_HUDKEY 0x00000010
00037
00038 OBJ *db = NULL;
00039 NAME *names = NULL;
00040 NAME *purenames = NULL;
00041
00042 int corrupt;
00043
00044 extern void desc_addhash(DESC *);
00045 extern void del_commac(dbref);
00046 extern void do_clear_macro(dbref player, char *s);
00047
00048 #ifdef TEST_MALLOC
00049 int malloc_count = 0;
00050
00051 #endif
00052
00053
00054
00055 extern VATTR *vattr_rename(char *, char *);
00056
00057 typedef struct atrcount ATRCOUNT;
00058 struct atrcount {
00059 dbref thing;
00060 int count;
00061 };
00062
00063
00064
00065
00066
00067 #ifdef GNU_MALLOC_TEST
00068 extern unsigned int malloc_sbrk_used;
00069 #endif
00070
00071
00072
00073
00074 extern int fwdlist_ck(int, dbref, dbref, int, char *);
00075
00076 extern void pcache_reload(dbref);
00077 extern void desc_reload(dbref);
00078
00079
00080 #define PLSTAT_MODE (AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL)
00081
00082
00083
00084
00085 ATTR attr[] = {
00086 {"Aahear", A_AAHEAR, AF_ODARK, NULL},
00087 {"Aclone", A_ACLONE, AF_ODARK, NULL},
00088 {"Aconnect", A_ACONNECT, AF_ODARK, NULL},
00089 {"Adesc", A_ADESC, AF_ODARK, NULL},
00090 {"Adfail", A_ADFAIL, AF_ODARK | AF_NOPROG, NULL},
00091 {"Adisconnect", A_ADISCONNECT, AF_ODARK, NULL},
00092 {"Adrop", A_ADROP, AF_ODARK, NULL},
00093 {"Aefail", A_AEFAIL, AF_ODARK | AF_NOPROG, NULL},
00094 {"Aenter", A_AENTER, AF_ODARK, NULL},
00095 {"Afail", A_AFAIL, AF_ODARK | AF_NOPROG, NULL},
00096 {"Agfail", A_AGFAIL, AF_ODARK | AF_NOPROG, NULL},
00097 {"Ahear", A_AHEAR, AF_ODARK, NULL},
00098 {"Akill", A_AKILL, AF_ODARK, NULL},
00099 {"Aleave", A_ALEAVE, AF_ODARK, NULL},
00100 {"Alfail", A_ALFAIL, AF_ODARK | AF_NOPROG, NULL},
00101 {"Alias", A_ALIAS, AF_NOPROG | AF_NOCMD | AF_GOD, NULL},
00102 {"Allowance", A_ALLOWANCE, AF_MDARK | AF_NOPROG | AF_WIZARD, NULL},
00103 {"Amail", A_AMAIL, AF_ODARK | AF_NOPROG, NULL},
00104 {"Amhear", A_AMHEAR, AF_ODARK, NULL},
00105 {"Amove", A_AMOVE, AF_ODARK, NULL},
00106 {"Apay", A_APAY, AF_ODARK, NULL},
00107 {"Arfail", A_ARFAIL, AF_ODARK | AF_NOPROG, NULL},
00108 {"Asucc", A_ASUCC, AF_ODARK, NULL},
00109 {"Atfail", A_ATFAIL, AF_ODARK | AF_NOPROG, NULL},
00110 {"Atport", A_ATPORT, AF_ODARK | AF_NOPROG, NULL},
00111 {"Atofail", A_ATOFAIL, AF_ODARK | AF_NOPROG, NULL},
00112 {"Aufail", A_AUFAIL, AF_ODARK | AF_NOPROG, NULL},
00113 {"Ause", A_AUSE, AF_ODARK, NULL},
00114 {"Away", A_AWAY, AF_ODARK | AF_NOPROG, NULL},
00115 {"Buildcoord", A_BUILDCOORD, AF_MDARK | AF_WIZARD, NULL},
00116 {"Buildentrance", A_BUILDENTRANCE, AF_MDARK | AF_WIZARD, NULL},
00117 {"Buildlinks", A_BUILDLINKS, AF_MDARK | AF_WIZARD, NULL},
00118 {"Charges", A_CHARGES, AF_ODARK | AF_NOPROG, NULL},
00119 {"Comment", A_COMMENT, AF_MDARK | AF_WIZARD, NULL},
00120 {"Contactoptions", A_CONTACTOPT, AF_ODARK, NULL},
00121 {"Cost", A_COST, AF_ODARK, NULL},
00122 {"Daily", A_DAILY, AF_ODARK, NULL},
00123 {"HHourly", A_HOURLY, AF_MDARK, NULL},
00124 {"Desc", A_DESC, AF_NOPROG, NULL},
00125 {"DefaultLock", A_LOCK, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00126 NULL},
00127 {"Destroyer", A_DESTROYER, AF_MDARK | AF_WIZARD | AF_NOPROG, NULL},
00128 {"Dfail", A_DFAIL, AF_ODARK | AF_NOPROG, NULL},
00129 {"Drop", A_DROP, AF_ODARK | AF_NOPROG, NULL},
00130 {"DropLock", A_LDROP, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00131 NULL},
00132 {"Ealias", A_EALIAS, AF_ODARK | AF_NOPROG, NULL},
00133 {"Efail", A_EFAIL, AF_ODARK | AF_NOPROG, NULL},
00134 {"Enter", A_ENTER, AF_ODARK, NULL},
00135 {"EnterLock", A_LENTER, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00136 NULL},
00137 {"Faction", A_FACTION, AF_MDARK | AF_WIZARD, NULL},
00138 {"Fail", A_FAIL, AF_ODARK | AF_NOPROG, NULL},
00139 {"Filter", A_FILTER, AF_ODARK | AF_NOPROG, NULL},
00140 {"Forwardlist", A_FORWARDLIST, AF_ODARK | AF_NOPROG, fwdlist_ck},
00141 {"Gfail", A_GFAIL, AF_ODARK | AF_NOPROG, NULL},
00142 {"GiveLock", A_LGIVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00143 {"Idesc", A_IDESC, AF_ODARK | AF_NOPROG, NULL},
00144 {"Idle", A_IDLE, AF_ODARK | AF_NOPROG, NULL},
00145 {"Infilter", A_INFILTER, AF_ODARK | AF_NOPROG, NULL},
00146 {"Inprefix", A_INPREFIX, AF_ODARK | AF_NOPROG, NULL},
00147 {"Job", A_JOB, AF_MDARK | AF_WIZARD, NULL},
00148 {"Kill", A_KILL, AF_ODARK, NULL},
00149 {"Lalias", A_LALIAS, AF_ODARK | AF_NOPROG, NULL},
00150 {"Last", A_LAST, AF_WIZARD | AF_NOCMD | AF_NOPROG, NULL},
00151 {"Lastname", A_LASTNAME, AF_WIZARD | AF_NOPROG | AF_MDARK, NULL},
00152 {"Lastpage", A_LASTPAGE, AF_INTERNAL | AF_NOCMD | AF_NOPROG | AF_GOD | AF_PRIVATE, NULL},
00153 {"Lastsite", A_LASTSITE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_GOD, NULL},
00154 {"Leave", A_LEAVE, AF_ODARK, NULL},
00155 {"LeaveLock", A_LLEAVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00156 {"Lfail", A_LFAIL, AF_ODARK | AF_NOPROG, NULL},
00157 {"LinkLock", A_LLINK, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00158 {"Listen", A_LISTEN, AF_ODARK, NULL},
00159
00160 {"Logindata", A_LOGINDATA, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00161 {"LRSheight", A_LRSHEIGHT, AF_ODARK, NULL},
00162 {"Unused1", A_UNUSED1, AF_WIZARD | AF_MDARK, NULL},
00163 {"Mailcurf", A_MAILCURF, AF_MDARK | AF_WIZARD | AF_NOPROG, NULL},
00164 {"Mailflags", A_MAILFLAGS, AF_MDARK | AF_WIZARD | AF_NOPROG, NULL},
00165 {"Mailfolders", A_MAILFOLDERS, AF_MDARK | AF_WIZARD | AF_NOPROG, NULL},
00166 {"Mailmsg", A_MAILMSG, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00167 {"Mailsub", A_MAILSUB, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00168 {"Mailsucc", A_MAIL, AF_ODARK | AF_NOPROG, NULL},
00169 {"Mailto", A_MAILTO, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00170 {"Mapcolor", A_MAPCOLOR, AF_ODARK, NULL},
00171 {"Mapvis", A_MAPVIS, AF_MDARK | AF_WIZARD, NULL},
00172 {"Mechdesc", A_MECHDESC, AF_MDARK, NULL},
00173 {"Mechname", A_MECHNAME, AF_MDARK, NULL},
00174 {"Mechstatus", A_MECHSTATUS, AF_MDARK | AF_WIZARD, NULL},
00175 {"Mechtype", A_MECHTYPE, AF_MDARK, NULL},
00176 {"MechPrefID", A_MECHPREFID, AF_MDARK | AF_WIZARD, NULL},
00177 {"Mechskills", A_MECHSKILLS, AF_MDARK, NULL},
00178 {"Mwtemplate", A_MWTEMPLATE, AF_MDARK, NULL},
00179 {"Move", A_MOVE, AF_ODARK, NULL},
00180 {"Name", A_NAME, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00181 {"Odesc", A_ODESC, AF_ODARK | AF_NOPROG, NULL},
00182 {"Odfail", A_ODFAIL, AF_ODARK | AF_NOPROG, NULL},
00183 {"Odrop", A_ODROP, AF_ODARK | AF_NOPROG, NULL},
00184 {"Oefail", A_OEFAIL, AF_ODARK | AF_NOPROG, NULL},
00185 {"Oenter", A_OENTER, AF_ODARK, NULL},
00186 {"Ofail", A_OFAIL, AF_ODARK | AF_NOPROG, NULL},
00187 {"Ogfail", A_OGFAIL, AF_ODARK | AF_NOPROG, NULL},
00188 {"Okill", A_OKILL, AF_ODARK, NULL},
00189 {"Amechdest", A_AMECHDEST, AF_MDARK, NULL},
00190 {"Aminetrigger", A_AMINETRIGGER, AF_MDARK, NULL},
00191 {"Oleave", A_OLEAVE, AF_ODARK, NULL},
00192 {"Olfail", A_OLFAIL, AF_ODARK | AF_NOPROG, NULL},
00193 {"Omove", A_OMOVE, AF_ODARK, NULL},
00194 {"Opay", A_OPAY, AF_ODARK, NULL},
00195 {"Orfail", A_ORFAIL, AF_ODARK | AF_NOPROG, NULL},
00196 {"Osucc", A_OSUCC, AF_ODARK | AF_NOPROG, NULL},
00197 {"Otfail", A_OTFAIL, AF_ODARK | AF_NOPROG, NULL},
00198 {"Otport", A_OTPORT, AF_ODARK | AF_NOPROG, NULL},
00199 {"Otofail", A_OTOFAIL, AF_ODARK | AF_NOPROG, NULL},
00200 {"Oufail", A_OUFAIL, AF_ODARK | AF_NOPROG, NULL},
00201 {"Ouse", A_OUSE, AF_ODARK, NULL},
00202 {"Oxenter", A_OXENTER, AF_ODARK, NULL},
00203 {"Oxleave", A_OXLEAVE, AF_ODARK, NULL},
00204 {"Oxtport", A_OXTPORT, AF_ODARK | AF_NOPROG, NULL},
00205 {"PageLock", A_LPAGE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00206 {"ParentLock", A_LPARENT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00207 {"Pay", A_PAY, AF_ODARK, NULL},
00208 {"PCequip", A_PCEQUIP, AF_MDARK, NULL},
00209 {"Pilot", A_PILOTNUM, AF_MDARK, NULL},
00210 {"Prefix", A_PREFIX, AF_ODARK | AF_NOPROG, NULL},
00211 {"ProgCmd", A_PROGCMD, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL, NULL},
00212 {"QueueMax", A_QUEUEMAX, AF_MDARK | AF_WIZARD | AF_NOPROG, NULL},
00213 {"Quota", A_QUOTA, AF_MDARK | AF_NOPROG | AF_GOD | AF_NOCMD, NULL},
00214 {"Ranknum", A_RANKNUM, AF_MDARK | AF_WIZARD, NULL},
00215 {"ReceiveLock", A_LRECEIVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK, NULL},
00216 {"Reject", A_REJECT, AF_ODARK | AF_NOPROG, NULL},
00217 {"Rfail", A_RFAIL, AF_ODARK | AF_NOPROG, NULL},
00218 {"Rquota", A_RQUOTA, AF_MDARK | AF_NOPROG | AF_GOD | AF_NOCMD, NULL},
00219 {"Runout", A_RUNOUT, AF_ODARK, NULL},
00220
00221 {"Semaphore", A_SEMAPHORE,
00222 AF_ODARK | AF_NOPROG | AF_WIZARD | AF_NOCMD, NULL},
00223 {"Sex", A_SEX, AF_NOPROG, NULL},
00224 {"Signature", A_SIGNATURE, AF_ODARK | AF_NOPROG, NULL},
00225 {"SpeechLock", A_LSPEECH, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00226 NULL},
00227 {"Startup", A_STARTUP, AF_ODARK, NULL},
00228 {"Succ", A_SUCC, AF_ODARK | AF_NOPROG, NULL},
00229 {"Tacsize", A_TACSIZE, AF_ODARK, NULL},
00230 {"TeloutLock", A_LTELOUT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00231 NULL},
00232 {"Tfail", A_TFAIL, AF_ODARK | AF_NOPROG, NULL},
00233 {"Timeout", A_TIMEOUT, AF_MDARK | AF_NOPROG | AF_WIZARD, NULL},
00234 {"Tport", A_TPORT, AF_ODARK | AF_NOPROG, NULL},
00235 {"TportLock", A_LTPORT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00236 NULL},
00237 {"Tofail", A_TOFAIL, AF_ODARK | AF_NOPROG, NULL},
00238 {"Tz", A_TZ, AF_NOPROG, NULL},
00239 {"Ufail", A_UFAIL, AF_ODARK | AF_NOPROG, NULL},
00240 {"Use", A_USE, AF_ODARK, NULL},
00241 {"UseLock", A_LUSE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00242 NULL},
00243 {"UserLock", A_LUSER, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK,
00244 NULL},
00245 {"VA", A_VA, AF_ODARK, NULL},
00246 {"VB", A_VA + 1, AF_ODARK, NULL},
00247 {"VC", A_VA + 2, AF_ODARK, NULL},
00248 {"VD", A_VA + 3, AF_ODARK, NULL},
00249 {"VE", A_VA + 4, AF_ODARK, NULL},
00250 {"VF", A_VA + 5, AF_ODARK, NULL},
00251 {"VG", A_VA + 6, AF_ODARK, NULL},
00252 {"VH", A_VA + 7, AF_ODARK, NULL},
00253 {"VI", A_VA + 8, AF_ODARK, NULL},
00254 {"VJ", A_VA + 9, AF_ODARK, NULL},
00255 {"VK", A_VA + 10, AF_ODARK, NULL},
00256 {"VL", A_VA + 11, AF_ODARK, NULL},
00257 {"VM", A_VA + 12, AF_ODARK, NULL},
00258 {"VN", A_VA + 13, AF_ODARK, NULL},
00259 {"VO", A_VA + 14, AF_ODARK, NULL},
00260 {"VP", A_VA + 15, AF_ODARK, NULL},
00261 {"VQ", A_VA + 16, AF_ODARK, NULL},
00262 {"VR", A_VA + 17, AF_ODARK, NULL},
00263 {"VS", A_VA + 18, AF_ODARK, NULL},
00264 {"VT", A_VA + 19, AF_ODARK, NULL},
00265 {"VU", A_VA + 20, AF_ODARK, NULL},
00266 {"VV", A_VA + 21, AF_ODARK, NULL},
00267 {"VW", A_VA + 22, AF_ODARK, NULL},
00268 {"VX", A_VA + 23, AF_ODARK, NULL},
00269 {"VY", A_VA + 24, AF_ODARK, NULL},
00270 {"VZ", A_VA + 25, AF_ODARK, NULL},
00271 {"Xtype", A_XTYPE, AF_MDARK | AF_WIZARD, NULL},
00272 {"*Password", A_PASS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
00273 NULL},
00274 {"*Privileges", A_PRIVS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
00275 NULL},
00276 {"*Money", A_MONEY, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
00277 NULL},
00278 {"Techtime", A_TECHTIME, AF_MDARK | AF_WIZARD,
00279 NULL},
00280 {"*EconParts", A_ECONPARTS,
00281 AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL,
00282 NULL},
00283 {"PLHEALTH", A_HEALTH, PLSTAT_MODE, NULL},
00284 {"PLATTRS", A_ATTRS, PLSTAT_MODE, NULL},
00285 {"PLADVS", A_ADVS, PLSTAT_MODE, NULL},
00286 {"PLSKILLS", A_SKILLS, PLSTAT_MODE, NULL},
00287
00288 {NULL, 0, 0, NULL}
00289 };
00290
00291
00292
00293
00294
00295 void fwdlist_set(dbref thing, FWDLIST * ifp)
00296 {
00297 FWDLIST *fp, *xfp;
00298 int i;
00299
00300
00301
00302
00303
00304 if(!ifp || (ifp->count <= 0)) {
00305 fwdlist_clr(thing);
00306 return;
00307 }
00308
00309
00310
00311
00312 fp = (FWDLIST *) XMALLOC(sizeof(int) * ((ifp->count) + 1), "fwdlist_set");
00313
00314 for(i = 0; i < ifp->count; i++) {
00315 fp->data[i] = ifp->data[i];
00316 }
00317 fp->count = ifp->count;
00318
00319
00320
00321
00322
00323 xfp = fwdlist_get(thing);
00324 if(xfp) {
00325 XFREE(xfp, "fwdlist_set");
00326 nhashrepl(thing, (int *) fp, &mudstate.fwdlist_htab);
00327 } else {
00328 nhashadd(thing, (int *) fp, &mudstate.fwdlist_htab);
00329 }
00330 }
00331
00332 void fwdlist_clr(dbref thing)
00333 {
00334 FWDLIST *xfp;
00335
00336
00337
00338
00339
00340 xfp = fwdlist_get(thing);
00341 if(xfp) {
00342 XFREE(xfp, "fwdlist_clr");
00343 nhashdelete(thing, &mudstate.fwdlist_htab);
00344 }
00345 }
00346
00347
00348
00349
00350
00351 int fwdlist_load(FWDLIST * fp, dbref player, char *atext)
00352 {
00353 dbref target;
00354 char *tp, *bp, *dp;
00355 int count, errors, fail;
00356
00357 count = 0;
00358 errors = 0;
00359 bp = tp = alloc_lbuf("fwdlist_load.str");
00360 StringCopy(tp, atext);
00361
00362 do {
00363 for(; *bp && isspace(*bp); bp++);
00364
00365
00366 for(dp = bp; *bp && !isspace(*bp); bp++);
00367
00368
00369 if(*bp)
00370 *bp++ = '\0';
00371
00372
00373 if((*dp++ == '#') && isdigit(*dp)) {
00374 target = atoi(dp);
00375 fail = (!Good_obj(target) || (!God(player) &&
00376 !controls(player, target) && (!Link_ok(target) || !could_doit(player, target,
00377 A_LLINK))));
00378 if(fail) {
00379 notify_printf(player,
00380 "Cannot forward to #%d: Permission denied.", target);
00381 errors++;
00382 } else {
00383 fp->data[count++] = target;
00384 }
00385 }
00386 } while (*bp);
00387
00388 free_lbuf(tp);
00389 fp->count = count;
00390 return errors;
00391 }
00392
00393
00394
00395
00396
00397 int fwdlist_rewrite(FWDLIST * fp, char *atext)
00398 {
00399 char *tp, *bp;
00400 int i, count;
00401
00402 if(fp && fp->count) {
00403 count = fp->count;
00404 tp = alloc_sbuf("fwdlist_rewrite.errors");
00405 bp = atext;
00406 for(i = 0; i < fp->count; i++) {
00407 if(Good_obj(fp->data[i])) {
00408 sprintf(tp, "#%d ", fp->data[i]);
00409 safe_str(tp, atext, &bp);
00410 } else {
00411 count--;
00412 }
00413 }
00414 *bp = '\0';
00415 free_sbuf(tp);
00416 } else {
00417 count = 0;
00418 *atext = '\0';
00419 }
00420 return count;
00421 }
00422
00423
00424
00425
00426
00427
00428 int fwdlist_ck(int key, dbref player, dbref thing, int anum, char *atext)
00429 {
00430 FWDLIST *fp;
00431 int count;
00432
00433 count = 0;
00434
00435 if(atext && *atext) {
00436 fp = (FWDLIST *) alloc_lbuf("fwdlist_ck.fp");
00437 fwdlist_load(fp, player, atext);
00438 } else {
00439 fp = NULL;
00440 }
00441
00442
00443
00444
00445
00446 fwdlist_set(thing, fp);
00447 count = fwdlist_rewrite(fp, atext);
00448 if(fp)
00449 free_lbuf(fp);
00450 return ((count > 0) || !atext || !*atext);
00451 }
00452
00453 FWDLIST *fwdlist_get(dbref thing)
00454 {
00455 FWDLIST *fp;
00456
00457 fp = ((FWDLIST *) nhashfind(thing, &mudstate.fwdlist_htab));
00458
00459 return fp;
00460 }
00461
00462 static char *set_string(char **ptr, char *new)
00463 {
00464
00465
00466
00467
00468 if(*ptr)
00469 XFREE(*ptr, "set_string");
00470
00471
00472
00473
00474
00475 if(!new)
00476
00477
00478 return (*ptr = NULL);
00479
00480
00481 *ptr = (char *) XMALLOC(strlen(new) + 1, "set_string");
00482 StringCopy(*ptr, new);
00483 return (*ptr);
00484 }
00485
00486
00487
00488
00489
00490 INLINE char *Name(dbref thing)
00491 {
00492 dbref aowner;
00493 int aflags;
00494 char *buff;
00495 static char *tbuff[MBUF_SIZE];
00496 char buffer[MBUF_SIZE];
00497
00498 if(mudconf.cache_names) {
00499 if(thing > mudstate.db_top || thing < 0) {
00500 return "#-1 INVALID DBREF";
00501 }
00502 if(!purenames[thing]) {
00503 buff = atr_get(thing, A_NAME, &aowner, &aflags);
00504 strip_ansi_r(buffer, buff, MBUF_SIZE);
00505 set_string(&purenames[thing], buffer);
00506 free_lbuf(buff);
00507 }
00508 }
00509
00510 atr_get_str((char *) tbuff, thing, A_NAME, &aowner, &aflags);
00511 return ((char *) tbuff);
00512 }
00513
00514 INLINE char *PureName(dbref thing)
00515 {
00516 dbref aowner;
00517 int aflags;
00518 char *buff;
00519 static char *tbuff[LBUF_SIZE];
00520 char new[LBUF_SIZE];
00521
00522 if(mudconf.cache_names) {
00523 if(thing > mudstate.db_top || thing < 0) {
00524 return "#-1 INVALID DBREF";
00525 }
00526 if(!purenames[thing]) {
00527 buff = atr_get(thing, A_NAME, &aowner, &aflags);
00528 strncpy(new, buff, LBUF_SIZE-1);
00529 set_string(&purenames[thing], strip_ansi_r(new,buff,strlen(buff)));
00530 free_lbuf(buff);
00531 }
00532 return purenames[thing];
00533 }
00534
00535 atr_get_str((char *) tbuff, thing, A_NAME, &aowner, &aflags);
00536 strncpy(new, (char *) tbuff,LBUF_SIZE-1);
00537 return (strip_ansi_r(new,(char *) tbuff,strlen((char *) tbuff)));
00538 }
00539
00540 INLINE void s_Name(dbref thing, char *s)
00541 {
00542 char new[MBUF_SIZE];
00543
00544
00545 strncpy(new,s,MBUF_SIZE-1);
00546 if(s && (strlen(s) > MBUF_SIZE))
00547 s[MBUF_SIZE] = '\0';
00548
00549 atr_add_raw(thing, A_NAME, (char *) s);
00550
00551 if(mudconf.cache_names) {
00552
00553 set_string(&purenames[thing], strip_ansi_r(new,s,strlen(s)));
00554 }
00555 }
00556
00557 void s_Pass(dbref thing, const char *s)
00558 {
00559 atr_add_raw(thing, A_PASS, (char *) s);
00560 }
00561
00562
00563
00564
00565
00566
00567 extern NAMETAB attraccess_nametab[];
00568
00569 void do_attribute(dbref player, dbref cause, int key, char *aname,
00570 char *value)
00571 {
00572 int success, negate, f;
00573 char *buff, *sp, *p, *q;
00574 VATTR *va;
00575 ATTR *va2;
00576
00577
00578
00579
00580
00581 buff = alloc_sbuf("do_attribute");
00582 for(p = buff, q = aname; *q && ((p - buff) < (SBUF_SIZE - 1)); p++, q++)
00583 *p = ToUpper(*q);
00584 *p = '\0';
00585
00586 va = (VATTR *) vattr_find(buff);
00587 if(!va) {
00588 notify(player, "No such user-named attribute.");
00589 free_sbuf(buff);
00590 return;
00591 }
00592 switch (key) {
00593 case ATTRIB_ACCESS:
00594
00595
00596
00597
00598
00599 for(sp = value; *sp; sp++)
00600 *sp = ToUpper(*sp);
00601 sp = strtok(value, " ");
00602 success = 0;
00603 while (sp != NULL) {
00604
00605
00606
00607
00608
00609 negate = 0;
00610 if(*sp == '!') {
00611 negate = 1;
00612 sp++;
00613 }
00614
00615
00616
00617
00618 f = search_nametab(player, attraccess_nametab, sp);
00619 if(f > 0) {
00620 success = 1;
00621 if(negate)
00622 va->flags &= ~f;
00623 else
00624 va->flags |= f;
00625 } else {
00626 notify_printf(player, "Unknown permission: %s.", sp);
00627 }
00628
00629
00630
00631
00632
00633 sp = strtok(NULL, " ");
00634 }
00635 if(success && !Quiet(player))
00636 notify(player, "Attribute access changed.");
00637 break;
00638
00639 case ATTRIB_RENAME:
00640
00641
00642
00643
00644
00645 va2 = atr_str(value);
00646 if(va2) {
00647 notify(player, "An attribute with that name already exists.");
00648 free_sbuf(buff);
00649 return;
00650 }
00651 if(vattr_rename(va->name, value) == NULL)
00652 notify(player, "Attribute rename failed.");
00653 else
00654 notify(player, "Attribute renamed.");
00655 break;
00656
00657 case ATTRIB_DELETE:
00658
00659
00660
00661
00662
00663 vattr_delete(buff);
00664 notify(player, "Attribute deleted.");
00665 break;
00666 }
00667 free_sbuf(buff);
00668 return;
00669 }
00670
00671
00672
00673
00674
00675
00676 void do_fixdb(dbref player, dbref cause, int key, char *arg1, char *arg2)
00677 {
00678 dbref thing, res;
00679
00680 init_match(player, arg1, NOTYPE);
00681 match_everything(0);
00682 thing = noisy_match_result();
00683 if(thing == NOTHING)
00684 return;
00685
00686 res = NOTHING;
00687 switch (key) {
00688 case FIXDB_OWNER:
00689 case FIXDB_LOC:
00690 case FIXDB_CON:
00691 case FIXDB_EXITS:
00692 case FIXDB_NEXT:
00693 init_match(player, arg2, NOTYPE);
00694 match_everything(0);
00695 res = noisy_match_result();
00696 break;
00697 case FIXDB_PENNIES:
00698 res = atoi(arg2);
00699 break;
00700 }
00701
00702 switch (key) {
00703 case FIXDB_OWNER:
00704 s_Owner(thing, res);
00705 if(!Quiet(player))
00706 notify_printf(player, "Owner set to #%d", res);
00707 break;
00708 case FIXDB_LOC:
00709 s_Location(thing, res);
00710 if(!Quiet(player))
00711 notify_printf(player, "Location set to #%d", res);
00712 break;
00713 case FIXDB_CON:
00714 s_Contents(thing, res);
00715 if(!Quiet(player))
00716 notify_printf(player, "Contents set to #%d", res);
00717 break;
00718 case FIXDB_EXITS:
00719 s_Exits(thing, res);
00720 if(!Quiet(player))
00721 notify_printf(player, "Exits set to #%d", res);
00722 break;
00723 case FIXDB_NEXT:
00724 s_Next(thing, res);
00725 if(!Quiet(player))
00726 notify_printf(player, "Next set to #%d", res);
00727 break;
00728 case FIXDB_PENNIES:
00729 s_Pennies(thing, res);
00730 if(!Quiet(player))
00731 notify_printf(player, "Pennies set to %d", res);
00732 break;
00733 case FIXDB_NAME:
00734 if(Typeof(thing) == TYPE_PLAYER) {
00735 if(!ok_player_name(arg2)) {
00736 notify(player, "That's not a good name for a player.");
00737 return;
00738 }
00739 if(lookup_player(NOTHING, arg2, 0) != NOTHING) {
00740 notify(player, "That name is already in use.");
00741 return;
00742 }
00743 STARTLOG(LOG_SECURITY, "SEC", "CNAME") {
00744 log_name(thing), log_text((char *) " renamed to ");
00745 log_text(arg2);
00746 ENDLOG;
00747 } if(Suspect(player)) {
00748 send_channel("Suspect", "%s renamed to %s",
00749 Name(thing), arg2);
00750 }
00751 delete_player_name(thing, Name(thing));
00752
00753 s_Name(thing, arg2);
00754 add_player_name(thing, arg2);
00755 } else {
00756 if(!ok_name(arg2)) {
00757 notify(player, "Warning: That is not a reasonable name.");
00758 }
00759 s_Name(thing, arg2);
00760 }
00761 if(!Quiet(player))
00762 notify_printf(player, "Name set to %s", arg2);
00763 break;
00764 }
00765 }
00766
00767
00768
00769
00770
00771
00772 void init_attrtab(void)
00773 {
00774 ATTR *a;
00775 char *buff, *p, *q;
00776
00777 hashinit(&mudstate.attr_name_htab, 512);
00778 buff = alloc_sbuf("init_attrtab");
00779 for(a = attr; a->number; a++) {
00780 anum_extend(a->number);
00781 anum_set(a->number, a);
00782 for(p = buff, q = (char *) a->name; *q; p++, q++)
00783 *p = ToUpper(*q);
00784 *p = '\0';
00785 hashadd(buff, (int *) a, &mudstate.attr_name_htab);
00786 }
00787 free_sbuf(buff);
00788 }
00789
00790
00791
00792
00793
00794
00795 ATTR *atr_str(char *s)
00796 {
00797 char *buff, *p, *q;
00798 ATTR *a;
00799 VATTR *va;
00800 static ATTR tattr;
00801
00802 if(!s || !*s) {
00803 return (NULL);
00804 }
00805
00806
00807
00808
00809
00810 buff = alloc_sbuf("atr_str");
00811 for(p = buff, q = s; *q && ((p - buff) < (SBUF_SIZE - 1)); p++, q++)
00812 *p = ToUpper(*q);
00813 *p = '\0';
00814
00815
00816
00817
00818
00819 a = (ATTR *) hashfind(buff, &mudstate.attr_name_htab);
00820 if(a != NULL) {
00821 free_sbuf(buff);
00822 return a;
00823 }
00824
00825
00826
00827
00828 va = (VATTR *) vattr_find(buff);
00829 free_sbuf(buff);
00830
00831
00832
00833
00834
00835 if(va != NULL) {
00836 tattr.name = va->name;
00837 tattr.number = va->number;
00838 tattr.flags = va->flags;
00839 tattr.check = NULL;
00840 return &tattr;
00841 }
00842
00843
00844
00845
00846 return NULL;
00847 }
00848
00849
00850
00851
00852
00853
00854 ATTR **anum_table = NULL;
00855 int anum_alc_top = 0;
00856
00857 void anum_extend(int newtop)
00858 {
00859 ATTR **anum_table2;
00860 int delta, i;
00861
00862 delta = mudconf.init_size;
00863
00864 if(newtop <= anum_alc_top)
00865 return;
00866 if(newtop < anum_alc_top + delta)
00867 newtop = anum_alc_top + delta;
00868 if(anum_table == NULL) {
00869 anum_table = (ATTR **) malloc((newtop + 1) * sizeof(ATTR *));
00870 for(i = 0; i <= newtop; i++)
00871 anum_table[i] = NULL;
00872 } else {
00873 anum_table2 = (ATTR **) malloc((newtop + 1) * sizeof(ATTR *));
00874 for(i = 0; i <= anum_alc_top; i++)
00875 anum_table2[i] = anum_table[i];
00876 for(i = anum_alc_top + 1; i <= newtop; i++)
00877 anum_table2[i] = NULL;
00878 free((char *) anum_table);
00879 anum_table = anum_table2;
00880 }
00881 anum_alc_top = newtop;
00882 }
00883
00884
00885
00886
00887
00888
00889 ATTR *atr_num(int anum)
00890 {
00891 VATTR *va;
00892 static ATTR tattr;
00893
00894
00895
00896
00897
00898 if(anum < A_USER_START)
00899 return anum_get(anum);
00900
00901 if(anum >= anum_alc_top)
00902 return NULL;
00903
00904
00905
00906
00907
00908 va = (VATTR *) anum_get(anum);
00909 if(va != NULL) {
00910 tattr.name = va->name;
00911 tattr.number = va->number;
00912 tattr.flags = va->flags;
00913 tattr.check = NULL;
00914 return &tattr;
00915 }
00916
00917
00918
00919
00920 return NULL;
00921 }
00922
00923
00924
00925
00926
00927
00928 int mkattr(char *buff)
00929 {
00930 ATTR *ap;
00931 VATTR *va;
00932
00933 if(!(ap = atr_str(buff))) {
00934
00935
00936
00937
00938
00939 va = vattr_alloc(buff, mudconf.vattr_flags);
00940 if(!va || !(va->number))
00941 return -1;
00942 return va->number;
00943 }
00944 if(!(ap->number))
00945 return -1;
00946 return ap->number;
00947 }
00948
00949
00950
00951
00952
00953
00954 int Commer(dbref thing)
00955 {
00956 char *s, *as, c;
00957 int attr, aflags;
00958 dbref aowner;
00959 ATTR *ap;
00960
00961 for(attr = atr_head(thing, &as); attr; attr = atr_next(&as)) {
00962 ap = atr_num(attr);
00963 if(!ap || (ap->flags & AF_NOPROG))
00964 continue;
00965
00966 s = atr_get(thing, attr, &aowner, &aflags);
00967 c = *s;
00968 free_lbuf(s);
00969 if((c == '$') && !(aflags & AF_NOPROG)) {
00970 return 1;
00971 }
00972 }
00973 return 0;
00974 }
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 static char *atr_encode(char *iattr, dbref thing, dbref owner, int flags,
00985 int atr, char *dest_buffer)
00986 {
00987
00988
00989
00990
00991
00992
00993 if(((owner == Owner(thing)) || (owner == NOTHING)) && !flags) {
00994 memset(dest_buffer, 0, LBUF_SIZE);
00995 strncpy(dest_buffer, iattr, LBUF_SIZE-1);
00996 return dest_buffer;
00997 }
00998
00999
01000
01001
01002
01003 if(owner == NOTHING)
01004 owner = Owner(thing);
01005 memset(dest_buffer, 0, LBUF_SIZE);
01006 snprintf(dest_buffer, LBUF_SIZE - 1, "%c%d:%d:%s", ATR_INFO_CHAR, owner, flags, iattr);
01007 return dest_buffer;
01008 }
01009
01010
01011
01012
01013
01014
01015 static void atr_decode(char *iattr, char *oattr, dbref thing, dbref * owner,
01016 int *flags, int atr)
01017 {
01018 char *cp;
01019 int neg;
01020
01021
01022
01023
01024
01025 if(*iattr == ATR_INFO_CHAR) {
01026
01027
01028
01029
01030
01031 cp = &iattr[1];
01032
01033
01034
01035
01036
01037 *owner = 0;
01038 neg = 0;
01039 if(*cp == '-') {
01040 neg = 1;
01041 cp++;
01042 }
01043 while (isdigit(*cp)) {
01044 *owner = (*owner * 10) + (*cp++ - '0');
01045 }
01046 if(neg)
01047 *owner = 0 - *owner;
01048
01049
01050
01051
01052
01053 if(*cp++ != ':') {
01054 *owner = Owner(thing);
01055 *flags = 0;
01056 if(oattr) {
01057 StringCopy(oattr, iattr);
01058 }
01059 return;
01060 }
01061
01062
01063
01064
01065 *flags = 0;
01066 while (isdigit(*cp)) {
01067 *flags = (*flags * 10) + (*cp++ - '0');
01068 }
01069
01070
01071
01072
01073
01074 if(*cp++ != ':') {
01075 *owner = Owner(thing);
01076 *flags = 0;
01077 if(oattr) {
01078 StringCopy(oattr, iattr);
01079 }
01080 }
01081
01082
01083
01084
01085 if(oattr) {
01086 StringCopy(oattr, cp);
01087 }
01088 if(*owner == NOTHING)
01089 *owner = Owner(thing);
01090 } else {
01091
01092
01093
01094
01095
01096 *owner = Owner(thing);
01097 *flags = 0;
01098 if(oattr) {
01099 StringCopy(oattr, iattr);
01100 }
01101 }
01102 }
01103
01104
01105
01106
01107
01108
01109 void atr_clr(dbref thing, int atr)
01110 {
01111 ATRLIST *list;
01112 int hi, lo, mid;
01113
01114 if(!db[thing].at_count || !db[thing].ahead)
01115 return;
01116
01117 if(db[thing].at_count < 0)
01118 abort();
01119
01120
01121
01122
01123 lo = 0;
01124 hi = db[thing].at_count - 1;
01125 list = db[thing].ahead;
01126 while (lo <= hi) {
01127 mid = ((hi - lo) >> 1) + lo;
01128 if(list[mid].number == atr) {
01129 free(list[mid].data);
01130 db[thing].at_count -= 1;
01131 if(mid != db[thing].at_count)
01132 bcopy((char *) (list + mid + 1), (char *) (list + mid),
01133 (db[thing].at_count - mid) * sizeof(ATRLIST));
01134 break;
01135 } else if(list[mid].number > atr) {
01136 hi = mid - 1;
01137 } else {
01138 lo = mid + 1;
01139 }
01140 }
01141
01142 switch (atr) {
01143 case A_STARTUP:
01144 s_Flags(thing, Flags(thing) & ~HAS_STARTUP);
01145 break;
01146 case A_DAILY:
01147 s_Flags2(thing, Flags2(thing) & ~HAS_DAILY);
01148 break;
01149 case A_HOURLY:
01150 s_Flags2(thing, Flags2(thing) & ~HAS_HOURLY);
01151 break;
01152 case A_FORWARDLIST:
01153 s_Flags2(thing, Flags2(thing) & ~HAS_FWDLIST);
01154 break;
01155 case A_LISTEN:
01156 s_Flags2(thing, Flags2(thing) & ~HAS_LISTEN);
01157 break;
01158 case A_TIMEOUT:
01159 desc_reload(thing);
01160 break;
01161 case A_QUEUEMAX:
01162 pcache_reload(thing);
01163 break;
01164 }
01165 }
01166
01167
01168
01169
01170
01171
01172 void atr_add_raw(dbref thing, int atr, char *buff)
01173 {
01174 ATRLIST *list;
01175 char *text;
01176 int found = 0;
01177 int hi, lo, mid;
01178
01179 if(!buff || !*buff) {
01180 atr_clr(thing, atr);
01181 return;
01182 }
01183 if(strlen(buff) >= LBUF_SIZE) {
01184 buff[LBUF_SIZE - 1] = '\0';
01185 }
01186 if((text = (char *) malloc(strlen(buff) + 1)) == NULL) {
01187 return;
01188 }
01189 StringCopy(text, buff);
01190
01191 if(!db[thing].ahead) {
01192 if((list = (ATRLIST *) malloc(sizeof(ATRLIST))) == NULL) {
01193 free(text);
01194 return;
01195 }
01196 db[thing].ahead = list;
01197 db[thing].at_count = 1;
01198 list[0].number = atr;
01199 list[0].data = text;
01200 list[0].size = strlen(text) + 1;
01201 found = 1;
01202 } else {
01203
01204
01205
01206
01207 lo = 0;
01208 hi = db[thing].at_count - 1;
01209
01210 list = db[thing].ahead;
01211 while (lo <= hi) {
01212 mid = ((hi - lo) >> 1) + lo;
01213 if(list[mid].number == atr) {
01214 free(list[mid].data);
01215 list[mid].data = text;
01216 list[mid].size = strlen(text) + 1;
01217 found = 1;
01218 break;
01219 } else if(list[mid].number > atr) {
01220 hi = mid - 1;
01221 } else {
01222 lo = mid + 1;
01223 }
01224 }
01225
01226 if(!found) {
01227
01228
01229
01230
01231
01232 list =
01233 (ATRLIST *) realloc(db[thing].ahead,
01234 (db[thing].at_count +
01235 1) * sizeof(ATRLIST));
01236
01237 if(!list)
01238 return;
01239
01240
01241
01242
01243 if(lo < db[thing].at_count)
01244 bcopy((char *) (list + lo), (char *) (list + lo + 1),
01245 (db[thing].at_count - lo) * sizeof(ATRLIST));
01246
01247 list[lo].data = text;
01248 list[lo].number = atr;
01249 list[lo].size = strlen(text) + 1;
01250 db[thing].at_count++;
01251 db[thing].ahead = list;
01252 }
01253 }
01254
01255 switch (atr) {
01256 case A_STARTUP:
01257 s_Flags(thing, Flags(thing) | HAS_STARTUP);
01258 break;
01259 case A_DAILY:
01260 s_Flags2(thing, Flags2(thing) | HAS_DAILY);
01261 break;
01262 case A_HOURLY:
01263 s_Flags2(thing, Flags2(thing) | HAS_HOURLY);
01264 break;
01265 case A_FORWARDLIST:
01266 s_Flags2(thing, Flags2(thing) | HAS_FWDLIST);
01267 break;
01268 case A_LISTEN:
01269 s_Flags2(thing, Flags2(thing) | HAS_LISTEN);
01270 break;
01271 case A_TIMEOUT:
01272 desc_reload(thing);
01273 break;
01274 case A_QUEUEMAX:
01275 pcache_reload(thing);
01276 break;
01277 }
01278 }
01279
01280 void atr_add(dbref thing, int atr, char *buff, dbref owner, int flags)
01281 {
01282 char *tbuff;
01283 char buffer[LBUF_SIZE];
01284
01285 if(!buff || !*buff) {
01286 atr_clr(thing, atr);
01287 } else {
01288 tbuff = atr_encode(buff, thing, owner, flags, atr, buffer);
01289 atr_add_raw(thing, atr, tbuff);
01290 }
01291 }
01292
01293 void atr_set_owner(dbref thing, int atr, dbref owner)
01294 {
01295 dbref aowner;
01296 int aflags;
01297 char *buff;
01298
01299 buff = atr_get(thing, atr, &aowner, &aflags);
01300 atr_add(thing, atr, buff, owner, aflags);
01301 free_lbuf(buff);
01302 }
01303
01304 void atr_set_flags(dbref thing, int atr, dbref flags)
01305 {
01306 dbref aowner;
01307 int aflags;
01308 char *buff;
01309
01310 buff = atr_get(thing, atr, &aowner, &aflags);
01311 atr_add(thing, atr, buff, aowner, flags);
01312 free_lbuf(buff);
01313 }
01314
01315
01316
01317
01318
01319
01320 int get_atr(char *name)
01321 {
01322 ATTR *ap;
01323
01324 if(!(ap = atr_str(name)))
01325 return 0;
01326 if(!(ap->number))
01327 return -1;
01328 return ap->number;
01329 }
01330
01331 char *atr_get_raw(dbref thing, int atr)
01332 {
01333 int lo, mid, hi;
01334 ATRLIST *list;
01335
01336 if(thing < 0)
01337 return NULL;
01338
01339
01340
01341
01342 lo = 0;
01343 hi = db[thing].at_count - 1;
01344 list = db[thing].ahead;
01345 if(!list)
01346 return NULL;
01347
01348 while (lo <= hi) {
01349 mid = ((hi - lo) >> 1) + lo;
01350 if(list[mid].number == atr) {
01351
01352 return list[mid].data;
01353 } else if(list[mid].number > atr) {
01354 hi = mid - 1;
01355 } else {
01356 lo = mid + 1;
01357 }
01358 }
01359 return NULL;
01360 }
01361
01362 char *atr_get_str(char *s, dbref thing, int atr, dbref * owner, int *flags)
01363 {
01364 char *buff;
01365
01366 buff = atr_get_raw(thing, atr);
01367 if(!buff) {
01368 *owner = Owner(thing);
01369 *flags = 0;
01370 *s = '\0';
01371 } else {
01372 atr_decode(buff, s, thing, owner, flags, atr);
01373 }
01374 return s;
01375 }
01376
01377 char *atr_get(dbref thing, int atr, dbref * owner, int *flags)
01378 {
01379 char *buff;
01380
01381 buff = alloc_lbuf("atr_get");
01382 return atr_get_str(buff, thing, atr, owner, flags);
01383 }
01384
01385 int atr_get_info(dbref thing, int atr, dbref * owner, int *flags)
01386 {
01387 char *buff;
01388
01389 buff = atr_get_raw(thing, atr);
01390 if(!buff) {
01391 *owner = Owner(thing);
01392 *flags = 0;
01393 return 0;
01394 }
01395 atr_decode(buff, NULL, thing, owner, flags, atr);
01396 return 1;
01397 }
01398
01399 char *atr_pget_str(char *s, dbref thing, int atr, dbref * owner, int *flags)
01400 {
01401 char *buff;
01402 dbref parent;
01403 int lev;
01404
01405 ATTR *ap;
01406
01407 ITER_PARENTS(thing, parent, lev) {
01408 buff = atr_get_raw(parent, atr);
01409 if(buff && *buff) {
01410 atr_decode(buff, s, thing, owner, flags, atr);
01411 if((lev == 0) || !(*flags & AF_PRIVATE))
01412 return s;
01413 }
01414 if((lev == 0) && Good_obj(Parent(parent))) {
01415 ap = atr_num(atr);
01416 if(!ap || ap->flags & AF_PRIVATE)
01417 break;
01418 }
01419 }
01420 *owner = Owner(thing);
01421 *flags = 0;
01422 *s = '\0';
01423 return s;
01424 }
01425
01426 char *atr_pget(dbref thing, int atr, dbref * owner, int *flags)
01427 {
01428 char *buff;
01429
01430 buff = alloc_lbuf("atr_pget");
01431 return atr_pget_str(buff, thing, atr, owner, flags);
01432 }
01433
01434 int atr_pget_info(dbref thing, int atr, dbref * owner, int *flags)
01435 {
01436 char *buff;
01437 dbref parent;
01438 int lev;
01439 ATTR *ap;
01440
01441 ITER_PARENTS(thing, parent, lev) {
01442 buff = atr_get_raw(parent, atr);
01443 if(buff && *buff) {
01444 atr_decode(buff, NULL, thing, owner, flags, atr);
01445 if((lev == 0) || !(*flags & AF_PRIVATE))
01446 return 1;
01447 }
01448 if((lev == 0) && Good_obj(Parent(parent))) {
01449 ap = atr_num(atr);
01450 if(!ap || ap->flags & AF_PRIVATE)
01451 break;
01452 }
01453 }
01454 *owner = Owner(thing);
01455 *flags = 0;
01456 return 0;
01457 }
01458
01459
01460
01461
01462
01463
01464 void atr_free(dbref thing)
01465 {
01466 free(db[thing].ahead);
01467 db[thing].ahead = NULL;
01468 }
01469
01470
01471
01472
01473 void atr_collect(dbref thing)
01474 {
01475
01476
01477
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487 void atr_cpy(dbref player, dbref dest, dbref source)
01488 {
01489 int attr, aflags;
01490 dbref owner, aowner;
01491 char *as, *buf;
01492 ATTR *at;
01493
01494 owner = Owner(dest);
01495 for(attr = atr_head(source, &as); attr; attr = atr_next(&as)) {
01496 buf = atr_get(source, attr, &aowner, &aflags);
01497 if(!(aflags & AF_LOCK))
01498 aowner = owner;
01499
01500
01501 at = atr_num(attr);
01502 if(attr && at) {
01503 if(Write_attr(owner, dest, at, aflags))
01504
01505
01506
01507 atr_add(dest, attr, buf, aowner, aflags);
01508 }
01509 free_lbuf(buf);
01510 }
01511 }
01512
01513
01514
01515
01516
01517
01518
01519 void atr_chown(dbref obj)
01520 {
01521 int attr, aflags;
01522 dbref owner, aowner;
01523 char *as, *buf;
01524
01525 owner = Owner(obj);
01526 for(attr = atr_head(obj, &as); attr; attr = atr_next(&as)) {
01527 buf = atr_get(obj, attr, &aowner, &aflags);
01528 if((aowner != owner) && !(aflags & AF_LOCK))
01529 atr_add(obj, attr, buf, owner, aflags);
01530 free_lbuf(buf);
01531 }
01532 }
01533
01534
01535
01536
01537
01538
01539 int atr_next(char **attrp)
01540 {
01541 ATRCOUNT *atr;
01542
01543 if(!attrp || !*attrp) {
01544 return 0;
01545 } else {
01546 atr = (ATRCOUNT *) * attrp;
01547 if(atr->count > db[atr->thing].at_count) {
01548 free(atr);
01549 return 0;
01550 }
01551 atr->count++;
01552 return db[atr->thing].ahead[atr->count - 2].number;
01553 }
01554 }
01555
01556
01557
01558
01559
01560
01561 int atr_head(dbref thing, char **attrp)
01562 {
01563 ATRCOUNT *atr;
01564
01565 if(db[thing].at_count) {
01566 atr = (ATRCOUNT *) malloc(sizeof(ATRCOUNT));
01567 atr->thing = thing;
01568 atr->count = 2;
01569 *attrp = (char *) atr;
01570 return db[thing].ahead[0].number;
01571 }
01572 return 0;
01573 }
01574
01575
01576
01577
01578
01579
01580 #define SIZE_HACK 1
01581
01582
01583
01584 void initialize_objects(dbref first, dbref last)
01585 {
01586 dbref thing;
01587
01588 for(thing = first; thing < last; thing++) {
01589 memset(&db[thing], 0, sizeof(db[0]));
01590 s_Owner(thing, GOD);
01591 s_Flags(thing, (TYPE_GARBAGE | GOING));
01592 s_Flags2(thing, 0);
01593 s_Flags3(thing, 0);
01594 s_Powers(thing, 0);
01595 s_Powers2(thing, 0);
01596 s_Location(thing, NOTHING);
01597 s_Contents(thing, NOTHING);
01598 s_Exits(thing, NOTHING);
01599 s_Link(thing, NOTHING);
01600 s_Next(thing, NOTHING);
01601 s_Zone(thing, NOTHING);
01602 s_Parent(thing, NOTHING);
01603 s_Stack(thing, NULL);
01604 db[thing].ahead = NULL;
01605 db[thing].at_count = 0;
01606 }
01607 }
01608
01609 void db_grow(dbref newtop)
01610 {
01611 int newsize, marksize, delta, i;
01612 MARKBUF *newmarkbuf;
01613 OBJ *newdb;
01614 NAME *newpurenames;
01615
01616 char *cp;
01617
01618 delta = mudconf.init_size;
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 if(newtop <= mudstate.db_top) {
01633 return;
01634 }
01635
01636
01637
01638
01639
01640
01641 if(newtop <= mudstate.db_size) {
01642 for(i = mudstate.db_top; i < newtop; i++) {
01643 if(mudconf.cache_names)
01644 purenames[i] = NULL;
01645 }
01646 initialize_objects(mudstate.db_top, newtop);
01647 mudstate.db_top = newtop;
01648 return;
01649 }
01650
01651
01652
01653
01654 if(newtop <= mudstate.db_size + delta) {
01655 newsize = mudstate.db_size + delta;
01656 } else {
01657 newsize = newtop;
01658 }
01659
01660
01661
01662
01663
01664 if(newsize < mudstate.min_size)
01665 newsize = mudstate.min_size + delta;;
01666
01667
01668
01669
01670
01671 if(mudconf.cache_names) {
01672 newpurenames =
01673 (NAME *) XMALLOC((newsize + SIZE_HACK) * sizeof(NAME),
01674 "db_grow.purenames");
01675
01676 if(!newpurenames) {
01677 LOG_SIMPLE(LOG_ALWAYS, "ALC", "DB",
01678 tprintf
01679 ("Could not allocate space for %d item name cache.",
01680 newsize));
01681 abort();
01682 }
01683 bzero((char *) newpurenames, (newsize + SIZE_HACK) * sizeof(NAME));
01684
01685 if(purenames) {
01686
01687
01688
01689
01690
01691 purenames -= SIZE_HACK;
01692 bcopy((char *) purenames, (char *) newpurenames,
01693 (newtop + SIZE_HACK) * sizeof(NAME));
01694 cp = (char *) purenames;
01695 XFREE(cp, "db_grow.purename");
01696 } else {
01697
01698
01699
01700
01701
01702
01703 purenames = newpurenames;
01704 for(i = 0; i < SIZE_HACK; i++) {
01705 purenames[i] = NULL;
01706 }
01707 }
01708 purenames = newpurenames + SIZE_HACK;
01709 newpurenames = NULL;
01710 }
01711
01712
01713
01714
01715 newdb = (OBJ *)
01716 XMALLOC((newsize + SIZE_HACK) * sizeof(OBJ), "db_grow.db");
01717 if(!newdb) {
01718
01719 LOG_SIMPLE(LOG_ALWAYS, "ALC", "DB",
01720 tprintf
01721 ("Could not allocate space for %d item struct database.",
01722 newsize));
01723 abort();
01724 }
01725 if(db) {
01726
01727
01728
01729
01730
01731 db -= SIZE_HACK;
01732 bcopy((char *) db, (char *) newdb,
01733 (mudstate.db_top + SIZE_HACK) * sizeof(OBJ));
01734 cp = (char *) db;
01735 XFREE(cp, "db_grow.db");
01736 } else {
01737
01738
01739
01740
01741
01742
01743
01744 db = newdb;
01745 for(i = 0; i < SIZE_HACK; i++) {
01746 s_Owner(i, GOD);
01747 s_Flags(i, (TYPE_GARBAGE | GOING));
01748 s_Powers(i, 0);
01749 s_Powers2(i, 0);
01750 s_Location(i, NOTHING);
01751 s_Contents(i, NOTHING);
01752 s_Exits(i, NOTHING);
01753 s_Link(i, NOTHING);
01754 s_Next(i, NOTHING);
01755 s_Zone(i, NOTHING);
01756 s_Parent(i, NOTHING);
01757 s_Stack(i, NULL);
01758 db[i].ahead = NULL;
01759 db[i].at_count = 0;
01760 }
01761 }
01762 db = newdb + SIZE_HACK;
01763 newdb = NULL;
01764
01765 for(i = mudstate.db_top; i < newtop; i++) {
01766 if(mudconf.cache_names) {
01767 purenames[i] = NULL;
01768 }
01769 }
01770 initialize_objects(mudstate.db_top, newtop);
01771 mudstate.db_top = newtop;
01772 mudstate.db_size = newsize;
01773
01774
01775
01776
01777
01778 marksize = (newsize + 7) >> 3;
01779 newmarkbuf = (MARKBUF *) XMALLOC(marksize, "db_grow");
01780 bzero((char *) newmarkbuf, marksize);
01781 if(mudstate.markbits) {
01782 marksize = (newtop + 7) >> 3;
01783 bcopy((char *) mudstate.markbits, (char *) newmarkbuf, marksize);
01784 cp = (char *) mudstate.markbits;
01785 XFREE(cp, "db_grow");
01786 }
01787 mudstate.markbits = newmarkbuf;
01788 }
01789
01790 void db_free(void)
01791 {
01792 char *cp;
01793
01794 if(db != NULL) {
01795 db -= SIZE_HACK;
01796 cp = (char *) db;
01797 XFREE(cp, "db_grow");
01798 db = NULL;
01799 }
01800 mudstate.db_top = 0;
01801 mudstate.db_size = 0;
01802 mudstate.freelist = NOTHING;
01803 }
01804
01805 void db_make_minimal(void)
01806 {
01807 dbref obj;
01808
01809 db_free();
01810 db_grow(1);
01811 s_Name(0, "Limbo");
01812 s_Flags(0, TYPE_ROOM);
01813 s_Powers(0, 0);
01814 s_Powers2(0, 0);
01815 s_Location(0, NOTHING);
01816 s_Exits(0, NOTHING);
01817 s_Link(0, NOTHING);
01818 s_Parent(0, NOTHING);
01819 s_Zone(0, NOTHING);
01820 s_Pennies(0, 1);
01821 s_Owner(0, 1);
01822 db[0].ahead = NULL;
01823 db[0].at_count = 0;
01824
01825
01826
01827 load_player_names();
01828 obj =
01829 create_player((char *) "Wizard", (char *) "potrzebie", NOTHING, 0, 0);
01830 s_Flags(obj, Flags(obj) | WIZARD);
01831 s_Powers(obj, 0);
01832 s_Powers2(obj, 0);
01833 s_Pennies(obj, 1000);
01834
01835
01836
01837
01838 s_Location(obj, 0);
01839 s_Next(obj, NOTHING);
01840 s_Contents(0, obj);
01841 s_Link(obj, 0);
01842 }
01843
01844 dbref parse_dbref(const char *s)
01845 {
01846 const char *p;
01847 int x;
01848
01849
01850
01851
01852
01853 for(p = s; *p; p++) {
01854 if(!isdigit(*p))
01855 return NOTHING;
01856 }
01857
01858 x = atoi(s);
01859 return ((x >= 0) ? x : NOTHING);
01860 }
01861
01862 void putref(FILE * f, dbref ref)
01863 {
01864 fprintf(f, "%d\n", ref);
01865 }
01866
01867 void putstring(FILE * f, const char *s)
01868 {
01869 putc('"', f);
01870
01871 while (s && *s) {
01872 switch (*s) {
01873 case '\\':
01874 case '"':
01875 putc('\\', f);
01876 default:
01877 putc(*s, f);
01878 }
01879 s++;
01880 }
01881 putc('"', f);
01882 putc('\n', f);
01883 }
01884
01885 const char *getstring_noalloc(FILE * f, int new_strings)
01886 {
01887 static char buf[LBUF_SIZE];
01888 char *p;
01889 int c, lastc;
01890
01891 p = buf;
01892 c = fgetc(f);
01893 if(!new_strings || (c != '"')) {
01894 ungetc(c, f);
01895 c = '\0';
01896 for(;;) {
01897 lastc = c;
01898 c = fgetc(f);
01899
01900
01901
01902
01903
01904 if(!c || (c == EOF)) {
01905 *p = '\0';
01906 return buf;
01907 }
01908
01909
01910
01911
01912
01913 if((c == '\n') && (lastc != '\r')) {
01914 *p = '\0';
01915 return buf;
01916 }
01917 safe_chr(c, buf, &p);
01918 }
01919 } else {
01920 for(;;) {
01921 c = fgetc(f);
01922 if(c == '"') {
01923 if((c = fgetc(f)) != '\n')
01924 ungetc(c, f);
01925 *p = '\0';
01926 return buf;
01927 } else if(c == '\\') {
01928 c = fgetc(f);
01929 }
01930 if((c == '\0') || (c == EOF)) {
01931 *p = '\0';
01932 return buf;
01933 }
01934 safe_chr(c, buf, &p);
01935 }
01936 }
01937 }
01938
01939 dbref getref(FILE * f)
01940 {
01941 static char buf[SBUF_SIZE];
01942
01943 fgets(buf, sizeof(buf), f);
01944 return (atoi(buf));
01945 }
01946
01947 void free_boolexp(BOOLEXP * b)
01948 {
01949 if(b == TRUE_BOOLEXP)
01950 return;
01951
01952 switch (b->type) {
01953 case BOOLEXP_AND:
01954 case BOOLEXP_OR:
01955 free_boolexp(b->sub1);
01956 free_boolexp(b->sub2);
01957 free_bool(b);
01958 break;
01959 case BOOLEXP_NOT:
01960 case BOOLEXP_CARRY:
01961 case BOOLEXP_IS:
01962 case BOOLEXP_OWNER:
01963 case BOOLEXP_INDIR:
01964 free_boolexp(b->sub1);
01965 free_bool(b);
01966 break;
01967 case BOOLEXP_CONST:
01968 free_bool(b);
01969 break;
01970 case BOOLEXP_ATR:
01971 case BOOLEXP_EVAL:
01972 free((char *) b->sub1);
01973 free_bool(b);
01974 break;
01975 }
01976 }
01977
01978 BOOLEXP *dup_bool(BOOLEXP * b)
01979 {
01980 BOOLEXP *r;
01981
01982 if(b == TRUE_BOOLEXP)
01983 return (TRUE_BOOLEXP);
01984
01985 r = alloc_bool("dup_bool");
01986 switch (r->type = b->type) {
01987 case BOOLEXP_AND:
01988 case BOOLEXP_OR:
01989 r->sub2 = dup_bool(b->sub2);
01990 case BOOLEXP_NOT:
01991 case BOOLEXP_CARRY:
01992 case BOOLEXP_IS:
01993 case BOOLEXP_OWNER:
01994 case BOOLEXP_INDIR:
01995 r->sub1 = dup_bool(b->sub1);
01996 case BOOLEXP_CONST:
01997 r->thing = b->thing;
01998 break;
01999 case BOOLEXP_EVAL:
02000 case BOOLEXP_ATR:
02001 r->thing = b->thing;
02002 r->sub1 = (BOOLEXP *) strsave((char *) b->sub1);
02003 break;
02004 default:
02005 fprintf(stderr, "bad bool type!!\n");
02006 return (TRUE_BOOLEXP);
02007 }
02008 return (r);
02009 }
02010
02011 void clone_object(dbref a, dbref b)
02012 {
02013 bcopy((char *) &db[b], (char *) &db[a], sizeof(struct object));
02014 }
02015
02016
02017
02018
02019 int check_zone(dbref player, dbref thing)
02020 {
02021 mudstate.zone_nest_num++;
02022
02023 if(!mudconf.have_zones || (Zone(thing) == NOTHING) ||
02024 (mudstate.zone_nest_num == mudconf.zone_nest_lim) ||
02025 (isPlayer(thing))) {
02026 mudstate.zone_nest_num = 0;
02027 return 0;
02028 }
02029
02030
02031
02032
02033
02034 if(atr_get_raw(Zone(thing), A_LENTER) &&
02035 could_doit(player, Zone(thing), A_LENTER)) {
02036 mudstate.zone_nest_num = 0;
02037 return 1;
02038 } else {
02039 return check_zone(player, Zone(thing));
02040 }
02041
02042 }
02043
02044 int check_zone_for_player(dbref player, dbref thing)
02045 {
02046 mudstate.zone_nest_num++;
02047
02048 if(!mudconf.have_zones || (Zone(thing) == NOTHING) ||
02049 (mudstate.zone_nest_num == mudconf.zone_nest_lim) ||
02050 !(isPlayer(thing))) {
02051 mudstate.zone_nest_num = 0;
02052 return 0;
02053 }
02054
02055 if(atr_get_raw(Zone(thing), A_LENTER) &&
02056 could_doit(player, Zone(thing), A_LENTER)) {
02057 mudstate.zone_nest_num = 0;
02058 return 1;
02059 } else {
02060 return check_zone(player, Zone(thing));
02061 }
02062
02063 }
02064
02065 void toast_player(dbref player)
02066 {
02067 do_clearcom(player, player, 0);
02068 do_channelnuke(player);
02069 del_commac(player);
02070 do_clear_macro(player, NULL);
02071 }
02072
02073
02074
02075
02076
02077
02078
02079 void dump_restart_db(void)
02080 {
02081 FILE *f;
02082 DESC *d;
02083 OBJQE *obq;
02084 int version = 0;
02085
02086
02087
02088
02089
02090 version |= RS_RECORD_PLAYERS;
02091 version |= RS_NEW_STRINGS;
02092 version |= RS_HUDKEY;
02093
02094 f = fopen("restart.db", "w");
02095 fprintf(f, "+V%d\n", version);
02096 putref(f, mudstate.start_time);
02097 putstring(f, mudstate.doing_hdr);
02098 putref(f, mudstate.record_players);
02099 for (d = descriptor_list ; d && d->next ; d = d->next);
02100 for(; d != NULL ; d = d->prev) {
02101 dprintk("d: %p dnext: %p dprev: %p", d, d->next, d->prev);
02102 putref(f, d->descriptor);
02103 putref(f, d->flags);
02104 putref(f, d->connected_at);
02105 putref(f, d->command_count);
02106 putref(f, d->timeout);
02107 putref(f, d->host_info);
02108 putref(f, d->player);
02109 putref(f, d->last_time);
02110 putstring(f, d->output_prefix);
02111 putstring(f, d->output_suffix);
02112 putstring(f, d->addr);
02113 putstring(f, d->doing);
02114 putstring(f, d->username);
02115 putstring(f, d->hudkey);
02116 }
02117 putref(f, 0);
02118 fclose(f);
02119 }
02120
02121 #define RESTART_MAGIC 0x0001D1ED
02122 void dump_restart_db_xdr(void)
02123 {
02124 struct mmdb_t *mmdb;
02125 DESC *d;
02126 int version = 0;
02127
02128
02129
02130
02131
02132 version |= RS_RECORD_PLAYERS;
02133 version |= RS_NEW_STRINGS;
02134 version |= RS_HUDKEY;
02135
02136
02137 mmdb = mmdb_open_write("restart.xdr");
02138 mmdb_write_uint32(mmdb, RESTART_MAGIC);
02139 mmdb_write_uint32(mmdb, 1);
02140 mmdb_write_uint32(mmdb, version);
02141 mmdb_write_uint32(mmdb, mudstate.start_time);
02142 mmdb_write_string(mmdb, mudstate.doing_hdr);
02143 mmdb_write_uint32(mmdb, mudstate.record_players);
02144 for (d = descriptor_list; d && d->next; d = d->next) ;
02145
02146 for (; d != NULL; d = d->prev) {
02147 dprintk("XDR!! d: %p dnext: %p dprev: %p", d, d->next, d->prev);
02148 mmdb_write_uint32(mmdb, d->descriptor);
02149 mmdb_write_uint32(mmdb, d->flags);
02150 mmdb_write_uint32(mmdb, d->connected_at);
02151 mmdb_write_uint32(mmdb, d->command_count);
02152 mmdb_write_uint32(mmdb, d->timeout);
02153 mmdb_write_uint32(mmdb, d->host_info);
02154 mmdb_write_uint32(mmdb, d->player);
02155 mmdb_write_uint32(mmdb, d->last_time);
02156 mmdb_write_string(mmdb, d->output_prefix);
02157 mmdb_write_string(mmdb, d->output_suffix);
02158 mmdb_write_string(mmdb, d->addr);
02159 mmdb_write_string(mmdb, d->doing);
02160 mmdb_write_string(mmdb, d->username);
02161 mmdb_write_string(mmdb, d->hudkey);
02162 }
02163 mmdb_write_uint32(mmdb, 0);
02164 cque_dump_restart(mmdb);
02165 mmdb_close(mmdb);
02166 }
02167
02168 void accept_client_input(int fd, short event, void *arg);
02169
02170 void bsd_write_callback(struct bufferevent *bufev, void *arg);
02171 void bsd_read_callback(struct bufferevent *bufev, void *arg);
02172 void bsd_error_callback(struct bufferevent *bufev, short whut, void *arg);
02173
02174 void load_restart_db()
02175 {
02176 FILE *f;
02177 DESC *d;
02178 DESC *p;
02179 struct stat statbuffer;
02180
02181 int val, version, new_strings = 0;
02182 char *temp, buf[8];
02183
02184 f = fopen("restart.db", "r");
02185 if(!f) {
02186 mudstate.restarting = 0;
02187 return;
02188 }
02189 mudstate.restarting = 1;
02190
02191 fgets(buf, 3, f);
02192 if(strncmp(buf, "+V", 2)) {
02193 abort();
02194 }
02195 version = getref(f);
02196
02197 if(version & RS_NEW_STRINGS)
02198 new_strings = 1;
02199
02200 mudstate.start_time = getref(f);
02201 time(&mudstate.restart_time);
02202 strcpy(mudstate.doing_hdr, getstring_noalloc(f, new_strings));
02203
02204 if(version & RS_RECORD_PLAYERS) {
02205 mudstate.record_players = getref(f);
02206 }
02207
02208 while ((val = getref(f)) != 0) {
02209 d = malloc(sizeof(DESC));
02210 memset(d, 0, sizeof(DESC));
02211 d->descriptor = val;
02212 d->flags = getref(f);
02213 d->connected_at = getref(f);
02214 d->command_count = getref(f);
02215 d->timeout = getref(f);
02216 d->host_info = getref(f);
02217 d->player = getref(f);
02218 d->last_time = getref(f);
02219 temp = (char *) getstring_noalloc(f, new_strings);
02220 if(*temp) {
02221 d->output_prefix = alloc_lbuf("set_userstring");
02222 strcpy(d->output_prefix, temp);
02223 } else {
02224 d->output_prefix = NULL;
02225 }
02226 temp = (char *) getstring_noalloc(f, new_strings);
02227 if(*temp) {
02228 d->output_suffix = alloc_lbuf("set_userstring");
02229 strcpy(d->output_suffix, temp);
02230 } else {
02231 d->output_suffix = NULL;
02232 }
02233
02234 strcpy(d->addr, getstring_noalloc(f, new_strings));
02235 strcpy(d->doing, getstring_noalloc(f, new_strings));
02236 strcpy(d->username, getstring_noalloc(f, new_strings));
02237
02238 if(version & RS_HUDKEY)
02239 strncpy(d->hudkey, getstring_noalloc(f, new_strings), HUDKEYLEN);
02240 else
02241 d->hudkey[0] = '\0';
02242
02243 d->output_size = 0;
02244 d->output_tot = 0;
02245 d->output_lost = 0;
02246 d->input_size = 0;
02247 d->input_tot = 0;
02248 d->input_lost = 0;
02249 memset(d->input, 0, sizeof(d->input));
02250 d->input_tail = 0;
02251 d->quota = mudconf.cmd_quota_max;
02252 d->program_data = NULL;
02253 d->hashnext = NULL;
02254 d->refcount = 1;
02255
02256 d->saddr_len = sizeof(d->saddr);
02257 getpeername(d->descriptor, (struct sockaddr *) &d->saddr,
02258 (socklen_t *) & d->saddr_len);
02259 d->outstanding_dnschild_query = dnschild_request(d);
02260
02261
02262
02263 if (descriptor_list)
02264 descriptor_list->prev = d;
02265 d->next = descriptor_list;
02266 d->prev = NULL;
02267 descriptor_list = d;
02268
02269 d->sock_buff = bufferevent_new(d->descriptor, bsd_write_callback,
02270 bsd_read_callback, bsd_error_callback,
02271 NULL);
02272
02273 bufferevent_disable(d->sock_buff, EV_READ);
02274 bufferevent_enable(d->sock_buff, EV_WRITE);
02275
02276 event_set(&d->sock_ev, d->descriptor, EV_READ | EV_PERSIST,
02277 accept_client_input, d);
02278 event_add(&d->sock_ev, NULL);
02279
02280 desc_addhash(d);
02281 if(isPlayer(d->player))
02282 s_Flags2(d->player, Flags2(d->player) | CONNECTED);
02283 }
02284
02285 DESC_ITER_CONN(d) {
02286 if(!isPlayer(d->player) || fstat(d->descriptor, &statbuffer) < 0) {
02287 dprintk("dropping descriptor %d.\n", d->descriptor);
02288 shutdownsock(d, R_QUIT);
02289 }
02290
02291 }
02292
02293 fclose(f);
02294 remove("restart.db");
02295 raw_broadcast(0, "Game: Restart finished.");
02296 }
02297
02298 int load_restart_db_xdr()
02299 {
02300 struct mmdb_t *mmdb;
02301 DESC *d;
02302 DESC *p;
02303 struct stat statbuffer;
02304
02305 int val, version, new_strings = 0;
02306 char *temp, buf[8];
02307
02308 mmdb = mmdb_open_read("restart.xdr");
02309 if(!mmdb) return 0;
02310
02311 val = mmdb_read_uint32(mmdb);
02312 if(val != RESTART_MAGIC) {
02313 printk("restart database had invalid magic.");
02314 printk("read %08x expected %08x.", val, RESTART_MAGIC);
02315 return 0;
02316 }
02317 mmdb_read_uint32(mmdb);
02318 mmdb_read_uint32(mmdb);
02319 mudstate.start_time = mmdb_read_uint32(mmdb);
02320 mmdb_read_opaque(mmdb, mudstate.doing_hdr, sizeof(mudstate.doing_hdr));
02321 mudstate.record_players = mmdb_read_uint32(mmdb);
02322
02323 mudstate.restarting = 1;
02324
02325 while( (val = mmdb_read_uint32(mmdb)) != 0) {
02326 dprintk("loading descriptor %d\n", val);
02327 d = malloc(sizeof(DESC));
02328 memset(d, 0, sizeof(DESC));
02329 d->descriptor = val;
02330 d->flags = mmdb_read_uint32(mmdb);
02331 d->connected_at = mmdb_read_uint32(mmdb);
02332 d->command_count = mmdb_read_uint32(mmdb);
02333 d->timeout = mmdb_read_uint32(mmdb);
02334 d->host_info = mmdb_read_uint32(mmdb);
02335 d->player = mmdb_read_uint32(mmdb);
02336 d->last_time = mmdb_read_uint32(mmdb);
02337
02338 d->output_prefix = mmdb_read_string(mmdb);
02339 d->output_suffix = mmdb_read_string(mmdb);
02340 mmdb_read_opaque(mmdb, d->addr, sizeof(d->addr));
02341 mmdb_read_opaque(mmdb, d->doing, sizeof(d->doing));
02342 mmdb_read_opaque(mmdb, d->username, sizeof(d->username));
02343 mmdb_read_opaque(mmdb, d->hudkey, sizeof(d->hudkey));
02344
02345 d->output_size = 0;
02346 d->output_tot = 0;
02347 d->output_lost = 0;
02348 d->input_size = 0;
02349 d->input_tot = 0;
02350 d->input_lost = 0;
02351 memset(d->input, 0, sizeof(d->input));
02352 d->input_tail = 0;
02353 d->quota = mudconf.cmd_quota_max;
02354 d->program_data = NULL;
02355 d->hashnext = NULL;
02356 d->refcount = 1;
02357
02358 d->saddr_len = sizeof(d->saddr);
02359 getpeername(d->descriptor, (struct sockaddr *) &d->saddr,
02360 (socklen_t *) & d->saddr_len);
02361 d->outstanding_dnschild_query = dnschild_request(d);
02362
02363
02364
02365
02366 if (descriptor_list)
02367 descriptor_list->prev = d;
02368 d->next = descriptor_list;
02369 d->prev = NULL;
02370 descriptor_list = d;
02371
02372 d->sock_buff = bufferevent_new(d->descriptor, bsd_write_callback,
02373 bsd_read_callback, bsd_error_callback,
02374 NULL);
02375 bufferevent_disable(d->sock_buff, EV_READ);
02376 bufferevent_enable(d->sock_buff, EV_WRITE);
02377
02378 event_set(&d->sock_ev, d->descriptor, EV_READ | EV_PERSIST,
02379 accept_client_input, d);
02380 event_add(&d->sock_ev, NULL);
02381
02382 desc_addhash(d);
02383 if(isPlayer(d->player))
02384 s_Flags2(d->player, Flags2(d->player) | CONNECTED);
02385 }
02386
02387 DESC_ITER_CONN(d) {
02388 if(!isPlayer(d->player) || fstat(d->descriptor, &statbuffer) < 0) {
02389 dprintk("dropping descriptor %d.\n", d->descriptor);
02390 shutdownsock(d, R_QUIT);
02391 }
02392
02393 }
02394 cque_load_restart(mmdb);
02395 mmdb_close(mmdb);
02396 remove("restart.xdr");
02397 remove("restart.db");
02398 raw_broadcast(0, "Game: Restart finished.");
02399 return 1;
02400 }