Support ircu's XQUERY and XRESPONSE.
authorMichael Poole <mdpoole@troilus.org>
Fri, 20 Jan 2012 02:29:02 +0000 (21:29 -0500)
committerMichael Poole <mdpoole@troilus.org>
Fri, 20 Jan 2012 02:29:02 +0000 (21:29 -0500)
src/proto-bahamut.c
src/proto-common.c
src/proto-p10.c
src/proto.h

index 18bceebe5bbe091e601cfada3ce6925b5d21369c..af7e5546ea133a75e8915bba9f05532fff64639d 100644 (file)
@@ -1105,6 +1105,7 @@ void init_parse(void) {
 
     userList_init(&dead_users);
     reg_exit_func(parse_cleanup);
+    (void)call_xquery_funcs;
 }
 
 int parse_line(char *line, int recursive) {
index 4fa2d2b49f5758258911794d5815136703f0893a..6039d759158228af5520aa5ea91ccd8a576723e7 100644 (file)
@@ -570,6 +570,34 @@ call_oper_funcs(struct userNode *user)
     }
 }
 
+static xquery_func_t *xqf_list;
+static unsigned int xqf_size = 0, xqf_used = 0;
+
+void
+reg_xquery_func(xquery_func_t handler)
+{
+    if (xqf_used == xqf_size) {
+        if (xqf_size) {
+            xqf_size <<= 1;
+            xqf_list = realloc(xqf_list, xqf_size*sizeof(xquery_func_t));
+        } else {
+            xqf_size = 8;
+            xqf_list = malloc(xqf_size*sizeof(xquery_func_t));
+        }
+    }
+    xqf_list[xqf_used++] = handler;
+}
+
+static void
+call_xquery_funcs(struct server *source, const char routing[], const char query[])
+{
+    unsigned int n;
+    for (n=0; n < xqf_used; n++)
+    {
+        xqf_list[n](source, routing, query);
+    }
+}
+
 struct mod_chanmode *
 mod_chanmode_alloc(unsigned int argc)
 {
index 9a8840071bc170712836e376368ee899cdf639c0..71f6d3766acd5f2ef97de6a6f155b5d1ec31038a 100644 (file)
 #define CMD_WHO                 "WHO"
 #define CMD_WHOIS               "WHOIS"
 #define CMD_WHOWAS              "WHOWAS"
+#define CMD_XQUERY              "XQUERY"
+#define CMD_XRESPONSE           "XRESPONSE"
 
 /* Tokenized commands. */
 #define TOK_ACCOUNT             "AC"
 #define TOK_WHO                 "H"
 #define TOK_WHOIS               "W"
 #define TOK_WHOWAS              "X"
+#define TOK_XQUERY              "XQ"
+#define TOK_XRESPONSE           "XR"
 
 /* Protocol messages; aliased to full commands or tokens depending
    on compile-time configuration. ircu prefers tokens WITH THE
 #define P10_WHO                 TYPE(WHO)
 #define P10_WHOIS               TYPE(WHOIS)
 #define P10_WHOWAS              TYPE(WHOWAS)
+#define P10_XQUERY              TYPE(XQUERY)
+#define P10_XRESPONSE           TYPE(XRESPONSE)
 
 /* Servers claiming to have a boot or link time before PREHISTORY
  * trigger errors to the log.  We hope no server has been running
@@ -908,6 +914,12 @@ irc_numeric(struct userNode *user, unsigned int num, const char *format, ...)
     putsock(":%s %03d %s %s", self->name, num, user->nick, buffer);
 }
 
+void
+irc_xresponse(struct server *target, const char *routing, const char *response)
+{
+    putsock("%s " P10_XRESPONSE " %s %s :%s", self->numeric, target->numeric, routing, response);
+}
+
 static void send_burst(void);
 
 static void
@@ -1666,6 +1678,16 @@ static CMD_FUNC(cmd_time)
     return 1;
 }
 
+static CMD_FUNC(cmd_xquery)
+{
+    struct server *source;
+    if ((argc < 4)
+        || !(source = GetServerH(origin)))
+        return 0;
+    call_xquery_funcs(source, argv[2], argv[3]);
+    return 1;
+}
+
 void
 free_user(struct userNode *user)
 {
@@ -1807,6 +1829,8 @@ init_parse(void)
     dict_insert(irc_func_dict, TOK_ADMIN, cmd_admin);
     dict_insert(irc_func_dict, CMD_TIME, cmd_time);
     dict_insert(irc_func_dict, TOK_TIME, cmd_time);
+    /* We don't handle XR or the (not really defined) XQUERY. */
+    dict_insert(irc_func_dict, TOK_XQUERY, cmd_xquery);
 
     /* In P10, DESTRUCT doesn't do anything except be broadcast to servers.
      * Apparently to obliterate channels from any servers that think they
index 99ca1099703fddf03aa3fd6b69d0e93de99dea48..6ded4dfb49463e798ea758455327894312a4c209 100644 (file)
@@ -104,6 +104,9 @@ void unreg_notice_func(struct userNode *user);
 typedef void (*oper_func_t) (struct userNode *user);
 void reg_oper_func(oper_func_t handler);
 
+typedef void (*xquery_func_t) (struct server *source, const char routing[], const char query[]);
+void reg_xquery_func(xquery_func_t handler);
+
 /* replay silliness */
 void replay_read_line(void);
 void replay_event_loop(void);
@@ -142,6 +145,7 @@ void irc_kill(struct userNode *from, struct userNode *target, const char *messag
 void irc_raw(const char *what);
 void irc_stats(struct userNode *from, struct server *target, char type);
 void irc_svsnick(struct userNode *from, struct userNode *target, const char *newnick);
+void irc_xresponse(struct server *target, const char *routing, const char *response);
 
 /* account maintenance */
 void irc_account(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial);