/** * Calculates the size of the given property directory AVL list. This * will iterate over the entire structure to give the entire size. It * is the low level equivalent of size_properties * * @see size_properties * * @param avl the Property directory AVL to check * @return the size of the loaded properties in memory -- this does NOT * do any diskbase loading. */ size_t size_proplist(PropPtr avl) { size_t bytes = 0; if (!avl) return 0; bytes += sizeof(struct plist); bytes += strlen(PropName(avl)); if (!(PropFlags(avl) & PROP_ISUNLOADED)) { switch (PropType(avl)) { case PROP_STRTYP: bytes += strlen(PropDataStr(avl)) + 1; break; case PROP_LOKTYP: bytes += size_boolexp(PropDataLok(avl)); break; default: break; } } bytes += size_proplist(avl->left); bytes += size_proplist(avl->right); bytes += size_proplist(PropDir(avl)); return bytes; }
void free_propnode(PropPtr p) { if (!(PropFlags(p) & PROP_ISUNLOADED)) { if (PropType(p) == PROP_STRTYP) free((void *) PropDataStr(p)); if (PropType(p) == PROP_LOKTYP) free_boolexp(PropDataLok(p)); } free(p); }
char * displayprop(dbref player, dbref obj, const char *name, char *buf) { char mybuf[BUFFER_LEN], tbuf[BUFFER_LEN]; int pdflag; PropPtr p = get_property(obj, name); if (!p) { sprintf(buf, SYSGLOOM "%s: No such property.", name); return buf; } #ifdef DISKBASE propfetch(obj, p); #endif pdflag = (PropDir(p) != NULL); sprintf(tbuf, "%.*s%c", (BUFFER_LEN / 4), name, (pdflag) ? PROPDIR_DELIMITER : '\0'); tct(tbuf, mybuf); switch (PropType(p)) { case PROP_STRTYP: sprintf(buf, SYSAQUA "str " SYSGREEN "%s" SYSRED ":" SYSCYAN "%.*s", mybuf, (BUFFER_LEN / 2), tct(PropDataUNCStr(p), tbuf)); break; case PROP_REFTYP: sprintf(buf, SYSBROWN "ref " SYSGREEN "%s" SYSRED ":%s", mybuf, ansi_unparse_object(player, PropDataRef(p))); break; case PROP_INTTYP: sprintf(buf, SYSFOREST "int " SYSGREEN "%s" SYSRED ":" SYSYELLOW "%d", mybuf, PropDataVal(p)); break; case PROP_FLTTYP: sprintf(buf, SYSNAVY "flt " SYSGREEN "%s" SYSRED ":" SYSBROWN "%.15g", mybuf, PropDataFVal(p)); break; case PROP_LOKTYP: if (PropFlags(p) & PROP_ISUNLOADED) { sprintf(buf, SYSCRIMSON "lok " SYSGREEN "%s" SYSRED ":" SYSPURPLE "*UNLOCKED*", mybuf); } else { sprintf(buf, SYSCRIMSON "lok " SYSGREEN "%s" SYSRED ":" SYSPURPLE "%.*s", mybuf, (BUFFER_LEN / 2), tct(unparse_boolexp(player, PropDataLok(p), 1), tbuf)); } break; case PROP_DIRTYP: sprintf(buf, SYSWHITE "dir " SYSGREEN "%s" SYSRED ":", mybuf); break; } return buf; }
void clear_propnode(PropPtr p) { if (!(PropFlags(p) & PROP_ISUNLOADED)) { if (PropType(p) == PROP_STRTYP) { free((void *) PropDataStr(p)); PropDataStr(p) = NULL; } if (PropType(p) == PROP_LOKTYP) free_boolexp(PropDataLok(p)); } SetPDataVal(p, 0); SetPFlags(p, (PropFlags(p) & ~PROP_ISUNLOADED)); SetPType(p, PROP_DIRTYP); }
/* return boolexp lock of property */ struct boolexp * get_property_lock(dbref player, const char *pclass) { PropPtr p; p = get_property(player, pclass); if (!p) return TRUE_BOOLEXP; #ifdef DISKBASE propfetch(player, p); if (PropFlags(p) & PROP_ISUNLOADED) return TRUE_BOOLEXP; #endif if (PropType(p) != PROP_LOKTYP) return TRUE_BOOLEXP; return PropDataLok(p); }
/* copies properties */ void copy_proplist(dbref obj, PropPtr * nu, PropPtr old) { PropPtr p; if (old) { #ifdef DISKBASE propfetch(obj, old); #endif p = new_prop(nu, PropName(old)); SetPFlagsRaw(p, PropFlagsRaw(old)); switch (PropType(old)) { case PROP_STRTYP: SetPDataStr(p, alloc_string(PropDataStr(old))); break; case PROP_LOKTYP: if (PropFlags(old) & PROP_ISUNLOADED) { SetPDataLok(p, TRUE_BOOLEXP); SetPFlags(p, (PropFlags(p) & ~PROP_ISUNLOADED)); } else { SetPDataLok(p, copy_bool(PropDataLok(old))); } break; case PROP_DIRTYP: SetPDataVal(p, 0); break; case PROP_FLTTYP: SetPDataFVal(p, PropDataFVal(old)); break; default: SetPDataVal(p, PropDataVal(old)); break; } copy_proplist(obj, &PropDir(p), PropDir(old)); copy_proplist(obj, &AVL_LF(p), AVL_LF(old)); copy_proplist(obj, &AVL_RT(p), AVL_RT(old)); /* copy_proplist(obj, nu, AVL_LF(old)); copy_proplist(obj, nu, AVL_RT(old)); */ } }
/** * This is the opposite of alloc_propnode, and is used to free the * PropPtr datastructure. It will free whatever data is associated * with the prop as well as the PropPtr as well. * * @param node the prop to free */ void free_propnode(PropPtr p) { if (!(PropFlags(p) & PROP_ISUNLOADED)) { if (PropType(p) == PROP_STRTYP) free(PropDataStr(p)); if (PropType(p) == PROP_LOKTYP) free_boolexp(PropDataLok(p)); } /* @TODO: The PropPtr object has a 'key' field which is * set up like char key[1]; In alloc_propnode, we use * strncpy to copy the name of the prop to the key field. * * I should think we would need to free the key or we would * have a leak. However, I should have also thought the key * should be a char* ... I don't actually understand how this * works. It seems like it should be segfaulting and/or * leaking memory. I want to review this in greater depth * later. */ free(p); }
void db_putprop(FILE * f, const char *dir, PropPtr p) { char buf[BUFFER_LEN * 2]; char fbuf[BUFFER_LEN]; char num[16]; char *ptr; const char *ptr2; if (PropType(p) == PROP_DIRTYP) return; for (ptr = buf, ptr2 = dir + 1; *ptr2;) *ptr++ = *ptr2++; for (ptr2 = PropName(p); *ptr2;) *ptr++ = *ptr2++; *ptr++ = PROP_DELIMITER; ptr2 = intostr(num, PropFlagsRaw(p) & ~(PROP_TOUCHED | PROP_ISUNLOADED | PROP_NOASCIICHK)); while (*ptr2) *ptr++ = *ptr2++; *ptr++ = PROP_DELIMITER; ptr2 = ""; switch (PropType(p)) { case PROP_INTTYP: if (!PropDataVal(p)) return; ptr2 = intostr(num, PropDataVal(p)); break; case PROP_FLTTYP: if (!PropDataFVal(p)) return; ptr2 = fltostr(fbuf, PropDataFVal(p)); break; case PROP_REFTYP: if (PropDataRef(p) == NOTHING) return; ptr2 = intostr(num, (int) PropDataRef(p)); break; case PROP_STRTYP: if (!*PropDataStr(p)) return; if (db_decompression_flag) { ptr2 = PropDataUNCStr(p); } else { ptr2 = PropDataStr(p); } break; case PROP_LOKTYP: if (PropFlags(p) & PROP_ISUNLOADED) return; if (PropDataLok(p) == TRUE_BOOLEXP) return; ptr2 = unparse_boolexp((dbref) 1, PropDataLok(p), 0); break; } while (*ptr2) if (*ptr2 != '\n') *ptr++ = *ptr2++; else { *ptr++ = '\\'; *ptr++ = 'n'; ptr2++; } *ptr++ = '\n'; *ptr++ = '\0'; if (fputs(buf, f) == EOF) { fprintf(stderr, "PANIC: Unable to write to db to write prop.\n"); abort(); } }
void prim_array_filter_prop(PRIM_PROTOTYPE) { char pattern[BUFFER_LEN]; char tname[BUFFER_LEN]; struct inst *in; struct inst temp1; stk_array *arr; stk_array *nu; char* prop; int len; CHECKOP(3); oper3 = POP(); /* str pattern */ oper2 = POP(); /* str propname */ oper1 = POP(); /* refarr Array */ if (oper1->type != PROG_ARRAY) abort_interp("Argument not an array. (1)"); if (!array_is_homogenous(oper1->data.array, PROG_OBJECT)) abort_interp("Argument not an array of dbrefs. (1)"); if (oper2->type != PROG_STRING || !oper2->data.string) abort_interp("Argument not a non-null string. (2)"); if (oper3->type != PROG_STRING) abort_interp("Argument not a string pattern. (3)"); len = oper2->data.string ? oper2->data.string->length : 0; strcpyn(tname, sizeof(tname), DoNullInd(oper2->data.string)); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } nu = new_array_packed(0); arr = oper1->data.array; prop = tname; strcpyn(pattern, sizeof(pattern), DoNullInd(oper3->data.string)); if (array_first(arr, &temp1)) { do { in = array_getitem(arr, &temp1); if (valid_object(in)) { ref = in->data.objref; CHECKREMOTE(ref); if (prop_read_perms(ProgUID, ref, prop, mlev)) { PropPtr pptr = get_property(ref, prop); if (pptr) { switch(PropType(pptr)) { case PROP_STRTYP: strncpy(buf, PropDataStr(pptr), BUFFER_LEN); break; case PROP_LOKTYP: if (PropFlags(pptr) & PROP_ISUNLOADED) { strncpy(buf, "*UNLOCKED*", BUFFER_LEN); } else { strncpy(buf, unparse_boolexp(ProgUID, PropDataLok(pptr), 0), BUFFER_LEN); } break; case PROP_REFTYP: snprintf(buf, BUFFER_LEN, "#%i", PropDataRef(pptr)); break; case PROP_INTTYP: snprintf(buf, BUFFER_LEN, "%i", PropDataVal(pptr)); break; case PROP_FLTTYP: snprintf(buf, BUFFER_LEN, "%g", PropDataFVal(pptr)); break; default: strncpy(buf, "", BUFFER_LEN); break; } } else strncpy(buf, "", BUFFER_LEN); if (equalstr(pattern, buf)) { array_appenditem(&nu, in); } } } } while (array_next(arr, &temp1)); } CLEAR(oper3); CLEAR(oper2); CLEAR(oper1); PushArrayRaw(nu); }
void prim_envpropstr(PRIM_PROTOTYPE) { CHECKOP(2); oper1 = POP(); oper2 = POP(); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (!oper1->data.string) abort_interp("Empty string argument (2)"); if (!valid_object(oper2)) abort_interp("Non-object argument (1)"); CHECKREMOTE(oper2->data.objref); { char tname[BUFFER_LEN]; dbref what; PropPtr ptr; const char *temp; int len = oper1->data.string->length; strcpyn(tname, sizeof(tname), oper1->data.string->data); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } what = oper2->data.objref; ptr = envprop(&what, tname, 0); if (!ptr) { temp = ""; } else { #ifdef DISKBASE propfetch(what, ptr); #endif switch (PropType(ptr)) { case PROP_STRTYP: temp = PropDataStr(ptr); break; /* *case PROP_INTTYP: * snprintf(buf, sizeof(buf), "%d", PropDataVal(ptr)); * temp = buf; * break; */ case PROP_REFTYP: snprintf(buf, sizeof(buf), "#%d", PropDataRef(ptr)); temp = buf; break; case PROP_LOKTYP: if (PropFlags(ptr) & PROP_ISUNLOADED) { temp = "*UNLOCKED*"; } else { temp = unparse_boolexp(ProgUID, PropDataLok(ptr), 1); } break; default: temp = ""; break; } } #ifdef LOG_PROPS log2file("props.log", "#%d (%d) ENVPROPSTR: o=%d so=%d n=\"%s\" s=\"%s\"", program, pc->line, what, oper2->data.objref, tname, temp); #endif if (what != NOTHING) { if (!prop_read_perms(ProgUID, what, oper1->data.string->data, mlev)) abort_interp("Permission denied."); /* if (Typeof(what) != TYPE_PLAYER) * ts_lastuseobject(what); */ } CLEAR(oper1); CLEAR(oper2); PushObject(what); PushString(temp); } }
void prim_envprop(PRIM_PROTOTYPE) { double fresult; CHECKOP(2); oper1 = POP(); oper2 = POP(); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (!oper1->data.string) abort_interp("Empty string argument (2)"); if (!valid_object(oper2)) abort_interp("Non-object argument (1)"); CHECKREMOTE(oper2->data.objref); { char tname[BUFFER_LEN]; dbref what; PropPtr ptr; int len = oper1->data.string->length; strcpyn(tname, sizeof(tname), oper1->data.string->data); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } what = oper2->data.objref; ptr = envprop(&what, tname, 0); if (what != NOTHING) { if (!prop_read_perms(ProgUID, what, oper1->data.string->data, mlev)) abort_interp("Permission denied."); } CLEAR(oper1); CLEAR(oper2); PushObject(what); if (!ptr) { result = 0; PushInt(result); } else { #ifdef DISKBASE propfetch(what, ptr); #endif switch (PropType(ptr)) { case PROP_STRTYP: PushString(PropDataStr(ptr)); break; case PROP_INTTYP: result = PropDataVal(ptr); PushInt(result); break; case PROP_FLTTYP: fresult = PropDataFVal(ptr); PushFloat(fresult); break; case PROP_REFTYP: ref = PropDataRef(ptr); PushObject(ref); break; case PROP_LOKTYP: if (PropFlags(ptr) & PROP_ISUNLOADED) { PushLock(TRUE_BOOLEXP); } else { PushLock(PropDataLok(ptr)); } break; default: result = 0; PushInt(result); break; } } } }
void prim_getprop(PRIM_PROTOTYPE) { const char *temp; PropPtr prptr; dbref obj2; CHECKOP(2); oper1 = POP(); oper2 = POP(); if (oper1->type != PROG_STRING) abort_interp("Non-string argument (2)"); if (!oper1->data.string) abort_interp("Empty string argument (2)"); if (!valid_object(oper2)) abort_interp("Non-object argument (1)"); CHECKREMOTE(oper2->data.objref); { char type[BUFFER_LEN]; int len = oper1->data.string->length; if (!prop_read_perms(ProgUID, oper2->data.objref, oper1->data.string->data, mlev)) abort_interp("Permission denied."); strcpyn(type, sizeof(type), oper1->data.string->data); while (len-- > 0 && type[len] == PROPDIR_DELIMITER) { type[len] = '\0'; } obj2 = oper2->data.objref; prptr = get_property(obj2, type); #ifdef LOG_PROPS log2file("props.log", "#%d (%d) GETPROP: o=%d n=\"%s\"", program, pc->line, oper2->data.objref, type); #endif CLEAR(oper1); CLEAR(oper2); if (prptr) { #ifdef DISKBASE propfetch(obj2, prptr); #endif switch (PropType(prptr)) { case PROP_STRTYP: temp = PropDataStr(prptr); PushString(temp); break; case PROP_LOKTYP: if (PropFlags(prptr) & PROP_ISUNLOADED) { PushLock(TRUE_BOOLEXP); } else { PushLock(PropDataLok(prptr)); } break; case PROP_REFTYP: PushObject(PropDataRef(prptr)); break; case PROP_INTTYP: PushInt(PropDataVal(prptr)); break; case PROP_FLTTYP: PushFloat(PropDataFVal(prptr)); break; default: result = 0; PushInt(result); break; } } else { result = 0; PushInt(result); } /* if (Typeof(oper2->data.objref) != TYPE_PLAYER) ts_lastuseobject(oper2->data.objref); */ } }