ircu2.10.12 pk910 fork
[ircu2.10.12-pk.git] / ircd / m_rehash.c
1 /*
2  * IRC - Internet Relay Chat, ircd/m_rehash.c
3  * Copyright (C) 1990 Jarkko Oikarinen and
4  *                    University of Oulu, Computing Center
5  *
6  * See file AUTHORS in IRC package for additional names of
7  * the programmers.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 1, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * $Id: m_rehash.c 1271 2004-12-11 05:14:07Z klmitch $
24  */
25
26 /*
27  * m_functions execute protocol messages on this server:
28  *
29  *    cptr    is always NON-NULL, pointing to a *LOCAL* client
30  *            structure (with an open socket connected!). This
31  *            identifies the physical socket where the message
32  *            originated (or which caused the m_function to be
33  *            executed--some m_functions may call others...).
34  *
35  *    sptr    is the source of the message, defined by the
36  *            prefix part of the message if present. If not
37  *            or prefix not found, then sptr==cptr.
38  *
39  *            (!IsServer(cptr)) => (cptr == sptr), because
40  *            prefixes are taken *only* from servers...
41  *
42  *            (IsServer(cptr))
43  *                    (sptr == cptr) => the message didn't
44  *                    have the prefix.
45  *
46  *                    (sptr != cptr && IsServer(sptr) means
47  *                    the prefix specified servername. (?)
48  *
49  *                    (sptr != cptr && !IsServer(sptr) means
50  *                    that message originated from a remote
51  *                    user (not local).
52  *
53  *            combining
54  *
55  *            (!IsServer(sptr)) means that, sptr can safely
56  *            taken as defining the target structure of the
57  *            message in this server.
58  *
59  *    *Always* true (if 'parse' and others are working correct):
60  *
61  *    1)      sptr->from == cptr  (note: cptr->from == cptr)
62  *
63  *    2)      MyConnect(sptr) <=> sptr == cptr (e.g. sptr
64  *            *cannot* be a local connection, unless it's
65  *            actually cptr!). [MyConnect(x) should probably
66  *            be defined as (x == x->from) --msa ]
67  *
68  *    parc    number of variable parameter strings (if zero,
69  *            parv is allowed to be NULL)
70  *
71  *    parv    a NULL terminated list of parameter pointers,
72  *
73  *                    parv[0], sender (prefix string), if not present
74  *                            this points to an empty string.
75  *                    parv[1]...parv[parc-1]
76  *                            pointers to additional parameters
77  *                    parv[parc] == NULL, *always*
78  *
79  *            note:   it is guaranteed that parv[0]..parv[parc-1] are all
80  *                    non-NULL pointers.
81  */
82 #include "config.h"
83
84 #include "client.h"
85 #include "hash.h"
86 #include "ircd.h"
87 #include "ircd_log.h"
88 #include "ircd_reply.h"
89 #include "ircd_string.h"
90 #include "motd.h"
91 #include "msg.h"
92 #include "numeric.h"
93 #include "numnicks.h"
94 #include "s_conf.h"
95 #include "send.h"
96
97 /* #include <assert.h> -- Now using assert in ircd_log.h */
98
99 /* Removes all chars except 'm' 'l' 'q' and 'r'. */
100 static void clean_rehash_string(char *str) {
101     unsigned int i, dest;
102
103     for(i = 0, dest = 0; str[i]; ++i) {
104         switch(str[i]) {
105             case 'm':
106             case 'l':
107             case 'q':
108             case 'r':
109                 str[dest++] = str[i];
110                 break;
111         }
112     }
113     str[dest] = 0;
114 }
115
116 /* Executes a rehash. */
117 static void execute_rehash(struct Client *sptr, char *opt) {
118     unsigned int i, fresh = 0;
119
120     if(!opt) {
121         send_reply(sptr, RPL_REHASHING, configfile);
122         rehash(sptr, 0);
123     }
124     else {
125         for(i = 0; opt[i]; ++i) {
126             switch(opt[i]) {
127                 case 'm':
128                     send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Flushing MOTD cache");
129                     motd_recache(); /* flush MOTD cache */
130                     break;
131                 case 'l':
132                     send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Reopening log files");
133                     log_reopen(); /* reopen log files */
134                     break;
135                 case 'q':
136                     fresh = 2;
137                     break;
138                 case 'r':
139                     fresh = 1;
140                     break;
141             }
142         }
143         if(fresh) {
144             send_reply(sptr, RPL_REHASHING, configfile);
145             rehash(sptr, (fresh == 2)?2:0);
146         }
147     }
148     sendto_opmask_butone(0, SNO_OLDSNO, "%C is rehashing Server config files (opt='%s')", sptr, opt?opt:"r");
149     log_write(LS_SYSTEM, L_INFO, 0, "REHASH From %#C (opt='%s')", sptr, opt?opt:"r");
150 }
151
152 /*
153  * mo_rehash - oper message handler
154  *
155  * parv[1] = String containing:
156  *           'm' flushes the MOTD cache
157  *           'l' reopens the log files
158  *           'q' to not rehash the resolver (optional)
159  *           'r' rehashes the config file
160  * parv[2] = Optional: Remote server where to send the rehash command to.
161  */
162 int mo_rehash(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
163 {
164   struct Client *acptr;
165
166   if (!HasPriv(sptr, PRIV_REHASH))
167     return send_reply(sptr, ERR_NOPRIVILEGES);
168
169   if(parc > 1) {
170     clean_rehash_string(parv[1]);
171
172     if(*parv[1]) {
173       if(parc > 2) {
174         if(!(acptr = FindServer(parv[2]))) return send_reply(sptr, SND_EXPLICIT | RPL_REHASHING, ":Unknown Server");
175         if(!IsMe(acptr)) {
176             sendcmdto_one(sptr, CMD_REHASH, acptr, "%s %s", cli_yxx(acptr), parv[1]);
177             return 0;
178         }
179       }
180       execute_rehash(sptr, parv[1]);
181     }
182   }
183   else execute_rehash(sptr, NULL);
184
185   return 0;
186 }
187
188 int ms_rehash(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) {
189     struct Client *acptr;
190
191     if(parc < 3) {
192         return protocol_violation(cptr, "Too few arguments for REHASH");
193     }
194
195     /* Ignore unknown servers. */
196     if(!(acptr = FindNServer(parv[1]))) return 0;
197
198     /* Ignore invalid parameter strings. */
199     clean_rehash_string(parv[2]);
200     if(!*parv[2]) return 0;
201
202     if(!IsMe(acptr)) {
203         sendcmdto_one(sptr, CMD_REHASH, acptr, "%s %s", cli_yxx(acptr), parv[2]);
204         return 0;
205     }
206
207     execute_rehash(sptr, parv[2]);
208     return 0;
209 }