}
static int
-is_valid_email_addr(const char *email)
+is_valid_email_addr(const char *org_email)
{
- return strchr(email, '@') != NULL;
+ char email[strlen(org_email)+1];
+ strcpy(email, org_email);
+ //validate email address
+ //1st check: there need to be one @
+ char *p1 = strchr(email, '@');
+ if(!p1 || strchr(p1+1, '@')) return 0;
+ *p1 = '\0';
+ //2nd check: username (bevore @) must be at least 1 char long and out of part_chars
+ char *part_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._%+-";
+ int i;
+ if(p1 - email == 0) return 0;
+ for(i = 0; i < (p1 - email); i++) {
+ if(!strchr(part_chars, email[i])) return 0;
+ }
+ //3rd check: there need to be at least 1 dot in the domain part and all characters out of part_chars
+ part_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
+ char *p2 = NULL;
+ p1++;
+ i = 0;
+ while(*p1) {
+ if(*p1 == '.') {
+ if(!i) return 0;
+ i = 0;
+ p2 = p1;
+ } else if(!strchr(part_chars, *p1))
+ return 0;
+ else
+ i++;
+ p1++;
+ }
+ if(!p2) return 0;
+ //4th check: TLD must be <= 5 chars, no special chars
+ i = 0;
+ p2++;
+ while(*p2) {
+ if(!isalpha(*p2))
+ return 0;
+ else
+ i++;
+ p2++;
+ }
+ if(i > 5) return 0;
+ return 1;
}
static const char *
}
reply("NSMSG_HANDLEINFO_INFOLINE", (hi->infoline ? hi->infoline : nsmsg_none));
- if (oper_has_access(user, cmd->parent->bot, 200, 1))
+ if ((oper_has_access(user, cmd->parent->bot, 200, 1)) || IsNetworkHelper(user))
reply("NSMSG_HANDLEINFO_DEVNULL", (hi->devnull ? hi->devnull : nsmsg_none));
if (user->handle_info && HANDLE_FLAGGED(user->handle_info, BOT))
reply("NSMSG_HANDLEINFO_WEBSITE", (hi->website ? hi->website : nsmsg_none));
struct handle_info *checklogin(const char *user, const char *pass, const char *numeric, const char *hostmask, const char *ipmask)
{
struct handle_info *hi;
- int match = 0, ii = 0;
+ unsigned int match = 0, ii = 0;
hi = dict_find(nickserv_handle_dict, user, NULL);
if(!hi)
return NULL;
} else {
devnull = unsplit_string(argv+1, argc-1, NULL);
if(devnull_check(devnull) == 1) {
+ if(hi->devnull)
+ free(hi->devnull);
hi->devnull = strdup(devnull);
}
}
static NICKSERV_FUNC(cmd_reclaim)
{
- struct handle_info *hi;
struct nick_info *ni;
struct userNode *victim;
NICKSERV_MIN_PARMS(2);
- hi = user->handle_info;
ni = dict_find(nickserv_nick_dict, argv[1], 0);
if (!ni) {
reply("NSMSG_UNKNOWN_NICK", argv[1]);
return 1;
}
+#define NICKSERV_DISCRIM_FIELDS_AUTH 0x01
+#define NICKSERV_DISCRIM_FIELDS_EMAIL 0x02
+#define NICKSERV_DISCRIM_FIELDS_SEEN 0x04
+#define NICKSERV_DISCRIM_FIELDS_ACCESS 0x08
+#define NICKSERV_DISCRIM_FIELDS_FAKEHOST 0x10
+#define NICKSERV_DISCRIM_FIELDS_WEBSITE 0x20
+#define NICKSERV_DISCRIM_FIELDS_DEVNULL 0x40
+
+#define NICKSERV_DISCRIM_FIELD_COUNT 7
+
struct nickserv_discrim {
+ unsigned int show_fields;
+ struct helpfile_table *output_table;
+ int output_table_pos;
+ unsigned int output_table_free_fields;
+
unsigned long flags_on, flags_off;
unsigned long min_registered, max_registered;
unsigned long lastseen;
const char *emailmask;
};
-typedef void (*discrim_search_func)(struct userNode *source, struct handle_info *hi);
+typedef void (*discrim_search_func)(struct userNode *source, struct handle_info *hi, struct nickserv_discrim *discrim);
struct discrim_apply_info {
struct nickserv_discrim *discrim;
discrim->limit = strtoul(argv[++i], NULL, 0);
} else if (!irccasecmp(argv[i], "flags")) {
nickserv_modify_handle_flags(user, nickserv, argv[++i], &discrim->flags_on, &discrim->flags_off);
+ } else if (!irccasecmp(argv[i], "fields")) {
+ char *fields = argv[++i];
+ char *delimiter = strstr(fields, ",");
+ while(1) {
+ if(delimiter)
+ *delimiter = '\0';
+ if(!irccasecmp(fields, "auth"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_AUTH;
+ else if(!irccasecmp(fields, "email"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_EMAIL;
+ else if(!irccasecmp(fields, "seen"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_SEEN;
+ else if(!irccasecmp(fields, "access"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_ACCESS;
+ else if(!irccasecmp(fields, "fakehost"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_FAKEHOST;
+ else if(!irccasecmp(fields, "website") && IsBot(user))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_WEBSITE;
+ else if(!irccasecmp(fields, "devnull"))
+ discrim->show_fields |= NICKSERV_DISCRIM_FIELDS_DEVNULL;
+ else {
+ send_message(user, nickserv, "MSG_INVALID_FIELD", fields);
+ goto fail;
+ }
+ if(delimiter) {
+ *delimiter = ',';
+ fields = delimiter+1;
+ if(*fields) {
+ delimiter = strstr(fields, ",");
+ continue;
+ }
+ }
+ break;
+ }
} else if (!irccasecmp(argv[i], "registered")) {
const char *cmp = argv[++i];
if (cmp[0] == '<') {
it = next) {
next = iter_next(it);
if (nickserv_discrim_match(discrim, iter_data(it))) {
- dsf(source, iter_data(it));
+ dsf(source, iter_data(it), discrim);
matched++;
}
}
}
static void
-search_print_func(struct userNode *source, struct handle_info *match)
+search_print_func(struct userNode *source, struct handle_info *match, struct nickserv_discrim *discrim)
{
- send_message(source, nickserv, "NSMSG_SEARCH_MATCH", match->handle);
+ if(discrim->show_fields) {
+ //custom fields
+ if(discrim->output_table) {
+ discrim->output_table->contents[++discrim->output_table_pos] = malloc(discrim->output_table->width * sizeof(discrim->output_table->contents[0][0]));
+ int i = 0;
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_AUTH)
+ discrim->output_table->contents[discrim->output_table_pos][i++] = match->handle;
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_EMAIL)
+ discrim->output_table->contents[discrim->output_table_pos][i++] = (match->email_addr ? match->email_addr : "*");
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_SEEN) {
+ char *seen;
+ char seenBuf[INTERVALLEN];
+ if(match->users) {
+ seen = "Here";
+ } else if(match->lastseen == 0) {
+ seen = "Never";
+ } else {
+ seen = intervalString(seenBuf, now - match->lastseen, source->handle_info);
+ }
+ discrim->output_table_free_fields |= 1 << i;
+ discrim->output_table->contents[discrim->output_table_pos][i++] = strdup(seen);
+ }
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_ACCESS)
+ discrim->output_table->contents[discrim->output_table_pos][i++] = strtab(match->opserv_level);
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_FAKEHOST)
+ 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 : "*");
+
+ }
+ } else
+ send_message(source, nickserv, "NSMSG_SEARCH_MATCH", match->handle);
}
static void
-search_count_func(UNUSED_ARG(struct userNode *source), UNUSED_ARG(struct handle_info *match))
+search_count_func(UNUSED_ARG(struct userNode *source), UNUSED_ARG(struct handle_info *match), UNUSED_ARG(struct nickserv_discrim *discrim))
{
}
static void
-search_unregister_func (struct userNode *source, struct handle_info *match)
+search_unregister_func (struct userNode *source, struct handle_info *match, UNUSED_ARG(struct nickserv_discrim *discrim))
{
if (oper_has_access(source, nickserv, match->opserv_level, 0))
nickserv_unregister_handle(match, source);
discrim->limit = INT_MAX;
matches = nickserv_discrim_search(discrim, action, user);
-
+
+ if(discrim->show_fields) {
+ int width = 0;
+ int ii;
+ for(ii = 0; ii < NICKSERV_DISCRIM_FIELD_COUNT; ii++) {
+ if(discrim->show_fields & (1 << ii)) width++;
+ }
+ discrim->output_table = malloc(sizeof(discrim->output_table[0]));
+ discrim->output_table->length = matches+1;
+ discrim->output_table->width = width;
+ discrim->output_table->flags = TABLE_NO_FREE;
+ discrim->output_table->contents = malloc(discrim->output_table->length * sizeof(discrim->output_table->contents[0]));
+ discrim->output_table->contents[0] = malloc(discrim->output_table->width * sizeof(discrim->output_table->contents[0][0]));
+
+ ii = 0;
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_AUTH)
+ discrim->output_table->contents[0][ii++] = "Auth";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_EMAIL)
+ discrim->output_table->contents[0][ii++] = "EMail";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_SEEN)
+ discrim->output_table->contents[0][ii++] = "Seen";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_ACCESS)
+ discrim->output_table->contents[0][ii++] = "Access";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_FAKEHOST)
+ discrim->output_table->contents[0][ii++] = "Fakehost";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_WEBSITE)
+ discrim->output_table->contents[0][ii++] = "Website";
+ if(discrim->show_fields & NICKSERV_DISCRIM_FIELDS_DEVNULL)
+ discrim->output_table->contents[0][ii++] = "DevNull";
+
+ nickserv_discrim_search(discrim, action, user);
+
+ table_send(nickserv, user->nick, 0, NULL, *discrim->output_table);
+
+ for(ii = 1; ii < discrim->output_table->length; ++ii) {
+ int ij;
+ for(ij = 0; ij < NICKSERV_DISCRIM_FIELD_COUNT; ij++) {
+ if(discrim->output_table_free_fields & (1 << ij))
+ free((char*)discrim->output_table->contents[ii][ij]);
+ }
+ free(discrim->output_table->contents[ii]);
+ }
+ free(discrim->output_table->contents[0]);
+ free(discrim->output_table->contents);
+ free(discrim->output_table);
+ }
if (matches)
reply("MSG_MATCH_COUNT", matches);
else
reply("MSG_NO_MATCHES");
+
free(discrim);
return 0;
}