/** * list.C: This file contains code for the NickServ LIST function. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Copyright © 2005-2007 Robin Burchell, et al. * Rights to this code are as documented in doc/pod/license.pod. * * $Id: list.C,v 1.8 2007/09/22 14:27:28 pippijn Exp $ */ #include #include "atheme.h" #include #include #include static char const rcsid[] = "$Id: list.C,v 1.8 2007/09/22 14:27:28 pippijn Exp $"; REGISTER_MODULE ("nickserv/list", false, "The Ermyth Team "); static void ns_cmd_list (sourceinfo_t *si, int parc, char *parv[]); command_t const ns_list = { "LIST", N_("Lists nicknames registered matching a given pattern."), PRIV_USER_AUSPEX, 1, ns_cmd_list }; E cmdvec ns_cmdtree; E helpvec ns_helptree; bool _modinit (module *m) { ns_cmdtree << ns_list; help_addentry (ns_helptree, "LIST", "help/nickserv/list", NULL); return true; } void _moddeinit () { ns_cmdtree >> ns_list; help_delentry (ns_helptree, "LIST"); } static void list_one (sourceinfo_t *si, myuser_t *mu, mynick_t *mn) { char buf[BUFSIZE]; if (mn != NULL) mu = mn->owner; *buf = '\0'; if (mu->find_metadata ("private:freeze:freezer")) { if (*buf) strlcat (buf, " ", BUFSIZE); strlcat (buf, "\2[frozen]\2", BUFSIZE); } if (mu->find_metadata ("private:mark:setter")) { if (*buf) strlcat (buf, " ", BUFSIZE); strlcat (buf, "\2[marked]\2", BUFSIZE); } if (mu->flags & MU_HOLD) { if (*buf) strlcat (buf, " ", BUFSIZE); strlcat (buf, "\2[held]\2", BUFSIZE); } if (mu->flags & MU_WAITAUTH) { if (*buf) strlcat (buf, " ", BUFSIZE); strlcat (buf, "\2[unverified]\2", BUFSIZE); } if (mn == NULL || !irccasecmp (mn->nick, mu->name)) command_success_nodata (si, "- %s (%s) %s", mu->name, mu->email, buf); else command_success_nodata (si, "- %s (%s) (%s) %s", mn->nick, mu->email, mu->name, buf); } static void ns_cmd_list (sourceinfo_t *si, int parc, char *parv[]) { char pat[512], *nickpattern = NULL, *hostpattern = NULL, *p; bool hostmatch; myuser_t *mu; mynick_t *mn; metadata *md; int matches = 0; if (parc < 1) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "LIST"); command_fail (si, fault::needmoreparams, _("Syntax: LIST [!]")); return; } strlcpy (pat, parv[0], sizeof pat); p = strrchr (pat, ' '); if (p == NULL) p = strrchr (pat, '!'); if (p != NULL) { *p++ = '\0'; nickpattern = pat; hostpattern = p; } else if (strchr (pat, '@')) hostpattern = pat; else nickpattern = pat; if (nickpattern && !strcmp (nickpattern, "*")) nickpattern = NULL; if (nicksvs.no_nick_ownership) { myuser_t::map_type::iterator it = myuser_t::map.begin (); myuser_t::map_type::iterator et = myuser_t::map.end (); snoop ("LIST:ACCOUNTS: \2%s\2 by \2%s\2", parv[0], get_oper_name (si)); while (it != et) { mu = it->second; if (nickpattern && match (nickpattern, mu->name)) continue; if (hostpattern) { hostmatch = false; md = mu->find_metadata ("private:host:actual"); if (md != NULL && !match (hostpattern, md->value)) hostmatch = true; md = mu->find_metadata ("private:host:vhost"); if (md != NULL && !match (hostpattern, md->value)) hostmatch = true; if (!hostmatch) continue; } list_one (si, mu, NULL); matches++; ++it; } } else { snoop ("LIST:NICKS: \2%s\2 by \2%s\2", parv[0], get_oper_name (si)); foreach (mynick_t::pair_type &mnp, mynick_t::map) { mn = mnp.second; if (nickpattern && match (nickpattern, mn->nick)) continue; mu = mn->owner; if (hostpattern) { hostmatch = false; md = mu->find_metadata ("private:host:actual"); if (md != NULL && !match (hostpattern, md->value)) hostmatch = true; md = mu->find_metadata ("private:host:vhost"); if (md != NULL && !match (hostpattern, md->value)) hostmatch = true; if (!hostmatch) continue; } list_one (si, NULL, mn); matches++; } } logcommand (si, CMDLOG_ADMIN, "LIST %s (%d matches)", parv[0], matches); if (matches == 0) command_success_nodata (si, _("No nicknames matched pattern \2%s\2"), parv[0]); else command_success_nodata (si, ngettext (N_("\2%d\2 match for pattern \2%s\2"), N_("\2%d\2 matches for pattern \2%s\2"), matches), matches, parv[0]); }