Get rid of hashtable in network_info (should speed things up a bit), add support...
authorJelmer Vernooij <jelmer@samba.org>
Sat, 17 Mar 2007 00:10:33 +0000 (01:10 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 17 Mar 2007 00:10:33 +0000 (01:10 +0100)
parameters in 005 lines.

NEWS
src/isupport.c
src/network.c
src/state.h
testsuite/test-isupport.c
testsuite/test-linestack.c
testsuite/test-networkinfo.c

diff --git a/NEWS b/NEWS
index 13cff8b0011a462d208a7735a31106599ec0ac88..7022a974485f0cbe3ff93754286637e40c64c328 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -40,7 +40,7 @@ Ctrlproxy 3.0.2 UNRELEASED
                NICKLEN, MAXBANS, MODES, NICKLEN, MAXBANS, TOPICLEN, KICKLEN, 
                AWAYLEN, MAXTARGETS, WALLCHOPS, WALLVOICES, RFC2812, PENALTY,
                FNC, SAFELIST, USERIP, CNOTICE, KNOCK, VCHANNELS, WHOX, CALLERID,
-               ACCEPT.
+               ACCEPT, KEYLEN, USERLEN, HOSTLEN and SILENCE
 
   PORTABILITY
 
index b22c3e8700d3dcbb540ef11cbee926b0a2ece263..c5aacdd3e94795353ff085fd25f981e60f805174 100644 (file)
@@ -38,8 +38,6 @@ void network_info_parse(struct network_info *info, const char *parameter)
                val = g_strdup(sep+1);
        }
        
-       g_hash_table_replace(info->features, key, val);
-
        if(!g_strcasecmp(key, "CASEMAPPING")) {
                if(!g_strcasecmp(val, "rfc1459")) {
                        info->casemapping = CASEMAP_RFC1459;
@@ -56,6 +54,10 @@ void network_info_parse(struct network_info *info, const char *parameter)
                info->name = g_strdup(val);
        } else if(!g_strcasecmp(key, "NICKLEN")) {
                info->nicklen = atoi(val);
+       } else if(!g_strcasecmp(key, "USERLEN")) {
+               info->userlen = atoi(val);
+       } else if(!g_strcasecmp(key, "HOSTLEN")) {
+               info->hostlen = atoi(val);
        } else if(!g_strcasecmp(key, "CHANNELLEN")) {
                info->channellen = atoi(val);
        } else if(!g_strcasecmp(key, "AWAYLEN")) {
@@ -100,9 +102,24 @@ void network_info_parse(struct network_info *info, const char *parameter)
                info->callerid = TRUE;
        } else if(!g_strcasecmp(key, "ACCEPT")) {
                info->accept = TRUE;
+       } else if(!g_strcasecmp(key, "KEYLEN")) {
+               info->keylen = atoi(val);
+       } else if(!g_strcasecmp(key, "SILENCE")) {
+               info->silence = atoi(val);
+       } else if(!g_strcasecmp(key, "CHANTYPES")) {
+               g_free(info->chantypes);
+               info->chantypes = g_strdup(val);
+       } else if(!g_strcasecmp(key, "PREFIX")) {
+               g_free(info->prefix);
+               info->prefix = g_strdup(val);
+       } else if(!g_strcasecmp(key, "CHARSET")) {
+               g_free(info->charset);
+               info->charset = g_strdup(val);
        } else {
                log_global(LOG_WARNING, "Unknown 005 parameter `%s'", key);
        }
+       g_free(key);
+       g_free(val);
 }
 
 void handle_005(struct network_state *s, struct line *l)
@@ -118,14 +135,6 @@ void handle_005(struct network_state *s, struct line *l)
                network_info_parse(s->info, l->args[i]);
 }
 
-gboolean network_supports(const struct network_info *n, const char *fe)
-{
-       gpointer k, v;
-       g_assert(n);
-       g_assert(n->features);
-       return g_hash_table_lookup_extended (n->features, fe, &k, &v);
-}
-
 int irccmp(const struct network_info *n, const char *a, const char *b)
 {
        switch(n?n->casemapping:CASEMAP_UNKNOWN) {
@@ -149,9 +158,7 @@ gboolean is_channelname(const char *name, const struct network_info *n)
        g_assert(name);
 
        if (n != NULL) {
-               g_assert(n->features);
-       
-               chantypes = g_hash_table_lookup(n->features, "CHANTYPES");
+               chantypes = n->chantypes;
        }
 
        if(chantypes == NULL) 
@@ -169,8 +176,7 @@ gboolean is_prefix(char p, const struct network_info *n)
        const char *pref_end;
        
        if (n != NULL) {
-               g_assert(n->features);
-               prefix = g_hash_table_lookup(n->features, "PREFIX");
+               prefix = n->prefix;
        }
        
        if (prefix == NULL) 
@@ -185,10 +191,8 @@ gboolean is_prefix(char p, const struct network_info *n)
 
 const char *get_charset(const struct network_info *n)
 {
-       char *ret = g_hash_table_lookup(n->features, "CHARSET");
-
-       if (ret != NULL)
-               return ret;
+       if (n != NULL && n->charset != NULL)
+               return n->charset;
 
        return DEFAULT_CHARSET;
 }
@@ -200,9 +204,7 @@ char get_prefix_by_mode(char mode, const struct network_info *n)
        char *pref_end;
 
        if (n != NULL) {
-               g_assert(n->features);
-
-               prefix = g_hash_table_lookup(n->features, "PREFIX");
+               prefix = n->prefix;
        }
 
        if (prefix == NULL) 
index 556c1cf8a2343a88e6f8d853195f48966c1abb4a..b2da24837d63cf5a936f86b9308c46c7c5a3c8b7 100644 (file)
@@ -895,7 +895,6 @@ struct network *load_network(struct global *global, struct network_config *sc)
 
        s = g_new0(struct network, 1);
        s->config = sc;
-       s->info.features = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
        s->name = g_strdup(s->config->name);
        s->connection.pending_lines = g_queue_new();
        s->global = global;
@@ -970,8 +969,6 @@ void unload_network(struct network *s)
        g_free(s->info.server);
        g_free(s->info.name);
 
-       g_hash_table_destroy(s->info.features);
-
 #ifdef HAVE_GNUTLS
        ssl_free_client_credentials(s->ssl_credentials);
 #endif
index 43f59659fb63343536c7db6864c7909cf12c2f23..c4d7f7231a209ab2ff2d8df036cd89d939ec599a 100644 (file)
@@ -111,13 +111,29 @@ struct network_info
 {
        char *name;
        char *server;
-       GHashTable *features;
        char *supported_user_modes;
        char *supported_channel_modes;
 
        /* Case mapping used for nick- and channel name comparing */
        enum casemapping casemapping;
 
+       /* A list of channel modes a person can get and the respective 
+        * prefix a channel or nickname will get in case the person has it */
+       char *prefix;
+
+       /* The supported channel prefixes */
+       char *chantypes;
+
+       /* Server supported character set */
+       char *charset;
+
+       /* Maximum key length */
+       int keylen;
+
+       /* The server support the SILENCE command. 
+        * The number is the maximum number of allowed entries in the list. */
+       int silence;
+
        /* Maximum channel name length */
        int channellen;
 
@@ -133,6 +149,12 @@ struct network_info
        /* Maximum nickname length */
        int nicklen;
 
+       /* Maximum username length */
+       int userlen;
+
+       /* Maximum hostname length */
+       int hostlen;
+
        /* Maximum number of channels allowed to join */
        int maxchannels;
 
@@ -223,7 +245,6 @@ G_MODULE_EXPORT gboolean is_channelname(const char *name, const struct network_i
 G_MODULE_EXPORT gboolean is_prefix(char p, const struct network_info *n);
 G_MODULE_EXPORT char get_prefix_by_mode(char p, const struct network_info *n);
 G_MODULE_EXPORT int irccmp(const struct network_info *n, const char *a, const char *b);
-G_MODULE_EXPORT gboolean network_supports(const struct network_info *n, const char *fe);
 G_MODULE_EXPORT const char *get_charset(const struct network_info *n);
 G_MODULE_EXPORT void network_info_parse(struct network_info *info, const char *parameter);
 
index f28c958dab5190dd8b7b81d5551e9055d959cf3a..6752c7e5438fe4313853b95b55cac04a625eb597 100644 (file)
@@ -43,7 +43,6 @@ END_TEST
 
 START_TEST(isupport_info_parse_casemapping)
        struct network_info *info = g_new0(struct network_info, 1);
-       info->features = g_hash_table_new(NULL, NULL);
        network_info_parse(info, "CASEMAPPING=ascii");
        fail_unless (info->casemapping == CASEMAP_ASCII);
        network_info_parse(info, "CASEMAPPING=strict-rfc1459");
@@ -52,7 +51,6 @@ END_TEST
 
 START_TEST(isupport_info_parse_name)
        struct network_info *info = g_new0(struct network_info, 1);
-       info->features = g_hash_table_new(NULL, NULL);
        network_info_parse(info, "NETWORK=bla");
        fail_unless (strcmp(info->name, "bla") == 0);
 END_TEST
index 351cf512e982d84dca39249e027d4a8ddf246244..5bde5d23da0effe653d89ff5a180faf11c129c97 100644 (file)
@@ -40,48 +40,6 @@ void stack_process(struct linestack_context *ctx, struct network_state *ns, cons
        return FALSE; \
 }
 
-struct hash_data {
-       GEqualFunc fn;
-       GHashTable *hash2;
-       gboolean success;
-};
-
-static void hash_traverse_equal(void *key, void *val1, void *userdata)
-{
-       struct hash_data *hash = userdata;
-       void *val2;
-
-       val2 = g_hash_table_lookup(hash->hash2, key);
-
-       hash->success &= hash->fn(val1, val2);
-}
-
-static gboolean hash_equal(GHashTable *hash1, GHashTable *hash2, GEqualFunc eqval)
-{
-       struct hash_data userdata;
-
-       null_equal(hash1, hash2);
-       
-       /* Traverse over all keys in hash1 and make sure they exist
-        * with the same value in hash1 and hash2 */
-
-       userdata.fn = eqval;
-       userdata.hash2 = hash2;
-       userdata.success = TRUE;
-       g_hash_table_foreach(hash1, hash_traverse_equal, &userdata);
-       if (!userdata.success)
-               return FALSE;
-       
-       /* Traverse over all keys in hash2 and make sure 
-        * they exist in hash1 */
-
-       userdata.fn = eqval;
-       userdata.hash2 = hash1;
-       g_hash_table_foreach(hash2, hash_traverse_equal, &userdata);
-
-       return userdata.success;
-}
-
 static gboolean list_equal(GList *list1, GList *list2, GEqualFunc eq)
 {
        GList *gl1, *gl2;
@@ -149,12 +107,38 @@ static gboolean network_info_equal(const struct network_info *info1, const struc
 
        return str_equal(info1->name, info2->name) &&
                   str_equal(info1->server, info2->server) &&
-                  hash_equal(info1->features, info2->features, (GEqualFunc)str_equal) &&
                   str_equal(info1->supported_user_modes, info2->supported_user_modes) &&
                   str_equal(info1->supported_channel_modes, info2->supported_channel_modes) &&
-                  info1->casemapping == info2->casemapping &&
+                  str_equal(info1->prefix, info2->prefix) &&
+                  str_equal(info1->chantypes, info2->chantypes) &&
+                  str_equal(info1->charset, info2->charset) &&
+                  info1->keylen == info2->keylen &&
+                  info1->silence == info2->silence &&
                   info1->channellen == info2->channellen &&
-                  info1->topiclen == info2->topiclen;
+                  info1->awaylen == info2->awaylen &&
+                  info1->maxtargets == info2->maxtargets &&
+                  info1->nicklen == info2->nicklen &&
+                  info1->userlen == info2->userlen &&
+                  info1->hostlen == info2->hostlen &&
+                  info1->maxchannels == info2->maxchannels &&
+                  info1->topiclen == info2->topiclen &&
+                  info1->maxbans == info2->maxbans &&
+                  info1->maxmodes == info2->maxmodes &&
+                  info1->wallchops == info2->wallchops &&
+                  info1->wallvoices == info2->wallvoices &&
+                  info1->rfc2812 == info2->rfc2812 &&
+                  info1->penalty == info2->penalty &&
+                  info1->forced_nick_changes == info2->forced_nick_changes &&
+                  info1->safelist == info2->safelist &&
+                  info1->userip == info2->userip &&
+                  info1->cprivmsg == info2->cprivmsg &&
+                  info1->cnotice == info2->cnotice &&
+                  info1->knock == info2->knock &&
+                  info1->vchannels == info2->vchannels &&
+                  info1->whox == info2->whox &&
+                  info1->callerid == info2->callerid &&
+                  info1->accept == info2->accept &&
+                  info1->casemapping == info2->casemapping;
 }
 
 static gboolean network_nick_equal(const struct network_nick *nick1, const struct network_nick *nick2)
index bcefa082bc913ba2d1d08ec3c3cc865594c8b92f..d4c31cb881698940c3e141bd7af263d62d902d83 100644 (file)
 #include "internals.h"
 #include "torture.h"
 
-START_TEST(test_network_supports)
-       struct network_info info;
-       info.features = g_hash_table_new(NULL, NULL);
-       g_hash_table_insert(info.features, "foo", "bla");
-       fail_if(network_supports(&info, "foo") == false);
-       fail_if(network_supports(&info, "foobar") == true);
-END_TEST
-
 START_TEST(test_is_prefix)
        struct network_info info;
-       info.features = g_hash_table_new(NULL, NULL);
-       g_hash_table_insert(info.features, "PREFIX", "(qaohv)~&@%+");
+       memset(&info, 0, sizeof(info));
+       network_info_parse(&info, "PREFIX=(qaohv)~&@%+");
        fail_unless(is_prefix('&', &info));
        fail_if(is_prefix(' ', &info));
-       g_hash_table_replace(info.features, "PREFIX", "");
+       network_info_parse(&info, "PREFIX=");
        fail_if(is_prefix('&', &info));
 END_TEST
 
 START_TEST(test_get_prefix_by_mode)
        struct network_info info;
-       info.features = g_hash_table_new(NULL, NULL);
-       g_hash_table_insert(info.features, "PREFIX", "(qaohv)~&@%+");
+       memset(&info, 0, sizeof(info));
+       network_info_parse(&info, "PREFIX=(qaohv)~&@%+");
        fail_unless(get_prefix_by_mode('a', &info) == '&');
        fail_unless(get_prefix_by_mode('q', &info) == '~');
        fail_unless(get_prefix_by_mode('h', &info) == '%');
        fail_unless(get_prefix_by_mode('!', &info) == ' ');
-       g_hash_table_replace(info.features, "PREFIX", "(qaohv~&@%+");
+       network_info_parse(&info, "PREFIX=(qaohv~&@%+");
        fail_unless(get_prefix_by_mode('a', &info) == ' ');
 END_TEST
 
 START_TEST(test_get_charset)
        struct network_info info;
-       info.features = g_hash_table_new(NULL, NULL);
-       g_hash_table_insert(info.features, "CHARSET", "ascii");
+       memset(&info, 0, sizeof(info));
+       network_info_parse(&info, "CHARSET=ascii");
        fail_unless(!strcmp(get_charset(&info), "ascii"));
 END_TEST
 
 START_TEST(test_get_charset_default)
        struct network_info info;
-       info.features = g_hash_table_new(NULL, NULL);
+       memset(&info, 0, sizeof(info));
        fail_unless(!strcmp(get_charset(&info), "iso8859-15"));
 END_TEST
 
@@ -73,7 +65,6 @@ Suite *networkinfo_suite()
        Suite *s = suite_create("networkinfo");
        TCase *tc_core = tcase_create("core");
        suite_add_tcase(s, tc_core);
-       tcase_add_test(tc_core, test_network_supports);
        tcase_add_test(tc_core, test_is_prefix);
        tcase_add_test(tc_core, test_get_prefix_by_mode);
        tcase_add_test(tc_core, test_get_charset);