*** db.h Sun Mar 2 23:18:26 1997 --- db.h Sun Oct 26 07:08:08 1997 *************** *** 336,342 **** VF_READ = 01, VF_WRITE = 02, VF_EXEC = 04, ! VF_DEBUG = 010 } db_verb_flag; typedef enum { --- 336,345 ---- VF_READ = 01, VF_WRITE = 02, VF_EXEC = 04, ! /*** -o_Verbs Patch ***/ ! VF_DEBUG = 010, ! VF_NOT_O = 02000 ! /*** end -o_Verbs Patch ***/ } db_verb_flag; typedef enum { *** db_verbs.c Sun Sep 7 19:58:37 1997 --- db_verbs.c Tue Jan 20 16:57:40 1998 *************** *** 192,198 **** #define DOBJSHIFT 4 #define IOBJSHIFT 6 #define OBJMASK 0x3 ! #define PERMMASK 0xF void db_add_verb(Objid oid, const char *vnames, Objid owner, unsigned flags, --- 192,200 ---- #define DOBJSHIFT 4 #define IOBJSHIFT 6 #define OBJMASK 0x3 ! /*** -o_Verbs Patch ***/ ! #define PERMMASK 0x70F ! /*** end -o_Verbs Patch ***/ void db_add_verb(Objid oid, const char *vnames, Objid owner, unsigned flags, *** objects.c Sun Jul 6 23:24:54 1997 --- objects.c Sun Nov 23 11:27:01 1997 *************** *** 27,32 **** --- 27,35 ---- #include "storage.h" #include "structures.h" #include "utils.h" + /*** -o_Verbs Patch ***/ + #include "verbs.h" + /*** end -o_Verbs Patch ***/ static int controls(Objid who, Objid what) *************** *** 329,334 **** --- 333,342 ---- if (oid == what) return make_error_pack(E_RECMOVE); + /*** -o_Verbs Patch ***/ + if (check_verbs_before_chparent(&parent, what)) + return make_error_pack(E_INVARG); + /*** end -o_Verbs Patch ***/ if (!db_change_parent(what, parent)) return make_error_pack(E_INVARG); else *** verbs.c Sun Mar 2 23:19:37 1997 --- verbs.c Sun Oct 26 07:40:02 1997 *************** *** 88,115 **** if (!valid(*owner)) return E_INVARG; ! for (*flags = 0, s = v.v.list[2].v.str; *s; s++) { ! switch (*s) { ! case 'r': ! case 'R': ! *flags |= VF_READ; ! break; ! case 'w': ! case 'W': ! *flags |= VF_WRITE; ! break; ! case 'x': ! case 'X': ! *flags |= VF_EXEC; ! break; ! case 'd': ! case 'D': ! *flags |= VF_DEBUG; ! break; ! default: ! return E_INVARG; } ! } *names = v.v.list[3].v.str; while (**names == ' ') --- 88,120 ---- if (!valid(*owner)) return E_INVARG; ! /*** -o_Verbs Patch ***/ ! if (server_flag_option("use_blocked_notation")) { ! for (*flags = 0, s = v.v.list[2].v.str; *s; s++) { ! switch (*s) { ! case 'r': case 'R': *flags |= VF_READ; break; ! case 'w': case 'W': *flags |= VF_WRITE; break; ! case 'x': case 'X': *flags |= VF_EXEC; break; ! case 'd': case 'D': *flags |= VF_DEBUG; break; ! case 'b': case 'B': *flags |= VF_NOT_O; break; ! default: ! return E_INVARG; ! } ! } ! } else { ! for (*flags = 0, *flags |= VF_NOT_O, s = v.v.list[2].v.str; *s; s++) { ! switch (*s) { ! case 'r': case 'R': *flags |= VF_READ; break; ! case 'w': case 'W': *flags |= VF_WRITE; break; ! case 'x': case 'X': *flags |= VF_EXEC; break; ! case 'd': case 'D': *flags |= VF_DEBUG; break; ! case 'o': case 'O': *flags &= ~VF_NOT_O; break; ! default: ! return E_INVARG; ! } ! } } ! /*** end -o_Verbs Patch ***/ *names = v.v.list[3].v.str; while (**names == ' ') *************** *** 170,175 **** --- 175,371 ---- return E_NONE; } + /*** -o_Verbs Patch ***/ + static const char cmap[] = + "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" + "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" + "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057" + "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077" + "\100\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" + "\160\161\162\163\164\165\166\167\170\171\172\133\134\135\136\137" + "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" + "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177" + "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" + "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" + "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" + "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" + "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" + "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" + "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" + "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"; + + static int + single_names_share_namespace(const char * cfoo, const char *cfend, const char * cbar, const char *cbend) { + int foostar, barstar; + const unsigned char *foo = (const unsigned char *) cfoo; + const unsigned char *bar = (const unsigned char *) cbar; + const unsigned char *fend = (const unsigned char *) cfend; + const unsigned char *bend = (const unsigned char *) cbend; + + while (foo[0] != '*' && bar[0] != '*') { + if (foo == fend && bar == bend) + return 1; + else if (foo == fend || bar == bend) + return 0; + else if (cmap[*foo] != cmap[*bar]) + return 0; + + foo++; + bar++; + } + + foostar = (foo[0] == '*'); + barstar = (bar[0] == '*'); + + while (foostar && !barstar) { + while (foo != fend && bar != bend && bar[0] != '*') { + if (foo[0] == '*') { + foo++; + continue; + } + if (cmap[foo[0]] != cmap[bar[0]]) + return 0; + foo++; + bar++; + } + if (bar == bend) + return 1; + else if (bar[0] == '*') + barstar = 1; + else + return foo[-1] == '*'; + } + + while (!foostar && barstar) { + while (foo != fend && bar != bend && foo[0] != '*') { + if (bar[0] == '*') { + bar++; + continue; + } + if (cmap[foo[0]] != cmap[bar[0]]) + return 0; + foo++; + bar++; + } + if (foo == fend) + return 1; + else if (foo[0] == '*') + barstar = 1; + else + return bar[-1] == '*'; + } + + while (foo != fend && bar != bend) { + if (foo[0] == '*') { + foo++; + continue; + } + if (bar[0] == '*') { + bar++; + continue; + } + if (cmap[foo[0]] != cmap[bar[0]]) + return 0; + foo++; + bar++; + } + return 1; + } + + static int + verbnames_share_namespace(const char *foo, const char *bar) { + const char * bar_start = bar; + const char *fend, *bend; + + while (foo[0] != '\0') { + if (foo[0] == ' ') { + foo++; + continue; + } + for(fend = foo; fend[0] != '\0' && fend[0] != ' '; fend++); + bar = bar_start; + while (bar[0] != '\0') { + if (bar[0] == ' ') { + bar++; + continue; + } + for (bend = bar; bend[0] != '\0' && bend[0] != ' '; bend++); + if (bend-bar && fend-foo && single_names_share_namespace(foo, fend, bar, bend)) + return 1; + bar = bend; + } + foo = fend; + } + return 0; + } + + struct o_verbs_pack { + Objid owner; + const char * names; + }; + + + static enum error + name_conflict_with_ancestor(const Objid oid, Objid owner, const char + *names) { + Objid victim; + db_verb_handle v; + int i; + + victim = oid; + while (valid(victim)) { + for (i = 0; i < db_count_verbs(victim); i++) { + v = db_find_indexed_verb(victim, i+1); + if ((db_verb_flags(v) & VF_NOT_O) + && (db_verb_owner(v) != owner) + && verbnames_share_namespace(names, db_verb_names(v))) + return 1; + } + victim = db_object_parent(victim); + } + return 0; + } + + static int + name_conflict_with_descendants_recursive(void *data, Objid oid) { + db_verb_handle v; + int i; + + for (i = 0; i < db_count_verbs(oid); i++) { + v = db_find_indexed_verb(oid, i+1); + if (!is_wizard(db_verb_owner(v)) + && db_verb_owner(v) != ((struct o_verbs_pack*)data)->owner + && verbnames_share_namespace(((struct o_verbs_pack*)data)->names, db_verb_names(v))) + return 1; + } + return db_for_all_children(oid, name_conflict_with_descendants_recursive, data); + } + + + static int + name_conflict_with_descendants(Objid oid, Objid owner, const char *names) { + struct o_verbs_pack data; + data.owner = owner; + data.names = names; + return db_for_all_children(oid, name_conflict_with_descendants_recursive, &data); + } + + int + check_verbs_before_chparent(void * new_parent, Objid oid) { + int i; + db_verb_handle v; + + for (i = 0; i < db_count_verbs(oid); i++) { + v = db_find_indexed_verb(oid, i+1); + if (!is_wizard(db_verb_owner(v)) + && name_conflict_with_ancestor(*((Objid *)new_parent), db_verb_owner(v), db_verb_names(v))) + return 1; + } + return db_for_all_children(oid, check_verbs_before_chparent, new_parent); + } + + /*** end -o_Verbs Patch ***/ + static package bf_add_verb(Var arglist, Byte next, void *vdata, Objid progr) { /* (object, info, args) */ *************** *** 193,198 **** --- 389,405 ---- || (progr != owner && !is_wizard(progr))) { free_str(names); e = E_PERM; + /*** -o_Verbs Patch ***/ + } else if (!is_wizard(progr) && (flags & VF_NOT_O) && server_flag_option("protect_o_flag")) { + free_str(names); + e = E_PERM; + } else if (!is_wizard(owner) && name_conflict_with_ancestor(db_object_parent(oid), owner, names)) { + free_str(names); + e = E_PERM; + } else if ((flags & VF_NOT_O) && name_conflict_with_descendants(oid, owner, names)) { + free_str(names); + e = E_INVARG; + /*** -o_Verbs Patch ***/ } else db_add_verb(oid, names, owner, flags, dobj, prep, iobj); *************** *** 284,290 **** r.v.list[1].type = TYPE_OBJ; r.v.list[1].v.obj = db_verb_owner(h); r.v.list[2].type = TYPE_STR; ! r.v.list[2].v.str = s = str_dup("xxxx"); flags = db_verb_flags(h); if (flags & VF_READ) *s++ = 'r'; --- 491,499 ---- r.v.list[1].type = TYPE_OBJ; r.v.list[1].v.obj = db_verb_owner(h); r.v.list[2].type = TYPE_STR; ! /*** -o_Verbs Patch ***/ ! r.v.list[2].v.str = s = str_dup("xxxxx"); ! /*** end -o_Verbs Patch ***/ flags = db_verb_flags(h); if (flags & VF_READ) *s++ = 'r'; *************** *** 294,299 **** --- 503,512 ---- *s++ = 'x'; if (flags & VF_DEBUG) *s++ = 'd'; + /*** -o_Verbs Patch ***/ + if (!(flags & VF_NOT_O) && !server_flag_option("use_blocked_notation")) *s++ = 'o'; + else if ((flags & VF_NOT_O) && server_flag_option("use_blocked_notation")) *s++ = 'b'; + /*** end -o_Verbs Patch ***/ *s = '\0'; r.v.list[3].type = TYPE_STR; r.v.list[3].v.str = str_ref(db_verb_names(h)); *************** *** 333,339 **** || (!is_wizard(progr) && db_verb_owner(h) != new_owner)) { free_str(new_names); return make_error_pack(E_PERM); ! } db_set_verb_owner(h, new_owner); db_set_verb_flags(h, new_flags); db_set_verb_names(h, new_names); --- 546,577 ---- || (!is_wizard(progr) && db_verb_owner(h) != new_owner)) { free_str(new_names); return make_error_pack(E_PERM); ! /*** -o_Verbs Patch ***/ ! } else if (!is_wizard(progr) && server_flag_option("protect_o_flag") ! && ((new_flags & VF_NOT_O) != (db_verb_flags(h) & VF_NOT_O))) { ! free_str(new_names); ! return make_error_pack(E_PERM); ! } else if ((new_owner != db_verb_owner(h) || mystrcasecmp(new_names, db_verb_names(h))) ! && !is_wizard(new_owner) ! && name_conflict_with_ancestor(db_object_parent(oid), new_owner, new_names)) ! { ! free_str(new_names); ! return make_error_pack(E_PERM); ! } else { ! /* ncwa mangles h sometimes... rematch it */ ! h = find_described_verb(oid, desc); ! if ((new_flags & VF_NOT_O) ! && (new_owner != db_verb_owner(h) ! || !(db_verb_flags(h) & VF_NOT_O) ! || !mystrcasecmp(new_names, db_verb_names(h))) ! && name_conflict_with_descendants(oid, new_owner, new_names)) { ! free_str(new_names); ! return make_error_pack(E_INVARG); ! } ! } ! /* If ncwa can do it, so can ncwd. Rematch again. */ ! h = find_described_verb(oid, desc); ! /*** end -o_Verbs Patch ***/ db_set_verb_owner(h, new_owner); db_set_verb_flags(h, new_flags); db_set_verb_names(h, new_names);
[home | help | who | search | setup | code]