/*! \brief UNLOAD subcommand handler * Attempts to unload a module, throwing an error if * the module could not be found * \param source_p Pointer to client issuing the command * \param arg Additional argument which might be needed by this handler */ static void module_unload(struct Client *source_p, const char *arg) { const char *m_bn = NULL; const struct module *modp = NULL; if ((modp = findmodule_byname((m_bn = libio_basename(arg)))) == NULL) { sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn); return; } if (modp->flags & MODULE_FLAG_CORE) { sendto_one_notice(source_p, &me, ":Module %s is a core module and may not be unloaded", m_bn); return; } if (modp->flags & MODULE_FLAG_NOUNLOAD) { sendto_one_notice(source_p, &me, ":Module %s is a resident module and may not be unloaded", m_bn); return; } if (unload_one_module(m_bn, 1) == -1) sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn); }
/* mo_mkpasswd - mkpasswd message handler * parv[1] = password * parv[2] = type */ static int mo_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { char *salt; const char *hashtype; const char hashdefault[] = "SHA512"; if(EmptyString(parv[1])) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD"); return 0; } if(parc < 3) hashtype = hashdefault; else hashtype = parv[2]; if(!irccmp(hashtype, "SHA256")) salt = make_sha256_salt(16); else if(!irccmp(hashtype, "SHA512")) salt = make_sha512_salt(16); else if(!irccmp(hashtype, "MD5")) salt = make_md5_salt(8); else { sendto_one_notice(source_p, ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]"); return 0; } sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], rb_crypt(parv[1], salt)); return 0; }
/* m_mkpasswd - mkpasswd message handler * parv[1] = password * parv[2] = type */ static int m_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static time_t last_used = 0; char *salt; const char *hashtype; const char hashdefault[] = "SHA512"; if (EmptyString(parv[1])) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD"); return 0; } if (parc < 3) hashtype = hashdefault; else hashtype = parv[2]; if ((last_used + ConfigFileEntry.pace_wait) > rb_current_time()) { /* safe enough to give this on a local connect only */ sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "MKPASSWD"); return 0; } else last_used = rb_current_time(); if (!irccmp(hashtype, "SHA256")) salt = make_sha256_salt(16); else if (!irccmp(hashtype, "SHA512")) salt = make_sha512_salt(16); else if (!irccmp(hashtype, "MD5")) salt = make_md5_salt(8); else { sendto_one_notice(source_p, ":MKPASSWD syntax error: MKPASSWD pass [SHA256|SHA512|MD5]"); return 0; } sendto_one_notice(source_p, ":Hash [%s] for %s: %s", hashtype, parv[1], rb_crypt(parv[1], salt)); return 0; }
/* * list_quote_commands() sends the client all the available commands. * Four to a line for now. */ static void list_quote_commands(struct Client *source_p) { unsigned int j = 0; const char *names[4] = { "", "", "", "" }; sendto_one_notice(source_p, &me, ":Available QUOTE SET commands:"); for (const struct SetStruct *tab = set_cmd_table; tab->handler; ++tab) { names[j++] = tab->name; if (j > 3) { sendto_one_notice(source_p, &me, ":%s %s %s %s", names[0], names[1], names[2], names[3]); j = 0; names[0] = names[1] = names[2] = names[3] = ""; } } if (j) sendto_one_notice(source_p, &me, ":%s %s %s %s", names[0], names[1], names[2], names[3]); }
/* SET MAX */ static void quote_max(struct Client *source_p, const char *arg, int newval) { if (newval > 0) { if (newval > MAXCLIENTS_MAX) { sendto_one_notice(source_p, &me, ":You cannot set MAXCLIENTS to > %d, restoring to %d", MAXCLIENTS_MAX, ConfigServerInfo.max_clients); return; } if (newval < MAXCLIENTS_MIN) { sendto_one_notice(source_p, &me, ":You cannot set MAXCLIENTS to < %d, restoring to %d", MAXCLIENTS_MIN, ConfigServerInfo.max_clients); return; } ConfigServerInfo.max_clients = newval; sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s set new MAXCLIENTS to %d (%d current)", get_oper_name(source_p), ConfigServerInfo.max_clients, Count.local); } else sendto_one_notice(source_p, &me, ":Current MAXCLIENTS = %d (%d)", ConfigServerInfo.max_clients, Count.local); }
/* SET AUTOCONN */ static void quote_autoconn(struct Client *source_p, const char *arg, int newval) { if (!EmptyString(arg)) { struct MaskItem *conf = find_exact_name_conf(CONF_SERVER, NULL, arg, NULL, NULL); if (conf) { if (newval) SetConfAllowAutoConn(conf); else ClearConfAllowAutoConn(conf); sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s has changed AUTOCONN for %s to %i", get_oper_name(source_p), arg, newval); sendto_one_notice(source_p, &me, ":AUTOCONN for %s is now set to %i", arg, newval); } else sendto_one_notice(source_p, &me, ":Cannot find %s", arg); } else sendto_one_notice(source_p, &me, ":Please specify a server name!"); }
/*! \brief RESTART command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = server name */ static int mo_restart(struct Client *source_p, int parc, char *parv[]) { char buf[IRCD_BUFSIZE] = ""; const char *const name = parv[1]; if (!HasOFlag(source_p, OPER_FLAG_RESTART)) { sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "restart"); return 0; } if (EmptyString(name)) { sendto_one_notice(source_p, &me, ":Need server name /restart %s", me.name); return 0; } if (irccmp(name, me.name)) { sendto_one_notice(source_p, &me, ":Mismatch on /restart %s", me.name); return 0; } snprintf(buf, sizeof(buf), "received RESTART command from %s", get_client_name(source_p, HIDE_IP)); server_die(buf, 1); return 0; }
/* static int remove_tkline_match(const char *host, const char *user) * * Inputs: gecos * Output: returns YES on success, NO if no tkline removed. * Side effects: Any matching tklines are removed. */ static void xline_remove(struct Client *source_p, const struct aline_ctx *aline) { struct GecosItem *gecos; if ((gecos = gecos_find(aline->mask, irccmp)) == NULL) { if (IsClient(source_p)) sendto_one_notice(source_p, &me, ":No X-Line for %s", aline->mask); return; } if (gecos->in_database == false) { if (IsClient(source_p)) sendto_one_notice(source_p, &me, ":The X-Line for %s is in the configuration file and must be removed by hand", gecos->mask); return; } if (IsClient(source_p)) sendto_one_notice(source_p, &me, ":X-Line for [%s] is removed", gecos->mask); sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "%s has removed the X-Line for: [%s]", get_oper_name(source_p), gecos->mask); ilog(LOG_TYPE_RESV, "%s removed X-Line for [%s]", get_oper_name(source_p), gecos->mask); gecos_delete(gecos, false); }
static void do_modreload(struct Client *source_p, const char *module) { int modindex; int check_core; char *m_bn = rb_basename(module); if((modindex = findmodule_byname(m_bn)) == -1) { sendto_one_notice(source_p, ":Module %s is not loaded", m_bn); rb_free(m_bn); return; } check_core = modlist[modindex]->core; if(unload_one_module(m_bn, true) == false) { sendto_one_notice(source_p, ":Module %s is not loaded", m_bn); rb_free(m_bn); return; } if((load_one_module(m_bn, modlist[modindex]->origin, check_core) == false) && check_core) { sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Error reloading core module: %s: terminating ircd", m_bn); ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn); exit(0); } rb_free(m_bn); }
static int do_chghost(struct Client *source_p, struct Client *target_p, const char *newhost, int is_encap) { if (!clean_host(newhost)) { sendto_realops_snomask(SNO_GENERAL, is_encap ? L_ALL : L_NETWIDE, "%s attempted to change hostname for %s to %s (invalid)", IsServer(source_p) ? source_p->name : get_oper_name(source_p), target_p->name, newhost); /* sending this remotely may disclose important * routing information -- jilles */ if (is_encap ? MyClient(target_p) : !ConfigServerHide.flatten_links) sendto_one_notice(target_p, ":*** Notice -- %s attempted to change your hostname to %s (invalid)", source_p->name, newhost); return 0; } change_nick_user_host(target_p, target_p->name, target_p->username, newhost, 0, "Changing host"); if (irccmp(target_p->host, target_p->orighost)) { SetDynSpoof(target_p); if (MyClient(target_p)) sendto_one_numeric(target_p, RPL_HOSTHIDDEN, "%s :is now your hidden host (set by %s)", target_p->host, source_p->name); } else { ClearDynSpoof(target_p); if (MyClient(target_p)) sendto_one_numeric(target_p, RPL_HOSTHIDDEN, "%s :hostname reset by %s", target_p->host, source_p->name); } if (MyClient(source_p)) sendto_one_notice(source_p, ":Changed hostname for %s to %s", target_p->name, target_p->host); if (!IsServer(source_p) && !IsService(source_p)) sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s changed hostname for %s to %s", get_oper_name(source_p), target_p->name, target_p->host); return 1; }
static void do_modunload(struct Client *source_p, const char *module) { int modindex; char *m_bn = rb_basename(module); if((modindex = findmodule_byname(m_bn)) == -1) { sendto_one_notice(source_p, ":Module %s is not loaded", m_bn); rb_free(m_bn); return; } if(modlist[modindex]->core) { sendto_one_notice(source_p, ":Module %s is a core module and may not be unloaded", m_bn); rb_free(m_bn); return; } if(unload_one_module(m_bn, true) == false) sendto_one_notice(source_p, ":Module %s is not loaded", m_bn); rb_free(m_bn); }
/*! \brief DIE command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = server name */ static int mo_die(struct Client *source_p, int parc, char *parv[]) { char buf[IRCD_BUFSIZE] = ""; if (!HasOFlag(source_p, OPER_FLAG_DIE)) { sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "die"); return 0; } if (parc < 2 || EmptyString(parv[1])) { sendto_one_notice(source_p, &me, ":Need server name /die %s", me.name); return 0; } if (irccmp(parv[1], me.name)) { sendto_one_notice(source_p, &me, ":Mismatch on /die %s", me.name); return 0; } snprintf(buf, sizeof(buf), "received DIE command from %s", get_client_name(source_p, HIDE_IP)); server_die(buf, 0); return 0; }
/* * list_quote_commands() sends the client all the available commands. * Four to a line for now. */ static void list_quote_commands(struct Client *source_p) { int i; int j = 0; const char *names[4]; sendto_one_notice(source_p, ":Available QUOTE SET commands:"); names[0] = names[1] = names[2] = names[3] = ""; for (i = 0; set_cmd_table[i].handler; i++) { names[j++] = set_cmd_table[i].name; if(j > 3) { sendto_one_notice(source_p, ":%s %s %s %s", names[0], names[1], names[2], names[3]); j = 0; names[0] = names[1] = names[2] = names[3] = ""; } } if(j) sendto_one_notice(source_p, ":%s %s %s %s", names[0], names[1], names[2], names[3]); }
/* SET MAX */ static void quote_max(struct Client *source_p, const char *arg, int newval) { if(newval > 0) { if(newval > maxconnections - MAX_BUFFER) { sendto_one_notice(source_p, ":You cannot set MAXCLIENTS to > %d", maxconnections - MAX_BUFFER); return; } if(newval < 32) { sendto_one_notice(source_p, ":You cannot set MAXCLIENTS to < 32 (%d:%d)", GlobalSetOptions.maxclients, rb_getmaxconnect()); return; } GlobalSetOptions.maxclients = newval; sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s!%s@%s set new MAXCLIENTS to %d (%lu current)", source_p->name, source_p->username, source_p->host, GlobalSetOptions.maxclients, rb_dlink_list_length(&lclient_list)); return; } else { sendto_one_notice(source_p, ":Current Maxclients = %d (%lu)", GlobalSetOptions.maxclients, rb_dlink_list_length(&lclient_list)); } }
static int m_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { sendto_one_notice(source_p, ":The BAN command is not user-accessible."); sendto_one_notice(source_p, ":To ban a user from a channel, see /QUOTE HELP CMODE"); if (IsOper(source_p)) sendto_one_notice(source_p, ":To ban a user from a server or from the network, see /QUOTE HELP KLINE"); return 0; }
/*! \brief UNKLINE command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = user\@host mask * - parv[2] = "ON" * - parv[3] = target server */ static int mo_unkline(struct Client *source_p, int parc, char *parv[]) { char *target_server = NULL; char *user, *host; if (!HasOFlag(source_p, OPER_FLAG_UNKLINE)) { sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "unkline"); return 0; } if (EmptyString(parv[1])) { sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "UNKLINE"); return 0; } if (parse_aline("UNKLINE", source_p, parc, parv, 0, &user, &host, NULL, &target_server, NULL) < 0) return 0; if (target_server) { sendto_match_servs(source_p, target_server, CAP_UNKLN, "UNKLINE %s %s %s", target_server, user, host); /* Allow ON to apply local unkline as well if it matches */ if (match(target_server, me.name)) return 0; } else cluster_a_line(source_p, "UNKLINE", CAP_UNKLN, SHARED_UNKLINE, "%s %s", user, host); if (remove_kline_match(host, user)) { sendto_one_notice(source_p, &me, ":K-Line for [%s@%s] is removed", user, host); sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, "%s has removed the K-Line for: [%s@%s]", get_oper_name(source_p), user, host); ilog(LOG_TYPE_KLINE, "%s removed K-Line for [%s@%s]", get_oper_name(source_p), user, host); } else sendto_one_notice(source_p, &me, ":No K-Line for [%s@%s] found", user, host); return 0; }
static int m_mkpasswd(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static time_t last_used = 0; int is_md5 = 0; if((last_used + ConfigFileEntry.pace_wait) > rb_time()) { /* safe enough to give this on a local connect only */ sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "MKPASSWD"); return 0; } else { last_used = rb_time(); } if(parc == 3) { if(!irccmp(parv[2], "MD5")) { is_md5 = 1; } else if(!irccmp(parv[2], "DES")) { /* Not really needed, but we may want to have a default encryption * setting somewhere down the road */ is_md5 = 0; } else { sendto_one_notice(source_p, ":MKPASSWD syntax error: MKPASSWD pass [DES|MD5]"); return 0; } } if(parc == 1) sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MKPASSWD"); else sendto_one_notice(source_p, ":Encryption for [%s]: %s", parv[1], crypt(parv[1], is_md5 ? make_md5_salt() : make_salt())); return 0; }
/* Disable this because of the abuse potential -- jilles * No, make it toggleable via ./configure. --nenolod */ static int mo_chghost(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } if (!(target_p = find_named_person(parv[1]))) { sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); return 0; } if (!clean_host(parv[2])) { sendto_one_notice(source_p, ":Hostname %s is invalid", parv[2]); return 0; } do_chghost(source_p, target_p, parv[2], 0); sendto_server(NULL, NULL, CAP_EUID | CAP_TS6, NOCAPS, ":%s CHGHOST %s %s", use_id(source_p), use_id(target_p), parv[2]); sendto_server(NULL, NULL, CAP_TS6, CAP_EUID, ":%s ENCAP * CHGHOST %s :%s", use_id(source_p), use_id(target_p), parv[2]); return 0; }
/* m_list() * parv[1] = channel * * XXX - With SAFELIST, do we really need to continue pacing? * In theory, the server cannot be lagged by this. --nenolod */ static int m_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static time_t last_used = 0L; if (source_p->localClient->safelist_data != NULL) { sendto_one_notice(source_p, ":/LIST aborted"); safelist_client_release(source_p); return 0; } if (parc < 2 || !IsChannelName(parv[1])) { /* pace this due to the sheer traffic involved */ if (((last_used + ConfigFileEntry.pace_wait) > rb_current_time())) { sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "LIST"); sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name); return 0; } else last_used = rb_current_time(); } return mo_list(client_p, source_p, parc, parv); }
/* SET SPAMNUM */ static void quote_spamnum(struct Client *source_p, const char *arg, int newval) { if(newval > 0) { if(newval == 0) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has disabled ANTI_SPAMBOT", source_p->name); GlobalSetOptions.spam_num = newval; return; } if(newval < MIN_SPAM_NUM) { GlobalSetOptions.spam_num = MIN_SPAM_NUM; } else /* if (newval < MIN_SPAM_NUM) */ { GlobalSetOptions.spam_num = newval; } sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed SPAMNUM to %i", source_p->name, GlobalSetOptions.spam_num); } else { sendto_one_notice(source_p, ":SPAMNUM is currently %i", GlobalSetOptions.spam_num); } }
/* * mo_restart * */ static int mo_restart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { if (!IsOperDie(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "die"); return 0; } if (parc < 2 || EmptyString(parv[1])) { sendto_one_notice(source_p, ":Need server name /restart %s", me.name); return 0; } if (parc > 2) { /* Remote restart. Pass it along. */ struct Client *server_p = find_server(NULL, parv[2]); if (!server_p) { sendto_one_numeric(source_p, ERR_NOSUCHSERVER, form_str(ERR_NOSUCHSERVER), parv[2]); return 0; } if (!IsMe(server_p)) { sendto_one(server_p, ":%s ENCAP %s RESTART %s", source_p->name, parv[2], parv[1]); return 0; } } return do_restart(source_p, parv[1]); }
/* SET OPERHOST */ static void quote_operhost(struct Client *source_p, const char *arg, int newval) { if(EmptyString(arg)) { sendto_one_notice(source_p, ":OPERHOST is currently '%s'", GlobalSetOptions.operhost); } else if(!valid_hostname(arg)) { sendto_one_notice(source_p, "Invalid hostmask."); } else { rb_strlcpy(GlobalSetOptions.operhost, arg, sizeof(GlobalSetOptions.operhost)); sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed OPERHOST to '%s'", get_oper_name(source_p), arg); } }
/*! \brief OPER command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = oper name * - parv[2] = oper password */ static int m_oper(struct Client *source_p, int parc, char *parv[]) { const char *const opername = parv[1]; const char *const password = parv[2]; if (EmptyString(password)) { sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "OPER"); return 0; } struct MaskItem *conf; if ((conf = operator_find(source_p, opername)) == NULL) { sendto_one_numeric(source_p, &me, ERR_NOOPERHOST); conf = operator_find(NULL, opername); failed_oper_notice(source_p, opername, conf ? "host mismatch" : "no operator {} block"); return 0; } if (IsConfSSL(conf) && !HasUMode(source_p, UMODE_SSL)) { sendto_one_numeric(source_p, &me, ERR_NOOPERHOST); failed_oper_notice(source_p, opername, "requires SSL/TLS"); return 0; } if (!EmptyString(conf->certfp)) { if (EmptyString(source_p->certfp) || strcasecmp(source_p->certfp, conf->certfp)) { sendto_one_numeric(source_p, &me, ERR_NOOPERHOST); failed_oper_notice(source_p, opername, "client certificate fingerprint mismatch"); return 0; } } if (match_conf_password(password, conf) == true) { if (conf_attach(source_p, conf)) { sendto_one_notice(source_p, &me, ":Can't attach conf!"); failed_oper_notice(source_p, opername, "can't attach conf!"); return 0; } oper_up(source_p, conf); } else { sendto_one_numeric(source_p, &me, ERR_PASSWDMISMATCH); failed_oper_notice(source_p, opername, "password mismatch"); } return 0; }
/* SET SPLITMODE */ static void quote_splitmode(struct Client *source_p, const char *charval, int intval) { if(charval) { int newval; for (newval = 0; splitmode_values[newval]; newval++) { if(!irccmp(splitmode_values[newval], charval)) break; } /* OFF */ if(newval == 0) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is disabling splitmode", get_oper_name(source_p)); splitmode = false; splitchecking = false; rb_event_delete(check_splitmode_ev); check_splitmode_ev = NULL; } /* ON */ else if(newval == 1) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is enabling and activating splitmode", get_oper_name(source_p)); splitmode = true; splitchecking = false; /* we might be deactivating an automatic splitmode, so pull the event */ rb_event_delete(check_splitmode_ev); check_splitmode_ev = NULL; } /* AUTO */ else if(newval == 2) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is enabling automatic splitmode", get_oper_name(source_p)); splitchecking = true; check_splitmode(NULL); } } else /* if we add splitchecking to splitmode*2 we get a unique table to * pull values back out of, splitmode can be four states - but you can * only set to three, which means we cant use the same table --fl_ */ sendto_one_notice(source_p, ":SPLITMODE is currently %s", splitmode_status[(splitchecking + (splitmode * 2))]); }
static int m_echotags(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { int i; sendto_one_notice(source_p, ":*** You sent %zu tags.", msgbuf_p->n_tags); for (i = 0; i < msgbuf_p->n_tags; i++) { struct MsgTag *tag = &msgbuf_p->tags[i]; if (tag->value) sendto_one_notice(source_p, ":*** %d: %s => %s", i, tag->key, tag->value); else sendto_one_notice(source_p, ":*** %d: %s", i, tag->key); } return 0; }
static void h_can_create_channel_authenticated(hook_data_client_approval *data) { struct Client *source_p = data->client; if (!IsOper(source_p)) { sendto_one_notice(source_p, ":*** Channel creation is restricted to network staff only."); data->approved = ERR_NEEDREGGEDNICK; } }
static void h_can_join(hook_data_channel *data) { struct Client *source_p = data->client; struct Channel *chptr = data->chptr; if((chptr->mode.mode & chmode_flags['S']) && !IsSSLClient(source_p)) { sendto_one_notice(source_p, ":Only users using SSL could join this channel!"); data->approved = ERR_CUSTOM; } }
/* * mo_unreject * */ static int mo_unreject(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0) { sendto_one_notice(source_p, ":Reject cache is disabled"); return 0; } if(!parse_netmask(parv[1], NULL, NULL)) { sendto_one_notice(source_p, ":Unable to parse netmask %s", parv[1]); return 0; } if(remove_reject(parv[1])) sendto_one_notice(source_p, ":Removed reject for %s", parv[1]); else sendto_one_notice(source_p, ":Unable to remove reject for %s", parv[1]); return 0; }
static void me_modrestart(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { if(!find_shared_conf(source_p->username, source_p->host, source_p->servptr->name, SHARED_MODULE)) { sendto_one_notice(source_p, ":*** You do not have an appropriate shared block " "to load modules on this server."); return; } do_modrestart(source_p); }
/*! \brief REHASH command handler * * \param source_p Pointer to allocated Client struct from which the message * originally comes from. This can be a local or remote client. * \param parc Integer holding the number of supplied arguments. * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL * pointers. * \note Valid arguments for this command are: * - parv[0] = command * - parv[1] = option [CONF, DNS, MOTD] * or for remote REHASH: * - parv[0] = command * - parv[1] = target server mask * - parv[2] = option [CONF, DNS, MOTD] */ static int mo_rehash(struct Client *source_p, int parc, char *parv[]) { const char *option = NULL; const char *server = NULL; if (EmptyString(parv[parc - 1])) { sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "REHASH"); return 0; } if (parc < 3) { if (!HasOFlag(source_p, OPER_FLAG_REHASH)) { sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "rehash"); return 0; } option = parv[1]; } else { if (!HasOFlag(source_p, OPER_FLAG_REHASH_REMOTE)) { sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "rehash:remote"); return 0; } server = parv[1]; option = parv[2]; } for (const struct RehashStruct *tab = rehash_cmd_table; tab->handler; ++tab) { if (irccmp(tab->option, option)) continue; if (!EmptyString(server)) sendto_match_servs(source_p, server, 0, "REHASH %s %s", server, option); if (EmptyString(server) || match(server, me.name)) tab->handler(source_p); return 0; } sendto_one_notice(source_p, &me, ":%s is not a valid option. " "Choose from CONF, DNS, MOTD", option); return 0; }