From 992bf78ff2a935baa18354a40ab50ef442b4733f Mon Sep 17 00:00:00 2001 From: pk910 Date: Mon, 15 Jul 2013 19:51:34 +0200 Subject: [PATCH] store devnull classes by their (new) id instead of their names --- src/nickserv.c | 94 +++++++++++++++++++++++++++----------------------- src/nickserv.h | 5 ++- src/opserv.c | 54 +++++++++++++++++++++-------- src/opserv.h | 4 ++- 4 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/nickserv.c b/src/nickserv.c index 17f9a15..d0caa90 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -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); diff --git a/src/nickserv.h b/src/nickserv.h index 322170e..a37195f 100644 --- a/src/nickserv.h +++ b/src/nickserv.h @@ -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); diff --git a/src/opserv.c b/src/opserv.c index 92abb8d..c4844b7 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -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) { diff --git a/src/opserv.h b/src/opserv.h index 0ff315e..01209bc 100644 --- a/src/opserv.h +++ b/src/opserv.h @@ -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); -- 2.20.1