#include <ctype.h>
#include <string.h>
#include "config.h"
#include "db.h"
#include "externs.h"
#include "interface.h"
#include "attrib.h"
#include "oldattrib.h"
#ifdef MEM_CHECK
#include "mem_check.h"
#endif
#ifdef USE_NALLOC
#include "nalloc.h"
extern NALLOC *db_strings;
#endif
/* attribute list */
ATTR attr[] =
{
{ (char *) "AAHEAR", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ACLONE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ACONNECT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ADEATH", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ADESCRIBE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ADISCONNECT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ADROP", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AEFAIL", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AENTER", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AFAILURE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AHEAR", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ALEAVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AMHEAR", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AMOVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "APAYMENT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ASUCCESS", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AUSE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "AWAY", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "CHARGES", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "CLASS", AF_NOPROG, NULL, 0 },
{ (char *) "COST", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "DEATH", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "DESCRIBE", AF_NOPROG, NULL, 0 },
{ (char *) "DOES", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "DROP", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "EALIAS", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "EFAIL", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ENTER", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "FAILURE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "HAVEN", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "IDESCRIBE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "IDLE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "LALIAS", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "LAST", AF_WIZARD | AF_LOCKED, NULL, 0 },
{ (char *) "LASTSITE", AF_LOCKED | AF_ODARK, NULL, 0 },
{ (char *) "LEAVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "LISTEN", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "MOVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ODEATH", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ODESCRIBE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "ODROP", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OEFAIL", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OENTER", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OFAILURE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OLEAVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OMOVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OPAYMENT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OSUCCESS", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OUSE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OXENTER", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "OXLEAVE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "PAYMENT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "QUEUE", AF_ODARK | AF_WIZARD, NULL, 0 },
{ (char *) "RACE", AF_NOPROG | AF_WIZARD, NULL, 0 },
{ (char *) "RQUOTA", AF_DARK | AF_WIZARD, NULL, 0 },
{ (char *) "RUNOUT", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "SEX", AF_NOPROG, NULL, 0 },
{ (char *) "STARTUP", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "SUCCESS", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "USE", AF_ODARK | AF_NOPROG, NULL, 0 },
{ (char *) "VA", AF_ODARK, NULL, 0 },
{ (char *) "VB", AF_ODARK, NULL, 0 },
{ (char *) "VC", AF_ODARK, NULL, 0 },
{ (char *) "VD", AF_ODARK, NULL, 0 },
{ (char *) "VE", AF_ODARK, NULL, 0 },
{ (char *) "VF", AF_ODARK, NULL, 0 },
{ (char *) "VG", AF_ODARK, NULL, 0 },
{ (char *) "VH", AF_ODARK, NULL, 0 },
{ (char *) "VI", AF_ODARK, NULL, 0 },
{ (char *) "VJ", AF_ODARK, NULL, 0 },
{ (char *) "VK", AF_ODARK, NULL, 0 },
{ (char *) "VL", AF_ODARK, NULL, 0 },
{ (char *) "VM", AF_ODARK, NULL, 0 },
{ (char *) "VN", AF_ODARK, NULL, 0 },
{ (char *) "VO", AF_ODARK, NULL, 0 },
{ (char *) "VP", AF_ODARK, NULL, 0 },
{ (char *) "VQ", AF_ODARK, NULL, 0 },
{ (char *) "VR", AF_ODARK, NULL, 0 },
{ (char *) "VS", AF_ODARK, NULL, 0 },
{ (char *) "VT", AF_ODARK, NULL, 0 },
{ (char *) "VU", AF_ODARK, NULL, 0 },
{ (char *) "VV", AF_ODARK, NULL, 0 },
{ (char *) "VW", AF_ODARK, NULL, 0 },
{ (char *) "VX", AF_ODARK, NULL, 0 },
{ (char *) "VY", AF_ODARK, NULL, 0 },
{ (char *) "VZ", AF_ODARK, NULL, 0 },
{ (char *) "WA", AF_ODARK, NULL, 0 },
{ (char *) "WB", AF_ODARK, NULL, 0 },
{ (char *) "WC", AF_ODARK, NULL, 0 },
{ (char *) "WD", AF_ODARK, NULL, 0 },
{ (char *) "WE", AF_ODARK, NULL, 0 },
{ (char *) "WF", AF_ODARK, NULL, 0 },
{ (char *) "WG", AF_ODARK, NULL, 0 },
{ (char *) "WH", AF_ODARK, NULL, 0 },
{ (char *) "WI", AF_ODARK, NULL, 0 },
{ (char *) "WJ", AF_ODARK, NULL, 0 },
{ (char *) "WK", AF_ODARK, NULL, 0 },
{ (char *) "WL", AF_ODARK, NULL, 0 },
{ (char *) "WM", AF_ODARK, NULL, 0 },
{ (char *) "WN", AF_ODARK, NULL, 0 },
{ (char *) "WO", AF_ODARK, NULL, 0 },
{ (char *) "WP", AF_ODARK, NULL, 0 },
{ (char *) "WQ", AF_ODARK, NULL, 0 },
{ (char *) "WR", AF_ODARK, NULL, 0 },
{ (char *) "WS", AF_ODARK, NULL, 0 },
{ (char *) "WT", AF_ODARK, NULL, 0 },
{ (char *) "WU", AF_ODARK, NULL, 0 },
{ (char *) "WV", AF_ODARK, NULL, 0 },
{ (char *) "WW", AF_ODARK, NULL, 0 },
{ (char *) "WX", AF_ODARK, NULL, 0 },
{ (char *) "WY", AF_ODARK, NULL, 0 },
{ (char *) "WZ", AF_ODARK, NULL, 0 },
{ (char *) "XA", AF_ODARK, NULL, 0 },
{ (char *) "XB", AF_ODARK, NULL, 0 },
{ (char *) "XC", AF_ODARK, NULL, 0 },
{ (char *) "XD", AF_ODARK, NULL, 0 },
{ (char *) "XE", AF_ODARK, NULL, 0 },
{ (char *) "XF", AF_ODARK, NULL, 0 },
{ (char *) "XG", AF_ODARK, NULL, 0 },
{ (char *) "XH", AF_ODARK, NULL, 0 },
{ (char *) "XI", AF_ODARK, NULL, 0 },
{ (char *) "XJ", AF_ODARK, NULL, 0 },
{ (char *) "XK", AF_ODARK, NULL, 0 },
{ (char *) "XL", AF_ODARK, NULL, 0 },
{ (char *) "XM", AF_ODARK, NULL, 0 },
{ (char *) "XN", AF_ODARK, NULL, 0 },
{ (char *) "XO", AF_ODARK, NULL, 0 },
{ (char *) "XP", AF_ODARK, NULL, 0 },
{ (char *) "XQ", AF_ODARK, NULL, 0 },
{ (char *) "XR", AF_ODARK, NULL, 0 },
{ (char *) "XS", AF_ODARK, NULL, 0 },
{ (char *) "XT", AF_ODARK, NULL, 0 },
{ (char *) "XU", AF_ODARK, NULL, 0 },
{ (char *) "XV", AF_ODARK, NULL, 0 },
{ (char *) "XW", AF_ODARK, NULL, 0 },
{ (char *) "XX", AF_ODARK, NULL, 0 },
{ (char *) "XY", AF_ODARK, NULL, 0 },
{ (char *) "XZ", AF_ODARK, NULL, 0 },
{ (char *) "XYXXY", AF_DARK | AF_NOPROG | AF_LOCKED | AF_WIZARD,
NULL, 0 },
{ NULL, 0, NULL, 0 }
};
char *clean_atr_name(s)
char *s;
{
static char buf[BUFFER_LEN];
char *q = buf;
char *a;
if(!*s || !s) {
sprintf(buf, "NULL");
return buf;
}
if(!string_compare("KILL", s)) {
sprintf(buf, "DEATH");
return buf;
}
if(!string_compare("KILL", s+1) &&
(*s == 'o' || *s == 'O' || *s == 'a' || *s == 'A')) {
sprintf(buf, "%c%s", *s, s+1);
return buf;
}
for(a = s; *a; a++)
if(isprint(*a) && !isspace(*a))
*q++ = *a;
*q = '\0';
return buf;
}
ATTR *atr_str(s)
char *s;
{
ATTR *result;
ATTR *a = attr;
int done = 0;
char *q;
#ifdef USE_NALLOC
result = (ATTR *)na_alloc(db_strings, sizeof (ATTR));
#else
result = (ATTR *)malloc(sizeof (ATTR));
#endif
q = clean_atr_name(s);
#ifdef USE_NALLOC
result->name = (char *) na_ualloc(db_strings, (strlen(q) + 1));
#else
result->name = (char *) malloc(strlen(q)+1);
#endif
#ifdef MEM_CHECK
add_check("attribute");
add_check("attribute_name");
#endif
strcpy(result->name, strupper(q));
result->flags = AF_ODARK;
while (a->name && !done) {
if(!string_compare(result->name, a->name)) {
result->flags = a->flags;
done++;
}
a++;
}
return result;
}
struct boolatr *alloc_atr(name, s)
char *name;
char *s;
{
struct boolatr *a;
const char *p;
#ifdef USE_NALLOC
a = (struct boolatr *)na_alloc(db_strings, sizeof(struct boolatr));
a->name = (char *)na_ualloc(db_strings, strlen(name) + 1);
#else
a = (struct boolatr *)malloc(sizeof (struct boolatr));
a->name = (char *)malloc(strlen(name)+1);
#endif
strcpy(a->name,name);
p = compress(s);
#ifdef USE_NALLOC
a->text = (char *)na_ualloc(db_strings, strlen(p) + 1);
#else
a->text = (char *)malloc(strlen(p)+1);
#endif
strcpy(a->text, p);
#ifdef MEM_CHECK
add_check("bool_atr");
add_check("bool_atr_name");
add_check("bool_atr_val");
#endif
return a;
}
void atr_clr(thing, atr)
dbref thing;
char *atr;
{
ALIST *ptr = db[thing].list;
while(ptr) {
if(!string_compare(atr, AL_NAME(ptr))) {
AL_DISPOSE(ptr);
return;
}
ptr = AL_NEXT(ptr);
}
}
ALIST *AL_MAKE(type, next, string, owner, flags)
char *type;
ALIST *next;
char *string;
dbref owner;
dbref flags;
{
ALIST *ptr;
const char *p;
#ifdef USE_NALLOC
ptr = (ALIST *)na_alloc(db_strings, sizeof(ALIST));
#else
ptr = (ALIST *)malloc(sizeof(ALIST));
#endif
AL_ATTR(ptr) = atr_str(type);
AL_CREATOR(ptr) = owner;
p = compress(string);
#ifdef USE_NALLOC
AL_STR(ptr) = (char *)na_ualloc(db_strings, strlen(p) + 1);
#else
AL_STR(ptr) = (char *)malloc(strlen(p) + 1);
#endif
#ifdef MEM_CHECK
add_check("ALIST");
add_check("attribute_value");
#endif
strcpy(AL_STR(ptr), p);
if(flags != NOTHING)
AL_FLAGS(ptr) |= flags;
AL_NEXT(ptr) = next;
return ptr;
}
void atr_new_add(thing, atr, s, player, flags)
dbref thing;
char *atr;
char *s;
dbref player;
dbref flags;
{
s = (char *) compress(s);
db[thing].list = AL_MAKE(atr, db[thing].list, s, player, flags);
}
int atr_add(thing, atr, s, player, flags)
dbref thing;
char *atr;
char *s;
dbref player;
dbref flags;
{
ALIST *ptr;
dbref privs;
if (thing == 0) {
privs = GOD; /* should only be hit by first couple objects */
db[player].owner = GOD;
}
else
privs = db[player].owner;
if(!s) s = (char *)"";
for (ptr = db[thing].list;
(ptr && string_compare(atr, AL_NAME(ptr)));
ptr = AL_NEXT(ptr));
if(!*s) {
if(ptr)
if(!Wizard(privs) &&
((AL_FLAGS(ptr) & AF_WIZARD) ||
((privs != db[AL_CREATOR(ptr)].owner) &&
(AL_FLAGS(ptr) & AF_LOCKED)))) {
return -1;
} else {
AL_DISPOSE(ptr);
return 1;
}
else
return 0;
}
s = (char *) compress(s);
if(!ptr) {
db[thing].list = AL_MAKE(atr, db[thing].list, s, privs, flags);
return 1;
} else {
if(!Wizard(privs) &&
((AL_FLAGS(ptr) & AF_WIZARD) ||
((privs != db[AL_CREATOR(ptr)].owner) &&
(AL_FLAGS(ptr) & AF_LOCKED)))) {
return -1;
} else {
const char *p;
#ifdef USE_NALLOC
na_unalloc(db_strings, (char *) AL_STR(ptr));
#else
free((char *) AL_STR(ptr));
#endif
#ifdef MEM_CHECK
del_check("attribute_value");
#endif
p = compress(s);
#ifdef USE_NALLOC
AL_STR(ptr) = (char *)na_ualloc(db_strings, strlen(p)+1);
#else
AL_STR(ptr) = (char *)malloc(strlen(p)+1);
#endif
#ifdef MEM_CHECK
add_check("attribute_value");
#endif
strcpy(AL_STR(ptr), p);
AL_CREATOR(ptr) = db[privs].owner;
if(flags != NOTHING)
AL_FLAGS(ptr) = flags;
if(AL_BAD(ptr))
AL_FLAGS(ptr) &= ~AF_NUKED;
return 1;
}
}
/*NOTREACHED*/
return 0;
}
ATTR *atr_get(thing, atr)
dbref thing;
char *atr;
{
ALIST *ptr;
if(thing == NOTHING || !atr) return NULL;
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
if(!AL_BAD(ptr) && !string_compare(AL_NAME(ptr), atr)) {
return AL_ATTR(ptr);
}
}
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
if(!AL_BAD(ptr) && string_prefix(AL_NAME(ptr), atr)) {
return(AL_ATTR(ptr));
}
}
return (ATTR *)NULL;
}
void free_attrib(thisattr)
ATTR *thisattr;
{
if (thisattr) {
#ifdef USE_NALLOC
if (thisattr->name)
na_unalloc(db_strings, (char *) thisattr->name);
if (thisattr->value)
na_unalloc(db_strings, (char *) thisattr->value);
na_unalloc(db_strings, (char *) thisattr);
#else
if (thisattr->name)
free((char *) thisattr->name);
if (thisattr->value)
free((char *) thisattr->value);
free((char *) thisattr);
#endif
}
#ifdef MEM_CHECK
del_check("attribute_name");
del_check("attribute_value");
del_check("attribute");
#endif
}
void atr_free(thing)
dbref thing;
{
ALIST *ptr, *next;
for(ptr = db[thing].list; ptr; ptr = next) {
next = AL_NEXT(ptr);
free_attrib(AL_ATTR(ptr));
#ifdef USE_NALLOC
na_unalloc(db_strings, (char *) ptr);
#else
free((char *) ptr);
#endif
#ifdef MEM_CHECK
del_check("ALIST");
#endif
}
db[thing].list = (ALIST *)NULL;
}
/* reconstruct an attribute list */
void atr_collect(thing)
dbref thing;
{
ALIST *ptr, *next;
ptr = db[thing].list;
db[thing].list = NULL;
while(ptr) {
if(!AL_BAD(ptr)) {
db[thing].list = AL_MAKE(AL_NAME(ptr), db[thing].list,
AL_STR(ptr), AL_CREATOR(ptr), AL_FLAGS(ptr));
}
next = AL_NEXT(ptr);
free_attrib(AL_ATTR(ptr));
#ifdef USE_NALLOC
na_unalloc(db_strings, (char *)ptr);
#else
free((char *) ptr);
#endif
#ifdef MEM_CHECK
del_check("ALIST");
#endif
ptr = next;
}
}
void atr_cpy(dest, source)
dbref dest, source;
{
ALIST *ptr;
ptr = db[source].list;
db[dest].list = NULL;
while(ptr) {
if(!AL_BAD(ptr)) {
db[dest].list = AL_MAKE(AL_NAME(ptr), db[dest].list,
AL_STR(ptr), AL_CREATOR(ptr), AL_FLAGS(ptr));
}
ptr = AL_NEXT(ptr);
}
}
const char *convert_atr(oldatr)
dbref oldatr;
{
const static char result[MAX_COMMAND_LEN];
int factor = 0;
switch(oldatr) {
case A_OSUCC:
return "OSUCCESS";
case A_OFAIL:
return "OFAILURE";
case A_FAIL:
return "FAILURE";
case A_SUCC:
return "SUCCESS";
case A_PASS:
return "XYXXY";
case A_DESC:
return "DESCRIBE";
case A_SEX:
return "SEX";
case A_ODROP:
return "ODROP";
case A_DROP:
return "DROP";
case A_OKILL:
return "OKILL";
case A_KILL:
return "KILL";
case A_ASUCC:
return "ASUCCESS";
case A_AFAIL:
return "AFAILURE";
case A_ADROP:
return "ADROP";
case A_AKILL:
return "AKILL";
case A_USE:
return "DOES";
case A_CHARGES:
return "CHARGES";
case A_RUNOUT:
return "RUNOUT";
case A_STARTUP:
return "STARTUP";
case A_ACLONE:
return "ACLONE";
case A_APAY:
return "APAYMENT";
case A_OPAY:
return "OPAYMENT";
case A_PAY:
return "PAYMENT";
case A_COST:
return "COST";
case A_RAND:
return "RAND";
case A_LISTEN:
return "LISTEN";
case A_AAHEAR:
return "AAHEAR";
case A_AMHEAR:
return "AMHEAR";
case A_AHEAR:
return "AHEAR";
case A_LAST:
return "LAST";
case A_QUEUE:
return "QUEUE";
case A_IDESC:
return "IDESCRIBE";
case A_ENTER:
return "ENTER";
case A_OXENTER:
return "OXENTER";
case A_AENTER:
return "AENTER";
case A_ADESC:
return "ADESCRIBE";
case A_ODESC:
return "ODESCRIBE";
case A_RQUOTA:
return "RQUOTA";
case A_ACONNECT:
return "ACONNECT";
case A_ADISCONNECT:
return "ADISCONNECT";
case A_LEAVE:
return "LEAVE";
case A_ALEAVE:
return "ALEAVE";
case A_OLEAVE:
return "OLEAVE";
case A_OENTER:
return "OENTER";
case A_OXLEAVE:
return "OXLEAVE";
default:
if(oldatr >= 100 && oldatr < 126)
factor = 0;
else if(oldatr >= 126 && oldatr < 152)
factor = 1;
else if(oldatr >= 152 && oldatr < 178)
factor = 2;
else {
fprintf(stderr,
"ERROR: Invalid attribute number in convert_atr. aborting.\n");
fflush(stderr);
abort();
}
sprintf((char *)result, "%c%c",
'V'+factor, oldatr - (100 + (factor * 26)) + 'A');
return result;
}
/*NOTREACHED*/
return "";
}
ATTR *atr_match(string)
char *string;
{
ATTR *a = attr;
while (a->name) {
if(!string_compare(string, a->name)) {
return a;
}
a++;
}
return (ATTR *)NULL;
}
int atr_comm_match(thing, player, type, end, str)
dbref thing, player;
char type, end;
char *str;
{
ALIST *ptr;
int match = 0;
char tbuf1[BUFFER_LEN];
char *s;
if(thing < 0 || thing >= db_top)
return 0;
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr)) {
if(!AL_BAD(ptr) && (*AL_STR(ptr) == type) && !(AL_FLAGS(ptr) & AF_NOPROG)){
strcpy(tbuf1, uncompress(AL_STR(ptr)));
for(s = tbuf1 + 1; *s && (*s != end); s++);
if(!*s)
continue;
*s++ = '\0';
if(wild_match(tbuf1 + 1, str)) {
match = 1;
if ((type == '$') &&
(!eval_boolexp(player, db[thing].usekey, thing, 0, USELOCK)))
notify(player, "Permission denied.");
else
parse_que(thing, s, player);
}
}
}
return match;
}
void do_atrlock(player, arg1, arg2)
dbref player;
const char *arg1, *arg2;
{
dbref thing;
char *p;
ALIST *ptr;
int status;
if(!arg2 || !*arg2)
status = 0;
else {
if(!string_compare(arg2, "on")) {
status = 1;
} else if(!string_compare(arg2, "off")) {
status = 2;
} else
status = 0;
}
if(!arg1 || !*arg1) {
notify(player, "You need to give an object/attribute pair.");
return;
}
if(!(p = index(arg1, '/')) || !(*(p+1))) {
notify(player, "You need to give an object/attribute pair.");
return;
}
*p++ = '\0';
init_match(player, arg1, NOTYPE);
match_everything();
if((thing = noisy_match_result()) == NOTHING)
return;
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr))
if(!AL_BAD(ptr) && !string_compare(AL_NAME(ptr), p))
break;
if(!ptr)
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr))
if(!AL_BAD(ptr) && string_prefix(AL_NAME(ptr), p))
break;
if(ptr) {
if(!status) {
notify(player, tprintf("That attribute is %slocked.",
(AL_FLAGS(ptr) & AF_LOCKED) ? "" : "un"));
return;
} else if(!Wizard(player) &&
(db[AL_CREATOR(ptr)].owner != db[player].owner)) {
notify(player, "You need to own the attribute to change its lock.");
return;
} else {
if(status == 1) {
AL_FLAGS(ptr) |= AF_LOCKED;
notify(player, "Attribute locked.");
return;
} else if(status == 2) {
AL_FLAGS(ptr) &= ~AF_LOCKED;
notify(player, "Attribute unlocked.");
return;
} else {
notify(player, "Invalid status on atrlock.. Notify god.");
return;
}
}
} else
notify(player, "No such attribute.");
return;
}
void do_atrchown(player, arg1, arg2)
dbref player;
const char *arg1, *arg2;
{
dbref thing, new_owner;
char *p;
ALIST *ptr;
if(!arg1 || !*arg1) {
notify(player, "You need to give an object/attribute pair.");
return;
}
if(!(p = index(arg1, '/')) || !(*(p+1))) {
notify(player, "You need to give an object/attribute pair.");
return;
}
*p++ = '\0';
init_match(player, arg1, NOTYPE);
match_everything();
if((thing = noisy_match_result()) == NOTHING)
return;
if((!arg2 && !*arg2) || !string_compare(arg2, "me"))
new_owner = player;
else
new_owner = lookup_player(arg2);
if(new_owner == NOTHING) {
notify(player, "I can't find that player");
return;
}
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr))
if(!AL_BAD(ptr) && !string_compare(AL_NAME(ptr), p))
break;
if(!ptr)
for(ptr = db[thing].list; ptr; ptr = AL_NEXT(ptr))
if(!AL_BAD(ptr) && string_prefix(AL_NAME(ptr), p))
break;
if(ptr) {
if((controls(player, thing) && !(AL_FLAGS(ptr) & AF_LOCKED)) ||
(db[player].owner == db[AL_CREATOR(ptr)].owner)) {
if(new_owner != db[thing].owner && !Wizard(player)) {
notify(player,
"You can only chown an attribute to the current owner of the object.");
return;
}
AL_CREATOR(ptr) = db[new_owner].owner;
notify(player, "Attribute owner changed.");
return;
} else {
notify(player, "You don't have the permission to chown that.");
return;
}
} else
notify(player, "No such attribute.");
}
ATTR *atr_complete_match(player, atr, privs)
dbref player;
char *atr;
dbref privs;
{
ATTR *a;
char *s = atr;
dbref thing;
if(*s == '_') s++;
if((a = atr_get(player, s)) != NULL) {
if(!controls(privs, player) &&
db[privs].owner != db[a->creator].owner &&
(a->flags & AF_ODARK)) {
DOLIST(thing, db[player].contents) {
if((a = atr_get(thing, s)) != NULL) {
if(!controls(privs, player) &&
db[privs].owner != db[a->creator].owner &&
(a->flags & AF_ODARK)) {
return NULL;
} else {
return a;
}
}
}
} else {
return a;
}
}
return NULL;
}