Fix several bugs; make off-channel a per-channel option
[srvx.git] / src / proto-common.c
index 6a042edbaa22a79ca2b7bf6fd014e4237d8fca5e..8f5f1b9a791fd0f5d43a2a3815f1c0d038fb825b 100644 (file)
@@ -366,34 +366,6 @@ static CMD_FUNC(cmd_stats)
     return 1;
 }
 
-static CMD_FUNC(cmd_whois)
-{
-    struct userNode *from;
-    struct userNode *who;
-
-    if (argc < 3)
-        return 0;
-    if (!(from = GetUserH(origin))) {
-        log_module(MAIN_LOG, LOG_ERROR, "Could not find WHOIS origin user %s", origin);
-        return 0;
-    }
-    if(!(who = GetUserH(argv[2]))) {
-        irc_numeric(from, ERR_NOSUCHNICK, "%s@%s :No such nick", argv[2], self->name);
-        return 1;
-    }
-    if (IsHiddenHost(who) && !IsOper(from)) {
-        /* Just stay quiet. */
-        return 1;
-    }
-    irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info);
-    irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description);
-    if (IsOper(who)) {
-        irc_numeric(from, RPL_WHOISOPERATOR, "%s :is a megalomaniacal power hungry tyrant", who->nick);
-    }
-    irc_numeric(from, RPL_ENDOFWHOIS, "%s :End of /WHOIS list", who->nick);
-    return 1;
-}
-
 static CMD_FUNC(cmd_version)
 {
     struct userNode *user;
@@ -442,6 +414,11 @@ static struct chanmsg_func {
     struct userNode *service;
 } chanmsg_funcs[256]; /* indexed by trigger character */
 
+static struct allchanmsg_func {
+    chanmsg_func_t func;
+    struct userNode *service;
+} allchanmsg_funcs[ALLCHANMSG_FUNCS_MAX];
+
 struct privmsg_desc {
     struct userNode *user;
     char *text;
@@ -455,6 +432,7 @@ privmsg_chan_helper(struct chanNode *cn, void *data)
     struct privmsg_desc *pd = data;
     struct modeNode *mn;
     struct chanmsg_func *cf = &chanmsg_funcs[(unsigned char)pd->text[0]];
+    int x;
 
     /* Don't complain if it can't find the modeNode because the channel might
      * be -n */
@@ -464,6 +442,15 @@ privmsg_chan_helper(struct chanNode *cn, void *data)
     /* Never send a NOTICE to a channel to one of the services */
     if (!pd->is_notice && cf->func && GetUserMode(cn, cf->service))
         cf->func(pd->user, cn, pd->text+1, cf->service);
+
+    /* This catches *all* text sent to the channel that the services server sees */
+    for (x = 0; x < ALLCHANMSG_FUNCS_MAX; x++) {
+       cf = (struct chanmsg_func *)&allchanmsg_funcs[x];
+       if (!cf->func)
+         break; /* end of list */
+       else
+       cf->func(pd->user, cn, pd->text, cf->service);
+    }
 }
 
 static void
@@ -491,6 +478,19 @@ reg_chanmsg_func(unsigned char prefix, struct userNode *service, chanmsg_func_t
     chanmsg_funcs[prefix].service = service;
 }
 
+void
+reg_allchanmsg_func(struct userNode *service, chanmsg_func_t handler)
+{
+    int x;
+    for (x = 0; x < ALLCHANMSG_FUNCS_MAX; x++) {
+       if (allchanmsg_funcs[x].func)
+         continue;
+       allchanmsg_funcs[x].func = handler;
+       allchanmsg_funcs[x].service = service;
+       break;
+    }
+}
+
 struct userNode *
 get_chanmsg_bot(unsigned char prefix)
 {