store devnull classes by their (new) id instead of their names
authorpk910 <philipp@zoelle1.de>
Mon, 15 Jul 2013 17:51:34 +0000 (19:51 +0200)
committerpk910 <philipp@zoelle1.de>
Mon, 15 Jul 2013 17:51:34 +0000 (19:51 +0200)
src/nickserv.c
src/nickserv.h
src/opserv.c
src/opserv.h

index 17f9a15c8dc3a0e9d9ffab109791919adad633af..d0caa9008f8f8825164dfbfc2bc9de1ac153aea1 100644 (file)
@@ -491,7 +491,7 @@ register_handle(const char *handle, const char *passwd, unsigned long id)
 
     hi->id = id;
     hi->website = NULL;
-    hi->devnull = NULL;
+    hi->devnull_id = 0;
     dict_insert(nickserv_id_dict, strdup(id_base64), hi);
 
     return hi;
@@ -578,7 +578,6 @@ free_handle_info(void *vhi)
     free(hi->infoline);
     free(hi->epithet);
     free(hi->fakehost);
-    free(hi->devnull);
     free(hi->website);
     free(hi->fakeident);
     if (hi->cookie) {
@@ -1510,8 +1509,10 @@ static NICKSERV_FUNC(cmd_handleinfo)
     }
 
     reply("NSMSG_HANDLEINFO_INFOLINE", (hi->infoline ? hi->infoline : nsmsg_none));
-    if ((oper_has_access(user, cmd->parent->bot, 200, 1)) || IsNetworkHelper(user))
-        reply("NSMSG_HANDLEINFO_DEVNULL", (hi->devnull ? hi->devnull : nsmsg_none));
+    if ((oper_has_access(user, cmd->parent->bot, 200, 1)) || IsNetworkHelper(user)) {
+        struct devnull_class *devnull_c = (hi->devnull_id ? devnull_find_id(hi->devnull_id) : NULL);
+        reply("NSMSG_HANDLEINFO_DEVNULL", (devnull_c ? devnull_c->name : nsmsg_none));
+    }
     if (user->handle_info && HANDLE_FLAGGED(user->handle_info, BOT))
         reply("NSMSG_HANDLEINFO_WEBSITE", (hi->website ? hi->website : nsmsg_none));
     if(hi->opserv_level > 0 && user->handle_info && HANDLE_FLAGGED(user->handle_info, BOT))
@@ -2649,52 +2650,47 @@ static OPTION_FUNC(opt_info)
 
 static OPTION_FUNC(opt_devnull)
 {
-    const char *devnull;
-    
+    const char *devnull_name;
+    int *devnull_id;
+    struct devnull_class *devnull_c;
+
     if (argc > 1) {
         if (!override) {
             send_message(user, nickserv, "MSG_SETTING_PRIVILEGED", argv[0]);
             return 0;
         }
         if ((argv[1][0] == '*') && (argv[1][1] == 0)) {
-            free(hi->devnull);
-            hi->devnull = NULL;
+            hi->devnull_id = 0;
         } else {
-            devnull = unsplit_string(argv+1, argc-1, NULL);
-            if(devnull_check_name(devnull)) { 
-                if(hi->devnull)
-                    free(hi->devnull);
-                hi->devnull = strdup(devnull);
-            }
+            devnull_name = unsplit_string(argv+1, argc-1, NULL);
+            devnull_c = devnull_find_name(devnull_name);
+            if(devnull_c)
+                hi->devnull_id = devnull_c->devnull_id;
         }
     }
 
-    devnull = hi->devnull ? hi->devnull : user_find_message(user, "MSG_NONE");
-    send_message(user, nickserv, "NSMSG_SET_DEVNULL", devnull);
-    return 1;
-}
-
-void nickserv_devnull_delete(char *name) {
-    dict_iterator_t it;
-    struct handle_info *hi;
-
-    for (it = dict_first(nickserv_handle_dict); it; it = iter_next(it)) {
-        hi = iter_data(it);
-        if (hi->devnull && !irccasecmp(name, hi->devnull)) {
-            free(hi->devnull);
-            hi->devnull = NULL;
+    if(hi->devnull_id) {
+        devnull_c = devnull_find_id(hi->devnull_id);
+        if(devnull_c)
+            devnull_name = devnull_c->name;
+        else {
+            devnull_name = user_find_message(user, "MSG_NONE");
+            hi->devnull_id = 0;
         }
-    }
+    } else
+        devnull_name = user_find_message(user, "MSG_NONE");
+    send_message(user, nickserv, "NSMSG_SET_DEVNULL", devnull_name);
+    return 1;
 }
 
-void nickserv_devnull_rename(char *oldname, char *newname) {
+void nickserv_devnull_delete(unsigned int devnull_id) {
     dict_iterator_t it;
     struct handle_info *hi;
 
     for (it = dict_first(nickserv_handle_dict); it; it = iter_next(it)) {
         hi = iter_data(it);
-        if (hi->devnull && !irccasecmp(oldname, hi->devnull)) {
-            hi->devnull = strdup(newname);
+        if (hi->devnull_id == devnull_id) {
+            hi->devnull_id = 0;
         }
     }
 }
@@ -3500,8 +3496,8 @@ nickserv_saxdb_write(struct saxdb_context *ctx) {
         saxdb_write_int(ctx, KEY_ID, hi->id);
         if (hi->infoline)
             saxdb_write_string(ctx, KEY_INFO, hi->infoline);
-        if (hi->devnull)
-            saxdb_write_string(ctx, KEY_DEVNULL, hi->devnull);
+        if (hi->devnull_id)
+            saxdb_write_int(ctx, KEY_DEVNULL, hi->devnull_id);
         if (hi->website)
             saxdb_write_string(ctx, KEY_WEBSITE, hi->website);
         if (hi->last_quit_host[0])
@@ -3730,9 +3726,10 @@ struct nickserv_discrim {
     const char *fakehostmask;
     const char *fakeidentmask;
     const char *website;
-    const char *devnullclass;
     const char *handlemask;
     const char *emailmask;
+    const char *devnull_name;
+    unsigned int devnull_id;
 };
 
 typedef void (*discrim_search_func)(struct userNode *source, struct handle_info *hi, struct nickserv_discrim *discrim);
@@ -3878,9 +3875,16 @@ nickserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[])
             }
         } else if (!irccasecmp(argv[i], "devnull")) {
             if (!irccasecmp(argv[++i], "*")) {
-                discrim->devnullclass = 0;
+                discrim->devnull_id = 0;
+                discrim->devnull_name = 0;
             } else {
-                discrim->devnullclass = argv[i];
+                struct devnull_class *th = devnull_find_name(argv[i]);
+                if(!th) {
+                    send_message(user, nickserv, "OSMSG_DEVNULL_NOTFOUND", argv[i]);
+                    goto fail;
+                }
+                discrim->devnull_name = argv[i];
+                discrim->devnull_id = th->id;
             }
         } else if (!irccasecmp(argv[i], "handlemask") || !irccasecmp(argv[i], "accountmask")) {
             if (!irccasecmp(argv[++i], "*")) {
@@ -3959,7 +3963,7 @@ nickserv_discrim_match(struct nickserv_discrim *discrim, struct handle_info *hi)
         || (discrim->fakehostmask && (!hi->fakehost || !match_ircglob(hi->fakehost, discrim->fakehostmask)))
         || (discrim->fakeidentmask && (!hi->fakeident || !match_ircglob(hi->fakeident, discrim->fakeidentmask)))
         || (discrim->website && (!hi->website || !match_ircglob(hi->website, discrim->website)))
-        || (discrim->devnullclass && (!hi->devnull || !match_ircglob(hi->devnull, discrim->devnullclass)))
+        || (discrim->devnull_id && discrim->devnull_id != hi->devnull_id)
         || (discrim->emailmask && (!hi->email_addr || !match_ircglob(hi->email_addr, discrim->emailmask)))
         || (discrim->min_level > hi->opserv_level)
         || (discrim->max_level < hi->opserv_level)
@@ -4043,9 +4047,14 @@ search_print_func(struct userNode *source, struct handle_info *match, struct nic
                 discrim->output_table->contents[discrim->output_table_pos][i++] = (match->fakehost ? match->fakehost : "*");
             if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_WEBSITE)
                 discrim->output_table->contents[discrim->output_table_pos][i++] = (match->website ? match->website : "*");
-            if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_DEVNULL)
-                discrim->output_table->contents[discrim->output_table_pos][i++] = (match->devnull ? match->devnull : "*");
-            
+            if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_DEVNULL) {
+                if(discrim->devnull_name) 
+                    discrim->output_table->contents[discrim->output_table_pos][i++] = discrim->devnull_name;
+                else {
+                    struct devnull_class *devnull = devnull_find_id(match->devnull_id);
+                    discrim->output_table->contents[discrim->output_table_pos][i++] = (devnull ? devnull->name : "*");
+                }
+            }
         }
     } else
         send_message(source, nickserv, "NSMSG_SEARCH_MATCH", match->handle);
@@ -4330,8 +4339,7 @@ nickserv_db_read_handle(const char *handle, dict_t obj)
     if (str)
         hi->website = strdup(str);
     str = database_get_data(obj, KEY_DEVNULL, RECDB_QSTRING);
-    if (str)
-        hi->devnull = strdup(str);
+    hi->devnull_id = str ? strtoul(str, NULL, 0) : 0;
     str = database_get_data(obj, KEY_REGISTER_ON, RECDB_QSTRING);
     hi->registered = str ? strtoul(str, NULL, 0) : now;
     str = database_get_data(obj, KEY_LAST_SEEN, RECDB_QSTRING);
index 322170e2825422abdfb1b805b17a7df2a0548c67..a37195fe2e27d40b5fdeba55bc2ca6de74ce62bc 100644 (file)
@@ -109,13 +109,13 @@ struct handle_info {
     struct language *language;
     struct authlogEntry *authlog;
     char *website;
-    char *devnull;
     char *email_addr;
     char *epithet;
     char *infoline;
     char *handle;
     char *fakehost;
     char *fakeident;
+    unsigned int devnull_id;
     unsigned long id;
     unsigned long registered;
     unsigned long lastseen;
@@ -158,8 +158,7 @@ int staff_has_access(struct userNode *user, struct userNode *bot, unsigned int m
 void nickserv_show_oper_accounts(struct userNode *user, struct svccmd *cmd);
 struct handle_info *checklogin(const char *user, const char *pass, const char *numeric, const char *hostmask, const char *ipmask);
 char *getfakehost(const char *user);
-void nickserv_devnull_delete(char *name);
-void nickserv_devnull_rename(char *oldname, char *newname);
+void nickserv_devnull_delete(unsigned int devnull_id);
 char *generate_fakehost(struct handle_info *handle);
 char *generate_fakeident(struct handle_info *handle, struct userNode *user);
 void apply_fakehost(struct handle_info *handle, struct userNode *user);
index 92abb8dc0a4af58f542720ba8af1c63763e5875f..c4844b7604a67c8b53cd0767445bb72a1d3db4c2 100644 (file)
@@ -79,6 +79,8 @@
 #define KEY_ISSUER "issuer"
 #define KEY_ISSUED "issued"
 #define KEY_DEVNULL_CLASSES "classes"
+#define KEY_DEVNULL_LASTID "lastid"
+#define KEY_DEVNULL_ID "id"
 #define KEY_DEVNULL_NAME "class"
 #define KEY_DEVNULL_MODE "modes"
 #define KEY_DEVNULL_MAXCHAN "chanlimit"
@@ -329,6 +331,7 @@ static unsigned int new_user_flood;
 const char *devnull_modes = DEVNULL_MODES;
 static char *level_strings[1001];
 static char devnull_inverse_modes[256];
+unsigned int devnull_last_id = 1;
 
 void *devnull_check_priv_func = NULL;
 
@@ -2816,12 +2819,16 @@ trusted_host_read(const char *host, void *data, UNUSED_ARG(void *extra))
 }
 
 static void
-opserv_add_devnull_class(const char *name, unsigned long modes, unsigned long maxchan, unsigned long maxsendq)
+opserv_add_devnull_class(const char *name, unsigned int id, unsigned long modes, unsigned long maxchan, unsigned long maxsendq)
 {
     struct devnull_class *th;
     th = calloc(1, sizeof(*th));
     if (!th)
         return;
+    if(id)
+        th->id = id;
+    else
+        th->id = (++devnull_last_id);
     th->name = strdup(name);
     th->modes = modes;
     th->maxchan = maxchan;
@@ -2843,12 +2850,16 @@ devnull_class_read(const char *name, void *data, UNUSED_ARG(void *extra))
     struct record_data *rd = data;
     const char *nameb = name, *str;
     unsigned long modes, maxchan, maxsendq;
-    unsigned int ii;
+    unsigned int id, ii;
 
     if (rd->type == RECDB_OBJECT) {
         dict_t obj = GET_RECORD_OBJECT(rd);
         /* new style structure */
-        nameb = database_get_data(obj, KEY_DEVNULL_NAME, RECDB_QSTRING);
+        str = database_get_data(obj, KEY_DEVNULL_ID, RECDB_QSTRING);
+        if(str)
+            id = atoi(str);
+        else
+            id = 0;
         str = database_get_data(obj, KEY_DEVNULL_MODE, RECDB_QSTRING);
         modes = 0;
         if (str) {
@@ -2862,7 +2873,7 @@ devnull_class_read(const char *name, void *data, UNUSED_ARG(void *extra))
     } else
         return 0;
 
-    opserv_add_devnull_class(nameb, modes, maxchan, maxsendq);
+    opserv_add_devnull_class(name, id, modes, maxchan, maxsendq);
     return 0;
 }
 
@@ -2873,6 +2884,7 @@ opserv_saxdb_read(struct dict *conf_db)
     struct record_data *rd;
     dict_iterator_t it;
     unsigned int nn;
+    char *str;
 
     if ((object = database_get_data(conf_db, KEY_RESERVES, RECDB_OBJECT)))
         dict_foreach(object, add_reserved, opserv_reserved_nick_dict);
@@ -2902,12 +2914,13 @@ opserv_saxdb_read(struct dict *conf_db)
             dict_insert(opserv_exempt_channels, strdup(rd->d.slist->list[nn]), NULL);
     }
     if ((object = database_get_data(conf_db, KEY_MAX_CLIENTS, RECDB_OBJECT))) {
-        char *str;
         if ((str = database_get_data(object, KEY_MAX, RECDB_QSTRING)))
             max_clients = atoi(str);
         if ((str = database_get_data(object, KEY_TIME, RECDB_QSTRING)))
             max_clients_time = atoi(str);
     }
+    if ((str = database_get_data(object, KEY_DEVNULL_LASTID, RECDB_QSTRING)))
+        devnull_last_id = atoi(str);
     if ((object = database_get_data(conf_db, KEY_TRUSTED_HOSTS, RECDB_OBJECT)))
         dict_foreach(object, trusted_host_read, opserv_trusted_hosts);
     if ((object = database_get_data(conf_db, KEY_DEVNULL_CLASSES, RECDB_OBJECT)))
@@ -2974,8 +2987,8 @@ opserv_saxdb_write(struct saxdb_context *ctx)
         saxdb_start_record(ctx, KEY_DEVNULL_CLASSES, 1);
         for (it = dict_first(opserv_devnull_classes); it; it = iter_next(it)) {
             struct devnull_class *th = iter_data(it);
-            saxdb_start_record(ctx, iter_key(it), 0);
-            if (th->name) saxdb_write_string(ctx, KEY_DEVNULL_NAME, th->name);
+            saxdb_start_record(ctx, th->name, 0);
+            saxdb_write_int(ctx, KEY_DEVNULL_ID, th->id);
             if (th->modes) {
                 int ii, flen;
                 char flags[50];
@@ -2991,6 +3004,7 @@ opserv_saxdb_write(struct saxdb_context *ctx)
         }
         saxdb_end_record(ctx);
     }
+    saxdb_write_int(ctx, KEY_DEVNULL_LASTID, devnull_last_id);
     /* gags */
     if (gagList) {
         struct gag_entry *gag;
@@ -4430,7 +4444,7 @@ static MODCMD_FUNC(cmd_adddevnull)
         return 0;
     }
     
-    opserv_add_devnull_class(argv[1], 0, 0, 0);
+    opserv_add_devnull_class(argv[1], (++devnull_last_id), 0, 0, 0);
     reply("OSMSG_DEVNULL_ADDED",argv[1]);
     return 1;
 }
@@ -4444,7 +4458,7 @@ static MODCMD_FUNC(cmd_deldevnull)
         struct devnull_class *th = dict_find(opserv_devnull_classes, argv[n], NULL);
         if (!th)
             continue;
-        nickserv_devnull_delete(th->name);
+        nickserv_devnull_delete(th->id);
         dict_remove(opserv_devnull_classes, argv[n]);
         reply("OSMSG_DEVNULL_REMOVED",argv[n]);
     }
@@ -4459,8 +4473,7 @@ static MODCMD_FUNC(cmd_renamedevnull)
         return 0;
     }
     if ((th = dict_find(opserv_devnull_classes, argv[1], NULL))) {
-        opserv_add_devnull_class(argv[2], th->modes, th->maxchan, th->maxsendq);
-        nickserv_devnull_rename(th->name,argv[2]);
+        opserv_add_devnull_class(argv[2], th->id, th->modes, th->maxchan, th->maxsendq);
         dict_remove(opserv_devnull_classes, argv[1]);
         reply("OSMSG_DEVNULL_RENAMED",argv[1],argv[2]);
     } else {
@@ -4712,11 +4725,22 @@ static MODCMD_FUNC(cmd_setdevnull)
     return 1;
 }
 
-int devnull_check_name(const char *name) { 
-    if (dict_find(opserv_devnull_classes, name, NULL)) {
-        return 1;
+struct devnull_class *devnull_find_id(unsigned int id) {
+    dict_iterator_t it;
+    for (it = dict_first(opserv_devnull_classes); it; it = iter_next(it)) {
+        struct devnull_class *th = iter_data(it);
+        if(th->id == id)
+            return th;
     }
-    return 0;
+    return NULL;
+}
+
+struct devnull_class *devnull_find_name(const char *name) {
+    struct devnull_class *th;
+    if ((th = dict_find(opserv_devnull_classes, name, NULL))) {
+        return th;
+    }
+    return NULL;
 }
 
 int devnull_user_has_priv(struct handle_info *hi, int devnull_priv) {
index 0ff315e0f3b40c67cf04296adfc78a83c0a277f1..01209bc9d14099058f8d51bd7e09bdc0e7514835 100644 (file)
@@ -45,6 +45,7 @@
 #define DEVNULL_CLEAR_PRIV(cl, tok) ((cl)->modes &= ~DEVNULL_##tok)
 
 struct devnull_class {
+    unsigned int id;
     char *name;
     unsigned long modes;
     unsigned long maxchan;
@@ -56,9 +57,10 @@ extern void *devnull_check_priv_func;
 void init_opserv(const char *nick);
 unsigned int gag_create(const char *mask, const char *owner, const char *reason, unsigned long expires);
 int opserv_bad_channel(const char *name);
-int devnull_check_name(const char *name);
 int devnull_user_has_priv(struct handle_info *hi, int devnull_priv);
 struct devnull_class devnull_user_get_class(struct handle_info *hi);
+struct devnull_class *devnull_find_id(unsigned int id);
+struct devnull_class *devnull_find_name(char *name);
 struct userNode* GetOpServ(void);
 void operpart(struct chanNode *chan, struct userNode *user);
 void operadd(struct userNode *user);