Forráskód Böngészése

* Bind table cleanups
* Removed bind_chain_t for now.


svn: 596

Bryan Drewery 22 éve
szülő
commit
7c0d4139c1
8 módosított fájl, 262 hozzáadás és 243 törlés
  1. 3 3
      src/Makefile.in
  2. 2 2
      src/mod/irc.mod/irc.c
  3. 1 1
      src/mod/module.h
  4. 1 1
      src/modules.c
  5. 0 24
      src/tclegg.h
  6. 233 134
      src/tclhash.c
  7. 22 77
      src/tclhash.h
  8. 0 1
      src/tclmisc.c

+ 3 - 3
src/Makefile.in

@@ -173,7 +173,7 @@ main.o: main.c stringfix main.h build.h ../config.h conf.h lang.h eggdrop.h flag
  ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
  compat/compat.h compat/inet_aton.h compat/inet_ntop.h ../src/main.h compat/snprintf.h \
  compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
- modules.h mod/modvals.h tandem.h  egg_timer.h traffic.h
+ modules.h mod/modvals.h tandem.h  egg_timer.h egg_timer.c traffic.h
 match.o: match.c stringfix ./main.h
 mem.o: mem.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h proto.h \
  ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
@@ -199,7 +199,7 @@ net.o: net.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h proto.
  ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h users.h \
  compat/compat.h compat/inet_aton.h compat/inet_ntop.h ../src/main.h compat/snprintf.h \
  compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
- egg_timer.h traffic.h
+ egg_timer.h egg_timer.c traffic.h
 rfc1459.o: rfc1459.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h \
  proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
  users.h compat/compat.h compat/inet_aton.h compat/inet_ntop.h ../src/main.h \
@@ -222,7 +222,7 @@ tclhash.o: tclhash.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.
  proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
  users.h compat/compat.h compat/inet_aton.h compat/inet_ntop.h ../src/main.h \
  compat/snprintf.h compat/memset.h compat/memcpy.h compat/strcasecmp.h \
- compat/strftime.h match.c
+ compat/strftime.h match.c egg_timer.h egg_timer.c
 tclmisc.o: tclmisc.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h \
  proto.h ../lush.h misc_file.h cmdt.h tclegg.h tclhash.h chan.h \
  users.h compat/compat.h compat/inet_aton.h compat/inet_ntop.h ../src/main.h \

+ 2 - 2
src/mod/irc.mod/irc.c

@@ -1671,8 +1671,8 @@ char *irc_start(Function * global_funcs)
 	       traced_rfccompliant, NULL);
   add_tcl_ints(myints);
 
-  BT_ctcp = bind_table_find("ctcp");
-  BT_ctcr = bind_table_find("ctcr");
+  BT_ctcp = bind_table_lookup("ctcp");
+  BT_ctcr = bind_table_lookup("ctcr");
 
   /* Add our commands to the imported tables. */
   add_builtins("dcc", irc_dcc);

+ 1 - 1
src/mod/module.h

@@ -546,7 +546,7 @@
 #define add_builtins ((void (*)(const char *, cmd_t *))global[344])
 /* 345 - 348 */
 #define rem_builtins ((void (*)(const char *, cmd_t *))global[345])
-#define bind_table_find ((bind_table_t *(*)(const char *))global[346])
+#define bind_table_lookup ((bind_table_t *(*)(const char *))global[346])
 #define check_bind ((int (*)(bind_table_t *, const char *, struct flag_record *, ...))global[347])
 
 extern int lfprintf(FILE *, char *, ...);

+ 1 - 1
src/modules.c

@@ -608,7 +608,7 @@ Function global_table[] =
   (Function) bind_table_add,
   (Function) add_builtins,
   (Function) rem_builtins,
-  (Function) bind_table_find,
+  (Function) bind_table_lookup,
   (Function) check_bind
 
 };

+ 0 - 24
src/tclegg.h

@@ -13,30 +13,6 @@
 #  include "proto.h"		/* This file needs this */
 #endif
 
-/* Match types for check_bind
- */
-#define MATCH_PARTIAL       0
-#define MATCH_EXACT         1
-#define MATCH_MASK          2
-#define MATCH_CASE          3
-
-/* Bitwise 'or' these:
- */
-#define BIND_USE_ATTR       0x04
-#define BIND_STACKABLE      0x08
-#define BIND_HAS_BUILTINS   0x10
-#define BIND_WANTRET        0x20
-#define BIND_ALTER_ARGS     0x40
-
-/* Return values
- */
-#define BIND_NOMATCH    0
-#define BIND_AMBIGUOUS  1
-#define BIND_MATCHED    2	/* But the proc couldn't be found */
-#define BIND_EXECUTED   3
-#define BIND_EXEC_LOG   4	/* Proc returned 1 -> wants to be logged */
-#define BIND_EXEC_BRK   5	/* Proc returned BREAK (quit) */
-
 /* Used for stub functions:
  */
 

+ 233 - 134
src/tclhash.c

@@ -13,6 +13,7 @@
 #include "chan.h"
 #include "users.h"
 #include "match.c"
+#include "egg_timer.h"
 
 extern struct dcc_t	*dcc;
 extern struct userrec	*userlist;
@@ -40,6 +41,12 @@ static bind_table_t *BT_chof;
 static bind_table_t *BT_chpt;
 static bind_table_t *BT_chjn;
 
+/* Variables to control garbage collection. */
+static int check_bind_executing = 0;
+static int already_scheduled = 0;
+static void bind_table_really_del(bind_table_t *table);
+static void bind_entry_really_del(bind_table_t *table, bind_entry_t *entry);
+
 
 extern cmd_t C_dcc[];
 
@@ -64,6 +71,39 @@ void binds_init(void)
 	add_builtins("dcc", C_dcc);
 }
 
+static int internal_bind_cleanup()
+{
+	bind_table_t *table, *next_table;
+	bind_entry_t *entry, *next_entry;
+
+	for (table = bind_table_list_head; table; table = next_table) {
+		next_table = table->next;
+		if (table->flags & BIND_DELETED) {
+			bind_table_really_del(table);
+			continue;
+		}
+		for (entry = table->entries; entry; entry = next_entry) {
+			next_entry = entry->next;
+			if (entry->flags & BIND_DELETED) bind_entry_really_del(table, entry);
+		}
+	}
+	already_scheduled = 0;
+	return(0);
+}
+
+static void schedule_bind_cleanup()
+{
+	egg_timeval_t when;
+
+	if (already_scheduled) return;
+	already_scheduled = 1;
+
+	when.sec = 0;
+	when.usec = 0;
+	timer_create(&when, internal_bind_cleanup);
+}
+
+
 void kill_binds(void)
 {
 	while (bind_table_list_head) bind_table_del(bind_table_list_head);
@@ -77,8 +117,7 @@ bind_table_t *bind_table_add(const char *name, int nargs, const char *syntax, in
 		if (!strcmp(table->name, name)) return(table);
 	}
 	/* Nope, we have to create a new one. */
-	table = (bind_table_t *)malloc(sizeof(*table));
-	table->chains = NULL;
+	table = (bind_table_t *)calloc(1, sizeof(*table));
 	table->name = strdup(name);
 	table->nargs = nargs;
 	table->syntax = strdup(syntax);
@@ -92,8 +131,6 @@ bind_table_t *bind_table_add(const char *name, int nargs, const char *syntax, in
 void bind_table_del(bind_table_t *table)
 {
 	bind_table_t *cur, *prev;
-	bind_chain_t *chain, *next_chain;
-	bind_entry_t *entry, *next_entry;
 
 	for (prev = NULL, cur = bind_table_list_head; cur; prev = cur, cur = cur->next) {
 		if (!strcmp(table->name, cur->name)) break;
@@ -106,99 +143,131 @@ void bind_table_del(bind_table_t *table)
 	}
 
 	/* Now delete it. */
+	if (check_bind_executing) {
+		table->flags |= BIND_DELETED;
+		schedule_bind_cleanup();
+	}
+	else {
+		bind_table_really_del(table);
+	}
+}
+
+static void bind_table_really_del(bind_table_t *table)
+{
+	bind_entry_t *entry, *next;
+
 	free(table->name);
-	for (chain = table->chains; chain; chain = next_chain) {
-		next_chain = chain->next;
-		for (entry = chain->entries; entry; entry = next_entry) {
-			next_entry = entry->next;
-			free(entry->function_name);
-			free(entry);
-		}
-		free(chain);
+	for (entry = table->entries; entry; entry = next) {
+		next = entry->next;
+		free(entry->function_name);
+		free(entry->mask);
+		free(entry);
 	}
+	free(table);
 }
 
-bind_table_t *bind_table_find(const char *name)
+bind_table_t *bind_table_lookup(const char *name)
 {
 	bind_table_t *table;
 
 	for (table = bind_table_list_head; table; table = table->next) {
-		if (!strcmp(table->name, name)) break;
+		if (!(table->flags & BIND_DELETED) && !strcmp(table->name, name)) break;
 	}
 	return(table);
 }
 
-int bind_entry_del(bind_table_t *table, const char *flags, const char *mask, const char *function_name, void *cdata)
+/* Look up a bind entry based on either function name or id. */
+bind_entry_t *bind_entry_lookup(bind_table_t *table, int id, const char *mask, const char *function_name)
 {
-	bind_chain_t *chain;
-	bind_entry_t *entry, *prev;
+	bind_entry_t *entry;
 
-	/* Find the correct mask entry. */
-	for (chain = table->chains; chain; chain = chain->next) {
-		if (!strcmp(chain->mask, mask)) break;
+	for (entry = table->entries; entry; entry = entry->next) {
+		if (entry->flags & BIND_DELETED) continue;
+		if (entry->id == id || (!strcmp(entry->mask, mask) && !strcmp(entry->function_name, function_name))) break;
 	}
-	if (!chain) return(1);
+	return(entry);
+}
+
+int bind_entry_del(bind_table_t *table, int id, const char *mask, const char *function_name, void *cdata)
+{
+	bind_entry_t *entry;
+
+	entry = bind_entry_lookup(table, id, mask, function_name);
+	if (!entry) return(-1);
 
-	/* Now find the function name in this mask entry. */
-	for (prev = NULL, entry = chain->entries; entry; prev = entry, entry = entry->next) {
-		if (!strcmp(entry->function_name, function_name)) break;
-	}
-	if (!entry) return(1);
 
 	/* Delete it. */
-	if (prev) prev->next = entry->next;
-	else chain->entries = entry->next;
+	if (check_bind_executing) {
+		entry->flags |= BIND_DELETED;
+		schedule_bind_cleanup();
+	}
+	else bind_entry_really_del(table, entry);
+	return(0);
+}
+
+static void bind_entry_really_del(bind_table_t *table, bind_entry_t *entry)
+{
+	if (entry->next) entry->next->prev = entry->prev;
+	if (entry->prev) entry->prev->next = entry->next;
+	else table->entries = entry->next;
 	free(entry->function_name);
+	free(entry->mask);
+	memset(entry, 0, sizeof(*entry));
 	free(entry);
+}
+
+/* Modify a bind entry's flags and mask. */
+int bind_entry_modify(bind_table_t *table, int id, const char *mask, const char *function_name, const char *newflags, const char *newmask)
+{
+	bind_entry_t *entry;
+
+	entry = bind_entry_lookup(table, id, mask, function_name);
+	if (!entry) return(-1);
+
+	/* Modify it. */
+	free(entry->mask);
+	entry->mask = strdup(newmask);
+	entry->user_flags.match = FR_GLOBAL | FR_CHAN;
+	break_down_flags(newflags, &(entry->user_flags), NULL);
 
 	return(0);
 }
 
 int bind_entry_add(bind_table_t *table, const char *flags, const char *mask, const char *function_name, int bind_flags, Function callback, void *client_data)
 {
-	bind_chain_t *chain;
-	bind_entry_t *entry;
+	bind_entry_t *entry, *old_entry;
 
-	/* Find the chain (mask) first. */
-	for (chain = table->chains; chain; chain = chain->next) {
-		if (!strcmp(chain->mask, mask)) break;
-	}
-
-	/* Create if it doesn't exist. */
-	if (!chain) {
-		chain = (bind_chain_t *)malloc(sizeof(*chain));
-		chain->entries = NULL;
-		chain->mask = strdup(mask);
-		chain->next = table->chains;
-		table->chains = chain;
-	}
+	old_entry = bind_entry_lookup(table, -1, mask, function_name);
 
-	/* If it's stackable */
-	if (table->flags & BIND_STACKABLE) {
-		/* Search for specific entry. */
-		for (entry = chain->entries; entry; entry = entry->next) {
-			if (!strcmp(entry->function_name, function_name)) break;
+	if (old_entry) {
+		if (table->flags & BIND_STACKABLE) {
+			entry = (bind_entry_t *)calloc(1, sizeof(*entry));
+			entry->prev = old_entry;
+			entry->next = old_entry->next;
+			old_entry->next = entry;
+			if (entry->next) entry->next->prev = entry;
+		}
+		else {
+			entry = old_entry;
+			free(entry->function_name);
+			free(entry->mask);
 		}
 	}
 	else {
-		/* Nope, just use first entry. */
-		entry = chain->entries;
-	}
-
-	/* If we have an old entry, re-use it. */
-	if (entry) free(entry->function_name);
-	else {
-		/* Otherwise, create a new entry. */
-		entry = (bind_entry_t *)malloc(sizeof(*entry));
-		entry->next = chain->entries;
-		chain->entries = entry;
+		for (old_entry = table->entries; old_entry && old_entry->next; old_entry = old_entry->next) {
+			; /* empty loop */
+		}
+		entry = (bind_entry_t *)calloc(1, sizeof(*entry));
+		if (old_entry) old_entry->next = entry;
+		else table->entries = entry;
+		entry->prev = old_entry;
 	}
 
+	entry->mask = strdup(mask);
 	entry->function_name = strdup(function_name);
 	entry->callback = callback;
 	entry->client_data = client_data;
-	entry->hits = 0;
-	entry->bind_flags = bind_flags;
+	entry->flags = bind_flags;
 
 	entry->user_flags.match = FR_GLOBAL | FR_CHAN;
 	break_down_flags(flags, &(entry->user_flags), NULL);
@@ -216,92 +285,121 @@ int findanyidx(register int z)
   return -1;
 }
 
-int check_bind(bind_table_t *table, const char *match, struct flag_record *_flags, ...)
+/* Execute a bind entry with the given argument list. */
+static int bind_entry_exec(bind_table_t *table, bind_entry_t *entry, void **al)
 {
-	int *al; /* Argument list */
-	struct flag_record *flags;
-	bind_chain_t *chain;
-	bind_entry_t *entry;
-	int len, cmp, r, hits;
-	Function cb;
+	bind_entry_t *prev;
 
-	/* Experimental way to not use va_list... */
-	flags = _flags;
-	al = (int *)&_flags;
+	/* Give this entry a hit. */
+	entry->nhits++;
 
-	/* Save the length for strncmp */
-	len = strlen(match);
+	/* Search for the last entry that isn't deleted. */
+	for (prev = entry->prev; prev; prev = prev->prev) {
+		if (!(prev->flags & BIND_DELETED) && (prev->nhits >= entry->nhits)) break;
+	}
 
-	/* Keep track of how many binds execute (or would) */
-	hits = 0;
+	/* See if this entry is more popular than the preceding one. */
+	if (entry->prev != prev) {
+		/* Remove entry. */
+		if (entry->prev) entry->prev->next = entry->next;
+		else table->entries = entry->next;
+		if (entry->next) entry->next->prev = entry->prev;
+
+		/* Re-add in correct position. */
+		if (prev) {
+			entry->next = prev->next;
+			if (prev->next) prev->next->prev = entry;
+			prev->next = entry;
+		}
+
+		else {
+			entry->next = table->entries;
+			table->entries = entry;
+		}
+		entry->prev = prev;
+		if (entry->next) entry->next->prev = entry;
+	}
+
+	/* Does the callback want client data? */
+	if (entry->flags & BIND_WANTS_CD) {
+		*al = entry->client_data;
+	}
+	else al++;
+
+	return entry->callback(al[0], al[1], al[2], al[3], al[4], al[5], al[6], al[7], al[8], al[9]);
+}		
+
+int check_bind(bind_table_t *table, const char *match, struct flag_record *flags, ...)
+{
+	void *args[11];
+	bind_entry_t *entry, *next;
+	int i, cmp, retval;
+	va_list ap;
+
+	check_bind_executing++;
+
+	va_start(ap, flags);
+	for (i = 1; i <= table->nargs; i++) {
+		args[i] = va_arg(ap, void *);
+	}
+	va_end(ap);
 
 	/* Default return value is 0 */
-	r = 0;
-
-	/* For each chain in the table... */
-	for (chain = table->chains; chain; chain = chain->next) {
-		/* Test to see if it matches. */
-		if (table->match_type & MATCH_PARTIAL) {
-			if (table->match_type & MATCH_CASE) cmp = strncmp(match, chain->mask, len);
-			else cmp = egg_strncasecmp(match, chain->mask, len);
+	retval = 0;
+
+	/* If it's a partial bind, we have to find the closest match. */
+	if (table->match_type & MATCH_PARTIAL) {
+		int len, tie;
+
+		len = strlen(match);
+		tie = 0;
+		for (entry = table->entries; entry; entry = entry->next) {
+			if (entry->flags & BIND_DELETED) continue;
+			if (!strncasecmp(match, entry->mask, len)) {
+				if (tie) return(-1);
+				tie = 1;
+			}
 		}
-		else if (table->match_type & MATCH_MASK) {
-			cmp = !wild_match_per((unsigned char *)chain->mask, (unsigned char *)match);
+		if (entry && !tie) retval = bind_entry_exec(table, entry, args);
+		else retval = -1;
+		check_bind_executing--;
+		return(retval);
+	}
+
+	for (entry = table->entries; entry; entry = next) {
+		next = entry->next;
+		if (entry->flags & BIND_DELETED) continue;
+
+		if (table->match_type & MATCH_MASK) {
+			cmp = !wild_match_per((unsigned char *)entry->mask, (unsigned char *)match);
 		}
 		else {
-			if (table->match_type & MATCH_CASE) cmp = strcmp(match, chain->mask);
-			else cmp = egg_strcasecmp(match, chain->mask);
+			if (table->match_type & MATCH_CASE) cmp = strcmp(entry->mask, match);
+			else cmp = strcasecmp(entry->mask, match);
 		}
 		if (cmp) continue; /* Doesn't match. */
 
-		/* Ok, now call the entries for this chain. */
-		/* If it's not stackable, There Can Be Only One. */
-		for (entry = chain->entries; entry; entry = entry->next) {
-			/* Check flags. */
-			if (table->match_type & BIND_USE_ATTR) {
-				if (table->match_type & BIND_STRICT_ATTR) cmp = flagrec_eq(&entry->user_flags, flags);
-				else cmp = flagrec_ok(&entry->user_flags, flags);
-				if (!cmp) continue;
-			}
-
-			/* This is a hit */
-			hits++;
-		
-			cb = entry->callback;
-			if (entry->bind_flags & BIND_WANTS_CD) {
-				al[0] = (int) entry->client_data;
-				table->nargs++;
-			}
-			else al++;
-
-			/* Default return value is 0. */
-			r = 0;
-
-			switch (table->nargs) {
-				case 0: r = cb(); break;
-				case 1: r = cb(al[0]); break;
-				case 2: r = cb(al[0], al[1]); break;
-				case 3: r = cb(al[0], al[1], al[2]); break;
-				case 4: r = cb(al[0], al[1], al[2], al[3]); break;
-				case 5: r = cb(al[0], al[1], al[2], al[3], al[4]); break;
-				case 6: r = cb(al[0], al[1], al[2], al[3], al[4], al[5]); break;
-				case 7: r = cb(al[0], al[1], al[2], al[3], al[4], al[5], al[6]);
-				case 8: r = cb(al[0], al[1], al[2], al[3], al[4], al[5], al[6], al[7]);
-			}
-
-			if (entry->bind_flags & BIND_WANTS_CD) table->nargs--;
-			else al--;
+		/* Check flags. */
+		if (table->flags & BIND_USE_ATTR) {
+			if (table->flags & BIND_STRICT_ATTR) cmp = flagrec_eq(&entry->user_flags, flags);
+			else cmp = flagrec_ok(&entry->user_flags, flags);
+			if (!cmp) continue;
+		}
 
-			if ((table->flags & BIND_BREAKABLE) && (r & BIND_RET_BREAK)) return(r);
+		retval = bind_entry_exec(table, entry, args);
+		if ((table->flags & BIND_BREAKABLE) && (retval & BIND_RET_BREAK)) {
+			check_bind_executing--;
+			return(retval);
 		}
 	}
-	return(r);
+	check_bind_executing--;
+	return(retval);
 }
 
 /* Check for tcl-bound dcc command, return 1 if found
  * dcc: proc-name <handle> <sock> <args...>
  */
-void check_dcc(const char *cmd, int idx, const char *args)
+void check_dcc(const char *cmd, int idx, const char *text)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
   int x;
@@ -342,10 +440,11 @@ void check_dcc(const char *cmd, int idx, const char *args)
     }
   }
 #endif /* S_DCCPASS */
-//    dprintf(idx, "What?  You need '%shelp'\n", dcc_prefix);
-  x = check_bind(BT_dcc, cmd, &fr, dcc[idx].user, idx, args);
-  if (x & BIND_RET_LOG) {
-     putlog(LOG_CMDS, "*", "#%s# %s %s", dcc[idx].nick, cmd, args);
+  x = check_bind(BT_dcc, cmd, &fr, dcc[idx].user, idx, text);
+  if (x == 0)
+    dprintf(idx, "What?  You need '%shelp'\n", dcc_prefix);
+  else if (x & BIND_RET_LOG) {
+     putlog(LOG_CMDS, "*", "#%s# %s %s", dcc[idx].nick, cmd, text);
   }
 }
 
@@ -455,7 +554,7 @@ void add_builtins(const char *table_name, cmd_t *cmds)
 	char name[50];
 	bind_table_t *table;
 
-	table = bind_table_find(table_name);
+	table = bind_table_lookup(table_name);
 	if (!table) return;
 
 	for (; cmds->name; cmds++) {
@@ -476,11 +575,11 @@ void rem_builtins(const char *table_name, cmd_t *cmds)
 	char name[50];
 	bind_table_t *table;
 
-	table = bind_table_find(table_name);
+	table = bind_table_lookup(table_name);
 	if (!table) return;
 
 	for (; cmds->name; cmds++) {
 		sprintf(name, "*%s:%s", table->name, cmds->funcname ? cmds->funcname : cmds->name);
-		bind_entry_del(table, cmds->flags, cmds->name, name, NULL);
+		bind_entry_del(table, -1, cmds->name, name, NULL);
 	}
 }

+ 22 - 77
src/tclhash.h

@@ -9,88 +9,49 @@
 
 #define TC_DELETED	0x0001	/* This command/trigger was deleted.	*/
 
-/* Flags for bind entries */
+/* Match type flags for bind tables. */
+#define MATCH_PARTIAL       1
+#define MATCH_EXACT         2
+#define MATCH_MASK          4
+#define MATCH_CASE          8
+
+/* Flags for binds. */
 /* Does the callback want their client_data inserted as the first argument? */
 #define BIND_WANTS_CD 1
 
-/* Flags for bind tables */
-#define BIND_STRICT_ATTR 0x80
-#define BIND_BREAKABLE 0x100
+#define BIND_USE_ATTR		2
+#define BIND_STRICT_ATTR	4
+#define BIND_BREAKABLE		8
+#define BIND_STACKABLE		16
+#define BIND_DELETED		32
 
 /* Flags for return values from bind callbacks */
 #define BIND_RET_LOG 1
 #define BIND_RET_BREAK 2
 
-/* Callback clientdata for a tcl bind */
-typedef struct tcl_cmd_cdata_b {
-        Tcl_Interp *irp;
-        char *cmd;
-        char *syntax;
-} tcl_cmd_cdata;
-
-
-/* Will replace tcl_cmd_t */
-/* This holds the final information for a function listening on a bind
-   table. */
+/* This holds the information of a bind entry. */
 typedef struct bind_entry_b {
-        struct bind_entry_b *next;
+	struct bind_entry_b *next, *prev;
         struct flag_record user_flags;
+	char *mask;
         char *function_name;
         Function callback;
         void *client_data;
-        int hits;
-        int bind_flags;
-} bind_entry_t;
-
-typedef struct tcl_cmd_b {
-  struct tcl_cmd_b	*next;
-
-  struct flag_record	 flags;
-  char			*func_name;	/* Proc name.			*/
-  int			 hits;		/* Number of times this proc
-					   was triggered.		*/
-  u_8bit_t		 attributes;	/* Flags for this entry. TC_*	*/
-} tcl_cmd_t;
-
-
-#define TBM_DELETED	0x0001	/* This mask was deleted.		*/
-
-/* Will replace tcl_bind_mask_t */
-/* This is the list of bind masks in a given table.
-   For instance, in the "msg" table you might have "pass", "op",
-   and "invite". */
-typedef struct bind_chain_b {
-        struct bind_chain_b *next;
-        bind_entry_t *entries;
-        char *mask;
+	int nhits;
         int flags;
-} bind_chain_t;
-
-typedef struct tcl_bind_mask_b {
-  struct tcl_bind_mask_b *next;
-
-  tcl_cmd_t		 *first;	/* List of commands registered
-					   for this bind.		*/
-  char			 *mask;
-  u_8bit_t		  flags;	/* Flags for this entry. TBM_*	*/
-} tcl_bind_mask_t;
-
+	int id;
+} bind_entry_t;
 
-#define HT_STACKABLE	0x0001	/* Triggers in this bind list may be
-				   stacked.				*/
-#define HT_DELETED	0x0002	/* This bind list was already deleted.
-				   Do not use it anymore.		*/
 typedef struct {
 	char *name;
 	struct flag_record     flags;
 } mycmds;
 
-/* Will replace tcl_bind_list_b */
 /* This is the highest-level structure. It's like the "msg" table
    or the "pubm" table. */
 typedef struct bind_table_b {
         struct bind_table_b *next;
-        bind_chain_t *chains;
+	bind_entry_t *entries;
         char *name;
         char *syntax;
         int nargs;
@@ -99,20 +60,6 @@ typedef struct bind_table_b {
 } bind_table_t;
 
 
-typedef struct tcl_bind_list_b {
-  struct tcl_bind_list_b *next;
-
-  tcl_bind_mask_t	 *first;	/* Pointer to registered binds
-					   for this list.		*/
-  char			  name[5];	/* Name of the bind.		*/
-  u_8bit_t		  flags;	/* Flags for this element. HT_*	*/
-  Function		  func;		/* Function used as the Tcl
-					   calling interface for procs
-					   actually representing C
-					   functions.			*/
-} tcl_bind_list_t, *p_tcl_bind_list;
-
-
 #ifndef MAKING_MODS
 
 
@@ -139,15 +86,13 @@ void check_chon(char *, int);
 void check_chof(char *, int);
 
 
-void check_loadunld(const char *, tcl_bind_list_t *);
-
-
 int check_bind(bind_table_t *table, const char *match, struct flag_record *_flags, ...);
 bind_table_t *bind_table_add(const char *name, int nargs, const char *syntax, int match_type, int flags);
 void bind_table_del(bind_table_t *table);
-bind_table_t *bind_table_find(const char *name);
+bind_table_t *bind_table_lookup(const char *name);
 int bind_entry_add(bind_table_t *table, const char *flags, const char *mask, const char *function_name, int bind_flags, Function callback, void *client_data);
-int bind_entry_del(bind_table_t *table, const char *flags, const char *mask, const char *function_name, void *cdata);
+int bind_entry_del(bind_table_t *table, int id, const char *mask, const char *function_name, void *cdata);
+int bind_entry_modify(bind_table_t *table, int id, const char *mask, const char *function_name, const char *newflags, const char *newmask);
 void add_builtins(const char *table_name, cmd_t *cmds);
 void rem_builtins(const char *table_name, cmd_t *cmds);
 

+ 0 - 1
src/tclmisc.c

@@ -9,7 +9,6 @@
 #include "modules.h"
 #include "tandem.h"
 
-extern p_tcl_bind_list	 bind_table_list;
 extern struct dcc_t	*dcc;
 extern char		 origbotname[], botnetnick[], quit_msg[];
 extern struct userrec	*userlist;