Cleaner handling of redirecting messages. Fixes JOIN issues + couple of
authorjelmer <jelmer>
Mon, 19 Sep 2005 19:55:06 +0000 (21:55 +0200)
committerjelmer <jelmer>
Mon, 19 Sep 2005 19:55:06 +0000 (21:55 +0200)
other minor issues.

TODO
client.c
client.h
ctrlproxy.h
internals.h
mods/nickserv.c
network.c
redirect.c
testsuite/test-state.c
util.c

diff --git a/TODO b/TODO
index 16102322dac233f89a0df05a5b7b7aff5d3e5563..1ff5500e52f73a261e083c0336e7cd206ed64ab9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
 2.7 showstoppers:
-- handle some currently unhandled responses (especially wrt JOIN's)
- - Special handler for join stuff
 - test and fix SSL support
 - update documentation
 
index 4f4cd7dc9a5b9cf0e2b85038c9e80c5c0a06a505..f5d053627525aeb3cc39d6be268bf6ae01f81a7d 100644 (file)
--- a/client.c
+++ b/client.c
@@ -104,7 +104,6 @@ static gboolean process_from_client(struct client *c, struct line *l)
                                                 "Please register only once per session", NULL);
        } else if(c->network->connection.state == NETWORK_CONNECTION_STATE_MOTD_RECVD) {
                if (c->network->config->disable_cache || !client_try_cache(c, l)) {
-                       redirect_record(c, l);
                        /* Perhaps check for validity of input here ? It could save us some bandwidth 
                         * to the server, though very unlikely to occur often */
                        network_send_line(c->network, c, l);
@@ -185,7 +184,7 @@ gboolean client_send_args(struct client *c, ...)
        return ret;
 }
 
-gboolean client_send_line(struct client *c, const struct line *l)
+gboolean client_send_line(const struct client *c, const struct line *l)
 {
        log_client_line(c, l, FALSE);
        return irc_send_line(c->incoming, l);
index 8b23df0ebcf6e7d5318ce45526257e3aa4b10498..cae709a92aa4cd4ee9b2dfdf8aac79a0284e5a8b 100644 (file)
--- a/client.h
+++ b/client.h
@@ -48,6 +48,6 @@ G_MODULE_EXPORT void disconnect_client(struct client *c, const char *reason);
 G_MODULE_EXPORT gboolean client_send_args(struct client *c, ...);
 G_MODULE_EXPORT gboolean client_send_args_ex(struct client *c, const char *hm, ...);
 G_MODULE_EXPORT gboolean client_send_response(struct client *c, int response, ...);
-G_MODULE_EXPORT gboolean client_send_line(struct client *c, const struct line *);
+G_MODULE_EXPORT gboolean client_send_line(const struct client *c, const struct line *);
 
 #endif /* __CTRLPROXY_CLIENT_H__ */
index 66495936b16bebe205f7b16eb81e55afaf9cd39b..9daf78e781832718cdc1e529530a33806183385f 100644 (file)
@@ -57,8 +57,8 @@ G_MODULE_EXPORT struct ctrlproxy_config *get_current_config(void);
 
 /* util.c */
 G_MODULE_EXPORT char *list_make_string(GList *);
-G_MODULE_EXPORT int verify_client(struct network *s, struct client *c);
-G_MODULE_EXPORT char *ctrlproxy_path(char *part);
+G_MODULE_EXPORT int verify_client(const struct network *s, const struct client *c);
+G_MODULE_EXPORT char *ctrlproxy_path(const char *part);
 G_MODULE_EXPORT int str_rfc1459cmp(const char *a, const char *b);
 G_MODULE_EXPORT int str_strictrfc1459cmp(const char *a, const char *b);
 G_MODULE_EXPORT int str_asciicmp(const char *a, const char *b);
index 11b0945d72efa503f60ea26d14ac58a5e428f556..5ae8cd7676fd38d90f1a4d1a80d1fd51f07c41ae 100644 (file)
@@ -87,7 +87,7 @@ void log_network_line(const struct network *n, const struct line *l, gboolean in
 void log_client_line(const struct client *c, const struct line *l, gboolean incoming);
 
 /* redirect.c */
-void redirect_record(struct client *c, struct line *l);
+void redirect_record(const struct network *n, const struct client *c, const struct line *l);
 void redirect_response(struct network *n, struct line *l);
 
 /* cache.c */
index 1cd0fa18c0711fdf332e7a9134089df191a03768..9d069e93a88a89ec2af60b29e3bb3b13bd4d6439 100644 (file)
@@ -66,7 +66,7 @@ static void identify_me(struct network *network, char *nick)
                network_send_args(network, "PRIVMSG", nickserv_n, raw, NULL);
                g_free(raw);
        } else {
-               log_network("nickserv", LOG_INFO, network, "Not identifying for %s; no entries found", nick);
+               log_network("nickserv", LOG_INFO, network, "No password known for `%s'", nick);
        }
 }
 
index 714b5ea2e00e959cc99af6bd0b0d10ade6ea5b95..662e5fba6ce480d8c5aa26a90f723f22f3ce6451 100644 (file)
--- a/network.c
+++ b/network.c
@@ -197,6 +197,9 @@ gboolean network_send_line(struct network *s, const struct client *c, const stru
        l.origin = NULL;                /* Never send origin to the server */
 
        log_network_line(s, &l, FALSE);
+
+       redirect_record(s, c, &l);
+
        switch (s->config->type) {
        case NETWORK_TCP:
                return irc_send_line(s->connection.data.tcp.outgoing, &l);
@@ -606,7 +609,7 @@ gboolean disconnect_network(struct network *s)
        return close_server(s);
 }
 
-int verify_client(struct network *s, struct client *c)
+int verify_client(const struct network *s, const struct client *c)
 {
        GList *gl = s->clients;
        while(gl) {
index 5d3a96003e7a4ecddb1b6158f20f536bd8fe43c2..db70e99d48c25af694f349b55673f7a40d5ef1e6 100644 (file)
@@ -24,8 +24,8 @@
 
 struct query_stack {
        struct query *query;
-       struct network *network;
-       struct client *client;  
+       const struct network *network;
+       const struct client *client;    
        struct query_stack *next;
 };
 
@@ -38,11 +38,11 @@ struct query {
        int errors[20];
        /* Should add this query to the stack. return TRUE if this has 
         * been done successfully, FALSE otherwise */
-       int (*handle) (struct line *, struct client *c, struct query *);
+       int (*handle) (const struct line *, const struct network *n, const struct client *c, struct query *);
 };
 
-static int handle_default(struct line *, struct client *c, struct query *);
-static int handle_topic(struct line *, struct client *c, struct query *);
+static int handle_default(const struct line *, const struct network *n, const struct client *c, struct query *);
+static int handle_topic(const struct line *, const struct network *n, const struct client *c, struct query *);
 
 static struct query queries[] = {
 /* Commands that get a one-client reply: 
@@ -203,6 +203,14 @@ static struct query queries[] = {
                handle_default
        },
 
+ /* USER <username> <hostname> <servername> <realname> */
+       { "USER",
+               { 0 },
+               { 0 },
+               { ERR_NEEDMOREPARAMS, ERR_ALREADYREGISTERED, 0 },
+               handle_default
+       },
+
  /* OPER <name> <password> */
        { "OPER",
            { 0 },
@@ -423,7 +431,8 @@ static void handle_464(struct network *n, struct line *l)
 }
 
 /* List of responses that should be sent to all clients */
-static int response_all[] = { RPL_NOWAWAY, RPL_UNAWAY, 0 };
+static int response_all[] = { RPL_NOWAWAY, RPL_UNAWAY, RPL_NAMREPLY, 
+       RPL_ENDOFNAMES, 0 };
 static int response_none[] = { ERR_NOMOTD, RPL_ENDOFMOTD, 0 };
 static struct {
        int response;
@@ -458,15 +467,15 @@ static struct query *find_query(char *name)
 
 void redirect_response(struct network *network, struct line *l)
 {
-       struct query_stack *s = stack, *p = NULL;
-       struct client *c = NULL;
+       struct query_stack *s, *p = NULL;
+       const struct client *c = NULL;
        int n;
        int i;
 
        n = atoi(l->args[0]);
 
        /* Find a request that this response is a reply to */
-       while(s) {
+       for (s = stack; s; s = s->next) {
                if(s->network == network && 
                   (is_reply(s->query->replies, n) || 
                        is_reply(s->query->errors, n) ||
@@ -484,9 +493,9 @@ void redirect_response(struct network *network, struct line *l)
                                g_free(s);
                        }
 
-                       break;
+                       return;
                }
-               p = s; s = s->next;
+               p = s; 
        }
 
        /* See if this is a response that should be sent to all clients */
@@ -504,6 +513,7 @@ void redirect_response(struct network *network, struct line *l)
                }
        }
 
+       /* Handle response using custom function */
        for (i = 0; response_handler[i].handler; i++) {
                if (response_handler[i].response == n) {
                        response_handler[i].handler(network, l);
@@ -517,24 +527,29 @@ void redirect_response(struct network *network, struct line *l)
        }
 }
 
-void redirect_record(struct client *c, struct line *l)
+void redirect_record(const struct network *n, const struct client *c, const struct line *l)
 {
        struct query *q;
 
        q = find_query(l->args[0]);
        if(!q) {
-               log_client(NULL, LOG_WARNING, c, "Unknown command from client: %s", l->args[0]);
+               if (c) {
+                       log_client(NULL, LOG_WARNING, c, "Unknown command from client: %s", l->args[0]);
+               } else {
+                       log_network(NULL, LOG_WARNING, n, "Sending unknown command '%s'", l->args[0]);
+               }
                return;
        }
 
+
        /* Push it up the stack! */
-       q->handle(l, c, q);
+       q->handle(l, n, c, q);
 }
 
-static int handle_default(struct line *l, struct client *c, struct query *q)
+static int handle_default(const struct line *l, const struct network *n, const struct client *c, struct query *q)
 {
        struct query_stack *s = g_new(struct query_stack,1);
-       s->network = c->network;
+       s->network = n;
        s->client = c;
        s->query = q;
        s->next = stack;
@@ -542,8 +557,8 @@ static int handle_default(struct line *l, struct client *c, struct query *q)
        return 1;
 }
 
-static int handle_topic(struct line *l, struct client *c, struct query *q)
+static int handle_topic(const struct line *l, const struct network *n, const struct client *c, struct query *q)
 {
        if(l->args[2])return 0;
-       return handle_default(l,c,q);
+       return handle_default(l,n,c,q);
 }
index 5d7042de1fda09f00aebab2f8e2c8c41bbc133b0..246856422d2df3cdc003183aca5aea3cbe30cc23 100644 (file)
@@ -25,6 +25,7 @@
 #include "ctrlproxy.h"
 
 gboolean network_nick_set_nick(struct network_nick *, const char *);
+gboolean network_nick_set_hostmask(struct network_nick *, const char *);
 
 static int state_join(void)
 {
diff --git a/util.c b/util.c
index 9a58b3411a766e12457a414373e9da3270536d54..10f58c8acd52ae80b7c4298b82cdc09549d414d8 100644 (file)
--- a/util.c
+++ b/util.c
@@ -46,7 +46,7 @@ char *list_make_string(GList *list)
        return ret;
 }
 
-char *ctrlproxy_path(char *part)
+char *ctrlproxy_path(const char *part)
 {
        char *p, *p1;
        p = g_strdup_printf("%s/.ctrlproxy", g_get_home_dir());