/* atr_tab.c */ #include "config.h" #ifdef I_STRING #include <string.h> #else #include <strings.h> #endif #ifdef I_STDLIB #include <stdlib.h> #endif #include <stdio.h> #include "conf.h" #include "externs.h" #include "atr_tab.h" #include "htab.h" #include "privtab.h" #include "mymalloc.h" #include "confmagic.h" typedef struct atr_alias ATRALIAS; struct atr_alias { const char *alias; const char *realname; }; HASHTAB htab_attrib; PRIV attr_privs[] = { {"no_command", '$', AF_NOPROG, AF_NOPROG}, {"no_inherit", 'i', AF_PRIVATE, AF_PRIVATE}, {"private", 'i', AF_PRIVATE, AF_PRIVATE}, {"no_clone", 'c', AF_NOCOPY, AF_NOCOPY}, {"wizard", 'w', AF_WIZARD, AF_WIZARD}, {"visual", 'v', AF_VISUAL, AF_VISUAL}, {"mortal_dark", 'm', AF_MDARK, AF_MDARK}, {"hidden", 'm', AF_MDARK, AF_MDARK}, {"regexp", 'R', AF_REGEXP, AF_REGEXP}, {NULL, '\0', 0, 0} }; ATTR *aname_hash_lookup _((const char *name)); void init_aname_hashtab _((void)); extern char *strdup _((const char *)); void do_attribute_access _((dbref player, char *name, char *perms, int retroactive)); void do_attribute_delete _((dbref player, char *name)); void do_attribute_rename _((dbref player, char *old, char *new)); void do_attribute_info _((dbref player, char *name)); void do_list_attribs _((dbref player)); /* this table can be expanded as necessary */ static ATRALIAS atr_alias_tab[] = { {"ACONN", "ACONNECT"}, {"ACON", "ACONNECT"}, {"ADEST", "ADESTROY"}, {"ADESTR", "ADESTROY"}, {"ADESTRO", "ADESTROY"}, {"ADESC", "ADESCRIBE"}, {"ADESCR", "ADESCRIBE"}, {"ADESCRI", "ADESCRIBE"}, {"ADISC", "ADISCONNECT"}, {"ADISCON", "ADISCONNECT"}, {"ADISCONN", "ADISCONNECT"}, {"AFAIL", "AFAILURE"}, {"AIDESC", "AIDESCRIBE"}, {"AIDESCR", "AIDESCRIBE"}, {"AIDESCRI", "AIDESCRIBE"}, {"APAY", "APAYMENT"}, {"ASUCC", "ASUCCESS"}, {"DESC", "DESCRIBE"}, {"DESCR", "DESCRIBE"}, {"DESCRI", "DESCRIBE"}, {"FAIL", "FAILURE"}, {"FILTE", "FILTER"}, {"FILT", "FILTER"}, {"FIL", "FILTER"}, {"IDESC", "IDESCRIBE"}, {"IDESCR", "IDESCRIBE"}, {"IDESCRI", "IDESCRIBE"}, {"INFILTE", "INFILTER"}, {"INFILT", "INFILTER"}, {"INFIL", "INFILTER"}, {"INFI", "INFILTER"}, {"INF", "INFILTER"}, {"INPREFI", "INPREFIX"}, {"INPREF", "INPREFIX"}, {"INPRE", "INPREFIX"}, {"INPR", "INPREFIX"}, {"INP", "INPREFIX"}, #ifdef USE_MAILER {"MAILFILTER", "MAILFILTERS"}, {"MAILFILT", "MAILFILTERS"}, {"MAILFIL", "MAILFILTERS"}, {"MAILFI", "MAILFILTERS"}, {"MAILFOLDER", "MAILFOLDERS"}, {"MAILFOLD", "MAILFOLDERS"}, {"MAILFOL", "MAILFOLDERS"}, {"MAILFO", "MAILFOLDERS"}, {"MAILSIGNATUR", "MAILSIGNATURE"}, {"MAILSIGNATU", "MAILSIGNATURE"}, {"MAILSIGNAT", "MAILSIGNATURE"}, {"MAILSIGNA", "MAILSIGNATURE"}, {"MAILSIGN", "MAILSIGNATURE"}, {"MAILSIG", "MAILSIGNATURE"}, {"MAILSI", "MAILSIGNATURE"}, #endif {"ODESC", "ODESCRIBE"}, {"ODESCR", "ODESCRIBE"}, {"ODESCRI", "ODESCRIBE"}, {"OFAIL", "OFAILURE"}, {"OIDESC", "OIDESCRIBE"}, {"OIDESCR", "OIDESCRIBE"}, {"OIDESCRI", "OIDESCRIBE"}, {"OPAY", "OPAYMENT"}, {"OSUCC", "OSUCCESS"}, {"PAY", "PAYMENT"}, {"PREFI", "PREFIX"}, {"PREF", "PREFIX"}, {"PRE", "PREFIX"}, {"SUCC", "SUCCESS"}, {NULL, NULL} }; /*---------------------------------------------------------------------- * Hash functions of various sorts */ ATTR * aname_hash_lookup(name) const char *name; { /* given an attribute name, look it up in the complete attribute table * (real names plus aliases), and return the appropriate real attribute. */ return (ATTR *) hashfind((char *) strupper(name), &htab_attrib); } void init_aname_hashtab() { ATTR *ap; ATRALIAS *aliasp; hashinit(&htab_attrib, 256); /* build the basic hash table */ for (ap = attr; ap->name; ap++) hashadd(ap->name, (void *) ap, &htab_attrib); /* now add in aliases */ for (aliasp = atr_alias_tab; aliasp->alias; aliasp++) { if ((ap = aname_hash_lookup(aliasp->realname)) != NULL) hashadd(aliasp->alias, (void *) ap, &htab_attrib); else fprintf(stderr, "ATR INIT: attribute alias %s matches no known attribute.\n", aliasp->alias); } } /* Add an attribute to the hash table, given its name and permissions */ void do_attribute_access(player, name, perms, retroactive) dbref player; char *name; char *perms; int retroactive; { ATTR *ap; int flags = 0; int i; /* Parse name and perms */ if (!name || !*name) { notify(player, "Which attribute do you mean?"); return; } flags = string_to_privs(attr_privs, perms, 0); if (!flags) { notify(player, "I don't understand those permissions."); return; } upcasestr(name); /* Is this attribute already in the table? */ ap = aname_hash_lookup(name); if (ap) { /* Already in the table, so we must delete before we add */ hashdelete(name, &htab_attrib); } else { /* Create fresh */ ap = (ATTR *) mush_malloc(sizeof(ATTR), "ATTR"); if (!ap) { notify(player, "Critical memory failure - Alert God!"); do_log(LT_ERR, 0, 0, "do_attribute_access: unable to malloc ATTR"); return; } AL_NAME(ap) = strdup(name); AL_STR(ap) = NULL; } AL_FLAGS(ap) = flags; AL_CREATOR(ap) = player; hashadd(name, (void *) ap, &htab_attrib); /* If we've been given the RETROACTIVE switch, we must set these * permissions on every object that has the attribute in question. */ for (i = 0; i < db_top; i++) { if ((ap = atr_get_noparent(i, name))) { AL_FLAGS(ap) = flags; AL_CREATOR(ap) = player; } } notify(player, tprintf("%s -- Attribute permissions now: %s", name, privs_to_string(attr_privs, flags))); } void do_attribute_delete(player, name) dbref player; char *name; { ATTR *ap; if (!name || !*name) { notify(player, "Which attribute do you mean?"); return; } upcasestr(name); /* Is this attribute in the table? */ ap = aname_hash_lookup(name); if (!ap) { notify(player, "That attribute isn't in the attribute table"); return; } /* Ok, take it out */ hashdelete(name, &htab_attrib); notify(player, tprintf("Removed %s from attribute table.", name)); return; } void do_attribute_rename(player, old, new) dbref player; char *old; char *new; { ATTR *ap; if (!old || !*old || !new || !*new) { notify(player, "Which attributes do you mean?"); return; } upcasestr(old); upcasestr(new); /* Is the new name already in use? */ ap = aname_hash_lookup(new); if (ap) { notify(player, tprintf("The name %s is already used in the attribute table.", new)); return; } /* Is the old name a real attribute? */ ap = aname_hash_lookup(old); if (!ap) { notify(player, "That attribute isn't in the attribute table"); return; } /* Ok, take it out and put it back under the new name */ hashdelete(old, &htab_attrib); hashadd(new, (void *) ap, &htab_attrib); notify(player, tprintf("Renamed %s to %s in attribute table.", old, new)); return; } /* Info on an attribute in the table */ void do_attribute_info(player, name) dbref player; char *name; { ATTR *ap; if (!name || !*name) { notify(player, "Which attribute do you mean?"); return; } upcasestr(name); /* Is this attribute in the table? */ ap = aname_hash_lookup(name); if (!ap) { notify(player, "That attribute isn't in the attribute table"); return; } notify(player, tprintf("Attribute: %s", AL_NAME(ap))); notify(player, tprintf(" Flags: %s", privs_to_string(attr_privs, AL_FLAGS(ap)))); notify(player, tprintf(" Creator: #%d", AL_CREATOR(ap))); return; } void do_list_attribs(player) dbref player; { ATTR *ap; char *ptrs[BUFFER_LEN / 2]; char buff[BUFFER_LEN]; char *bp; int nptrs = 0, i; HASHTAB temp; hashinit(&temp, 256); ap = hash_firstentry(&htab_attrib); while (ap) { hashadd(ap->name, (void *) ap->name, &temp); ap = hash_nextentry(&htab_attrib); } bp = hash_firstentry(&temp); while (bp) { ptrs[nptrs++] = (char *) bp; bp = hash_nextentry(&temp); } do_gensort(ptrs, nptrs, 0); bp = buff; safe_str("Attribs:", buff, &bp); for (i = 0; i < nptrs; i++) { safe_chr(' ', buff, &bp); safe_str(ptrs[i], buff, &bp); } *bp = '\0'; notify(player, buff); hashfree(&temp); }