Index: include/s_newconf.h =================================================================== --- include/s_newconf.h (revision 20598) +++ include/s_newconf.h (working copy) @@ -94,6 +94,7 @@ #define SHARED_TRESV 0x0800 #define SHARED_PRESV 0x0100 #define SHARED_UNRESV 0x0200 +#define SHARED_REHASH 0x0400 #define SHARED_ALL (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\ SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\ Index: src/newconf.c =================================================================== --- src/newconf.c (revision 20598) +++ src/newconf.c (working copy) @@ -385,6 +385,7 @@ { "tresv", SHARED_TRESV }, { "unresv", SHARED_UNRESV }, { "locops", SHARED_LOCOPS }, + { "rehash", SHARED_REHASH }, { "all", SHARED_ALL }, { "none", 0 }, {NULL, 0} Index: help/opers/rehash =================================================================== --- help/opers/rehash (revision 20598) +++ help/opers/rehash (working copy) @@ -4,12 +4,23 @@ ircd.conf file. [option] can be one of the following: + BANS - Re-reads kline.conf, dline.conf, resv.conf and xline.conf DNS - Re-read the /etc/resolv.conf file + GLINES - Clears G Lines MOTD - Re-reads MOTD file OMOTD - Re-reads Oper MOTD file - CHANNELS - Forces a channel cleanup + PGLINES - Clears pending G Lines + REJECTCACHE - Clears the reject cache TDLINES - Clears temporary D Lines TKLINES - Clears temporary K Lines - PGLINES - Clears pending G Lines + TRESVS - Clears temporary nick and channel resvs + TXLINES - Clears temporary X Lines - Requires Oper Priv: H + +REHASH [option] irc.server + +Rehashes [option], or the config file if none given, on irc.server if +irc.server accepts remote rehashes. + +- Requires Oper Priv: HB Index: doc/example.conf =================================================================== --- doc/example.conf (revision 20598) +++ doc/example.conf (working copy) @@ -473,6 +473,7 @@ * unresv - allow removing xlines * all - allow oper/server to do all of above. * locops - allow locops - only used for servers who cluster + * rehash - allow rehashing * none - disallow everything */ Index: doc/example.efnet.conf =================================================================== --- doc/example.efnet.conf (revision 20598) +++ doc/example.efnet.conf (working copy) @@ -480,6 +480,7 @@ * unresv - allow removing xlines * locops - allow locops - only used for servers who cluster * all - allow oper/server to do all of above. + * rehash - allow rehashing * none - disallow everything */ Index: modules/m_rehash.c =================================================================== --- modules/m_rehash.c (revision 20598) +++ modules/m_rehash.c (working copy) @@ -31,6 +31,7 @@ #include "irc_string.h" #include "ircd.h" #include "s_gline.h" +#include "s_serv.h" #include "numeric.h" #include "res.h" #include "s_conf.h" @@ -46,10 +47,11 @@ #include "cache.h" static int mo_rehash(struct Client *, struct Client *, int, const char **); +static int me_rehash(struct Client *, struct Client *, int, const char **); struct Message rehash_msgtab = { "REHASH", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_rehash, 0}} + {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_rehash, 0}, {mo_rehash, 0}} }; mapi_clist_av1 rehash_clist[] = { &rehash_msgtab, NULL }; @@ -280,36 +282,25 @@ }; /* *INDENT-ON* */ -/* - * mo_rehash - REHASH message handler - * - */ -static int -mo_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +static void +do_rehash(struct Client *source_p, const char *type) { - if(!IsOperRehash(source_p)) + if (type != NULL) { - sendto_one(source_p, form_str(ERR_NOPRIVS), - me.name, source_p->name, "rehash"); - return 0; - } - - if(parc > 1) - { int x; char cmdbuf[100]; for (x = 0; rehash_commands[x].cmd != NULL && rehash_commands[x].handler != NULL; x++) { - if(irccmp(parv[1], rehash_commands[x].cmd) == 0) + if(irccmp(type, rehash_commands[x].cmd) == 0) { sendto_one(source_p, form_str(RPL_REHASHING), me.name, source_p->name, rehash_commands[x].cmd); rehash_commands[x].handler(source_p); - ilog(L_MAIN, "REHASH %s From %s[%s]", parv[1], + ilog(L_MAIN, "REHASH %s From %s[%s]", type, get_oper_name(source_p), source_p->sockhost); - return 0; + return; } } @@ -333,8 +324,69 @@ ilog(L_MAIN, "REHASH From %s[%s]", get_oper_name(source_p), source_p->sockhost); rehash(0); + } +} + +/* + * mo_rehash - REHASH message handler + * + * parv[1] = rehash type or destination + * parv[2] = destination + */ +static int +mo_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ + const char *type = NULL, *target_server = NULL; + + if(!IsOperRehash(source_p)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "rehash"); return 0; } + if (parc > 2) + type = parv[1], target_server = parv[2]; + else if (parc > 1 && (strchr(parv[1], '.') || strchr(parv[1], '?') || strchr(parv[1], '*'))) + type = NULL, target_server = parv[1]; + else if (parc > 1) + type = parv[1], target_server = NULL; + else + type = NULL, target_server = NULL; + + if (target_server != NULL) + { + if(!IsOperRemoteBan(source_p)) + { + sendto_one(source_p, form_str(ERR_NOPRIVS), + me.name, source_p->name, "remoteban"); + return 0; + } + sendto_match_servs(source_p, target_server, + CAP_ENCAP, NOCAPS, + "ENCAP %s REHASH %s", + target_server, type != NULL ? type : ""); + if (match(target_server, me.name) == 0) + return 0; + } + + do_rehash(source_p, type); + return 0; } + +static int +me_rehash(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ + + if (!IsPerson(source_p)) + return 0; + + if (!find_shared_conf(source_p->username, source_p->host, + source_p->user->server, SHARED_REHASH)) + return 0; + + do_rehash(source_p, parc > 1 ? parv[1] : NULL); + + return 0; +}