static void insert_prop(Objid oid, int pos, Pval pval) { Pval *new_propval; Object *o; int i, nprops; nprops = dbpriv_count_properties(oid); new_propval = mymalloc(nprops * sizeof(Pval), M_PVAL); o = dbpriv_find_object(oid); for (i = 0; i < pos; i++) new_propval[i] = o->propval[i]; new_propval[pos] = pval; new_propval[pos].var = var_ref(pval.var); if (new_propval[pos].perms & PF_CHOWN) new_propval[pos].owner = o->owner; for (i = pos + 1; i < nprops; i++) new_propval[i] = o->propval[i - 1]; if (o->propval) myfree(o->propval, M_PVAL); o->propval = new_propval; }
int db_object_bytes(Objid oid) { Object *o = objects[oid]; int i, len, count; Verbdef *v; count = sizeof(Object) + sizeof(Object *); count += memo_strlen(o->name) + 1; for (v = o->verbdefs; v; v = v->next) { count += sizeof(Verbdef); count += memo_strlen(v->name) + 1; if (v->program) count += program_bytes(v->program); } count += sizeof(Propdef) * o->propdefs.cur_length; for (i = 0; i < o->propdefs.cur_length; i++) count += memo_strlen(o->propdefs.l[i].name) + 1; len = dbpriv_count_properties(oid); count += (sizeof(Pval) - sizeof(Var)) * len; for (i = 0; i < len; i++) count += value_bytes(o->propval[i].var); return count; }
static void write_object(Objid oid) { Object *o; Verbdef *v; int i; int nverbdefs, nprops; if (!valid(oid)) { dbio_printf("#%d recycled\n", oid); return; } o = dbpriv_find_object(oid); dbio_printf("#%d\n", oid); dbio_write_string(o->name); dbio_write_string(""); /* placeholder for old handles string */ dbio_write_num(o->flags); dbio_write_objid(o->owner); dbio_write_objid(o->location); dbio_write_objid(o->contents); dbio_write_objid(o->next); dbio_write_objid(o->parent); dbio_write_objid(o->child); dbio_write_objid(o->sibling); for (v = o->verbdefs, nverbdefs = 0; v; v = v->next) nverbdefs++; dbio_write_num(nverbdefs); for (v = o->verbdefs; v; v = v->next) write_verbdef(v); dbio_write_num(o->propdefs.cur_length); for (i = 0; i < o->propdefs.cur_length; i++) write_propdef(&o->propdefs.l[i]); nprops = dbpriv_count_properties(oid); dbio_write_num(nprops); for (i = 0; i < nprops; i++) write_propval(o->propval + i); }
Objid db_renumber_object(Objid old) { Objid newbie; Object *o; db_priv_affected_callable_verb_lookup(); for (newbie = 0; newbie < old; newbie++) { if (objects[newbie] == 0) { /* Change the identity of the object. */ o = objects[newbie] = objects[old]; objects[old] = 0; objects[newbie]->id = newbie; /* Fix up the parent/children hierarchy */ { Objid oid, *oidp; if (o->parent != NOTHING) { oidp = &objects[o->parent]->child; while (*oidp != old && *oidp != NOTHING) oidp = &objects[*oidp]->sibling; if (*oidp == NOTHING) panic("Object not in parent's children list"); *oidp = newbie; } for (oid = o->child; oid != NOTHING; oid = objects[oid]->sibling) objects[oid]->parent = newbie; } /* Fix up the location/contents hierarchy */ { Objid oid, *oidp; if (o->location != NOTHING) { oidp = &objects[o->location]->contents; while (*oidp != old && *oidp != NOTHING) oidp = &objects[*oidp]->next; if (*oidp == NOTHING) panic("Object not in location's contents list"); *oidp = newbie; } for (oid = o->contents; oid != NOTHING; oid = objects[oid]->next) objects[oid]->location = newbie; } /* Fix up the list of users, if necessary */ if (is_user(newbie)) { int i; for (i = 1; i <= all_users.v.list[0].v.num; i++) if (all_users.v.list[i].v.obj == old) { all_users.v.list[i].v.obj = newbie; break; } } /* Fix the owners of verbs, properties and objects */ { Objid oid; for (oid = 0; oid < num_objects; oid++) { Object *o = objects[oid]; Verbdef *v; Pval *p; int i, count; if (!o) continue; if (o->owner == newbie) o->owner = NOTHING; else if (o->owner == old) o->owner = newbie; for (v = o->verbdefs; v; v = v->next) if (v->owner == newbie) v->owner = NOTHING; else if (v->owner == old) v->owner = newbie; count = dbpriv_count_properties(oid); p = o->propval; for (i = 0; i < count; i++) if (p[i].owner == newbie) p[i].owner = NOTHING; else if (p[i].owner == old) p[i].owner = newbie; } } return newbie; } } /* There are no recycled objects less than `old', so keep its number. */ return old; }