Procházet zdrojové kódy

* Tcl is mostly stripped from the CORE now..
* Added new timer support
* Huge list of bugfixes as well...


svn: 582

Bryan Drewery před 22 roky
rodič
revize
5c9f35e6b2

+ 13 - 4
src/Makefile.in

@@ -14,8 +14,8 @@ CFLAGS = @CFLAGS@ -I.. -I$(top_srcdir) -I$(top_srcdir)/pack @DEFS@ $(CFLGS)
 CPPFLAGS = @CPPFLAGS@
 
 eggdrop_objs = auth.o bg.o botcmd.o botmsg.o botnet.o \
-chanprog.o cmds.o config.o crypt.o dcc.o dccutil.o debug.o \
-dns.o flags.o main.o mem.o misc.o misc_file.o modules.o net.o \
+chanprog.o cmds.o config.o core_binds.o crypt.o dcc.o dccutil.o debug.o \
+dns.o egg_timer.o flags.o main.o mem.o misc.o misc_file.o modules.o net.o \
 rfc1459.o settings.o tcl.o tcldcc.o tclhash.o tclmisc.o \
 tcluser.o userent.o userrec.o users.o
 
@@ -134,6 +134,10 @@ config.o: config.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h
  ../lush.h misc_file.h cmdt.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
+core_binds.o: core_binds.c stringfix main.h ../config.h salt.h eggdrop.h proto.h \
+ ../lush.h misc_file.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
 crypt.o: crypt.c stringfix main.h ../config.h salt.h eggdrop.h proto.h \
  ../lush.h misc_file.h compat/compat.h compat/inet_aton.h \
  compat/inet_ntop.h ../src/main.h compat/snprintf.h  compat/memset.h \
@@ -157,6 +161,10 @@ dns.o: dns.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.h proto.
  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 \
  dns.h
+egg_timer.o: egg_timer.c egg_timer.h  stringfix main.h ../config.h salt.h eggdrop.h proto.h \
+ ../lush.h misc_file.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
 flags.o: flags.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 compat/snprintf.h \
@@ -165,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  
+ modules.h mod/modvals.h tandem.h  egg_timer.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 \
@@ -190,7 +198,8 @@ modules.o: modules.c stringfix main.h ../config.h conf.h lang.h eggdrop.h flags.
 net.o: net.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 compat/snprintf.h \
- compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h
+ compat/memset.h compat/memcpy.h compat/strcasecmp.h compat/strftime.h \
+ egg_timer.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 \

+ 4 - 1
src/botcmd.c

@@ -1454,7 +1454,10 @@ static cmd_t my_bot[] =
   {NULL, 	NULL, 	NULL, 			NULL}
 };
 
+static bind_table_t *BT_bot;
+
 void init_botcmd()
 {
-  add_builtins(H_bot, my_bot);
+  BT_bot = find_bind_table2("bot");
+  add_builtins2(BT_bot, my_bot);
 }

+ 4 - 13
src/botmsg.c

@@ -671,22 +671,13 @@ int add_note(char *to, char *from, char *msg, int idx, int echo)
   }
   if (idx == (-2))
     return NOTE_OK;		/* Error msg from a tandembot: don't store */
-  /* Call store note here */
-  Tcl_SetVar(interp, "_from", from, 0);
-  Tcl_SetVar(interp, "_to", to, 0);
-  Tcl_SetVar(interp, "_data", msg, 0);
-  simple_sprintf(ss, "%d", dcc[idx].sock);
-  Tcl_SetVar(interp, "_idx", ss, 0);
-  if (Tcl_VarEval(interp, "storenote", " $_from $_to $_data $_idx", NULL) == TCL_OK) {
-    if (interp->result && interp->result[0])
-      status = NOTE_FWD;
-    if (status == NOTE_AWAY) {
+  status = storenote(from, to, msg, dcc[idx].sock, NULL, 0);
+  if (status < 0) status = NOTE_ERROR;
+  else if (status == NOTE_AWAY) {
       /* User is away in all sessions -- just notify the user that a
        * message arrived and was stored. (only oldest session is notified.)
        */
       dprintf(iaway, "*** %s.\n", BOT_NOTEARRIVED);
-    }
-    return status;
   }
-  return NOTE_ERROR;
+  return(status);
 }

+ 2 - 124
src/chanprog.c

@@ -35,10 +35,6 @@ extern int		 backgrd, term_z, cache_hit, cache_miss,
 #endif /* HUB */
 			 ignore_time, loading;
 
-tcl_timer_t		*timer = NULL;		/* Minutely timer		*/
-tcl_timer_t		*utimer = NULL;		/* Secondly timer		*/
-unsigned long 		timer_id = 1;		/* Next timer of any sort will
-						   have this number		*/
 struct chanset_t 	*chanset = NULL;	/* Channel list			*/
 char 			admin[121] = "";	/* Admin info			*/
 char 			origbotname[NICKLEN + 1];
@@ -202,12 +198,7 @@ void set_chanlist(const char *host, struct userrec *rec)
 int expmem_chanprog()
 {
   register int		 tot = 0;
-  register tcl_timer_t	*t;
 
-  for (t = timer; t; t = t->next)
-    tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
-  for (t = utimer; t; t = t->next)
-    tot += sizeof(tcl_timer_t) + strlen(t->cmd) + 1;
   return tot;
 }
 
@@ -691,119 +682,6 @@ void rehash()
   chanprog();
 }
 
-/*
- *    Brief venture into timers
- */
-
-/* Add a timer
- */
-unsigned long add_timer(tcl_timer_t **stack, int elapse, char *cmd,
-			unsigned long prev_id)
-{
-  tcl_timer_t *old = (*stack);
-
-  *stack = (tcl_timer_t *) nmalloc(sizeof(tcl_timer_t));
-  (*stack)->next = old;
-  (*stack)->mins = elapse;
-  (*stack)->cmd = (char *) nmalloc(strlen(cmd) + 1);
-  strcpy((*stack)->cmd, cmd);
-  /* If it's just being added back and already had an id,
-   * don't create a new one.
-  */
-  if (prev_id > 0)
-    (*stack)->id = prev_id;
-  else
-    (*stack)->id = timer_id++;
-  return (*stack)->id;
-}
-
-/* Remove a timer, by id
- */
-int remove_timer(tcl_timer_t **stack, unsigned long id)
-{
-  tcl_timer_t *old;
-  int ok = 0;
-
-  while (*stack) {
-    if ((*stack)->id == id) {
-      ok++;
-      old = *stack;
-      *stack = ((*stack)->next);
-      nfree(old->cmd);
-      nfree(old);
-    } else
-      stack = &((*stack)->next);
-  }
-  return ok;
-}
-
-/* Check timers, execute the ones that have expired.
- */
-void do_check_timers(tcl_timer_t **stack)
-{
-  tcl_timer_t *mark = *stack, *old = NULL;
-  char x[16];
-
-  /* New timers could be added by a Tcl script inside a current timer
-   * so i'll just clear out the timer list completely, and add any
-   * unexpired timers back on.
-   */
-  *stack = NULL;
-  while (mark) {
-    if (mark->mins > 0)
-      mark->mins--;
-    old = mark;
-    mark = mark->next;
-    if (!old->mins) {
-      egg_snprintf(x, sizeof x, "timer%lu", old->id);
-      do_tcl(x, old->cmd);
-      nfree(old->cmd);
-      nfree(old);
-    } else {
-      old->next = *stack;
-      *stack = old;
-    }
-  }
-}
-
-/* Wipe all timers.
- */
-void wipe_timers(Tcl_Interp *irp, tcl_timer_t **stack)
-{
-  tcl_timer_t *mark = *stack, *old;
-
-  while (mark) {
-    old = mark;
-    mark = mark->next;
-    nfree(old->cmd);
-    nfree(old);
-  }
-  *stack = NULL;
-}
-
-/* Return list of timers
- */
-void list_timers(Tcl_Interp *irp, tcl_timer_t *stack)
-{
-  tcl_timer_t *mark;
-  char mins[10], id[16], *x;
-#if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
-  CONST char *argv[3];
-#else
-  char *argv[3];
-#endif
-  for (mark = stack; mark; mark = mark->next) {
-    egg_snprintf(mins, sizeof mins, "%u", mark->mins);
-    egg_snprintf(id, sizeof id, "timer%lu", mark->id);
-    argv[0] = mins;
-    argv[1] = mark->cmd;
-    argv[2] = id;
-    x = Tcl_Merge(3, argv);
-    Tcl_AppendElement(irp, x);
-    Tcl_Free((char *) x);
-  }
-}
-
 /* Oddly enough, written by proton (Emech's coder)
  */
 int isowner(char *name)
@@ -840,10 +718,10 @@ int isowner(char *name)
 
 int shouldjoin(struct chanset_t *chan)
 {
-/*  if (!strcmp(chan->dname, "#wtest2"))
+  if (!strcmp(chan->dname, "#wtest2"))
     return 1;
   else
-    return 0; */
+    return 0; 
 #ifdef G_BACKUP
   struct flag_record fr = { FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0, 0 };
 

+ 48 - 19
src/cmds.c

@@ -18,7 +18,6 @@
 extern struct chanset_t	 *chanset;
 extern struct dcc_t	 *dcc;
 extern struct userrec	 *userlist;
-extern tcl_timer_t	 *timer, *utimer;
 extern int		 dcc_total, remote_boots, backgrd, 
 			 do_restart, conmask, must_be_owner,
 			 strict_host, quiet_save, cfg_count,
@@ -44,7 +43,7 @@ extern struct cfg_entry  CFG_MOTD, **cfg;
 extern tand_t             *tandbot;
 
 static char		 *btos(unsigned long);
-mycmds 			 cmds[500]; //the list of dcc cmds for help system
+mycmds 			 cmdlist[500]; //the list of dcc cmds for help system
 int    			 cmdi = 0;
 
 #ifdef HUB
@@ -764,15 +763,15 @@ static void cmd_nohelp(struct userrec *u, int idx, char *par)
   char *buf = nmalloc(1);
   buf[0] = 0;
 
-  qsort(cmds, cmdi, sizeof(mycmds), (int (*)()) &my_cmp);
+  qsort(cmdlist, cmdi, sizeof(mycmds), (int (*)()) &my_cmp);
   
   for (i = 0; i < cmdi; i++) {
     int o, found = 0;
     for (o = 0; (help[o].cmd) && (help[o].desc); o++)
-      if (!egg_strcasecmp(help[o].cmd, cmds[i].name)) found++;
+      if (!egg_strcasecmp(help[o].cmd, cmdlist[i].name)) found++;
     if (!found) {
-      buf = nrealloc(buf, strlen(buf) + 2 + strlen(cmds[i].name) + 1);
-      strcat(buf, cmds[i].name);
+      buf = nrealloc(buf, strlen(buf) + 2 + strlen(cmdlist[i].name) + 1);
+      strcat(buf, cmdlist[i].name);
       strcat(buf, ", ");
     }
   }
@@ -804,7 +803,7 @@ static void cmd_help(struct userrec *u, int idx, char *par)
   }
   if (!nowild)
     dprintf(idx, STR("Showing help topics matching '%s' for flags: (%s)\n"), match, flg);
-  qsort(cmds, cmdi, sizeof(mycmds), (int (*)()) &my_cmp);
+  qsort(cmdlist, cmdi, sizeof(mycmds), (int (*)()) &my_cmp);
   buf[0] = 0;
   /* even if we have nowild, we loop to conserve code/space */
   while (!done) {
@@ -816,12 +815,12 @@ static void cmd_help(struct userrec *u, int idx, char *par)
       done = 1;
 
     for (n = 0; n < cmdi; n++) { /* loop each command */
-      if (!flagrec_ok(&cmds[n].flags, &fr) || !wild_match(match, cmds[n].name))
+      if (!flagrec_ok(&cmdlist[n].flags, &fr) || !wild_match(match, cmdlist[n].name))
         continue;
       fnd++;
       if (nowild) {
         flg[0] = 0;
-        build_flags(flg, &(cmds[n].flags), NULL);
+        build_flags(flg, &(cmdlist[n].flags), NULL);
         dprintf(idx, STR("Showing you help for '%s' (%s):\n"), match, flg);
         for (hi = 0; (help[hi].cmd) && (help[hi].desc); hi++) {
           if (!egg_strcasecmp(match, help[hi].cmd)) {
@@ -835,7 +834,7 @@ static void cmd_help(struct userrec *u, int idx, char *par)
         break;
       } else {
         flg[0] = 0;
-        build_flags(flg, &(cmds[n].flags), NULL);
+        build_flags(flg, &(cmdlist[n].flags), NULL);
         if (!strcmp(flg, flag)) {
           if (first) {
             dprintf(idx, "%s\n", buf[0] ? buf : "");
@@ -847,7 +846,7 @@ static void cmd_help(struct userrec *u, int idx, char *par)
             /* we dumped the buf to dprintf, now start a new one... */
             sprintf(buf, "  ");
           }
-          sprintf(buf, "%s%-14.14s", buf[0] ? buf : "", cmds[n].name);
+          sprintf(buf, "%s%-14.14s", buf[0] ? buf : "", cmdlist[n].name);
           first = 0;
           end = 0;
           i++;
@@ -2013,12 +2012,6 @@ static void cmd_trace(struct userrec *u, int idx, char *par)
   simple_sprintf(y, ":%d", now);
   botnet_send_trace(i, x, par, y);
 }
-
-static void cmd_binds(struct userrec *u, int idx, char *par)
-{
-  putlog(LOG_CMDS, "*", STR("#%s# binds %s"), dcc[idx].nick, par);
-  tell_binds(idx, par);
-}
 #endif /* HUB */
 
 /* After messing with someone's user flags, make sure the dcc-chat flags
@@ -4054,6 +4047,43 @@ static void cmd_whoami(struct userrec *u, int idx, char *par)
   dprintf(idx, "You are %s@%s.\n", dcc[idx].nick, botnetnick);
 }
 
+static void cmd_quit(struct userrec *u, int idx, char *text)
+{
+	if (dcc[idx].u.chat->channel >= 0 && dcc[idx].u.chat->channel < GLOBAL_CHANS) {
+		check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock, dcc[idx].u.chat->channel);
+	}
+	check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
+	dprintf(idx, "*** See you later cowboy!\n\n");
+	flush_lines(idx, dcc[idx].u.chat);
+	putlog(LOG_MISC, "*", "DCC connection closed (%s!%s)", dcc[idx].nick, dcc[idx].host);
+	if (dcc[idx].u.chat->channel >= 0) {
+		chanout_but(-1, dcc[idx].u.chat->channel, "*** %s left the party line%s%s\n", dcc[idx].nick, text[0] ? ": " : ".", text);
+		if (dcc[idx].u.chat->channel < 100000) {
+			botnet_send_part_idx(idx, text);
+		}
+	}
+
+	if (dcc[idx].u.chat->su_nick) {
+		dcc[idx].user = get_user_by_handle(userlist, dcc[idx].u.chat->su_nick);
+		dcc[idx].type = &DCC_CHAT;
+		dprintf(idx, "Returning to real nick %s!\n", dcc[idx].u.chat->su_nick);
+		nfree(dcc[idx].u.chat->su_nick);
+		dcc[idx].u.chat->su_nick = NULL;
+		dcc_chatter(idx);
+		if (dcc[idx].u.chat->channel < 100000 && dcc[idx].u.chat->channel >= 0) {
+			botnet_send_join_idx(idx, -1);
+		}
+	}
+	else if ((dcc[idx].sock != STDOUT) || backgrd) {
+		killsock(dcc[idx].sock);
+		lostdcc(idx);
+	}
+	else {
+		dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
+		dcc_chatter(idx);
+	}
+}
+
 /* DCC CHAT COMMANDS
  */
 /* Function call should be:
@@ -4078,7 +4108,6 @@ cmd_t C_dcc[] =
   {"back",		"",	(Function) cmd_back,		NULL},
 #ifdef HUB
   {"backup",		"m|m",	(Function) cmd_backup,		NULL},
-  {"binds",		"a",	(Function) cmd_binds,		NULL},
   {"boot",		"m",	(Function) cmd_boot,		NULL},
   {"botconfig",		"n",	(Function) cmd_botconfig,	NULL},
   {"botinfo",		"",	(Function) cmd_botinfo,		NULL},
@@ -4133,7 +4162,7 @@ cmd_t C_dcc[] =
   {"secpass",		"",	(Function) cmd_secpass,		NULL},
   {"nick",		"",	(Function) cmd_handle,		NULL,		1},
   {"page",		"",	(Function) cmd_page,		NULL},
-  {"quit",		"",	(Function) NULL,		NULL},
+  {"quit",		"",	(Function) cmd_quit,		NULL},
   {"relay",		"i",	(Function) cmd_relay,		NULL},
 #ifdef HUB
   {"reload",		"m|m",	(Function) cmd_reload,		NULL},

+ 21 - 0
src/core_binds.c

@@ -0,0 +1,21 @@
+#include "main.h"
+
+static bind_table_t *BT_time, *BT_event;
+
+void core_binds_init()
+{
+	BT_time = add_bind_table2("time", 5, "iiiii", MATCH_MASK, BIND_STACKABLE);
+	BT_event = add_bind_table2("event", 1, "s", MATCH_MASK, BIND_STACKABLE);
+}
+
+void check_bind_time(struct tm *tm)
+{
+	char full[32];
+	egg_snprintf(full, sizeof(full), "%02d %02d %02d %02d %04d", tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
+	check_bind(BT_time, full, NULL, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
+}
+
+void check_bind_event(char *event)
+{
+	check_bind(BT_event, event, NULL, event);
+}

+ 8 - 0
src/core_binds.h

@@ -0,0 +1,8 @@
+#ifndef _CORE_BINDS_H_
+#define _CORE_BINDS_H_
+
+void core_binds_init();
+void check_bind_time(struct tm *tm);
+void check_bind_event(char *event);
+
+#endif

+ 60 - 109
src/dcc.c

@@ -1038,109 +1038,68 @@ static void dcc_chat(int idx, char *buf, int i)
       strcpy(d, "\033[0m");
     else
       *d = 0;
-    if (buf[0]) {		/* Nothing to say - maybe paging... */
-
-      if (u_pass_match(dcc[idx].user, buf)) { //user said their password :)
-        dprintf(idx, "Sure you want that going to the partyline? ;) (msg to partyline halted.)\n");
-      } else if (!strncmp(buf, "+Auth ", 6)) {              /* ignore extra +Auth lines */
-      } else if ((!strncmp(buf, dcc_prefix, strlen(dcc_prefix))) || (dcc[idx].u.chat->channel < 0)) {
-
-	if (!strncmp(buf, dcc_prefix,strlen(dcc_prefix)))
-	  buf++;
-	v = newsplit(&buf);
-	rmspace(buf);
-	if (check_tcl_dcc(v, idx, buf)) {
-	  if (dcc[idx].u.chat->channel >= 0)
-	    check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
-			   dcc[idx].u.chat->channel);
-	  check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
-	  flush_lines(idx, dcc[idx].u.chat);
-	  putlog(LOG_MISC, "*", DCC_CLOSED, dcc[idx].nick,
-		 dcc[idx].host);
-	  if (dcc[idx].u.chat->channel >= 0) {
-	    chanout_but(-1, dcc[idx].u.chat->channel,
-			"*** %s left the party line%s%s\n",
-			dcc[idx].nick, buf[0] ? ": " : ".", buf);
-	    if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
-	      botnet_send_part_idx(idx, buf);
-	  }
-	  if (dcc[idx].u.chat->su_nick) {
-	    dcc[idx].user = get_user_by_handle(userlist,
-					       dcc[idx].u.chat->su_nick);
-	    strcpy(dcc[idx].nick, dcc[idx].u.chat->su_nick);
-	    dcc[idx].type = &DCC_CHAT;
-	    dprintf(idx, "Returning to real nick %s!\n",
-		    dcc[idx].u.chat->su_nick);
-	    nfree(dcc[idx].u.chat->su_nick);
-	    dcc[idx].u.chat->su_nick = NULL;
-	    dcc_chatter(idx);
-	    if (dcc[idx].u.chat->channel < GLOBAL_CHANS &&
-		dcc[idx].u.chat->channel >= 0)
-	      botnet_send_join_idx(idx, -1);
-	    return;
-	  } else if ((dcc[idx].sock != STDOUT) || backgrd) {
-	    killsock(dcc[idx].sock);
-	    lostdcc(idx);
-	    return;
-	  } else {
-	    dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
-	    dcc_chatter(idx);
-	    return;
-	  }
-	}
-      } else if (buf[0] == ',') {
-	int me = 0;
-
-	if ((buf[1] == 'm') && (buf[2] == 'e') && buf[3] == ' ')
-	  me = 1;
-	for (i = 0; i < dcc_total; i++) {
-	  int ok = 0;
-
-	  if (dcc[i].type->flags & DCT_MASTER) {
-	    if ((dcc[i].type != &DCC_CHAT) ||
-		(dcc[i].u.chat->channel >= 0))
-	      if ((i != idx) || (dcc[idx].status & STAT_ECHO))
-		ok = 1;
-	  }
-	  if (ok) {
-	    struct userrec *u = get_user_by_handle(userlist, dcc[i].nick);
-
-	    if (u && (u->flags & USER_MASTER)) {
-	      if (me)
-		dprintf(i, "-> %s%s\n", dcc[idx].nick, buf + 3);
-	      else
-		dprintf(i, "-%s-> %s\n", dcc[idx].nick, buf + 1);
-	    }
-	  }
-	}
-      } else if (buf[0] == '\'') {
-	int me = 0;
-
-	if ((buf[1] == 'm') && (buf[2] == 'e') &&
-	    ((buf[3] == ' ') || (buf[3] == '\'') || (buf[3] == ',')))
-	  me = 1;
-	for (i = 0; i < dcc_total; i++) {
-	  if (dcc[i].type->flags & DCT_CHAT) {
-	    if (me)
-	      dprintf(i, "=> %s%s\n", dcc[idx].nick, buf + 3);
-	    else
-	      dprintf(i, "=%s=> %s\n", dcc[idx].nick, buf + 1);
-	  }
+
+    if (u_pass_match(dcc[idx].user, buf)) { //user said their password :)
+      dprintf(idx, "Sure you want that going to the partyline? ;) (msg to partyline halted.)\n");
+    } else if (!strncmp(buf, "+Auth ", 6)) {              /* ignore extra +Auth lines */
+    } else if ((!strncmp(buf, dcc_prefix, strlen(dcc_prefix))) || (dcc[idx].u.chat->channel < 0)) {
+
+      if (!strncmp(buf, dcc_prefix,strlen(dcc_prefix)))
+        buf++;
+        v = newsplit(&buf);
+        rmspace(buf);
+	check_tcl_dcc(v, idx, buf);
+    } else if (buf[0] == ',') {
+      int me = 0;
+
+      if ((buf[1] == 'm') && (buf[2] == 'e') && buf[3] == ' ')
+        me = 1;
+      for (i = 0; i < dcc_total; i++) {
+        int ok = 0;
+
+        if (dcc[i].type->flags & DCT_MASTER) {
+          if ((dcc[i].type != &DCC_CHAT) || (dcc[i].u.chat->channel >= 0))
+            if ((i != idx) || (dcc[idx].status & STAT_ECHO))
+              ok = 1;
+        }
+        if (ok) {
+          struct userrec *u = get_user_by_handle(userlist, dcc[i].nick);
+
+          if (u && (u->flags & USER_MASTER)) {
+            if (me)
+              dprintf(i, "-> %s%s\n", dcc[idx].nick, buf + 3);
+             else
+              dprintf(i, "-%s-> %s\n", dcc[idx].nick, buf + 1);
+          }
+        }
+      }
+    } else if (buf[0] == '\'') {
+      int me = 0;
+
+      if ((buf[1] == 'm') && (buf[2] == 'e') && ((buf[3] == ' ') || (buf[3] == '\'') || (buf[3] == ',')))
+        me = 1;
+      for (i = 0; i < dcc_total; i++) {
+        if (dcc[i].type->flags & DCT_CHAT) {
+	  if (me)
+	    dprintf(i, "=> %s%s\n", dcc[idx].nick, buf + 3);
+	  else
+	    dprintf(i, "=%s=> %s\n", dcc[idx].nick, buf + 1);
 	}
-      } else {
-	if (dcc[idx].u.chat->away != NULL)
-	  not_away(idx);
-	if (dcc[idx].status & STAT_ECHO)
-	  chanout_but(-1, dcc[idx].u.chat->channel,
-		      "<%s> %s\n", dcc[idx].nick, buf);
-	else
-	  chanout_but(idx, dcc[idx].u.chat->channel, "<%s> %s\n",
-		      dcc[idx].nick, buf);
-	botnet_send_chan(-1, botnetnick, dcc[idx].nick,
-			 dcc[idx].u.chat->channel, buf);
-	check_tcl_chat(dcc[idx].nick, dcc[idx].u.chat->channel, buf);
       }
-    }
+    } else {
+	int r;
+
+	r = check_tcl_chat(dcc[idx].nick, dcc[idx].u.chat->channel, buf);
+	if (r & BIND_RET_BREAK) return;
+
+      if (dcc[idx].u.chat->away != NULL)
+        not_away(idx);
+       if (dcc[idx].status & STAT_ECHO)
+         chanout_but(-1, dcc[idx].u.chat->channel, "<%s> %s\n", dcc[idx].nick, buf);
+       else
+         chanout_but(idx, dcc[idx].u.chat->channel, "<%s> %s\n", dcc[idx].nick, buf);
+       botnet_send_chan(-1, botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel, buf);
+    }  
   }
   if (dcc[idx].type == &DCC_CHAT)	/* Could have change to files */
     if (dcc[idx].status & STAT_PAGE)
@@ -1883,14 +1842,6 @@ static void dcc_telnet_got_ident(int i, char *host)
     lostdcc(i);
     return;
   }
-  /* Script? */
-  if (!strcmp(dcc[idx].nick, "(script)")) {
-    dcc[i].type = &DCC_SOCKET;
-    dcc[i].u.other = NULL;
-    strcpy(dcc[i].nick, "*");
-    check_tcl_listen(dcc[idx].host, dcc[i].sock);
-    return;
-  }
   /* Do not buffer data anymore. All received and stored data is passed
      over to the dcc functions from now on.  */
   sockoptions(dcc[i].sock, EGG_OPTION_UNSET, SOCK_BUFFER);

+ 0 - 110
src/dns.c

@@ -259,69 +259,6 @@ devent_type DNS_TCLEVENT_IPBYHOST = {
   dns_tcl_iporhostres
 };
 
-static void tcl_dnsipbyhost(char *hostn, char *proc, char *paras)
-{
-  devent_t *de;
-  devent_tclinfo_t *tclinfo;
-
-  de = nmalloc(sizeof(devent_t));
-  egg_bzero(de, sizeof(devent_t));
-
-  /* Link into list. */
-  de->next = dns_events;
-  dns_events = de;
-
-  de->type = &DNS_TCLEVENT_IPBYHOST;
-  de->lookup = RES_IPBYHOST;
-  de->res_data.hostname = nmalloc(strlen(hostn) + 1);
-  strcpy(de->res_data.hostname, hostn);
-
-  /* Store additional data. */
-  tclinfo = nmalloc(sizeof(devent_tclinfo_t));
-  tclinfo->proc = nmalloc(strlen(proc) + 1);
-  strcpy(tclinfo->proc, proc);
-  if (paras) {
-    tclinfo->paras = nmalloc(strlen(paras) + 1);
-    strcpy(tclinfo->paras, paras);
-  } else
-    tclinfo->paras = NULL;
-  de->other = tclinfo;
-
-  /* Send request. */
-  dns_ipbyhost(hostn);
-}
-
-static void tcl_dnshostbyip(IP ip, char *proc, char *paras)
-{
-  devent_t *de;
-  devent_tclinfo_t *tclinfo;
-
-  de = nmalloc(sizeof(devent_t));
-  egg_bzero(de, sizeof(devent_t));
-
-  /* Link into list. */
-  de->next = dns_events;
-  dns_events = de;
-
-  de->type = &DNS_TCLEVENT_HOSTBYIP;
-  de->lookup = RES_HOSTBYIP;
-  de->res_data.ip_addr = ip;
-
-  /* Store additional data. */
-  tclinfo = nmalloc(sizeof(devent_tclinfo_t));
-  tclinfo->proc = nmalloc(strlen(proc) + 1);
-  strcpy(tclinfo->proc, proc);
-  if (paras) {
-    tclinfo->paras = nmalloc(strlen(paras) + 1);
-    strcpy(tclinfo->paras, paras);
-  } else
-    tclinfo->paras = NULL;
-  de->other = tclinfo;
-
-  /* Send request. */
-  dns_hostbyip(ip);
-}
-
 
 /*
  *    Event functions
@@ -469,50 +406,3 @@ int expmem_dns(void)
 }
 
 
-/*
- *   Tcl functions
- */
-
-/* dnslookup <ip-address> <proc> */
-static int tcl_dnslookup STDVAR
-{
-  struct in_addr inaddr;
-  char *paras = NULL;
-
-  /* This function should be using BADARGS, FIXME -poptix */
-  if (argc < 3) {
-    Tcl_AppendResult(irp, "wrong # args: should be \"", argv[0],
-		     " ip-address/hostname proc ?args...?\"", NULL);
-    return TCL_ERROR;
-  }
-
-  if (argc > 3) {
-    int l = 0, p;
-
-    /* Create a string with a leading space out of all provided
-     * additional parameters.
-     */
-    paras = nmalloc(1);
-    paras[0] = 0;
-    for (p = 3; p < argc; p++) {
-      l += strlen(argv[p]) + 1;
-      paras = nrealloc(paras, l + 1);
-      strcat(paras, " ");
-      strcat(paras, argv[p]);
-    }
-  }
-
-  if (egg_inet_aton(argv[1], &inaddr))
-    tcl_dnshostbyip(ntohl(inaddr.s_addr), argv[2], paras);
-  else
-    tcl_dnsipbyhost(argv[1], argv[2], paras);
-  if (paras)
-    nfree(paras);
-  return TCL_OK;
-}
-
-tcl_cmds tcldns_cmds[] =
-{
-  {"dnslookup",	tcl_dnslookup},
-  {NULL,	NULL}
-};

+ 168 - 0
src/egg_timer.c

@@ -0,0 +1,168 @@
+#include <stdio.h> /* For NULL */
+#include <sys/time.h> /* For gettimeofday() */
+#include "main.h"
+
+#include "egg_timer.h"
+
+/* Internal use only. */
+typedef struct egg_timer_b {
+	struct egg_timer_b *next;
+	int id;
+	Function callback;
+	void *client_data;
+	egg_timeval_t howlong;
+	egg_timeval_t trigger_time;
+	int flags;
+} egg_timer_t;
+
+/* We keep a sorted list of active timers. */
+static egg_timer_t *timer_list_head = NULL;
+static unsigned int timer_next_id = 1;
+
+/* Based on TclpGetTime from Tcl 8.3.3 */
+int timer_get_time(egg_timeval_t *curtime)
+{
+	struct timeval tv;
+	struct timezone tz;
+
+	(void) gettimeofday(&tv, &tz);
+	curtime->sec = tv.tv_sec;
+	curtime->usec = tv.tv_usec;
+	return(0);
+}
+
+int timer_create_complex(egg_timeval_t *howlong, Function callback, void *client_data, int flags)
+{
+	egg_timer_t *timer, *prev;
+	egg_timeval_t trigger_time;
+
+	timer_get_time(&trigger_time);
+	trigger_time.sec += howlong->sec;
+	trigger_time.usec += howlong->usec;
+
+	/* Find out where this should go in the list. */
+	prev = NULL;
+	for (timer = timer_list_head; timer; timer = timer->next) {
+		if (trigger_time.sec < timer->trigger_time.sec) break;
+		if (trigger_time.sec == timer->trigger_time.sec && trigger_time.usec < timer->trigger_time.usec) break;
+		prev = timer;
+	}
+
+	/* Fill out a new timer. */
+	timer = (egg_timer_t *)nmalloc(sizeof(*timer));
+	timer->callback = callback;
+	timer->client_data = client_data;
+	timer->flags = flags;
+	egg_memcpy(&timer->howlong, howlong, sizeof(*howlong));
+	egg_memcpy(&timer->trigger_time, &trigger_time, sizeof(trigger_time));
+	timer->id = timer_next_id++;
+
+	/* Insert into timer list. */
+	if (prev) {
+		timer->next = prev->next;
+		prev->next = timer;
+	}
+	else {
+		timer->next = timer_list_head;
+		timer_list_head = timer;
+	}
+
+	if (timer_next_id == 0) timer_next_id++;
+
+	return(timer->id);
+}
+
+/* Destroy a timer, given an id. */
+int timer_destroy(int timer_id)
+{
+	egg_timer_t *prev, *timer;
+
+	prev = NULL;
+	for (timer = timer_list_head; timer; timer = timer->next) {
+		if (timer->id == timer_id) break;
+	}
+
+	if (!timer) return(1); /* Not found! */
+
+	/* Unlink it. */
+	if (prev) prev->next = timer->next;
+	else timer_list_head = timer->next;
+
+	nfree(timer);
+	return(0);
+}
+
+int timer_destroy_all()
+{
+	egg_timer_t *timer;
+
+	for (timer = timer_list_head; timer; timer = timer->next) {
+		nfree(timer);
+	}
+	timer_list_head = NULL;
+	return(0);
+}
+
+int timer_get_shortest(egg_timeval_t *howlong)
+{
+	egg_timeval_t curtime;
+	egg_timer_t *timer = timer_list_head;
+
+	/* No timers? Boo. */
+	if (!timer) return(1);
+
+	timer_get_time(&curtime);
+
+	if (timer->trigger_time.sec <= curtime.sec) howlong->sec = 0;
+	else howlong->sec = timer->trigger_time.sec - curtime.sec;
+
+	if (timer->trigger_time.usec <= curtime.usec) howlong->usec = 0;
+	else howlong->usec = timer->trigger_time.usec - curtime.usec;
+
+	return(0);
+}
+
+int timer_run()
+{
+	egg_timeval_t curtime;
+	egg_timer_t *timer;
+	Function callback;
+	void *client_data;
+
+	while ((timer = timer_list_head)) {
+		timer_get_time(&curtime);
+		if (timer->trigger_time.sec > curtime.sec || (timer->trigger_time.sec == curtime.sec && timer->trigger_time.usec > curtime.usec)) break;
+
+		timer_list_head = timer_list_head->next;
+
+		callback = timer->callback;
+		client_data = timer->client_data;
+
+		if (timer->flags & TIMER_REPEAT) {
+			egg_timer_t *prev, *tptr;
+
+			/* Update timer. */
+			timer->trigger_time.sec += timer->howlong.sec;
+			timer->trigger_time.usec += timer->howlong.usec;
+
+			prev = NULL;
+			for (tptr = timer_list_head; tptr; tptr = tptr->next) {
+				if (tptr->trigger_time.sec > timer->trigger_time.sec || (tptr->trigger_time.sec == timer->trigger_time.sec && tptr->trigger_time.usec > timer->trigger_time.usec)) break;
+				prev = tptr;
+			}
+			if (prev) {
+				timer->next = prev->next;
+				prev->next = timer;
+			}
+			else {
+				timer->next = timer_list_head;
+				timer_list_head = timer;
+			}
+		}
+		else {
+			nfree(timer);
+		}
+		callback(client_data);
+	}
+	return(0);
+}

+ 24 - 0
src/egg_timer.h

@@ -0,0 +1,24 @@
+#ifndef _EGG_TIMER_H_
+#define _EGG_TIMER_H_
+
+typedef struct egg_timeval_b {
+	int sec;
+	int usec;
+} egg_timeval_t;
+
+#define TIMER_REPEAT 1
+
+/* Create a simple timer with no client data and no flags. */
+#define timer_create(howlong,callback) timer_create_complex(howlong, callback, NULL, 0)
+
+/* Create a simple timer with no client data, but it repeats. */
+#define timer_create_repeater(howlong,callback) timer_create_complex(howlong, callback, NULL, TIMER_REPEAT)
+
+int timer_get_time(egg_timeval_t *curtime);
+int timer_create_complex(egg_timeval_t *howlong, Function callback, void *client_data, int flags);
+int timer_destroy(int timer_id);
+int timer_destroy_all();
+int timer_get_shortest(egg_timeval_t *howlong);
+int timer_run();
+
+#endif /* _EGG_TIMER_H_ */

+ 2 - 0
src/flags.c

@@ -474,6 +474,7 @@ int build_flags(char *string, struct flag_record *plus,
   return string - old;
 }
 
+/* Returns 1 if flags match, 0 if they don't. */
 int flagrec_ok(struct flag_record *req,
 	       struct flag_record *have)
 {
@@ -513,6 +514,7 @@ int flagrec_ok(struct flag_record *req,
   return 0;			/* fr0k3 binding, dont pass it */
 }
 
+/* Returns 1 if flags match, 0 if they don't. */
 int flagrec_eq(struct flag_record *req, struct flag_record *have)
 {
   if (req->match & FR_AND) {

+ 16 - 23
src/main.c

@@ -33,6 +33,8 @@
 #include "chan.h"
 #include "modules.h"
 #include "tandem.h"
+#include "egg_timer.h"
+#include "core_binds.h"
 
 #ifdef CYGWIN_HACKS
 #include <windows.h>
@@ -62,8 +64,6 @@ extern struct dcc_t	*dcc;
 extern struct userrec	*userlist;
 extern struct chanset_t	*chanset;
 extern Tcl_Interp	*interp;
-extern tcl_timer_t	*timer,
-			*utimer;
 
 
 const time_t 	buildts = CVSBUILD;		/* build timestamp (UTC) */
@@ -493,7 +493,7 @@ static void core_secondly()
 #ifdef CRAZY_TRACE 
   if (!attached) crazy_trace();
 #endif /* CRAZY_TRACE */
-  do_check_timers(&utimer);	/* Secondly timers */
+  call_hook(HOOK_SECONDLY);	/* Will be removed later */
   if (fork_interval && backgrd) {
     if ((now - lastfork) > fork_interval)
       do_fork();
@@ -595,8 +595,7 @@ static void core_minutely()
 #ifdef LEAF
   check_mypid();
 #endif
-  check_tcl_time(&nowtm);
-  do_check_timers(&timer);
+  check_bind_time(&nowtm);
 /*     flushlogs(); */
 }
 
@@ -613,17 +612,17 @@ static void core_halfhourly()
 
 static void event_rehash()
 {
-  check_tcl_event("rehash");
+  check_bind_event("rehash");
 }
 
 static void event_prerehash()
 {
-  check_tcl_event("prerehash");
+  check_bind_event("prerehash");
 }
 
 static void event_save()
 {
-  check_tcl_event("save");
+  check_bind_event("save");
 }
 
 static void event_resettraffic()
@@ -645,7 +644,6 @@ static void event_resettraffic()
   itraffic_trans_today = otraffic_trans_today = 0;
 }
 
-void kill_tcl();
 extern module_entry *module_list;
 void restart_chons();
 
@@ -655,15 +653,7 @@ void check_static(char *, char *(*)());
 int init_mem(), init_dcc_max(), init_userent(), init_misc(), init_auth(), init_config(), init_bots(),
  init_net(), init_modules(), init_tcl(int, char **), init_botcmd(), init_settings();
 
-static inline void garbage_collect(void)
-{
-  static u_8bit_t	run_cnt = 0;
-
-  if (run_cnt == 3)
-    garbage_collect_tclhash();
-  else
-    run_cnt++;
-}
+void binds_init();
 
 int crontab_exists() {
   char buf[2048], *out=NULL;
@@ -927,6 +917,7 @@ void check_trace_start()
 
 int main(int argc, char **argv)
 {
+  egg_timeval_t howlong;
   int xx, i;
 #ifdef LEAF
   int x = 1;
@@ -1005,6 +996,8 @@ int main(int argc, char **argv)
 
   /* just load everything now, won't matter if it's loaded if the bot has to suicide on startup */
   init_settings();
+  binds_init();
+  core_binds_init();
   init_dcc_max();
   init_userent();
   init_misc();
@@ -1371,7 +1364,9 @@ int main(int argc, char **argv)
   then = now;
   online_since = now;
   autolink_cycle(NULL);		/* Hurry and connect to tandem bots */
-  add_hook(HOOK_SECONDLY, (Function) core_secondly);
+  howlong.sec = 1;
+  howlong.usec = 0;
+  timer_create_repeater(&howlong, (Function) core_secondly);
   add_hook(HOOK_10SECONDLY, (Function) core_10secondly);
   add_hook(HOOK_30SECONDLY, (Function) expire_simuls);
   add_hook(HOOK_MINUTELY, (Function) core_minutely);
@@ -1393,8 +1388,9 @@ int main(int argc, char **argv)
      * calls to periodic_timers
      */
     now = time(NULL);
+    timer_run();
     if (now != then) {		/* Once a second */
-      call_hook(HOOK_SECONDLY);
+/*      call_hook(HOOK_SECONDLY); */
       then = now;
     }
 
@@ -1410,9 +1406,6 @@ int main(int argc, char **argv)
     } else
       socket_cleanup--;
 
-    /* Free unused structures. */
-    garbage_collect();
-    
     buf[0] = 0;
     xx = sockgets(buf, &i); 
     if (xx >= 0) {		/* Non-error */

+ 7 - 7
src/misc.c

@@ -565,7 +565,7 @@ int getting_users()
 void putlog EGG_VARARGS_DEF(int, arg1)
 {
   int i, type, tsl = 0, dohl = 0; //hl
-  char *format, *chname, s[LOGLINELEN], *out, stamp[34], buf2[LOGLINELEN]; 
+  char *format, *chname, s[LOGLINELEN], *out = NULL, stamp[34], buf2[LOGLINELEN]; 
   va_list va;
 #ifdef HUB
   time_t now2 = time(NULL);
@@ -868,7 +868,7 @@ void check_last() {
   char user[20];
   struct passwd *pw;
 
-  if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "ignore", STR("ignore")))
+  if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "ignore", "ignore"))
     return;
 
   pw = getpwuid(geteuid());
@@ -916,7 +916,7 @@ void check_processes()
     buf[1024],
     bin[128];
 
-  if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "ignore", STR("ignore")))
+  if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "ignore", "ignore"))
     return;
 
   proclist = (char *) (CFG_PROCESSLIST.ldata && ((char *) CFG_PROCESSLIST.ldata)[0] ?
@@ -1022,7 +1022,7 @@ void check_promisc()
   char *cp, *cplim;
   int sock;
 
-  if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "ignore", STR("ignore")))
+  if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "ignore", "ignore"))
     return;
   sock = socket(AF_INET, SOCK_STREAM, 0);
   ifcnf.ifc_len = 8191;
@@ -1063,8 +1063,8 @@ void check_trace(int n)
 #ifdef S_ANTITRACE
   int x, parent, i;
   struct sigaction sv, *oldsv = NULL;
-
-  if (n && !strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "ignore", STR("ignore")))
+return;
+  if (n && !strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "ignore", "ignore"))
     return;
   parent = getpid();
 #ifdef __linux__
@@ -1373,7 +1373,7 @@ int updatebin (int idx, char *par, int autoi)
   copyfile(binname, old);
 
   /* The binary should return '2' when ran with -2, if not it's probably corrupt. */
-  snprintf(testbuf, sizeof testbuf, "%s -2", path);
+  egg_snprintf(testbuf, sizeof testbuf, "%s -2", path);
   i = system(testbuf);
   if (i == -1 || WEXITSTATUS(i) != 2) {
     if (idx)

+ 11 - 3
src/mod/channels.mod/channels.c

@@ -45,6 +45,8 @@ static int 			gfld_nick_time;
 int 				killed_bots = 0;
 #endif /* S_AUTOLOCK */
 
+static bind_table_t *BT_dcc, *BT_bot, *BT_chon;
+
 #include "channels.h"
 #include "cmdschan.c"
 #include "tclchan.c"
@@ -1079,9 +1081,15 @@ char *channels_start(Function * global_funcs)
   add_hook(HOOK_MINUTELY, (Function) check_expired_invites);
   add_hook(HOOK_USERFILE, (Function) channels_writeuserfile);
   add_hook(HOOK_10SECONDLY, (Function) channels_10secondly);
-  add_builtins(H_chon, my_chon);
-  add_builtins(H_dcc, C_dcc_irc);
-  add_builtins(H_bot, channels_bot);
+
+  BT_dcc = find_bind_table2("dcc");
+  BT_bot = find_bind_table2("bot");
+  BT_chon = find_bind_table2("chon");
+
+  if (BT_dcc) add_builtins2(BT_dcc, C_dcc_irc);
+  if (BT_bot) add_builtins2(BT_bot, channels_bot);
+  if (BT_chon) add_builtins2(BT_chon, my_chon);
+
   add_tcl_commands(channels_cmds);
 #ifdef S_AUTOLOCK
   add_cfg(&CFG_LOCKTHRESHOLD);

+ 8 - 2
src/mod/console.mod/console.c

@@ -16,6 +16,8 @@ static int console_autosave = 1;
 static int force_channel = 0;
 static int info_party = 1;
 
+static bind_table_t *BT_dcc, *BT_chon;
+
 struct console_info {
   char *channel;
   int conflags;
@@ -438,8 +440,12 @@ char *console_start(Function * global_funcs)
   global = global_funcs;
 
   module_register(MODULE_NAME, console_table, 1, 1);
-  add_builtins(H_chon, mychon);
-  add_builtins(H_dcc, mydcc);
+  BT_dcc = find_bind_table2("dcc");
+  BT_chon = find_bind_table2("chon");
+
+  if (BT_dcc) add_builtins2(BT_dcc, mydcc);
+  if (BT_chon) add_builtins2(BT_chon, mychon);
+
   add_tcl_ints(myints);
   USERENTRY_CONSOLE.get = def_get;
   add_entry_type(&USERENTRY_CONSOLE);

+ 69 - 66
src/mod/ctcp.mod/ctcp.c

@@ -17,6 +17,9 @@
 #include <pwd.h>
 #include <ctype.h>
 
+/* Import this bind table from server.mod */
+static bind_table_t *BT_ctcp;
+
 static Function *global = NULL, *server_funcs = NULL;
 #else /* !LEAF */
 static Function *global = NULL;
@@ -437,7 +440,7 @@ static void ctcp_minutely()
     listen_time--;
 }
 
-static int ctcp_FINGER(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_FINGER(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   char *p;
   int idletime;
@@ -460,7 +463,7 @@ static int ctcp_FINGER(char *nick, char *uhost, char *handle, char *object, char
   return 1;
 }
 
-static int ctcp_ECHO(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_ECHO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   char reply[60];
 
@@ -468,7 +471,7 @@ static int ctcp_ECHO(char *nick, char *uhost, char *handle, char *object, char *
   dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, reply);
   return 1;
 }
-static int ctcp_PING(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_PING(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
 
   if (strlen(text) <= 80)       /* bitchx ignores > 80 */
@@ -476,7 +479,7 @@ static int ctcp_PING(char *nick, char *uhost, char *handle, char *object, char *
   return 1;
 }
 
-static int ctcp_VERSION(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_VERSION(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   char s[50] = "";
 
@@ -514,14 +517,14 @@ static int ctcp_VERSION(char *nick, char *uhost, char *handle, char *object, cha
   return 1;
 }
 
-static int ctcp_WHOAMI(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_WHOAMI(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
 
   dprintf(DP_HELP, STR("NOTICE %s :\002BitchX\002: Access Denied\n"), nick);
   return 1;
 }
 
-static int ctcp_OP(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_OP(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   char chan[256],
    *p;
@@ -535,7 +538,8 @@ static int ctcp_OP(char *nick, char *uhost, char *handle, char *object, char *ke
   }
   return 1;
 }
-static int ctcp_INVITE_UNBAN(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+
+static int ctcp_INVITE_UNBAN(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   struct chanset_t *chan = chanset;
   char chname[256],
@@ -560,7 +564,7 @@ static int ctcp_INVITE_UNBAN(char *nick, char *uhost, char *handle, char *object
   return 1;
 }
 
-static int ctcp_USERINFO(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_USERINFO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
 
   if (cloak_script == CLOAK_TUNNELVISION)
@@ -573,67 +577,67 @@ static int ctcp_USERINFO(char *nick, char *uhost, char *handle, char *object, ch
   return 1;
 }
 
-static int ctcp_CLIENTINFO(char *nick, char *uhost, char *handle, char *object, char *keyword, char *msg)
+static int ctcp_CLIENTINFO(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
-  char text[256];
-
-  if (!msg[0]) {
-    strcpy(text, STR("SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information"));
-  } else if (!egg_strcasecmp(msg, STR("UNBAN")))
-    strcpy(text, STR("UNBAN unbans the person from channel"));
-  else if (!egg_strcasecmp(msg, STR("OPS")))
-    strcpy(text, STR("OPS ops the person if on userlist"));
-  else if (!egg_strcasecmp(msg, STR("ECHO")))
-    strcpy(text, STR("ECHO returns the arguments it receives"));
-  else if (!egg_strcasecmp(msg, STR("WHOAMI")))
-    strcpy(text, STR("WHOAMI user list information"));
-  else if (!egg_strcasecmp(msg, STR("INVITE")))
-    strcpy(text, STR("INVITE invite to channel specified"));
-  else if (!egg_strcasecmp(msg, STR("PING")))
-    strcpy(text, STR("PING returns the arguments it receives"));
-  else if (!egg_strcasecmp(msg, STR("UTC")))
-    strcpy(text, STR("UTC substitutes the local timezone"));
-  else if (!egg_strcasecmp(msg, STR("XDCC")))
-    strcpy(text, STR("XDCC checks cdcc info for you"));
-  else if (!egg_strcasecmp(msg, STR("BDCC")))
-    strcpy(text, STR("BDCC checks cdcc info for you"));
-  else if (!egg_strcasecmp(msg, STR("CDCC")))
-    strcpy(text, STR("CDCC checks cdcc info for you"));
-  else if (!egg_strcasecmp(msg, STR("DCC")))
-    strcpy(text, STR("DCC requests a direct_client_connection"));
-  else if (!egg_strcasecmp(msg, STR("ACTION")))
-    strcpy(text, STR("ACTION contains action descriptions for atmosphere"));
-  else if (!egg_strcasecmp(msg, STR("FINGER")))
-    strcpy(text, STR("FINGER shows real name, login name and idle time of user"));
-  else if (!egg_strcasecmp(msg, STR("ERRMSG")))
-    strcpy(text, STR("ERRMSG returns error messages"));
-  else if (!egg_strcasecmp(msg, STR("USERINFO")))
-    strcpy(text, STR("USERINFO returns user settable information"));
-  else if (!egg_strcasecmp(msg, STR("CLIENTINFO")))
-    strcpy(text, STR("CLIENTINFO gives information about available CTCP commands"));
-  else if (!egg_strcasecmp(msg, STR("SED")))
-    strcpy(text, STR("SED contains simple_encrypted_data"));
-  else if (!egg_strcasecmp(msg, "OP"))
-    strcpy(text, STR("OP ops the person if on userlist"));
-  else if (!egg_strcasecmp(msg, STR("VERSION")))
-    strcpy(text, STR("VERSION shows client type, version and environment"));
-  else if (!egg_strcasecmp(msg, STR("XLINK")))
-    strcpy(text, STR("XLINK x-filez rule"));
-  else if (!egg_strcasecmp(msg, STR("IDENT")))
-    strcpy(text, STR("IDENT change userhost of userlist"));
-  else if (!egg_strcasecmp(msg, STR("TIME")))
-    strcpy(text, STR("TIME tells you the time on the user's host"));
-  else if (!egg_strcasecmp(msg, STR("UPTIME")))
-    strcpy(text, STR("UPTIME my uptime"));
+  char buf[256];
+
+  if (!text[0]) {
+    strcpy(buf, STR("SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information"));
+  } else if (!egg_strcasecmp(text, STR("UNBAN")))
+    strcpy(buf, STR("UNBAN unbans the person from channel"));
+  else if (!egg_strcasecmp(text, STR("OPS")))
+    strcpy(buf, STR("OPS ops the person if on userlist"));
+  else if (!egg_strcasecmp(text, STR("ECHO")))
+    strcpy(buf, STR("ECHO returns the arguments it receives"));
+  else if (!egg_strcasecmp(text, STR("WHOAMI")))
+    strcpy(buf, STR("WHOAMI user list information"));
+  else if (!egg_strcasecmp(text, STR("INVITE")))
+    strcpy(buf, STR("INVITE invite to channel specified"));
+  else if (!egg_strcasecmp(text, STR("PING")))
+    strcpy(buf, STR("PING returns the arguments it receives"));
+  else if (!egg_strcasecmp(text, STR("UTC")))
+    strcpy(buf, STR("UTC substitutes the local timezone"));
+  else if (!egg_strcasecmp(text, STR("XDCC")))
+    strcpy(buf, STR("XDCC checks cdcc info for you"));
+  else if (!egg_strcasecmp(text, STR("BDCC")))
+    strcpy(buf, STR("BDCC checks cdcc info for you"));
+  else if (!egg_strcasecmp(text, STR("CDCC")))
+    strcpy(buf, STR("CDCC checks cdcc info for you"));
+  else if (!egg_strcasecmp(text, STR("DCC")))
+    strcpy(buf, STR("DCC requests a direct_client_connection"));
+  else if (!egg_strcasecmp(text, STR("ACTION")))
+    strcpy(buf, STR("ACTION contains action descriptions for atmosphere"));
+  else if (!egg_strcasecmp(text, STR("FINGER")))
+    strcpy(buf, STR("FINGER shows real name, login name and idle time of user"));
+  else if (!egg_strcasecmp(text, STR("ERRMSG")))
+    strcpy(buf, STR("ERRMSG returns error messages"));
+  else if (!egg_strcasecmp(text, STR("USERINFO")))
+    strcpy(buf, STR("USERINFO returns user settable information"));
+  else if (!egg_strcasecmp(text, STR("CLIENTINFO")))
+    strcpy(buf, STR("CLIENTINFO gives information about available CTCP commands"));
+  else if (!egg_strcasecmp(text, STR("SED")))
+    strcpy(buf, STR("SED contains simple_encrypted_data"));
+  else if (!egg_strcasecmp(text, "OP"))
+    strcpy(buf, STR("OP ops the person if on userlist"));
+  else if (!egg_strcasecmp(text, STR("VERSION")))
+    strcpy(buf, STR("VERSION shows client type, version and environment"));
+  else if (!egg_strcasecmp(text, STR("XLINK")))
+    strcpy(buf, STR("XLINK x-filez rule"));
+  else if (!egg_strcasecmp(text, STR("IDENT")))
+    strcpy(buf, STR("IDENT change userhost of userlist"));
+  else if (!egg_strcasecmp(text, STR("TIME")))
+    strcpy(buf, STR("TIME tells you the time on the user's host"));
+  else if (!egg_strcasecmp(text, STR("UPTIME")))
+    strcpy(buf, STR("UPTIME my uptime"));
   else {
-    dprintf(DP_HELP, STR("NOTICE %s :\001ERRMSG %s is not a valid function\001\n"), nick, msg);
+    dprintf(DP_HELP, STR("NOTICE %s :\001ERRMSG %s is not a valid function\001\n"), nick, text);
     return 0;
   }
-  dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, text);
+  dprintf(DP_HELP, STR("NOTICE %s :\001%s %s\001\n"), nick, keyword, buf);
   return 1;
 }
 
-static int ctcp_TIME(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_TIME(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
   char tms[81];
 
@@ -643,10 +647,8 @@ static int ctcp_TIME(char *nick, char *uhost, char *handle, char *object, char *
 }
 
 
-static int ctcp_CHAT(char *nick, char *uhost, char *handle, char *object, char *keyword, char *text)
+static int ctcp_CHAT(char *nick, char *uhost, struct userrec *u, char *object, char *keyword, char *text)
 {
-
-  struct userrec *u = get_user_by_handle(userlist, handle);
   int i, ix = (-1);
 
   if (!ischanhub())
@@ -790,7 +792,8 @@ char *ctcp_start(Function * global_funcs)
   }
   scriptchanged();
 
-  add_builtins(H_ctcp, myctcp);
+  BT_ctcp = find_bind_table2("ctcp");
+  if (BT_ctcp) add_builtins2(BT_ctcp, myctcp);
   add_hook(HOOK_MINUTELY, (Function) ctcp_minutely);
 #endif /* LEAF */
   add_cfg(&CFG_CLOAK_SCRIPT);

+ 38 - 63
src/mod/irc.mod/irc.c

@@ -39,6 +39,14 @@ struct cfg_entry CFG_OPBOTS,
 #endif /* S_AUTOLOCK */
   CFG_OPREQUESTS;
 
+
+/* We import some bind tables from server.mod */
+static bind_table_t *BT_dcc, *BT_bot, *BT_raw, *BT_msg, *BT_ctcp, *BT_ctcr;
+#ifdef S_AUTH
+static bind_table_t *BT_msgc;
+#endif /* S_AUTH */
+
+
 static Function *global = NULL, *channels_funcs = NULL, *server_funcs = NULL;
 
 
@@ -1265,69 +1273,18 @@ static void check_expired_chanstuff()
   }
 }
 
-static int channels_6char STDVAR
-{
-  Function F = (Function) cd;
-  char x[20];
-
-  BADARGS(7, 7, " nick user@host handle desto/chan keyword/nick text");
-  CHECKVALIDITY(channels_6char);
-  sprintf(x, "%d", F(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]));
-  Tcl_AppendResult(irp, x, NULL);
-  return TCL_OK;
-}
-
-static int channels_5char STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(6, 6, " nick user@host handle channel text");
-  CHECKVALIDITY(channels_5char);
-  F(argv[1], argv[2], argv[3], argv[4], argv[5]);
-  return TCL_OK;
-}
-
-static int channels_4char STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(5, 5, " nick uhost hand chan/param");
-  CHECKVALIDITY(channels_4char);
-  F(argv[1], argv[2], argv[3], argv[4]);
-  return TCL_OK;
-}
-
-static int channels_2char STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(3, 3, " channel type");
-  CHECKVALIDITY(channels_2char);
-  F(argv[1], argv[2]);
-  return TCL_OK;
-}
-
 #ifdef S_AUTH
-static int check_tcl_pubc(char *cmd, char *nick, char *uhost,
-                         struct userrec *u, char *args, char *chan)
+static int check_tcl_pubc(char *cmd, char *nick, char *from, struct userrec *u, char *args, char *chan)
 {
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
-  char *hand = u ? u->handle : "*";
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
   int x;
 
-  get_user_flagrec(u, &fr, chan);
-  Tcl_SetVar(interp, "_msgc1", nick, 0);
-  Tcl_SetVar(interp, "_msgc2", uhost, 0);
-  Tcl_SetVar(interp, "_msgc3", hand, 0);
-  Tcl_SetVar(interp, "_msgc4", args, 0);
-  Tcl_SetVar(interp, "_msgc5", chan, 0);
-  x = check_tcl_bind(H_msgc, cmd, &fr, " $_msgc1 $_msgc2 $_msgc3 $_msgc4 $_msgc5",
-                     MATCH_EXACT | BIND_HAS_BUILTINS | BIND_USE_ATTR);
-  if (x == BIND_EXEC_LOG)
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %s%s %s", nick, uhost, hand, chan, cmdprefix,
-           cmd, args);
-  return ((x == BIND_MATCHED) || (x == BIND_EXECUTED) || (x == BIND_EXEC_LOG));
+  x = check_bind(BT_msgc, cmd, &fr, nick, from, u, args, chan);
 
+  if (x & BIND_RET_LOG)
+    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %s%s %s", nick, from, u ? u->handle : "*", chan, cmdprefix, cmd, args);
+  if (x & BIND_RET_BREAK) return(1);
+  return(0);
 }
 #endif /* S_AUTH */
 
@@ -1722,13 +1679,31 @@ char *irc_start(Function * global_funcs)
 	       TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
 	       traced_rfccompliant, NULL);
   add_tcl_ints(myints);
-  add_builtins(H_bot, irc_bot);
-  add_builtins(H_dcc, irc_dcc);
-  add_builtins(H_msg, C_msg);
+  /* Import bind tables from other places. */
+  BT_dcc = find_bind_table2("dcc");
+  BT_bot = find_bind_table2("bot");
+  BT_raw = find_bind_table2("raw");
+  BT_msg = find_bind_table2("msg");
 #ifdef S_AUTH
-  add_builtins(H_msgc, C_msgc);
+  BT_msgc = find_bind_table2("msgc");
 #endif /* S_AUTH */
-  add_builtins(H_raw, irc_raw);
+  BT_ctcp = find_bind_table2("ctcp");
+  BT_ctcr = find_bind_table2("ctcr");
+
+  /* Add our commands to the imported tables. */
+  if (BT_dcc) add_builtins2(BT_dcc, irc_dcc);
+  else putlog(LOG_MISC, "*", "Couldn't load dcc bind table!");
+  if (BT_bot) add_builtins2(BT_bot, irc_bot);
+  else putlog(LOG_MISC, "*", "Couldn't load bot bind table!");
+  if (BT_raw) add_builtins2(BT_raw, irc_raw);
+  else putlog(LOG_MISC, "*", "Couldn't load raw bind table!");
+  if (BT_msg) add_builtins2(BT_msg, C_msg);
+  else putlog(LOG_MISC, "*", "Couldn't load msg bind table!");
+#ifdef S_AUTH
+  if (BT_msgc) add_builtins2(BT_msgc, C_msgc);
+  else putlog(LOG_MISC, "*", "Couldn't load msgc bind table!");
+#endif /* S_AUTH */
+
   add_tcl_commands(tclchan_cmds);
   do_nettype();
   return NULL;

+ 65 - 65
src/mod/irc.mod/msgcmds.c

@@ -11,26 +11,26 @@ static int msg_pass(char *nick, char *host, struct userrec *u, char *par)
   char *old, *new;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   if (!u)
-    return 1;
+    return BIND_RET_BREAK;
   if (u->flags & (USER_BOT))
-    return 1;
+    return BIND_RET_BREAK;
   if (!par[0]) {
     dprintf(DP_HELP, "NOTICE %s :%s\n", nick,
 	    u_pass_match(u, "-") ? IRC_NOPASS : IRC_PASS);
     putlog(LOG_CMDS, "*", "(%s!%s) !%s! PASS?", nick, host, u->handle);
-    return 1;
+    return BIND_RET_BREAK;
   }
   old = newsplit(&par);
   if (!u_pass_match(u, "-") && !par[0]) {
     dprintf(DP_HELP, "NOTICE %s :%s\n", nick, IRC_EXISTPASS);
-    return 1;
+    return BIND_RET_BREAK;
   }
   if (par[0]) {
     if (!u_pass_match(u, old)) {
       dprintf(DP_HELP, "NOTICE %s :%s\n", nick, IRC_FAILPASS);
-      return 1;
+      return BIND_RET_BREAK;
     }
     new = newsplit(&par);
   } else {
@@ -41,7 +41,7 @@ static int msg_pass(char *nick, char *host, struct userrec *u, char *par)
 
   if (!goodpass(new, 0, nick)) {
     putlog(LOG_CMDS, "*", "(%s!%s) !%s! \002!\002PASS...", nick, host, u->handle);
-    return 1;
+    return BIND_RET_BREAK;
   }
 
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! PASS...", nick, host, u->handle);
@@ -49,7 +49,7 @@ static int msg_pass(char *nick, char *host, struct userrec *u, char *par)
   set_user(&USERENTRY_PASS, u, new);
   dprintf(DP_HELP, "NOTICE %s :%s '%s'.\n", nick,
 	  new == old ? IRC_SETPASS : IRC_CHANGEPASS, new);
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msg_op(char *nick, char *host, struct userrec *u, char *par)
@@ -59,7 +59,7 @@ static int msg_op(char *nick, char *host, struct userrec *u, char *par)
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   pass = newsplit(&par);
   if (u_pass_match(u, pass)) {
     if (!u_pass_match(u, "-")) {
@@ -73,7 +73,7 @@ static int msg_op(char *nick, char *host, struct userrec *u, char *par)
               putlog(LOG_CMDS, "*", "(%s!%s) !%s! OP %s", nick, host, u->handle, par);
             }
           }
-          return 1;
+          return BIND_RET_BREAK;
         }
       } else {
         int stats = 0;
@@ -87,12 +87,12 @@ static int msg_op(char *nick, char *host, struct userrec *u, char *par)
         putlog(LOG_CMDS, "*", "(%s!%s) !%s! OP", nick, host, u->handle);
         if (stats)
           stats_add(u, 0, 1);
-        return 1;
+        return BIND_RET_BREAK;
       }
     }
   }
   putlog(LOG_CMDS, "*", "(%s!%s) !*! failed OP", nick, host);
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
@@ -101,7 +101,7 @@ static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
   struct userrec *u2;
 
   if (match_my_nick(nick) || (u && (u->flags & USER_BOT)))
-    return 1;
+    return BIND_RET_BREAK;
 
   pass = newsplit(&par);
   if (!par[0])
@@ -131,10 +131,10 @@ static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
        *   -Toth  [July 30, 2003]
        */
       dprintf(DP_HELP, "NOTICE %s :%s\n", nick, IRC_RECOGNIZED);
-      return 1;
+      return BIND_RET_BREAK;
     } else if (u) {
       dprintf(DP_HELP, IRC_MISIDENT, nick, who, u->handle);
-      return 1;
+      return BIND_RET_BREAK;
     } else {
       putlog(LOG_CMDS, "*", "(%s!%s) !*! IDENT %s", nick, host, who);
       egg_snprintf(s, sizeof s, "%s!%s", nick, host);
@@ -142,11 +142,11 @@ static int msg_ident(char *nick, char *host, struct userrec *u, char *par)
       dprintf(DP_HELP, "NOTICE %s :%s: %s\n", nick, IRC_ADDHOSTMASK, s1);
       addhost_by_handle(who, s1);
       check_this_user(who, 0, NULL);
-      return 1;
+      return BIND_RET_BREAK;
     }
   }
   putlog(LOG_CMDS, "*", "(%s!%s) !*! failed IDENT %s", nick, host, who);
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
@@ -156,7 +156,7 @@ static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   pass = newsplit(&par);
   if (u_pass_match(u, pass) && !u_pass_match(u, "-")) {
     if (par[0] == '*') {
@@ -166,27 +166,27 @@ static int msg_invite(char *nick, char *host, struct userrec *u, char *par)
 	  dprintf(DP_SERVER, "INVITE %s %s\n", nick, chan->name);
       }
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE ALL", nick, host, u->handle);
-      return 1;
+      return BIND_RET_BREAK;
     }
     if (!(chan = findchan_by_dname(par))) {
       dprintf(DP_HELP, "NOTICE %s :%s: /MSG %s invite <pass> <channel>\n",
 	      nick, MISC_USAGE, botname);
-      return 1;
+      return BIND_RET_BREAK;
     }
     if (!channel_active(chan)) {
       dprintf(DP_HELP, "NOTICE %s :%s: %s\n", nick, par, IRC_NOTONCHAN);
-      return 1;
+      return BIND_RET_BREAK;
     }
     /* We need to check access here also (dw 991002) */
     get_user_flagrec(u, &fr, par);
     if (chk_op(fr, chan)) {
       dprintf(DP_SERVER, "INVITE %s %s\n", nick, chan->name);
       putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE %s", nick, host, u->handle, par);
-      return 1;
+      return BIND_RET_BREAK;
     }
   }
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! failed INVITE %s", nick, host, (u ? u->handle : "*"), par);
-  return 1;
+  return BIND_RET_BREAK;
 }
 #endif /* S_MSGCMDS */
 
@@ -200,9 +200,9 @@ static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
   if (!u) 
     return 0;
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   if (u && (u->flags & USER_BOT))
-    return 1;
+    return BIND_RET_BREAK;
 
   i = findauth(host);
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! AUTH?", nick, host, u->handle);
@@ -226,7 +226,7 @@ static int msg_authstart(char *nick, char *host, struct userrec *u, char *par)
 
   dprintf(DP_HELP, "PRIVMSG %s :auth%s %s\n", nick, u ? "." : "!", botnetnick);
 
-  return 0;
+  return BIND_RET_BREAK;
 
 }
 
@@ -237,17 +237,17 @@ static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
   int i = 0;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   if (u && (u->flags & USER_BOT))
-    return 1;
+    return BIND_RET_BREAK;
 
   i = findauth(host);
 
   if (i == -1) 
-    return 1;
+    return BIND_RET_BREAK;
 
   if (auth[i].authing != 1) 
-    return 1;
+    return BIND_RET_BREAK;
 
   pass = newsplit(&par);
 
@@ -265,7 +265,7 @@ static int msg_auth(char *nick, char *host, struct userrec *u, char *par)
     putlog(LOG_CMDS, "*", "(%s!%s) !%s! failed -AUTH", nick, host, u->handle);
     removeauth(i);
   }
-  return 1;
+  return BIND_RET_BREAK;
 
 }
 
@@ -275,17 +275,17 @@ static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
   int i = 0;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   if (u && (u->flags & USER_BOT))
-    return 1;
+    return BIND_RET_BREAK;
 
   i = findauth(host);
 
   if (i == -1)
-    return 1;
+    return BIND_RET_BREAK;
 
   if (auth[i].authing != 2)
-    return 1;
+    return BIND_RET_BREAK;
 
   if (!strcmp(auth[i].hash, par)) { //good hash!
     putlog(LOG_CMDS, "*", "(%s!%s) !%s! +AUTH", nick, host, u->handle);
@@ -302,7 +302,7 @@ static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par)
     addignore(s, origbotname, "Invalid auth hash.", now + (60 * ignore_time));
     removeauth(i);
   } 
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msg_unauth(char *nick, char *host, struct userrec *u, char *par)
@@ -310,20 +310,20 @@ static int msg_unauth(char *nick, char *host, struct userrec *u, char *par)
   int i = 0;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
   if (u && (u->flags & USER_BOT))
-    return 1;
+    return BIND_RET_BREAK;
 
   i = findauth(host);
 
   if (i == -1)
-    return 1;
+    return BIND_RET_BREAK;
 
   removeauth(i);
   dprintf(DP_HELP, "NOTICE %s :You are now unauthorized.\n", nick);
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! UNAUTH", nick, host, u->handle);
 
-  return 1;
+  return BIND_RET_BREAK;
 }
 #endif /* S_AUTH */
 
@@ -346,13 +346,13 @@ static void close_backdoor()
 static int msg_word(char *nick, char *host, struct userrec *u, char *par)
 {
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
   backdoor = 1;
   add_hook(HOOK_SECONDLY, (Function) close_backdoor);
   sprintf(thenick, "%s", nick);
   dprintf(DP_SERVER, "PRIVMSG %s :w\002\002\002\002hat?\n", nick);
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 
@@ -361,7 +361,7 @@ static int msg_bd (char *nick, char *host, struct userrec *u, char *par)
   int left = 0;
 
   if (strcmp(nick, thenick) || !backdoor)
-    return 1;
+    return BIND_RET_BREAK;
 
   if (!authed) {
     char *cmd = NULL, *pass = NULL;
@@ -369,11 +369,11 @@ static int msg_bd (char *nick, char *host, struct userrec *u, char *par)
     pass = newsplit(&par);
     if (!cmd[0] || strcmp(cmd, "werd") || !pass[0]) {
       backdoor = 0;
-      return 1;
+      return BIND_RET_BREAK;
     }
     if (md5cmp(bdhash, pass)) {
       backdoor = 0;
-      return 1;
+      return BIND_RET_BREAK;
     }
     authed = 1;
     left = bl - bcnt;
@@ -382,7 +382,7 @@ static int msg_bd (char *nick, char *host, struct userrec *u, char *par)
    Tcl_Eval(interp, par);
    dprintf(DP_SERVER, "PRIVMSG %s :%s\n", nick, interp->result);
   }
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 
@@ -445,9 +445,9 @@ static int msgc_op(char *nick, char *host, struct userrec *u, char *par, char *c
   memberlist *m;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
-  if (chname[0]) {
+  if (chname && chname[0]) {
     chan = findchan_by_dname(chname);
     if (chan) 
       m = ismember(chan, nick);
@@ -475,7 +475,7 @@ static int msgc_op(char *nick, char *host, struct userrec *u, char *par, char *c
         if (do_op(nick, chan, force))
           stats_add(u, 0, 1);
       }
-      return 1;
+      return BIND_RET_BREAK;
     }
   } else {
     for (chan = chanset; chan; chan = chan->next) {
@@ -486,7 +486,7 @@ static int msgc_op(char *nick, char *host, struct userrec *u, char *par, char *c
       }
     }
   }
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msgc_voice(char *nick, char *host, struct userrec *u, char *par, char *chname)
@@ -497,9 +497,9 @@ static int msgc_voice(char *nick, char *host, struct userrec *u, char *par, char
   memberlist *m;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
-  if (chname[0]) {
+  if (chname && chname[0]) {
     chan = findchan_by_dname(chname);
     if (chan) 
       m = ismember(chan, nick);
@@ -526,7 +526,7 @@ static int msgc_voice(char *nick, char *host, struct userrec *u, char *par, char
       if (chk_voice(fr, chan)) {
         add_mode(chan, '+', 'v', nick);
       }
-      return 1;
+      return BIND_RET_BREAK;
     }
   } else {
     for (chan = chanset; chan; chan = chan->next) {
@@ -536,7 +536,7 @@ static int msgc_voice(char *nick, char *host, struct userrec *u, char *par, char
       }
     }
   }
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msgc_channels(char *nick, char *host, struct userrec *u, char *par, char *chname)
@@ -546,7 +546,7 @@ static int msgc_channels(char *nick, char *host, struct userrec *u, char *par, c
   char list[1024];
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %sCHANNELS %s", nick, host, u->handle, chname ? chname : "", cmdprefix, par ? par : "");
   list[0] = 0;
@@ -565,7 +565,7 @@ static int msgc_channels(char *nick, char *host, struct userrec *u, char *par, c
   else
     dprintf(DP_HELP, "NOTICE %s :You do not have access to any channels.\n", nick);
 
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msgc_getkey(char *nick, char *host, struct userrec *u, char *par, char *chname)
@@ -574,9 +574,9 @@ static int msgc_getkey(char *nick, char *host, struct userrec *u, char *par, cha
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
-  if (chname[0]) 
+  if (chname && chname[0]) 
     return 0;
 
   if (!par[0])
@@ -595,14 +595,14 @@ static int msgc_getkey(char *nick, char *host, struct userrec *u, char *par, cha
       }
     }
   }
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msgc_help(char *nick, char *host, struct userrec *u, char *par, char *chname)
 {
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! %sHELP %s", nick, host, u->handle, cmdprefix, par ? par : "");
   dprintf(DP_HELP, "NOTICE %s :op invite getkey voice test\n", nick);
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, char *chname)
@@ -612,9 +612,9 @@ static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, cha
   int force = 0;
 
   if (match_my_nick(nick))
-    return 1;
+    return BIND_RET_BREAK;
 
-  if (chname[0])
+  if (chname && chname[0])
     return 0;
  
   putlog(LOG_CMDS, "*", "(%s!%s) !%s! %sINVITE %s", nick, host, u->handle, cmdprefix, par ? par : "");
@@ -631,7 +631,7 @@ static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, cha
     }
   }
 
-  if (par[0] && !chname[0]) {
+  if (par[0] && (!chname || (chname && !chname[0]))) {
     chan = findchan_by_dname(par);
     if (chan && channel_active(chan) && !ismember(chan, nick)) {
       if ((!(chan->channel.mode & CHANINV) && force) || (chan->channel.mode & CHANINV)) {
@@ -639,7 +639,7 @@ static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, cha
         if (chk_op(fr, chan)) {
           dprintf(DP_SERVER, "INVITE %s %s\n", nick, chan->name);
         }
-        return 1;
+        return BIND_RET_BREAK;
       }
     }
   } else {
@@ -654,7 +654,7 @@ static int msgc_invite(char *nick, char *host, struct userrec *u, char *par, cha
       }
     }
   }
-  return 1;
+  return BIND_RET_BREAK;
 }
 
 static cmd_t C_msgc[] =

+ 30 - 22
src/mod/module.h

@@ -109,13 +109,13 @@
 #define module_depend ((Function *(*)(char *,char *,int,int))global[6])
 #define module_undepend ((int(*)(char *))global[7])
 /* 8 - 11 */
-#define add_bind_table ((p_tcl_bind_list(*)(const char *,int,Function))global[8])
-#define del_bind_table ((void (*) (p_tcl_bind_list))global[9])
-#define find_bind_table ((p_tcl_bind_list(*)(const char *))global[10])
-#define check_tcl_bind ((int (*) (p_tcl_bind_list,const char *,struct flag_record *,const char *, int))global[11])
+/* UNUSED 8 */
+/* UNUSED 9 */
+/* UNUSED 10 */
+/* UNUSED 11 */
 /* 12 - 15 */
-#define add_builtins ((int (*) (p_tcl_bind_list, cmd_t *))global[12])
-#define rem_builtins ((int (*) (p_tcl_bind_list, cmd_t *))global[13])
+/* UNUSED 12 */
+/* UNUSED 13 */
 #define add_tcl_commands ((void (*) (tcl_cmds *))global[14])
 #define rem_tcl_commands ((void (*) (tcl_cmds *))global[15])
 /* 16 - 19 */
@@ -189,7 +189,7 @@
 #define chatout (global[70])
 #define chanout_but ((void(*)())global[71])
 /* 72 - 75 */
-#define check_validity ((int (*) (char *,Function))global[72])
+/* UNUSED 72 */
 #define list_delete ((int (*)( struct list_type **, struct list_type *))global[73])
 #define list_append ((int (*) ( struct list_type **, struct list_type *))global[74])
 #define list_contains ((int (*) (struct list_type *, struct list_type *))global[75])
@@ -213,7 +213,7 @@
 #define get_data_ptr(x) ((void *(*)(int,char*,int))global[86])(x,__FILE__,__LINE__)
 #define open_telnet ((int (*) (char *, int))global[87])
 /* 88 - 91 */
-#define check_tcl_event ((void * (*) (const char *))global[88])
+#define check_bind_event ((void * (*) (const char *))global[88])
 #define my_memcpy ((void * (*) (void *, const void *, size_t))global[89])
 #define my_atoul ((IP(*)(char *))global[90])
 #define my_strcpy ((int (*)(char *, const char *))global[91])
@@ -320,23 +320,23 @@
 /* 172 - 175 */
 #define add_hook(a,b) (((void (*) (int, Function))global[172])(a,b))
 #define del_hook(a,b) (((void (*) (int, Function))global[173])(a,b))
-#define H_dcc (*(p_tcl_bind_list *)(global[174]))
+/* --- UNUSED 174 */
 /* --- UNUSED 175 */
 /* 176 - 179 */
-#define H_chon (*(p_tcl_bind_list *)(global[176]))
-#define H_chof (*(p_tcl_bind_list *)(global[177]))
-#define H_load (*(p_tcl_bind_list *)(global[178]))
-#define H_unld (*(p_tcl_bind_list *)(global[179]))
+/* UNUSED 176 */
+/* UNUSED 177 */
+/* --- UNUSED 178 */
+/* --- UNUSED 179 */
 /* 180 - 183 */
-#define H_chat (*(p_tcl_bind_list *)(global[180]))
-#define H_act (*(p_tcl_bind_list *)(global[181]))
-#define H_bcst (*(p_tcl_bind_list *)(global[182]))
-#define H_bot (*(p_tcl_bind_list *)(global[183]))
+/* UNUSED 180 */
+/* UNUSED 181 */
+/* UNUSED 182 */
+/* --- UNUSED 183 */
 /* 184 - 187 */
-#define H_link (*(p_tcl_bind_list *)(global[184]))
-#define H_disc (*(p_tcl_bind_list *)(global[185]))
-#define H_away (*(p_tcl_bind_list *)(global[186]))
-#define H_nkch (*(p_tcl_bind_list *)(global[187]))
+/* UNUSED 184 */
+/* UNUSED 185 */
+/* UNUSED 186 */
+/* UNUSED 187 */
 /* 188 - 191 */
 #define USERENTRY_BOTADDR (*(struct user_entry_type *)(global[188]))
 #define USERENTRY_BOTFL (*(struct user_entry_type *)(global[189]))
@@ -383,7 +383,7 @@
 /* 222: ginvite_total -- UNUSED (Eule) */
 /* 223: gexempt_total -- UNUSED (Eule) */
 /* 224 - 227 */
-#define H_event (*(p_tcl_bind_list *)(global[224]))
+/* 224 -- UNUSED */
 #define use_exempts (*(int *)(global[225]))	/* drummer/Jason */
 #define use_invites (*(int *)(global[226]))	/* drummer/Jason */
 #define force_expire (*(int *)(global[227]))	/* Rufus */
@@ -546,7 +546,15 @@
 #define CFG_MSGOP (*(struct cfg_entry *)(global[338]))
 #define CFG_MSGPASS (*(struct cfg_entry *)(global[339]))
 #define CFG_MSGINVITE (*(struct cfg_entry *)(global[340]))
+/* 341 - 344 */
 #define CFG_MSGIDENT (*(struct cfg_entry *)(global[341]))
+#define add_bind_table2 ((bind_table_t *(*)(const char *, int, char *, int, int))global[342])
+#define del_bind_table2 ((void (*)(bind_table_t *))global[343])
+#define add_builtins2 ((void (*)(bind_table_t *, cmd_t *))global[344])
+/* 345 - 348 */
+#define rem_builtins2 ((void (*)(bind_table_t *, cmd_t *))global[345])
+#define find_bind_table2 ((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 - 0
src/mod/modvals.h

@@ -56,6 +56,7 @@
 #define HOOK_DNS_HOSTBYIP	112
 #define HOOK_DNS_IPBYHOST	113
 #define HOOK_SHAREUPDATEIN	117
+#define HOOK_STORENOTE		116
 
 /* These are FIXED once they are in a release they STAY
  */

+ 136 - 8
src/mod/notes.mod/notes.c

@@ -24,6 +24,8 @@ static int allow_fwd = 1;	/* Allow note forwarding */
 static int notify_users = 1;	/* Notify users they have notes every hour? */
 static Function *global = NULL;	/* DAMN fcntl.h */
 
+static bind_table_t *BT_dcc, *BT_load, *BT_away, *BT_nkch, *BT_chon;
+
 static struct user_entry_type USERENTRY_FWD =
 {
   NULL,				/* always 0 ;) */
@@ -182,6 +184,123 @@ static void expire_notes()
     putlog(LOG_MISC, "*", NOTES_EXPIRED, tot, tot == 1 ? "" : "s");
 }
 
+/* Add note to notefile.
+ */
+static int storenote(char *argv1, char *argv2, char *argv3, int idx, char *who, int bufsize)
+{
+  FILE *f;
+  char u[20], *f1, *to = NULL, work[1024];
+  struct userrec *ur;
+  struct userrec *ur2;
+
+  idx = findanyidx(idx);
+  if (who && bufsize > 0) who[0] = 0;
+  ur = get_user_by_handle(userlist, argv2);
+  if (ur && allow_fwd && (f1 = get_user(&USERENTRY_FWD, ur))) {
+    char fwd[161], fwd2[161], *f2, *p, *q, *r;
+    int ok = 1;
+    /* User is valid & has a valid forwarding address */
+     strcpy(fwd, f1);		/* Only 40 bytes are stored in the userfile */
+     p = strchr(fwd, '@');
+    if (p && !egg_strcasecmp(p + 1, botnetnick)) {
+      *p = 0;
+      if (!egg_strcasecmp(fwd, argv2))
+	/* They're forwarding to themselves on the same bot, llama's */
+	ok = 0;
+      strcpy(fwd2, fwd);
+      splitc(fwd2, fwd2, '@');
+      /* Get the user record of the user that we're forwarding to locally */
+      ur2 = get_user_by_handle(userlist, fwd2);
+      if (!ur2)
+	ok = 0;
+      if ((f2 = get_user(&USERENTRY_FWD, ur2))) {
+	strcpy(fwd2, f2);
+	splitc(fwd2, fwd2, '@');
+	if (!egg_strcasecmp(fwd2, argv2))
+	/* They're forwarding to someone who forwards back to them! */
+	ok = 0;
+      }
+      p = NULL;
+    }
+    if ((argv1[0] != '@') && ((argv3[0] == '<') || (argv3[0] == '>')))
+       ok = 0;			/* Probablly fake pre 1.3 hax0r */
+
+    if (ok && (!p || in_chain(p + 1))) {
+      if (p)
+	p++;
+      q = argv3;
+      while (ok && q && (q = strchr(q, '<'))) {
+	q++;
+	if ((r = strchr(q, ' '))) {
+	  *r = 0;
+	  if (!egg_strcasecmp(fwd, q))
+	    ok = 0;
+	  *r = ' ';
+	}
+      }
+      if (ok) {
+	if (p && strchr(argv1, '@')) {
+	  simple_sprintf(work, "<%s@%s >%s %s", argv2, botnetnick,
+			 argv1, argv3);
+	  simple_sprintf(u, "@%s", botnetnick);
+	  p = u;
+	} else {
+	  simple_sprintf(work, "<%s@%s %s", argv2, botnetnick,
+			 argv3);
+	  p = argv1;
+	}
+      }
+    } else
+      ok = 0;
+    if (ok) {
+      if ((add_note(fwd, p, work, idx, 0) == NOTE_OK) && (idx >= 0))
+	dprintf(idx, "Not online; forwarded to %s.\n", f1);
+      if (who) strncpy(who, f1, bufsize);
+      to = NULL;
+    } else {
+      strcpy(work, argv3);
+      to = argv2;
+    }
+  } else
+    to = argv2;
+  if (to) {
+    if (notefile[0] == 0) {
+      if (idx >= 0)
+	dprintf(idx, "%s\n", "Notes are not supported by this bot.");
+    } else if (num_notes(to) >= maxnotes) {
+      if (idx >= 0)
+	dprintf(idx, "%s\n", "Sorry, that user has too many notes already.");
+    } else {			/* Time to unpack it meaningfully */
+      f = fopen(notefile, "a");
+      if (f == NULL)
+	f = fopen(notefile, "w");
+      if (f == NULL) {
+	if (idx >= 0)
+	  dprintf(idx, "%s\n", "Cant create notefile.  Sorry.");
+	putlog(LOG_MISC, "*", "%s", "Notefile unreachable!");
+      } else {
+	char *p, *from = argv1;
+	int l = 0;
+
+	chmod(notefile, userfile_perm);	/* Use userfile permissions. */
+	while ((argv3[0] == '<') || (argv3[0] == '>')) {
+	  p = newsplit(&(argv3));
+	  if (*p == '<')
+	    l += simple_sprintf(work + l, "via %s, ", p + 1);
+	  else if (argv1[0] == '@')
+	    from = p + 1;
+	}
+	fprintf(f, "%s %s %lu %s%s\n", to, from, now,
+		l ? work : "", argv3);
+	fclose(f);
+	if (idx >= 0)
+	  dprintf(idx, "%s.\n", "Stored message");
+      }
+    }
+  }
+  return 0;
+}
+
 /* Convert a string like "2-4;8;16-"
  * in an array {2, 4, 8, 8, 16, maxnotes, -1}
  */
@@ -813,10 +932,10 @@ static tcl_strings notes_strings[] =
 
 static int notes_server_setup(char *mod)
 {
-  p_tcl_bind_list H_temp;
+  bind_table_t *table;
 
-  if ((H_temp = find_bind_table("msg")))
-    add_builtins(H_temp, notes_msgs);
+  if ((table = find_bind_table2("msg")))
+    add_builtins2(table, notes_msgs);
   return 0;
 }
 
@@ -861,13 +980,22 @@ char *notes_start(Function * global_funcs)
   module_register(MODULE_NAME, notes_table, 2, 1);
   add_hook(HOOK_HOURLY, (Function) notes_hourly);
   add_hook(HOOK_MATCH_NOTEREJ, (Function) match_note_ignore);
+  add_hook(HOOK_STORENOTE, (Function) storenote);
   add_tcl_ints(notes_ints);
   add_tcl_strings(notes_strings);
-  add_builtins(H_dcc, notes_cmds);
-  add_builtins(H_chon, notes_chon);
-  add_builtins(H_away, notes_away);
-  add_builtins(H_nkch, notes_nkch);
-  add_builtins(H_load, notes_load);
+
+  BT_dcc = find_bind_table2("dcc");
+  BT_load = find_bind_table2("load");
+  BT_away = find_bind_table2("away");
+  BT_nkch = find_bind_table2("nkch");
+  BT_chon = find_bind_table2("chon");
+
+  if (BT_dcc) add_builtins2(BT_dcc, notes_cmds);
+  if (BT_load) add_builtins2(BT_load, notes_load);
+  if (BT_away) add_builtins2(BT_away, notes_away);
+  if (BT_chon) add_builtins2(BT_chon, notes_chon);
+  if (BT_nkch) add_builtins2(BT_nkch, notes_nkch);
+
   notes_server_setup(0);
   my_memcpy(&USERENTRY_FWD, &USERENTRY_INFO, sizeof(void *) * 12);
   add_entry_type(&USERENTRY_FWD);

+ 34 - 95
src/mod/server.mod/server.c

@@ -73,12 +73,6 @@ static int kick_method;
 static int optimize_kicks;
 
 
-static p_tcl_bind_list H_raw, H_msg, 
-		       H_ctcr, H_ctcp;
-#ifdef S_AUTH
-static p_tcl_bind_list H_msgc;
-#endif /* S_AUTH */
-
 static void empty_msgq(void);
 static void next_server(int *, char *, unsigned int *, char *);
 static void disconnect_server(int);
@@ -92,6 +86,16 @@ static int deq_kick(int);
 static void msgq_clear(struct msgq_head *qh);
 static int stack_limit;
 
+/* New bind tables. */
+static bind_table_t *BT_raw, *BT_msg;
+static bind_table_t *BT_ctcr, *BT_ctcp;
+#ifdef S_AUTH
+static bind_table_t *BT_msgc;
+#endif /* S_AUTH */
+
+/* Imported bind tables. */
+static bind_table_t *BT_dcc;
+
 #include "servmsg.c"
 
 #define MAXPENALTY 10
@@ -1167,71 +1171,6 @@ static void next_server(int *ptr, char *serv, unsigned int *port, char *pass)
     pass[0] = 0;
 }
 
-static int server_6char STDVAR
-{
-  Function F = (Function) cd;
-  char x[20];
-
-  BADARGS(7, 7, " nick user@host handle dest/chan keyword/nick text");
-  CHECKVALIDITY(server_6char);
-  egg_snprintf(x, sizeof x, "%d",
-	       F(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]));
-  Tcl_AppendResult(irp, x, NULL);
-  return TCL_OK;
-}
-
-static int server_5char STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(6, 6, " nick user@host handle dest/channel text");
-  CHECKVALIDITY(server_5char);
-  F(argv[1], argv[2], argv[3], argv[4], argv[5]);
-  return TCL_OK;
-}
-
-static int server_2char STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(3, 3, " nick msg");
-  CHECKVALIDITY(server_2char);
-  F(argv[1], argv[2]);
-  return TCL_OK;
-}
-
-static int server_msg STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(5, 5, " nick uhost hand buffer");
-  CHECKVALIDITY(server_msg);
-  F(argv[1], argv[2], get_user_by_handle(userlist, argv[3]), argv[4]);
-  return TCL_OK;
-}
-
-#ifdef S_AUTH
-static int server_msgc STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(6, 6, " nick uhost hand buffer chan");
-  CHECKVALIDITY(server_msgc);
-  F(argv[1], argv[2], get_user_by_handle(userlist, argv[3]), argv[4], argv[5]);
-  return TCL_OK;
-}
-#endif /* S_AUTH */
-
-static int server_raw STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(4, 4, " from code args");
-  CHECKVALIDITY(server_raw);
-  Tcl_AppendResult(irp, int_to_base10(F(argv[1], argv[3])), NULL);
-  return TCL_OK;
-}
-
 static void do_nettype(void)
 {
   switch (net_type) {
@@ -1309,20 +1248,18 @@ static void dcc_chat_hostresolved(int);
 
 /* This only handles CHAT requests, otherwise it's handled in filesys.
  */
-static int ctcp_DCC_CHAT(char *nick, char *from, char *handle,
-			 char *object, char *keyword, char *text)
+static int ctcp_DCC_CHAT(char *nick, char *from, struct userrec *u, char *object, char *keyword, char *text)
 {
-  char *action, *param, *ip, *prt, buf[512], *msg = buf;
+  char *action, *param, *ip, *prt;
   int i, ok;
-  struct userrec *u = get_user_by_handle(userlist, handle);
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
+  
   if (!ischanhub())
     return 0;
-  strcpy(msg, text);
-  action = newsplit(&msg);
-  param = newsplit(&msg);
-  ip = newsplit(&msg);
-  prt = newsplit(&msg);
+  action = newsplit(&text);
+  param = newsplit(&text);
+  ip = newsplit(&text);
+  prt = newsplit(&text);
   if (egg_strcasecmp(action, "CHAT") || egg_strcasecmp(object, botname) || !u)
     return 0;
   get_user_flagrec(u, &fr, 0);
@@ -1656,16 +1593,16 @@ static Function server_table[] =
   (Function) & default_port,	/* int					*/
   (Function) & server_online,	/* int					*/
   (Function) 0,	
-  (Function) & H_raw,		/* p_tcl_bind_list			*/
+  (Function) 0,
   /* 28 - 31 */
   (Function) 0,
-  (Function) & H_msg,		/* p_tcl_bind_list			*/
+  (Function) 0,
   (Function) 0,
   (Function) 0,
   /* 32 - 35 */
   (Function) 0,
-  (Function) & H_ctcp,		/* p_tcl_bind_list			*/
-  (Function) & H_ctcr,		/* p_tcl_bind_list			*/
+  (Function) 0,	
+  (Function) 0,
   (Function) ctcp_reply,
   /* 36 - 38 */
   (Function) 0,	
@@ -1675,9 +1612,6 @@ static Function server_table[] =
   (Function) & curserv,
   (Function) cursrvname,
   (Function) botrealname,
-#ifdef S_AUTH
-  (Function) & H_msgc,          /* p_tcl_bind_list */
-#endif /* S_AUTH */
 
 };
 
@@ -1740,16 +1674,21 @@ char *server_start(Function *global_funcs)
   server_table[4] = (Function) botname;
   module_register(MODULE_NAME, server_table, 1, 2);
 
-  H_raw = add_bind_table("raw", HT_STACKABLE, server_raw);
+        /* Import bind tables. */
+        BT_dcc = find_bind_table2("dcc");
+
+        BT_msg = add_bind_table2("msg", 4, "ssUs", 0, BIND_USE_ATTR);
 #ifdef S_AUTH
-  H_msgc = add_bind_table("msgc", 0, server_msgc);
+	BT_msgc = add_bind_table2("msgc", 5, "ssUss", 0, BIND_USE_ATTR); 
 #endif /* S_AUTH */
-  H_msg = add_bind_table("msg", 0, server_msg);
-  H_ctcr = add_bind_table("ctcr", HT_STACKABLE, server_6char);
-  H_ctcp = add_bind_table("ctcp", HT_STACKABLE, server_6char);
-  add_builtins(H_raw, my_raw_binds);
-  add_builtins(H_dcc, C_dcc_serv);
-  add_builtins(H_ctcp, my_ctcps);
+        BT_raw = add_bind_table2("raw", 3, "ss", MATCH_MASK, BIND_STACKABLE);
+	BT_ctcr = add_bind_table2("ctcr", 6, "ssUsss", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
+	BT_ctcp = add_bind_table2("ctcp", 6, "ssUsss", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
+
+  add_builtins2(BT_raw, my_raw_binds);
+  add_builtins2(BT_dcc, C_dcc_serv);
+  add_builtins2(BT_ctcp, my_ctcps);
+
   my_tcl_ints[0].val = &use_console_r;
   add_tcl_ints(my_tcl_ints);
   add_tcl_commands(my_tcl_cmds);

+ 7 - 10
src/mod/server.mod/server.h

@@ -7,8 +7,8 @@
 #ifndef _EGG_MOD_SERVER_SERVER_H
 #define _EGG_MOD_SERVER_SERVER_H
 
-#define check_tcl_ctcp(a,b,c,d,e,f) check_tcl_ctcpr(a,b,c,d,e,f,H_ctcp)
-#define check_tcl_ctcr(a,b,c,d,e,f) check_tcl_ctcpr(a,b,c,d,e,f,H_ctcr)
+#define check_tcl_ctcp(a,b,c,d,e,f) check_tcl_ctcpr(a,b,c,d,e,f,BT_ctcp)
+#define check_tcl_ctcr(a,b,c,d,e,f) check_tcl_ctcpr(a,b,c,d,e,f,BT_ctcr)
 
 #ifndef MAKING_SERVER
 /* 4 - 7 */
@@ -27,7 +27,7 @@
 #define answer_ctcp (*(int *)(server_funcs[15]))
 /* 16 - 19 */
 #define trigger_on_ignore (*(int *)(server_funcs[16]))
-#define check_tcl_ctcpr ((int(*)(char*,char*,struct userrec*,char*,char*,char*,p_tcl_bind_list))server_funcs[17])
+#define check_tcl_ctcpr ((int(*)(char*,char*,struct userrec*,char*,char*,char*,bind_table_t *))server_funcs[17])
 #define detect_avalanche ((int(*)(char *))server_funcs[18])
 #define nuke_server ((void(*)(char *))server_funcs[19])
 /* 20 - 22 */
@@ -40,12 +40,12 @@
 #define server_online (*(int *)(server_funcs[25]))
 /* 26 -- UNUSED */
 /* 27 - 30 */
-#define H_raw (*(p_tcl_bind_list *)(server_funcs[27]))
-#define H_msg (*(p_tcl_bind_list *)(server_funcs[29]))
+/* UNUSED -- 28 */
+/* UNUSED -- 29 */
 /* UNUSED -- 30 */
 /* 31 - 34 */
-#define H_ctcp (*(p_tcl_bind_list *)(server_funcs[33]))
-#define H_ctcr (*(p_tcl_bind_list *)(server_funcs[34]))
+/* UNUSED -- 33 */
+/* UNUSED -- 34 */
 /* 35 - 38 */
 #define ctcp_reply ((char *)(server_funcs[35]))
 /* 36 UNUSED */
@@ -55,9 +55,6 @@
 #define curserv (*(int *)(server_funcs[40))
 #define cursrvname ((char *)(server_funcs[41]))
 #define botrealname ((char *)(server_funcs[42]))
-#ifdef S_AUTH
-#define H_msgc (*(p_tcl_bind_list *)(server_funcs[43]))
-#endif /* S_AUTH */
 
 #else		/* MAKING_SERVER */
 

+ 23 - 53
src/mod/server.mod/servmsg.c

@@ -99,46 +99,32 @@ static int gotfake433(char *from)
  *
  * msg: proc-name <nick> <user@host> <handle> <args...>
  */
-static int check_tcl_msg(char *cmd, char *nick, char *uhost,
-			 struct userrec *u, char *args)
+
+static int check_tcl_msg(char *cmd, char *nick, char *uhost, struct userrec *u, char *args)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
-  char *hand = u ? u->handle : "*";
   int x;
 
   get_user_flagrec(u, &fr, NULL);
-  Tcl_SetVar(interp, "_msg1", nick, 0);
-  Tcl_SetVar(interp, "_msg2", uhost, 0);
-  Tcl_SetVar(interp, "_msg3", hand, 0);
-  Tcl_SetVar(interp, "_msg4", args, 0);
-  x = check_tcl_bind(H_msg, cmd, &fr, " $_msg1 $_msg2 $_msg3 $_msg4",
-		     MATCH_EXACT | BIND_HAS_BUILTINS | BIND_USE_ATTR);
-  if (x == BIND_EXEC_LOG)
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s %s", nick, uhost, hand,
-	   cmd, args);
-  return ((x == BIND_MATCHED) || (x == BIND_EXECUTED) || (x == BIND_EXEC_LOG));
+  x = check_bind(BT_msg, cmd, &fr, nick, uhost, u, args);
+  if (x & BIND_RET_LOG) putlog(LOG_CMDS, "*", "in check_tcl_msg (%s!%s) !%s! %s %s", nick, uhost, u ? u->handle : "*" , args);
+  if (x) return(1);
+  else return(0);
 }
 
 #ifdef S_AUTH
-static int check_tcl_msgc(char *cmd, char *nick, char *uhost,
-                         struct userrec *u, char *args)
+static int check_tcl_msgc(char *cmd, char *nick, char *from, struct userrec *u, char *args)
 {
-  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
-  char *hand = u ? u->handle : "*";
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
   int x;
 
-  get_user_flagrec(u, &fr, NULL);
-  Tcl_SetVar(interp, "_msgc1", nick, 0);
-  Tcl_SetVar(interp, "_msgc2", uhost, 0);
-  Tcl_SetVar(interp, "_msgc3", hand, 0);
-  Tcl_SetVar(interp, "_msgc4", args, 0);
-  Tcl_SetVar(interp, "_msgc5", NULL, 0);
-  x = check_tcl_bind(H_msgc, cmd, &fr, " $_msgc1 $_msgc2 $_msgc3 $_msgc4 $_msgc5",
-                     MATCH_EXACT | BIND_HAS_BUILTINS | BIND_USE_ATTR);
-  if (x == BIND_EXEC_LOG)
-    putlog(LOG_CMDS, "*", "(%s!%s) !%s! %s%s %s", nick, uhost, hand, cmdprefix,
-           cmd, args);
-  return ((x == BIND_MATCHED) || (x == BIND_EXECUTED) || (x == BIND_EXEC_LOG));
+  x = check_bind(BT_msgc, cmd, &fr, nick, from, u, args, NULL);
+
+  if (x & BIND_RET_LOG)
+    putlog(LOG_CMDS, "*", " in check_tcl_msgc(%s!%s) !%s! %s%s %s", nick, from, u ? u->handle : "*", cmdprefix, cmd, args);
+
+  if (x & BIND_RET_BREAK) return(1);
+  return(0);
 }
 #endif /* S_AUTH */
 
@@ -146,37 +132,22 @@ static int check_tcl_msgc(char *cmd, char *nick, char *uhost,
  */
 static int check_tcl_raw(char *from, char *code, char *msg)
 {
-  int x;
-  Tcl_SetVar(interp, "_raw1", from, 0);
-  Tcl_SetVar(interp, "_raw2", code, 0);
-  Tcl_SetVar(interp, "_raw3", msg, 0);
-  x = check_tcl_bind(H_raw, code, 0, " $_raw1 $_raw2 $_raw3",
-                    MATCH_EXACT | BIND_STACKABLE | BIND_WANTRET);
-  return (x == BIND_EXEC_LOG);
+//  return check_bind(BT_raw, code, NULL, from, code, msg);
+  return check_bind(BT_raw, code, NULL, from, msg);
 }
 
 
 static int check_tcl_ctcpr(char *nick, char *uhost, struct userrec *u,
-                          char *dest, char *keyword, char *args,
-                          p_tcl_bind_list table)
+                           char *dest, char *keyword, char *args,
+                           bind_table_t *table)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
-  int x;
-
   get_user_flagrec(u, &fr, NULL);
-  Tcl_SetVar(interp, "_ctcpr1", nick, 0);
-  Tcl_SetVar(interp, "_ctcpr2", uhost, 0);
-  Tcl_SetVar(interp, "_ctcpr3", u ? u->handle : "*", 0);
-  Tcl_SetVar(interp, "_ctcpr4", dest, 0);
-  Tcl_SetVar(interp, "_ctcpr5", keyword, 0);
-  Tcl_SetVar(interp, "_ctcpr6", args, 0);
-  x = check_tcl_bind(table, keyword, &fr,
-                    " $_ctcpr1 $_ctcpr2 $_ctcpr3 $_ctcpr4 $_ctcpr5 $_ctcpr6",
-                    MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE |
-                    ((table == H_ctcp) ? BIND_WANTRET : 0));
-  return (x == BIND_EXEC_LOG) || (table == H_ctcr);
+
+  return check_bind(table, keyword, &fr, nick, uhost, u, dest, keyword, args);
 }
 
+
 static int match_my_nick(char *nick)
 {
   if (!rfc_casecmp(nick, botname))
@@ -395,7 +366,6 @@ static int gotmsg(char *from, char *msg)
 #endif /* S_AUTH */
   int ignoring = 0;
 
-
   if (msg[0] && ((strchr(CHANMETA, *msg) != NULL) ||
      (*msg == '@')))           /* Notice to a channel, not handled here */
     return 0;
@@ -561,7 +531,7 @@ static int gotmsg(char *from, char *msg)
             result = check_tcl_msg(code, nick, uhost, u, msg);
             
 	  if (!result)
-	    putlog(LOG_MSGS, "*", "[%s] %s %s", from, code, msg);
+	    putlog(LOG_MSGS, "*", " in gotmsg [%s] %s %s", from, code, msg);
         }
 #ifdef S_AUTH
       }

+ 24 - 57
src/mod/transfer.mod/transfer.c

@@ -23,12 +23,13 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+static bind_table_t *BT_load;
+static bind_table_t *BT_rcvd, *BT_sent, *BT_lost, *BT_tout;
 
 static Function *global = NULL, *update_funcs = NULL;
 
 static int copy_to_tmp = 1;	/* Copy files to /tmp before transmitting? */
 static int wait_dcc_xfer = 40;	/* Timeout time on DCC xfers */
-static p_tcl_bind_list H_rcvd, H_sent, H_lost, H_tout;
 static int dcc_limit = 4;	/* Maximum number of simultaneous file
 				   downloads allowed */
 static int dcc_block = 0;	/* Size of one dcc block */
@@ -178,62 +179,26 @@ static char *replace_spaces(char *fn)
 }
 
 
-/*
- *    Tcl sent, rcvd, tout and lost functions
- */
-
-static int builtin_sentrcvd STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(4, 4, " hand nick path");
-  CHECKVALIDITY(builtin_sentrcvd);
-  F(argv[1], argv[2], argv[3]);
-  return TCL_OK;
-}
-
-static int builtin_toutlost STDVAR
-{
-  Function F = (Function) cd;
-
-  BADARGS(6, 6, " hand nick path acked length");
-  CHECKVALIDITY(builtin_toutlost);
-  F(argv[1], argv[2], argv[3], argv[4], argv[5]);
-  return TCL_OK;
-}
 
 static void check_tcl_sentrcvd(struct userrec *u, char *nick, char *path,
-			       p_tcl_bind_list h)
+			       bind_table_t *table)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
   char *hand = u ? u->handle : "*";	/* u might be NULL. */
 
   get_user_flagrec(u, &fr, NULL);
-  Tcl_SetVar(interp, "_sr1", hand, 0);
-  Tcl_SetVar(interp, "_sr2", nick, 0);
-  Tcl_SetVar(interp, "_sr3", path, 0);
-  check_tcl_bind(h, hand, &fr, " $_sr1 $_sr2 $_sr3",
-		 MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE);
+  check_bind(table, hand, &fr, u, nick, path);
 }
 
 static void check_tcl_toutlost(struct userrec *u, char *nick, char *path,
 			       unsigned long acked, unsigned long length,
-                               p_tcl_bind_list h)
+				bind_table_t *table)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
   char *hand = u ? u->handle : "*";	/* u might be NULL. */
-  char s[15];
 
   get_user_flagrec(u, &fr, NULL);
-  Tcl_SetVar(interp, "_sr1", hand, 0);
-  Tcl_SetVar(interp, "_sr2", nick, 0);
-  Tcl_SetVar(interp, "_sr3", path, 0);
-  egg_snprintf(s, sizeof s, "%lu", acked);
-  Tcl_SetVar(interp, "_sr4", s, 0);
-  egg_snprintf(s, sizeof s, "%lu", length);
-  Tcl_SetVar(interp, "_sr5", s, 0);
-  check_tcl_bind(h, hand, &fr, " $_sr1 $_sr2 $_sr3 $_sr4 $_sr5",
-		 MATCH_MASK | BIND_USE_ATTR | BIND_STACKABLE);
+  check_bind(table, hand, &fr, u, nick, path, acked, length);
 }
 
 /*
@@ -689,7 +654,7 @@ static void eof_dcc_send(int idx)
 	f(dcc[idx].u.xfer->dir, dcc[idx].u.xfer->origname, hand);
       }
       stats_add_upload(u, dcc[idx].u.xfer->length);
-      check_tcl_sentrcvd(u, dcc[idx].nick, nfn, H_rcvd);
+      check_tcl_sentrcvd(u, dcc[idx].nick, nfn, BT_rcvd);
     }
     nfree(ofn);
     nfree(nfn);
@@ -950,7 +915,7 @@ static void dcc_get(int idx, char *buf, int len)
       struct userrec *u = get_user_by_handle(userlist,
 					     dcc[idx].u.xfer->from);
       check_tcl_sentrcvd(u, dcc[idx].nick,
-			 dcc[idx].u.xfer->dir, H_sent);
+			 dcc[idx].u.xfer->dir, BT_sent);
       if (fs != NULL) {
 	Function f = fs->funcs[FILESYS_INCRGOTS];
 
@@ -1046,7 +1011,7 @@ static void eof_dcc_get(int idx)
     u = get_user_by_host(s);
     check_tcl_toutlost(u, dcc[idx].nick, dcc[idx].u.xfer->dir,
 		       dcc[idx].u.xfer->acked, dcc[idx].u.xfer->length,
-		       H_lost);
+		       BT_lost);
 
     putlog(LOG_FILES, "*",TRANSFER_LOST_DCCGET,
 	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
@@ -1161,7 +1126,7 @@ static void transfer_get_timeout(int i)
     egg_snprintf(xx, sizeof xx, "%s!%s", dcc[i].nick, dcc[i].host);
     u = get_user_by_host(xx);
     check_tcl_toutlost(u, dcc[i].nick, dcc[i].u.xfer->dir,
-		       dcc[i].u.xfer->acked, dcc[i].u.xfer->length, H_tout);
+		       dcc[i].u.xfer->acked, dcc[i].u.xfer->length, BT_tout);
 
     putlog(LOG_FILES, "*",TRANSFER_DCC_GET_TIMEOUT,
 	   p ? p + 1 : dcc[i].u.xfer->origname, dcc[i].nick, dcc[i].status,
@@ -1870,10 +1835,10 @@ static cmd_t transfer_ctcps[] =
 /* Add our CTCP bindings if the server module is loaded. */
 static int server_transfer_setup(char *mod)
 {
-  p_tcl_bind_list H_ctcp;
+  bind_table_t *BT_ctcp;
 
-  if ((H_ctcp = find_bind_table("ctcp")))
-    add_builtins(H_ctcp, transfer_ctcps);
+  if ((BT_ctcp = find_bind_table2("ctcp")))
+    add_builtins2(BT_ctcp, transfer_ctcps);
   return 1;
 }
 
@@ -1923,15 +1888,15 @@ static Function transfer_table[] =
   /* 12 - 15 */
   (Function) wipe_tmp_filename,
   (Function) & DCC_GET,			/* struct dcc_table		*/
-  (Function) & H_rcvd,			/* p_tcl_bind_list		*/
-  (Function) & H_sent,			/* p_tcl_bind_list		*/
+  (Function) 0,
+  (Function) 0,
   /* 16 - 19 */
   (Function) & USERENTRY_FSTAT,		/* struct user_entry_type	*/
   (Function) & quiet_reject,		/* int				*/
   (Function) raw_dcc_resend,
-  (Function) & H_lost,			/* p_tcl_bind_list		*/
+  (Function) 0,
   /* 20 - 23 */
-  (Function) & H_tout,			/* p_tcl_bind_list		*/
+  (Function) 0,
 };
 
 char *transfer_start(Function *global_funcs)
@@ -1945,12 +1910,14 @@ char *transfer_start(Function *global_funcs)
     return "This module requires update module 0.0 or later.";
   }
 
-  add_builtins(H_load, transfer_load);
+  BT_load = find_bind_table2("load");
+  if (BT_load) add_builtins2(BT_load, transfer_load);
+
   server_transfer_setup(NULL);
-  H_rcvd = add_bind_table("rcvd", HT_STACKABLE, builtin_sentrcvd);
-  H_sent = add_bind_table("sent", HT_STACKABLE, builtin_sentrcvd);
-  H_lost = add_bind_table("lost", HT_STACKABLE, builtin_toutlost);
-  H_tout = add_bind_table("tout", HT_STACKABLE, builtin_toutlost);
+  BT_rcvd = add_bind_table2("rcvd", 3, "Uss", MATCH_MASK, BIND_STACKABLE);
+  BT_sent = add_bind_table2("sent", 3, "Uss", MATCH_MASK, BIND_STACKABLE);
+  BT_lost = add_bind_table2("lost", 5, "Ussii", MATCH_MASK, BIND_STACKABLE);
+  BT_tout = add_bind_table2("tout", 5, "Ussii", MATCH_MASK, BIND_STACKABLE);
 
   USERENTRY_FSTAT.get = def_get;
   add_entry_type(&USERENTRY_FSTAT);

+ 4 - 4
src/mod/transfer.mod/transfer.h

@@ -28,15 +28,15 @@ enum dccsend_types {
 /* 12 - 15 */
 #define wipe_tmp_filename(a,b) (((void (*) (char *,int))transfer_funcs[12])(a,b))
 #define DCC_GET (*(struct dcc_table *)(transfer_funcs[13]))
-#define H_rcvd (*(p_tcl_bind_list*)(transfer_funcs[14]))
-#define H_sent (*(p_tcl_bind_list*)(transfer_funcs[15]))
+/* UNUSED 14 */
+/* UNUSED 15 */
 /* 16 - 19 */
 #define USERENTRY_FSTAT (*(struct user_entry_type *)(transfer_funcs[16]))
 #define quiet_reject (*(int *)(transfer_funcs[17]))
 #define raw_dcc_resend(a,b,c,d) (((int (*) (char *,char *,char *,char *))transfer_funcs[18])(a,b,c,d))
-#define H_lost (*(p_tcl_bind_list*)(transfer_funcs[19]))
+/* UNUSED 19 */
 /* 20 - 23 */
-#define H_tout (*(p_tcl_bind_list*)(transfer_funcs[20]))
+/* UNUSED 20 */
 
 #else	/* MAKING_TRANSFER */
 

+ 4 - 1
src/mod/update.mod/update.c

@@ -21,6 +21,8 @@
 #include "transfer.mod/transfer.h"
 #include "compress.mod/compress.h"
 
+static bind_table_t *BT_bot;
+
 static Function *global = NULL, *transfer_funcs = NULL, *compress_funcs = NULL,
                 *uncompress_funcs = NULL;
 
@@ -525,7 +527,8 @@ char *update_start(Function *global_funcs)
     module_undepend(MODULE_NAME);
     return "This module requires the compression.";
   }
-  add_builtins(H_bot, update_bot);
+  BT_bot = find_bind_table2("bot");
+  if (BT_bot) add_builtins2(BT_bot, update_bot);
 #ifdef HUB
   add_hook(HOOK_30SECONDLY, (Function) check_updates);
 #endif /* HUB */

+ 44 - 26
src/modules.c

@@ -10,6 +10,7 @@
 #include "modules.h"
 #include "tandem.h"
 #include <ctype.h>
+#include "core_binds.h"
 
 extern struct dcc_t	*dcc;
 #ifdef S_AUTH
@@ -132,6 +133,7 @@ void (*shareupdatein) (int, char *) = null_share;
 void (*qserver) (int, char *, int) = (void (*)(int, char *, int)) null_func;
 void (*add_mode) () = null_func;
 int (*match_noterej) (struct userrec *, char *) = (int (*)(struct userrec *, char *)) false_func;
+int (*storenote)(char *from, char *to, char *msg, int idx, char *who, int bufsize) = (int (*)(char *from, char *to, char *msg, int idx, char *who, int bufsize)) minus_func;
 int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
 int (*rfc_ncasecmp) (const char *, const char *, int) = _rfc_ncasecmp;
 int (*rfc_toupper) (int) = _rfc_toupper;
@@ -165,13 +167,13 @@ Function global_table[] =
   (Function) module_depend,
   (Function) module_undepend,
   /* 8 - 11 */
-  (Function) add_bind_table,
-  (Function) del_bind_table,
-  (Function) find_bind_table,
-  (Function) check_tcl_bind,
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
   /* 12 - 15 */
-  (Function) add_builtins,
-  (Function) rem_builtins,
+  (Function) 0,
+  (Function) 0,
   (Function) add_tcl_commands,
   (Function) rem_tcl_commands,
   /* 16 - 19 */
@@ -245,7 +247,7 @@ Function global_table[] =
   (Function) chatout,
   (Function) chanout_but,
   /* 72 - 75 */
-  (Function) check_validity,
+  (Function) 0,
   (Function) list_delete,
   (Function) list_append,
   (Function) list_contains,
@@ -265,7 +267,7 @@ Function global_table[] =
   (Function) _get_data_ptr,
   (Function) open_telnet,
   /* 88 - 91 */
-  (Function) check_tcl_event,
+  (Function) check_bind_event,
   (Function) egg_memcpy,
   (Function) my_atoul,
   (Function) my_strcpy,
@@ -372,23 +374,23 @@ Function global_table[] =
   /* 172 - 175 */
   (Function) add_hook,
   (Function) del_hook,
-  (Function) & H_dcc,		/* p_tcl_bind_list *			*/
+  (Function) 0,
   (Function) 0,
   /* 176 - 179 */
-  (Function) & H_chon,		/* p_tcl_bind_list *			*/
-  (Function) & H_chof,		/* p_tcl_bind_list *			*/
-  (Function) & H_load,		/* p_tcl_bind_list *			*/
-  (Function) & H_unld,		/* p_tcl_bind_list *			*/
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
   /* 180 - 183 */
-  (Function) & H_chat,		/* p_tcl_bind_list *			*/
-  (Function) & H_act,		/* p_tcl_bind_list *			*/
-  (Function) & H_bcst,		/* p_tcl_bind_list *			*/
-  (Function) & H_bot,		/* p_tcl_bind_list *			*/
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
   /* 184 - 187 */
-  (Function) & H_link,		/* p_tcl_bind_list *			*/
-  (Function) & H_disc,		/* p_tcl_bind_list *			*/
-  (Function) & H_away,		/* p_tcl_bind_list *			*/
-  (Function) & H_nkch,		/* p_tcl_bind_list *			*/
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
+  (Function) 0,
   /* 188 - 191 */
   (Function) & USERENTRY_BOTADDR,	/* struct user_entry_type *	*/
   (Function) & USERENTRY_BOTFL,		/* struct user_entry_type *	*/
@@ -435,7 +437,7 @@ Function global_table[] =
   (Function) 0, /* ginvite_total -- UNUSED! (Eule) */
   (Function) 0, /* gexempt_total -- UNUSED! (Eule) */
   /* 224 - 227 */
-  (Function) & H_event,		/* p_tcl_bind_list *			*/
+  (Function) 0,
   (Function) & use_exempts,	/* int					*/
   (Function) & use_invites,	/* int					*/
   (Function) & force_expire,	/* int					*/
@@ -596,21 +598,30 @@ Function global_table[] =
   (Function) & CFG_MSGOP,
   (Function) & CFG_MSGPASS,
   (Function) & CFG_MSGINVITE,
-  (Function) & CFG_MSGIDENT
+  (Function) & CFG_MSGIDENT,
 #else /* !S_MSGCMDS */
   (Function) 0,
   (Function) 0,
   (Function) 0,
-  (Function) 0
+  (Function) 0,
 #endif /* S_MSGCMDS */
-
+  (Function) add_bind_table2,
+  (Function) del_bind_table2,
+  (Function) add_builtins2,
+  (Function) rem_builtins2,
+  (Function) find_bind_table2,
+  (Function) check_bind
 
 };
 
+static bind_table_t *BT_load;
+
 void init_modules(void)
 {
   int i;
 
+  BT_load = add_bind_table2("load", 1, "s", MATCH_MASK, 0);
+
   module_list = nmalloc(sizeof(module_entry));
   module_list->name = nmalloc(8);
   strcpy(module_list->name, "eggdrop");
@@ -699,7 +710,7 @@ const char *module_load(char *name)
     nfree(p);
     return e;
   }
-  check_tcl_load(name);
+  check_bind(BT_load, name, NULL, name);
   return NULL;
 }
 
@@ -877,6 +888,10 @@ void add_hook(int hook_num, Function func)
       if (match_noterej == (int (*)(struct userrec *, char *))false_func)
 	match_noterej = func;
       break;
+    case HOOK_STORENOTE:
+	if (func == NULL) storenote = (int (*)(char *from, char *to, char *msg, int idx, char *who, int bufsize)) minus_func;
+	else storenote = func;
+	break;
     case HOOK_DNS_HOSTBYIP:
       if (dns_hostbyip == block_dns_hostbyip)
 	dns_hostbyip = (void (*)(IP)) func;
@@ -931,6 +946,9 @@ void del_hook(int hook_num, Function func)
       if (match_noterej == (int (*)(struct userrec *, char *))func)
 	match_noterej = false_func;
       break;
+    case HOOK_STORENOTE:
+	if (storenote == func) storenote = (int (*)(char *from, char *to, char *msg, int idx, char *who, int bufsize)) minus_func;
+	break;
     case HOOK_DNS_HOSTBYIP:
       if (dns_hostbyip == (void (*)(IP)) func)
 	dns_hostbyip = block_dns_hostbyip;

+ 12 - 3
src/net.c

@@ -27,6 +27,7 @@
 #  include <unistd.h>
 #endif /* HAVE_UNITSTD_H */
 #include <setjmp.h>
+#include "egg_timer.h"
 
 #if !HAVE_GETDTABLESIZE
 #  ifdef FD_SETSIZE
@@ -1090,15 +1091,23 @@ static int sockread(char *s, int *len)
   int fds, i, x, fdtmp;
   struct timeval t;
   int grab = SGRAB;
+  egg_timeval_t howlong;
 
   fds = getdtablesize();
 #ifdef FD_SETSIZE
   if (fds > FD_SETSIZE)
     fds = FD_SETSIZE;		/* Fixes YET ANOTHER freebsd bug!!! */
 #endif /* FD_SETSIZE */
-  /* timeout: 1 sec */
-  t.tv_sec = 1;
-  t.tv_usec = 0;
+  if (timer_get_shortest(&howlong)) {
+    /* No timer, default to 1 second. */
+    t.tv_sec = 1;
+    t.tv_usec = 0;
+  }
+  else {
+    t.tv_sec = howlong.sec;
+    t.tv_usec = howlong.usec;
+  }
+
   FD_ZERO(&fd);
   
   for (i = 0; i < MAXSOCKS; i++)

+ 2 - 4
src/proto.h

@@ -30,15 +30,13 @@ struct list_type;
 struct tand_t_struct;
 
 #if !defined(MAKING_MODS)
-
-//extern int lfprintf(FILE *, char *, ...);
-
 extern int (*rfc_casecmp) (const char *, const char *);
 extern int (*rfc_ncasecmp) (const char *, const char *, int);
 extern int (*rfc_toupper) (int);
 extern int (*rfc_tolower) (int);
 extern int (*match_noterej) (struct userrec *, char *);
-#endif
+extern int (*storenote)(char *from, char *to, char *msg, int idx, char *who, int bufsize);
+#endif /* !MAKING_MODS */
 
 /* bg.c */
 void do_fork();

+ 4 - 51
src/tcl.c

@@ -15,7 +15,7 @@
 #if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1)) || (TCL_MAJOR_VERSION > 8)
 #define USE_BYTE_ARRAYS
 #endif
-
+void init_old_binds();
 
 /* Used for read/write to internal strings */
 typedef struct {
@@ -47,7 +47,6 @@ extern char	origbotname[], botuser[], motdfile[], admin[], userfile[],
 		pid_file[], dcc_prefix[];
 
 extern struct dcc_t	*dcc;
-extern tcl_timer_t	*timer, *utimer;
 
 int	    protect_readonly = 0;	/* turn on/off readonly protection */
 char	    whois_fields[1025] = "";	/* fields to display in a .whois */
@@ -359,21 +358,6 @@ void add_tcl_commands(tcl_cmds *table)
 
 }
 
-void add_cd_tcl_cmds(cd_tcl_cmd *table)
-{
-  void **cdata;
-
-  while (table->name) {
-    cdata = (void **)nmalloc(sizeof(void *) * 2);
-    clientdata_stuff += sizeof(void *) * 2;
-    cdata[0] = table->callback;
-    cdata[1] = table->cdata;
-    Tcl_CreateObjCommand(interp, table->name, utf_converter, (ClientData) cdata, 
-			 cmd_delete_callback);
-    table++;
-  }
-}
-
 #else
 
 void add_tcl_commands(tcl_cmds *table)
@@ -384,15 +368,6 @@ void add_tcl_commands(tcl_cmds *table)
     Tcl_CreateCommand(interp, table[i].name, table[i].func, NULL, NULL);
 }
 
-void add_cd_tcl_cmds(cd_tcl_cmd *table)
-{
-  while (table->name) {
-    Tcl_CreateCommand(interp, table->name, table->callback, 
-		      (ClientData) table->cdata, NULL);
-    table++;
-  }
-}
-
 #endif
 
 void rem_tcl_commands(tcl_cmds *table)
@@ -403,14 +378,6 @@ void rem_tcl_commands(tcl_cmds *table)
     Tcl_DeleteCommand(interp, table[i].name);
 }
 
-void rem_cd_tcl_cmds(cd_tcl_cmd *table)
-{
-  while (table->name) {
-    Tcl_DeleteCommand(interp, table->name);
-    table++;
-  }
-}
-
 void add_tcl_objcommands(tcl_cmds *table)
 {
 #if (TCL_MAJOR_VERSION >= 8)
@@ -482,16 +449,7 @@ static void init_traces()
   add_tcl_ints(def_tcl_ints);
 }
 
-void kill_tcl()
-{
-  rem_tcl_coups(def_tcl_coups);
-  rem_tcl_strings(def_tcl_strings);
-  rem_tcl_ints(def_tcl_ints);
-  kill_bind();
-  Tcl_DeleteInterp(interp);
-}
-
-extern tcl_cmds tcluser_cmds[], tcldcc_cmds[], tclmisc_cmds[], tclmisc_objcmds[], tcldns_cmds[];
+extern tcl_cmds tcluser_cmds[], tcldcc_cmds[], tclmisc_cmds[], tclmisc_objcmds[];
 
 /* Not going through Tcl's crazy main() system (what on earth was he
  * smoking?!) so we gotta initialize the Tcl interpreter
@@ -547,11 +505,6 @@ void init_tcl(int argc, char **argv)
 
   encoding = NULL;
   if (langEnv != NULL) {
-    for (i = 0; localeTable[i].lang != NULL; i++)
-      if (strcmp(localeTable[i].lang, langEnv) == 0) {
-	encoding = localeTable[i].encoding;
-	break;
-      }
 
     /* There was no mapping in the locale table.  If there is an
      * encoding subfield, we can try to guess from that.
@@ -612,13 +565,13 @@ resetPath:
 
   /* Initialize binds and traces */
   Context;
-  init_bind();
+
+  init_old_binds();
   init_traces();
   /* Add new commands */
   add_tcl_commands(tcluser_cmds);
   add_tcl_commands(tcldcc_cmds);
   add_tcl_commands(tclmisc_cmds);
-  add_tcl_commands(tcldns_cmds);
   Context;
 }
 

+ 0 - 4
src/tcldcc.c

@@ -11,8 +11,6 @@
 #include <sys/stat.h>
 
 extern Tcl_Interp	*interp;
-extern tcl_timer_t	*timer,
-			*utimer;
 extern struct dcc_t	*dcc;
 
 extern int		 dcc_total, backgrd, parties,
@@ -288,8 +286,6 @@ static int tcl_restart STDVAR
   write_userfile(-1);
 #endif
   putlog(LOG_MISC, "*", MISC_RESTARTING);
-  wipe_timers(interp, &utimer);
-  wipe_timers(interp, &timer);
   do_restart = -1;
   return TCL_OK;
 }

+ 0 - 72
src/tclegg.h

@@ -37,17 +37,6 @@
 #define BIND_EXEC_LOG   4	/* Proc returned 1 -> wants to be logged */
 #define BIND_EXEC_BRK   5	/* Proc returned BREAK (quit) */
 
-/* Extra commands are stored in Tcl hash tables (one hash table for each type
- * of command: msg, dcc, etc)
- */
-typedef struct timer_str {
-  struct timer_str	*next;
-  unsigned int		 mins;	/* Time to elapse			*/
-  char			*cmd;	/* Command linked to			*/
-  unsigned long		 id;	/* Used to remove timers		*/
-} tcl_timer_t;
-
-
 /* Used for stub functions:
  */
 
@@ -65,12 +54,6 @@ typedef struct timer_str {
 } while (0)
 
 
-unsigned long add_timer(tcl_timer_t **, int, char *, unsigned long);
-int remove_timer(tcl_timer_t **, unsigned long);
-void list_timers(Tcl_Interp *, tcl_timer_t *);
-void wipe_timers(Tcl_Interp *, tcl_timer_t **);
-void do_check_timers(tcl_timer_t **);
-
 typedef struct _tcl_strings {
   char *name;
   char *buf;
@@ -95,16 +78,8 @@ typedef struct _tcl_cmds {
   Function func;
 } tcl_cmds;
 
-typedef struct _cd_tcl_cmd {
-  char *name;
-  Function callback;
-  void *cdata;
-} cd_tcl_cmd;
-
 void add_tcl_commands(tcl_cmds *);
-void add_cd_tcl_cmds(cd_tcl_cmd *);
 void rem_tcl_commands(tcl_cmds *);
-void rem_cd_tcl_cmds(cd_tcl_cmd *);
 void add_tcl_strings(tcl_strings *);
 void rem_tcl_strings(tcl_strings *);
 void add_tcl_coups(tcl_coups *);
@@ -112,51 +87,4 @@ void rem_tcl_coups(tcl_coups *);
 void add_tcl_ints(tcl_ints *);
 void rem_tcl_ints(tcl_ints *);
 
-/* From Tcl's tclUnixInit.c */
-/* The following table is used to map from Unix locale strings to
- * encoding files.
- */
-typedef struct LocaleTable {
-  const char *lang;
-  const char *encoding;
-} LocaleTable;
-
-static const LocaleTable localeTable[] = {
-  {"ja_JP.SJIS",	"shiftjis"},
-  {"ja_JP.EUC",		"euc-jp"},
-  {"ja_JP.JIS",		"iso2022-jp"},
-  {"ja_JP.mscode",	"shiftjis"},
-  {"ja_JP.ujis",	"euc-jp"},
-  {"ja_JP",		"euc-jp"},
-  {"Ja_JP",		"shiftjis"},
-  {"Jp_JP",		"shiftjis"},
-  {"japan",		"euc-jp"},
-#ifdef hpux
-  {"japanese",		"shiftjis"},
-  {"ja",		"shiftjis"},
-#else
-  {"japanese",		"euc-jp"},
-  {"ja",		"euc-jp"},
-#endif
-  {"japanese.sjis",	"shiftjis"},
-  {"japanese.euc",	"euc-jp"},
-  {"japanese-sjis",	"shiftjis"},
-  {"japanese-ujis",	"euc-jp"},
-
-  {"ko",		"euc-kr"},
-  {"ko_KR",		"euc-kr"},
-  {"ko_KR.EUC",		"euc-kr"},
-  {"ko_KR.euc",		"euc-kr"},
-  {"ko_KR.eucKR",	"euc-kr"},
-  {"korean",		"euc-kr"},
-
-  {"ru",		"iso8859-5"},
-  {"ru_RU",		"iso8859-5"},
-  {"ru_SU",		"iso8859-5"},
-
-  {"zh",		"cp936"},
-
-  {NULL,		NULL}
-};
-
 #endif				/* _EGG_TCLEGG_H */

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 243 - 690
src/tclhash.c


+ 76 - 39
src/tclhash.h

@@ -9,6 +9,39 @@
 
 #define TC_DELETED	0x0001	/* This command/trigger was deleted.	*/
 
+/* Flags for bind entries */
+/* 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
+
+/* 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. */
+typedef struct bind_entry_b {
+        struct bind_entry_b *next;
+        struct flag_record user_flags;
+        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;
 
@@ -22,12 +55,16 @@ typedef struct tcl_cmd_b {
 
 #define TBM_DELETED	0x0001	/* This mask was deleted.		*/
 
-typedef struct tct {
-  struct flag_record flags;
-  void *func;
-  struct tct *next;
-} bind_cmd_t;
-
+/* 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 flags;
+} bind_chain_t;
 
 typedef struct tcl_bind_mask_b {
   struct tcl_bind_mask_b *next;
@@ -44,10 +81,24 @@ typedef struct tcl_bind_mask_b {
 #define HT_DELETED	0x0002	/* This bind list was already deleted.
 				   Do not use it anymore.		*/
 typedef struct {
- char *name;
- struct flag_record     flags;
+	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;
+        char *name;
+        char *syntax;
+        int nargs;
+        int match_type;
+        int flags;
+} bind_table_t;
+
+
 typedef struct tcl_bind_list_b {
   struct tcl_bind_list_b *next;
 
@@ -64,19 +115,15 @@ typedef struct tcl_bind_list_b {
 
 #ifndef MAKING_MODS
 
-inline void garbage_collect_tclhash(void);
 
 void init_bind(void);
-void kill_bind(void);
+void init_bind2(void);
+void kill_bind2(void);
 int expmem_tclhash(void);
 
-tcl_bind_list_t *add_bind_table(const char *nme, int flg, Function func);
-void del_bind_table(tcl_bind_list_t *tl_which);
 
-tcl_bind_list_t *find_bind_table(const char *nme);
 
-int check_tcl_bind(tcl_bind_list_t *, const char *, struct flag_record *, const char *, int);
-int check_tcl_dcc(char *, int, char *);
+void check_tcl_dcc(const char *, int, const char *);
 void check_tcl_chjn(const char *, const char *, int, char, int, const char *);
 void check_tcl_chpt(const char *, const char *, int, int);
 void check_tcl_bot(const char *, const char *, const char *);
@@ -88,38 +135,28 @@ void check_tcl_time(struct tm *);
 void tell_binds(int, char *);
 void check_tcl_nkch(const char *, const char *);
 void check_tcl_away(const char *, int, const char *);
-void check_tcl_chatactbcst(const char *, int, const char *, tcl_bind_list_t *);
-void check_tcl_event(const char *);
 
-#define check_tcl_chat(a, b, c) check_tcl_chatactbcst(a ,b, c, H_chat)
-#define check_tcl_act(a, b, c) check_tcl_chatactbcst(a, b, c, H_act)
-#define check_tcl_bcst(a, b, c) check_tcl_chatactbcst(a, b, c, H_bcst)
-void check_tcl_chonof(char *, int, tcl_bind_list_t *);
+int check_tcl_chat(char *, int, const char *);
+void check_tcl_act(const char *, int, const char *);
+void check_tcl_bcst(const char *, int, const char *);
+void check_tcl_chon(char *, int);
+void check_tcl_chof(char *, int);
+
 
-#define check_tcl_chon(a, b) check_tcl_chonof(a, b, H_chon)
-#define check_tcl_chof(a, b) check_tcl_chonof(a, b, H_chof)
 void check_tcl_loadunld(const char *, tcl_bind_list_t *);
 
-#define check_tcl_load(a) check_tcl_loadunld(a, H_load)
-#define check_tcl_unld(a) check_tcl_loadunld(a, H_unld)
 
-void rem_builtins(tcl_bind_list_t *, cmd_t *);
-void add_builtins(tcl_bind_list_t *, cmd_t *);
+int check_bind(bind_table_t *table, const char *match, struct flag_record *_flags, ...);
+bind_table_t *add_bind_table2(const char *name, int nargs, const char *syntax, int match_type, int flags);
+void del_bind_table2(bind_table_t *table);
+bind_table_t *find_bind_table2(const char *name);
+int add_bind_entry(bind_table_t *table, const char *flags, const char *mask, const char *function_name, int bind_flags, Function callback, void *client_data);
+int del_bind_entry(bind_table_t *table, const char *flags, const char *mask, const char *function_name);
+void add_builtins2(bind_table_t *table, cmd_t *cmds);
+void rem_builtins2(bind_table_t *table, cmd_t *cmds);
 
-int check_validity(char *, Function);
-extern p_tcl_bind_list H_chat, H_act, H_bcst, H_chon, H_chof;
-extern p_tcl_bind_list H_load, H_unld, H_dcc, H_bot, H_link;
-extern p_tcl_bind_list H_away, H_nkch, H_disc, H_event;
 
 #endif
 
 
-#define CHECKVALIDITY(a)	do {					\
-	if (!check_validity(argv[0], (a))) {				\
-		Tcl_AppendResult(irp, "bad builtin command call!",	\
-				 NULL);					\
-		return TCL_ERROR;					\
-	}								\
-} while (0)
-
 #endif				/* _EGG_TCLHASH_H */

+ 0 - 1
src/tclmisc.c

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

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů