store devnull classes by their (new) id instead of their names
[srvx.git] / src / nickserv.c
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);