*** 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);