00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include "attrs.h"
00015 #include "command.h"
00016 #include "comsys.h"
00017 #include "interface.h"
00018 #include "powers.h"
00019 #include "vattr.h"
00020 #include "ansi.h"
00021
00022 #ifndef O_ACCMODE
00023 #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
00024 #endif // O_ACCMODE
00025
00026 OBJ *db = NULL;
00027
00028 typedef struct atrcount ATRCOUNT;
00029 struct atrcount
00030 {
00031 dbref thing;
00032 int count;
00033 };
00034
00035
00036
00037 ATTR attr[] =
00038 {
00039 {"Aahear", A_AAHEAR, AF_ODARK | AF_NOPROG},
00040 {"Aclone", A_ACLONE, AF_ODARK | AF_NOPROG},
00041 {"Aconnect", A_ACONNECT, AF_ODARK | AF_NOPROG},
00042 {"Adesc", A_ADESC, AF_ODARK | AF_NOPROG},
00043 {"Adfail", A_ADFAIL, AF_ODARK | AF_NOPROG},
00044 {"Adisconnect", A_ADISCONNECT, AF_ODARK | AF_NOPROG},
00045 {"Adrop", A_ADROP, AF_ODARK | AF_NOPROG},
00046 {"Aefail", A_AEFAIL, AF_ODARK | AF_NOPROG},
00047 {"Aenter", A_AENTER, AF_ODARK | AF_NOPROG},
00048 {"Afail", A_AFAIL, AF_ODARK | AF_NOPROG},
00049 {"Agfail", A_AGFAIL, AF_ODARK | AF_NOPROG},
00050 {"Ahear", A_AHEAR, AF_ODARK | AF_NOPROG},
00051 {"Akill", A_AKILL, AF_ODARK | AF_NOPROG},
00052 {"Aleave", A_ALEAVE, AF_ODARK | AF_NOPROG},
00053 {"Alfail", A_ALFAIL, AF_ODARK | AF_NOPROG},
00054 {"Alias", A_ALIAS, AF_NOPROG | AF_NOCMD | AF_NOCLONE | AF_PRIVATE | AF_CONST | AF_VISUAL},
00055 {"Allowance", A_ALLOWANCE, AF_MDARK | AF_NOPROG | AF_WIZARD},
00056 {"Amail", A_AMAIL, AF_ODARK | AF_NOPROG},
00057 {"Amhear", A_AMHEAR, AF_ODARK | AF_NOPROG},
00058 {"Amove", A_AMOVE, AF_ODARK | AF_NOPROG},
00059 {"Apay", A_APAY, AF_ODARK | AF_NOPROG},
00060 {"Arfail", A_ARFAIL, AF_ODARK | AF_NOPROG},
00061 {"Asucc", A_ASUCC, AF_ODARK | AF_NOPROG},
00062 {"Atfail", A_ATFAIL, AF_ODARK | AF_NOPROG},
00063 {"Atport", A_ATPORT, AF_ODARK | AF_NOPROG},
00064 {"Atofail", A_ATOFAIL, AF_ODARK | AF_NOPROG},
00065 {"Aufail", A_AUFAIL, AF_ODARK | AF_NOPROG},
00066 {"Ause", A_AUSE, AF_ODARK | AF_NOPROG},
00067 {"Away", A_AWAY, AF_ODARK | AF_NOPROG},
00068 {"Charges", A_CHARGES, AF_ODARK | AF_NOPROG},
00069 {"CmdCheck", A_CMDCHECK, AF_DARK | AF_NOPROG | AF_NOCMD | AF_NOCLONE | AF_PRIVATE | AF_CONST},
00070 {"Comment", A_COMMENT, AF_MDARK | AF_WIZARD},
00071 {"ConFormat", A_CONFORMAT, AF_ODARK | AF_NOPROG},
00072 {"Cost", A_COST, AF_ODARK | AF_NOPROG},
00073 {"Created", A_CREATED, AF_GOD | AF_VISUAL | AF_NOPROG | AF_NOCMD},
00074 {"Daily", A_DAILY, AF_ODARK | AF_NOPROG},
00075 {"Desc", A_DESC, AF_VISUAL | AF_NOPROG},
00076 {"DefaultLock", A_LOCK, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00077 {"DescFormat", A_DESCFORMAT, AF_ODARK | AF_NOPROG},
00078 {"Destroyer", A_DESTROYER, AF_MDARK | AF_WIZARD | AF_NOPROG},
00079 {"Dfail", A_DFAIL, AF_ODARK | AF_NOPROG},
00080 {"Drop", A_DROP, AF_ODARK | AF_NOPROG},
00081 {"DropLock", A_LDROP, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00082 {"Ealias", A_EALIAS, AF_ODARK | AF_NOPROG},
00083 {"Efail", A_EFAIL, AF_ODARK | AF_NOPROG},
00084 {"Enter", A_ENTER, AF_ODARK | AF_NOPROG},
00085 {"EnterLock", A_LENTER, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00086 {"ExitFormat", A_EXITFORMAT, AF_ODARK | AF_NOPROG},
00087 {"ExitTo", A_EXITVARDEST, AF_ODARK | AF_NOPROG | AF_WIZARD},
00088 {"Fail", A_FAIL, AF_ODARK | AF_NOPROG},
00089 {"Filter", A_FILTER, AF_ODARK | AF_NOPROG},
00090 {"Forwardlist", A_FORWARDLIST, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_CONST},
00091 {"GetFromLock", A_LGET, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00092 {"Gfail", A_GFAIL, AF_ODARK | AF_NOPROG},
00093 {"GiveLock", A_LGIVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00094 {"Idesc", A_IDESC, AF_ODARK | AF_NOPROG},
00095 {"Idle", A_IDLE, AF_ODARK | AF_NOPROG},
00096 {"IdleTimeout", A_IDLETMOUT, AF_ODARK | AF_NOPROG},
00097 {"Infilter", A_INFILTER, AF_ODARK | AF_NOPROG},
00098 {"Inprefix", A_INPREFIX, AF_ODARK | AF_NOPROG},
00099 {"Kill", A_KILL, AF_ODARK | AF_NOPROG},
00100 {"Lalias", A_LALIAS, AF_ODARK | AF_NOPROG},
00101 {"Last", A_LAST, AF_WIZARD | AF_NOCMD | AF_NOPROG | AF_NOCLONE},
00102 {"Lastpage", A_LASTPAGE, AF_INTERNAL | AF_NOCMD | AF_NOPROG | AF_GOD | AF_PRIVATE},
00103 {"Lastsite", A_LASTSITE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_NOCLONE | AF_GOD},
00104 {"LastIP", A_LASTIP, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_GOD},
00105 {"Leave", A_LEAVE, AF_ODARK | AF_NOPROG},
00106 {"LeaveLock", A_LLEAVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00107 {"Lfail", A_LFAIL, AF_ODARK | AF_NOPROG},
00108 {"LinkLock", A_LLINK, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00109 {"Listen", A_LISTEN, AF_ODARK | AF_NOPROG},
00110 {"Logindata", A_LOGINDATA, AF_MDARK | AF_NOPROG | AF_NOCMD | AF_CONST},
00111 {"Mailcurf", A_MAILCURF, AF_MDARK | AF_WIZARD | AF_NOPROG | AF_NOCLONE},
00112 {"Mailflags", A_MAILFLAGS, AF_MDARK | AF_WIZARD | AF_NOPROG | AF_NOCLONE},
00113 {"Mailfolders", A_MAILFOLDERS, AF_MDARK | AF_WIZARD | AF_NOPROG | AF_NOCLONE},
00114 {"MailLock", A_LMAIL, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00115 {"Mailmsg", A_MAILMSG, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00116 {"Mailsub", A_MAILSUB, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00117 {"Mailsucc", A_MAIL, AF_ODARK | AF_NOPROG},
00118 {"Mailto", A_MAILTO, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00119 {"Mfail", A_MFAIL, AF_ODARK | AF_NOPROG},
00120 {"Modified", A_MODIFIED, AF_GOD | AF_VISUAL | AF_NOPROG | AF_NOCMD},
00121 {"Moniker", A_MONIKER, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_CONST},
00122 {"Move", A_MOVE, AF_ODARK | AF_NOPROG},
00123 {"Name", A_NAME, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00124 {"NameFormat", A_NAMEFORMAT, AF_ODARK | AF_NOPROG | AF_WIZARD},
00125 {"Odesc", A_ODESC, AF_ODARK | AF_NOPROG},
00126 {"Odfail", A_ODFAIL, AF_ODARK | AF_NOPROG},
00127 {"Odrop", A_ODROP, AF_ODARK | AF_NOPROG},
00128 {"Oefail", A_OEFAIL, AF_ODARK | AF_NOPROG},
00129 {"Oenter", A_OENTER, AF_ODARK | AF_NOPROG},
00130 {"Ofail", A_OFAIL, AF_ODARK | AF_NOPROG},
00131 {"Ogfail", A_OGFAIL, AF_ODARK | AF_NOPROG},
00132 {"Okill", A_OKILL, AF_ODARK | AF_NOPROG},
00133 {"Oleave", A_OLEAVE, AF_ODARK | AF_NOPROG},
00134 {"Olfail", A_OLFAIL, AF_ODARK | AF_NOPROG},
00135 {"Omove", A_OMOVE, AF_ODARK | AF_NOPROG},
00136 {"Opay", A_OPAY, AF_ODARK | AF_NOPROG},
00137 {"OpenLock", A_LOPEN, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00138 {"Orfail", A_ORFAIL, AF_ODARK | AF_NOPROG},
00139 {"Osucc", A_OSUCC, AF_ODARK | AF_NOPROG},
00140 {"Otfail", A_OTFAIL, AF_ODARK | AF_NOPROG},
00141 {"Otport", A_OTPORT, AF_ODARK | AF_NOPROG},
00142 {"Otofail", A_OTOFAIL, AF_ODARK | AF_NOPROG},
00143 {"Oufail", A_OUFAIL, AF_ODARK | AF_NOPROG},
00144 {"Ouse", A_OUSE, AF_ODARK | AF_NOPROG},
00145 {"Oxenter", A_OXENTER, AF_ODARK | AF_NOPROG},
00146 {"Oxleave", A_OXLEAVE, AF_ODARK | AF_NOPROG},
00147 {"Oxtport", A_OXTPORT, AF_ODARK | AF_NOPROG},
00148 {"PageLock", A_LPAGE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00149 {"ParentLock", A_LPARENT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00150 {"Pay", A_PAY, AF_ODARK | AF_NOPROG},
00151 {"Prefix", A_PREFIX, AF_ODARK | AF_NOPROG},
00152 {"ProgCmd", A_PROGCMD, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00153 {"QueueMax", A_QUEUEMAX, AF_MDARK | AF_WIZARD | AF_NOPROG},
00154 {"Quota", A_QUOTA, AF_MDARK | AF_NOPROG | AF_GOD | AF_NOCMD | AF_NOCLONE},
00155 {"ReceiveLock", A_LRECEIVE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00156 {"Reject", A_REJECT, AF_ODARK | AF_NOPROG},
00157 {"Rfail", A_RFAIL, AF_ODARK | AF_NOPROG},
00158 {"Rquota", A_RQUOTA, AF_MDARK | AF_NOPROG | AF_GOD | AF_NOCMD | AF_NOCLONE},
00159 {"Runout", A_RUNOUT, AF_ODARK | AF_NOPROG},
00160 {"SayString", A_SAYSTRING, AF_ODARK | AF_NOPROG},
00161 {"Semaphore", A_SEMAPHORE, AF_ODARK | AF_NOPROG | AF_WIZARD | AF_NOCMD | AF_NOCLONE},
00162 {"Sex", A_SEX, AF_VISUAL | AF_NOPROG},
00163 {"Signature", A_SIGNATURE, AF_ODARK | AF_NOPROG},
00164 {"SpeechMod", A_SPEECHMOD, AF_ODARK | AF_NOPROG},
00165 {"SpeechLock", A_LSPEECH, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00166 {"Startup", A_STARTUP, AF_ODARK | AF_NOPROG},
00167 {"Succ", A_SUCC, AF_ODARK | AF_NOPROG},
00168 {"TeloutLock", A_LTELOUT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00169 {"Tfail", A_TFAIL, AF_ODARK | AF_NOPROG},
00170 {"Timeout", A_TIMEOUT, AF_MDARK | AF_NOPROG | AF_WIZARD},
00171 {"Tport", A_TPORT, AF_ODARK | AF_NOPROG},
00172 {"TportLock", A_LTPORT, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00173 {"Tofail", A_TOFAIL, AF_ODARK | AF_NOPROG},
00174 {"Ufail", A_UFAIL, AF_ODARK | AF_NOPROG},
00175 {"Use", A_USE, AF_ODARK | AF_NOPROG},
00176 {"UseLock", A_LUSE, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00177 {"UserLock", A_LUSER, AF_ODARK | AF_NOPROG | AF_NOCMD | AF_IS_LOCK},
00178 {"VA", A_VA, AF_ODARK},
00179 {"VB", A_VA + 1, AF_ODARK},
00180 {"VC", A_VA + 2, AF_ODARK},
00181 {"VD", A_VA + 3, AF_ODARK},
00182 {"VE", A_VA + 4, AF_ODARK},
00183 {"VF", A_VA + 5, AF_ODARK},
00184 {"VG", A_VA + 6, AF_ODARK},
00185 {"VH", A_VA + 7, AF_ODARK},
00186 {"VI", A_VA + 8, AF_ODARK},
00187 {"VJ", A_VA + 9, AF_ODARK},
00188 {"VK", A_VA + 10, AF_ODARK},
00189 {"VL", A_VA + 11, AF_ODARK},
00190 {"VM", A_VA + 12, AF_ODARK},
00191 {"VN", A_VA + 13, AF_ODARK},
00192 {"VO", A_VA + 14, AF_ODARK},
00193 {"VP", A_VA + 15, AF_ODARK},
00194 {"VQ", A_VA + 16, AF_ODARK},
00195 {"VR", A_VA + 17, AF_ODARK},
00196 {"VS", A_VA + 18, AF_ODARK},
00197 {"VT", A_VA + 19, AF_ODARK},
00198 {"VU", A_VA + 20, AF_ODARK},
00199 {"VV", A_VA + 21, AF_ODARK},
00200 {"VW", A_VA + 22, AF_ODARK},
00201 {"VX", A_VA + 23, AF_ODARK},
00202 {"VY", A_VA + 24, AF_ODARK},
00203 {"VZ", A_VA + 25, AF_ODARK},
00204 {"VRML_URL", A_VRML_URL, AF_ODARK | AF_NOPROG},
00205 {"HTDesc", A_HTDESC, AF_NOPROG},
00206
00207
00208 {"Reason", A_REASON, AF_PRIVATE | AF_MDARK | AF_NOPROG | AF_NOCMD | AF_GOD},
00209 #ifdef GAME_DOOFERMUX
00210 {"RegInfo", A_REGINFO, AF_PRIVATE | AF_MDARK | AF_NOPROG | AF_NOCMD | AF_WIZARD},
00211 #endif // GAME_DOOFERMUX
00212 {"ConnInfo", A_CONNINFO, AF_PRIVATE | AF_MDARK | AF_NOPROG | AF_NOCMD | AF_GOD},
00213 {"*Password", A_PASS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00214 {"*Privileges", A_PRIVS, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00215 {"*Money", A_MONEY, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00216 #ifdef REALITY_LVLS
00217 {"Rlevel", A_RLEVEL, AF_DARK | AF_NOPROG | AF_NOCMD | AF_INTERNAL},
00218 #endif
00219 {NULL, 0, 0}
00220 };
00221
00222 char *aszSpecialDBRefNames[1-NOPERM] =
00223 {
00224 "", "*NOTHING*", "*AMBIGUOUS*", "*HOME*", "*NOPERMISSION*"
00225 };
00226
00227
00228
00229
00230
00231 void fwdlist_set(dbref thing, FWDLIST *ifp)
00232 {
00233 FWDLIST *fp, *xfp;
00234 int i;
00235
00236
00237
00238 if (!ifp || (ifp->count <= 0))
00239 {
00240 fwdlist_clr(thing);
00241 return;
00242 }
00243
00244
00245
00246 fp = (FWDLIST *)MEMALLOC(sizeof(int) * ((ifp->count) + 1));
00247 ISOUTOFMEMORY(fp);
00248
00249 for (i = 0; i < ifp->count; i++)
00250 {
00251 fp->data[i] = ifp->data[i];
00252 }
00253 fp->count = ifp->count;
00254
00255
00256
00257 xfp = fwdlist_get(thing);
00258 if (xfp)
00259 {
00260 MEMFREE(xfp);
00261 xfp = NULL;
00262 hashreplLEN(&thing, sizeof(thing), fp, &mudstate.fwdlist_htab);
00263 }
00264 else
00265 {
00266 hashaddLEN(&thing, sizeof(thing), fp, &mudstate.fwdlist_htab);
00267 }
00268 }
00269
00270 void fwdlist_clr(dbref thing)
00271 {
00272
00273
00274 FWDLIST *xfp = fwdlist_get(thing);
00275 if (xfp)
00276 {
00277 MEMFREE(xfp);
00278 xfp = NULL;
00279 hashdeleteLEN(&thing, sizeof(thing), &mudstate.fwdlist_htab);
00280 }
00281 }
00282
00283
00284
00285
00286
00287 int fwdlist_load(FWDLIST *fp, dbref player, char *atext)
00288 {
00289 dbref target;
00290 char *tp, *bp, *dp;
00291 bool fail;
00292
00293 int count = 0;
00294 int errors = 0;
00295 bp = tp = alloc_lbuf("fwdlist_load.str");
00296 strcpy(tp, atext);
00297 do
00298 {
00299
00300
00301 for (; mux_isspace(*bp); bp++)
00302 {
00303 ;
00304 }
00305
00306
00307
00308 for (dp = bp; *bp && !mux_isspace(*bp); bp++)
00309 {
00310 ;
00311 }
00312
00313
00314
00315 if (*bp)
00316 {
00317 *bp++ = '\0';
00318 }
00319
00320 if ( *dp++ == '#'
00321 && mux_isdigit(*dp))
00322 {
00323 target = mux_atol(dp);
00324 if (mudstate.bStandAlone)
00325 {
00326 fail = !Good_obj(target);
00327 }
00328 else
00329 {
00330 fail = ( !Good_obj(target)
00331 || ( !God(player)
00332 && !Controls(player, target)
00333 && ( !Link_ok(target)
00334 || !could_doit(player, target, A_LLINK))));
00335 }
00336 if (fail)
00337 {
00338 if (!mudstate.bStandAlone)
00339 {
00340 notify(player,
00341 tprintf("Cannot forward to #%d: Permission denied.",
00342 target));
00343 }
00344 errors++;
00345 }
00346 else
00347 {
00348 if (count < 1000)
00349 {
00350 fp->data[count++] = target;
00351 }
00352 }
00353 }
00354 } while (*bp);
00355 free_lbuf(tp);
00356 fp->count = count;
00357 return errors;
00358 }
00359
00360
00361
00362
00363
00364 int fwdlist_rewrite(FWDLIST *fp, char *atext)
00365 {
00366 int count = 0;
00367 atext[0] = '\0';
00368
00369 if (fp && fp->count)
00370 {
00371 char *bp = atext;
00372 ITL pContext;
00373 ItemToList_Init(&pContext, atext, &bp, '#');
00374 for (int i = 0; i < fp->count; i++)
00375 {
00376 if ( Good_obj(fp->data[i])
00377 && ItemToList_AddInteger(&pContext, fp->data[i]))
00378 {
00379 count++;
00380 }
00381 }
00382 ItemToList_Final(&pContext);
00383 }
00384 return count;
00385 }
00386
00387
00388
00389
00390 bool fwdlist_ck(dbref player, dbref thing, int anum, char *atext)
00391 {
00392 UNUSED_PARAMETER(anum);
00393
00394 if (mudstate.bStandAlone)
00395 {
00396 return true;
00397 }
00398
00399 FWDLIST *fp;
00400 int count = 0;
00401
00402 if (atext && *atext)
00403 {
00404 fp = (FWDLIST *) alloc_lbuf("fwdlist_ck.fp");
00405 fwdlist_load(fp, player, atext);
00406 }
00407 else
00408 {
00409 fp = NULL;
00410 }
00411
00412
00413
00414 fwdlist_set(thing, fp);
00415 count = fwdlist_rewrite(fp, atext);
00416 if (fp)
00417 {
00418 free_lbuf(fp);
00419 }
00420 return ((count > 0) || !atext || !*atext);
00421 }
00422
00423 FWDLIST *fwdlist_get(dbref thing)
00424 {
00425 static FWDLIST *fp = NULL;
00426 if (mudstate.bStandAlone)
00427 {
00428 if (!fp)
00429 {
00430 fp = (FWDLIST *) alloc_lbuf("fwdlist_get");
00431 }
00432 dbref aowner;
00433 int aflags;
00434 char *tp = atr_get(thing, A_FORWARDLIST, &aowner, &aflags);
00435 fwdlist_load(fp, GOD, tp);
00436 free_lbuf(tp);
00437 }
00438 else
00439 {
00440 fp = (FWDLIST *) hashfindLEN(&thing, sizeof(thing),
00441 &mudstate.fwdlist_htab);
00442 }
00443 return fp;
00444 }
00445
00446
00447
00448
00449
00450 const char *Name(dbref thing)
00451 {
00452 if (thing < 0)
00453 {
00454 return aszSpecialDBRefNames[-thing];
00455 }
00456
00457 dbref aowner;
00458 int aflags;
00459 #ifdef MEMORY_BASED
00460 static char tbuff[LBUF_SIZE];
00461 atr_get_str(tbuff, thing, A_NAME, &aowner, &aflags);
00462 return tbuff;
00463 #else // MEMORY_BASED
00464 if (!db[thing].name)
00465 {
00466 size_t len;
00467 char *pName = atr_get_LEN(thing, A_NAME, &aowner, &aflags, &len);
00468 db[thing].name = StringCloneLen(pName, len);
00469 free_lbuf(pName);
00470 }
00471 return db[thing].name;
00472 #endif // MEMORY_BASED
00473 }
00474
00475 const char *PureName(dbref thing)
00476 {
00477 if (thing < 0)
00478 {
00479 return aszSpecialDBRefNames[-thing];
00480 }
00481
00482 dbref aowner;
00483 int aflags;
00484
00485 char *pName, *pPureName;
00486 if (mudconf.cache_names)
00487 {
00488 if (!db[thing].purename)
00489 {
00490 size_t nName;
00491 size_t nPureName;
00492 #ifdef MEMORY_BASED
00493 pName = atr_get_LEN(thing, A_NAME, &aowner, &aflags, &nName);
00494 pPureName = strip_ansi(pName, &nPureName);
00495 free_lbuf(pName);
00496 db[thing].purename = StringCloneLen(pPureName, nPureName);
00497 #else // MEMORY_BASED
00498 if (!db[thing].name)
00499 {
00500 pName = atr_get_LEN(thing, A_NAME, &aowner, &aflags, &nName);
00501 db[thing].name = StringCloneLen(pName, nName);
00502 free_lbuf(pName);
00503 }
00504 else
00505 {
00506 nName = strlen(db[thing].name);
00507 }
00508 pName = db[thing].name;
00509 pPureName = strip_ansi(pName, &nPureName);
00510 if (nPureName == nName)
00511 {
00512 db[thing].purename = pName;
00513 }
00514 else
00515 {
00516 db[thing].purename = StringCloneLen(pPureName, nPureName);
00517 }
00518 #endif // MEMORY_BASED
00519 }
00520 return db[thing].purename;
00521 }
00522 pName = atr_get(thing, A_NAME, &aowner, &aflags);
00523 pPureName = strip_ansi(pName);
00524 free_lbuf(pName);
00525 return pPureName;
00526 }
00527
00528 const char *Moniker(dbref thing)
00529 {
00530 if (thing < 0)
00531 {
00532 return aszSpecialDBRefNames[-thing];
00533 }
00534 if (db[thing].moniker)
00535 {
00536 return db[thing].moniker;
00537 }
00538
00539
00540
00541
00542 const char *pPureName = strip_accents(PureName(thing));
00543 char *pPureNameCopy = StringClone(pPureName);
00544
00545 size_t nMoniker;
00546 dbref aowner;
00547 int aflags;
00548 char *pMoniker = atr_get_LEN(thing, A_MONIKER, &aowner, &aflags,
00549 &nMoniker);
00550 char *pPureMoniker = strip_accents(strip_ansi(pMoniker));
00551
00552 const char *pReturn = NULL;
00553 static char tbuff[LBUF_SIZE];
00554 if (strcmp(pPureNameCopy, pPureMoniker) == 0)
00555 {
00556
00557
00558
00559
00560 if (mudconf.cache_names)
00561 {
00562 #ifdef MEMORY_BASED
00563 db[thing].moniker = StringCloneLen(pMoniker, nMoniker);
00564 #else // MEMORY_BASED
00565 if (strcmp(pMoniker, Name(thing)) == 0)
00566 {
00567 db[thing].moniker = db[thing].name;
00568 }
00569 else
00570 {
00571 db[thing].moniker = StringCloneLen(pMoniker, nMoniker);
00572 }
00573 #endif // MEMORY_BASED
00574 pReturn = db[thing].moniker;
00575 }
00576 else
00577 {
00578 memcpy(tbuff, pMoniker, nMoniker+1);
00579 pReturn = tbuff;
00580 }
00581 }
00582 else
00583 {
00584
00585
00586
00587 #ifdef MEMORY_BASED
00588 if (mudconf.cache_names)
00589 {
00590 db[thing].moniker = StringClone(Name(thing));
00591 pReturn = db[thing].moniker;
00592 }
00593 else
00594 {
00595 pReturn = Name(thing);
00596 }
00597 #else // MEMORY_BASED
00598 if (mudconf.cache_names)
00599 {
00600 db[thing].moniker = db[thing].name;
00601 pReturn = db[thing].moniker;
00602 }
00603 else
00604 {
00605 pReturn = Name(thing);
00606 }
00607 #endif // MEMORY_BASED
00608 }
00609 free_lbuf(pMoniker);
00610 MEMFREE(pPureNameCopy);
00611
00612 return pReturn;
00613 }
00614
00615 void s_Name(dbref thing, const char *s)
00616 {
00617 atr_add_raw(thing, A_NAME, s);
00618 #ifndef MEMORY_BASED
00619 if (db[thing].name)
00620 {
00621 if (mudconf.cache_names)
00622 {
00623 if (db[thing].name == db[thing].purename)
00624 {
00625 db[thing].purename = NULL;
00626 }
00627 if (db[thing].name == db[thing].moniker)
00628 {
00629 db[thing].moniker = NULL;
00630 }
00631 }
00632 MEMFREE(db[thing].name);
00633 db[thing].name = NULL;
00634 }
00635 if (s)
00636 {
00637 db[thing].name = StringClone(s);
00638 }
00639 #endif // !MEMORY_BASED
00640 if (mudconf.cache_names)
00641 {
00642 if (db[thing].purename)
00643 {
00644 MEMFREE(db[thing].purename);
00645 db[thing].purename = NULL;
00646 }
00647 if (db[thing].moniker)
00648 {
00649 MEMFREE(db[thing].moniker);
00650 db[thing].moniker = NULL;
00651 }
00652 }
00653 }
00654
00655 void s_Moniker(dbref thing, const char *s)
00656 {
00657 atr_add_raw(thing, A_MONIKER, s);
00658 if (mudconf.cache_names)
00659 {
00660 #ifndef MEMORY_BASED
00661 if (db[thing].name == db[thing].moniker)
00662 {
00663 db[thing].moniker = NULL;
00664 }
00665 #endif // !MEMORY_BASED
00666 if (db[thing].moniker)
00667 {
00668 MEMFREE(db[thing].moniker);
00669 db[thing].moniker = NULL;
00670 }
00671 }
00672 }
00673
00674 void s_Pass(dbref thing, const char *s)
00675 {
00676 atr_add_raw(thing, A_PASS, s);
00677 }
00678
00679
00680
00681
00682
00683 void do_attribute
00684 (
00685 dbref executor,
00686 dbref caller,
00687 dbref enactor,
00688 int key,
00689 int nargs,
00690 char *aname,
00691 char *value
00692 )
00693 {
00694 UNUSED_PARAMETER(caller);
00695 UNUSED_PARAMETER(enactor);
00696 UNUSED_PARAMETER(nargs);
00697
00698
00699
00700 int nName;
00701 bool bValid;
00702 ATTR *va;
00703 char *pName = MakeCanonicalAttributeName(aname, &nName, &bValid);
00704 if (bValid)
00705 {
00706 va = (ATTR *)vattr_find_LEN(pName, nName);
00707 if (!va)
00708 {
00709 bValid = false;
00710 }
00711 }
00712
00713 if (!bValid)
00714 {
00715 notify(executor, "No such user-named attribute.");
00716 return;
00717 }
00718
00719 int f;
00720 char *sp;
00721 ATTR *va2;
00722 bool negate, success;
00723
00724 switch (key)
00725 {
00726 case ATTRIB_ACCESS:
00727
00728
00729
00730 mux_strupr(value);
00731 MUX_STRTOK_STATE tts;
00732 mux_strtok_src(&tts, value);
00733 mux_strtok_ctl(&tts, " ");
00734 sp = mux_strtok_parse(&tts);
00735 success = false;
00736 while (sp != NULL)
00737 {
00738
00739
00740 negate = false;
00741 if (*sp == '!')
00742 {
00743 negate = true;
00744 sp++;
00745 }
00746
00747
00748
00749 if (search_nametab(executor, attraccess_nametab, sp, &f))
00750 {
00751 success = true;
00752 if (negate)
00753 va->flags &= ~f;
00754 else
00755 va->flags |= f;
00756 }
00757 else
00758 {
00759 notify(executor, tprintf("Unknown permission: %s.", sp));
00760 }
00761
00762
00763
00764 sp = mux_strtok_parse(&tts);
00765 }
00766 if (success && !Quiet(executor))
00767 notify(executor, "Attribute access changed.");
00768 break;
00769
00770 case ATTRIB_RENAME:
00771
00772 {
00773
00774
00775 char OldName[SBUF_SIZE];
00776 int nOldName = nName;
00777 memcpy(OldName, pName, nName+1);
00778
00779
00780
00781
00782 va2 = atr_str(value);
00783 if (va2)
00784 {
00785 notify(executor, "An attribute with that name already exists.");
00786 return;
00787 }
00788 pName = MakeCanonicalAttributeName(value, &nName, &bValid);
00789 if (!bValid || vattr_rename_LEN(OldName, nOldName, pName, nName) == NULL)
00790 notify(executor, "Attribute rename failed.");
00791 else