Author: Bleep <tomh@inxpress.net>
[ircu2.10.12-pk.git] / ircd / m_motd.c
1 /*
2  * IRC - Internet Relay Chat, ircd/m_motd.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$
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 #if 0
83 /*
84  * No need to include handlers.h here the signatures must match
85  * and we don't need to force a rebuild of all the handlers everytime
86  * we add a new one to the list. --Bleep
87  */
88 #include "handlers.h"
89 #endif /* 0 */
90 #include "client.h"
91 #include "ircd.h"
92 #include "ircd_reply.h"
93 #include "ircd_string.h"
94 #include "match.h"
95 #include "msg.h"
96 #include "numeric.h"
97 #include "numnicks.h"
98 #include "s_conf.h"
99 #include "s_user.h"
100 #include "send.h"
101
102 #include <assert.h>
103
104 /*
105  * m_motd - generic message handler
106  *
107  * parv[0] - sender prefix
108  * parv[1] - servername
109  *
110  * modified 30 mar 1995 by flux (cmlambertus@ucdavis.edu)
111  * T line patch - display motd based on hostmask
112  * modified again 7 sep 97 by Ghostwolf with code and ideas 
113  * stolen from comstud & Xorath.  All motd files are read into
114  * memory in read_motd() in s_conf.c
115  *
116  * When NODEFAULTMOTD is defined, then it is possible that
117  * sptr == NULL, which means that this function is called from
118  * register_user.
119  */
120 int m_motd(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
121 {
122   struct tm *tm = &motd_tm;     /* Default: Most general case */
123   struct TRecord *ptr;
124   int count;
125   struct MotdItem *temp;
126
127 #ifdef NODEFAULTMOTD
128   int no_motd;
129
130   if (sptr)
131   {
132     no_motd = 0;
133 #endif
134     if (hunt_server(0, cptr, sptr, "%s%s " TOK_MOTD " %s", 1, parc,
135         parv) != HUNTED_ISME)
136       return 0;
137 #ifdef NODEFAULTMOTD
138   }
139   else
140   {
141     sptr = cptr;
142     no_motd = 1;
143   }
144 #endif
145
146   /*
147    * Find out if this is a remote query or if we have a T line for our hostname
148    */
149   if (IsServer(cptr))
150   {
151     tm = 0;                  /* Remote MOTD */
152     temp = rmotd;
153   }
154   else
155   {
156     for (ptr = tdata; ptr; ptr = ptr->next)
157     {
158       if (!match(ptr->hostmask, cptr->sockhost))
159         break;
160     }
161     if (ptr)
162     {
163       temp = ptr->tmotd;
164       tm = &ptr->tmotd_tm;
165     }
166     else
167       temp = motd;
168   }
169   if (temp == 0)
170   {
171     sendto_one(sptr, err_str(ERR_NOMOTD), me.name, parv[0]);
172     return 0;
173   }
174 #ifdef NODEFAULTMOTD
175   if (!no_motd)
176   {
177 #endif
178     if (tm)                     /* Not remote? */
179     {
180       sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
181       sendto_one(sptr, ":%s %d %s :- %d/%d/%d %d:%02d", me.name, RPL_MOTD,
182           parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year,
183           tm->tm_hour, tm->tm_min);
184       count = 100;
185     }
186     else
187       count = 3;
188     for (; temp; temp = temp->next)
189     {
190       sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0], temp->line);
191       if (--count == 0)
192         break;
193     }
194 #ifdef NODEFAULTMOTD
195   }
196   else
197   {
198     sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
199     sendto_one(sptr, ":%s %d %s :%s", me.name, RPL_MOTD, parv[0],
200         "\ 2Type /MOTD to read the AUP before continuing using this service.\ 2");
201     sendto_one(sptr,
202         ":%s %d %s :The message of the day was last changed: %d/%d/%d", me.name,
203         RPL_MOTD, parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
204   }
205 #endif
206   sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);
207   return 0;
208 }
209
210 /*
211  * ms_motd - server message handler
212  *
213  * parv[0] - sender prefix
214  * parv[1] - servername
215  *
216  * modified 30 mar 1995 by flux (cmlambertus@ucdavis.edu)
217  * T line patch - display motd based on hostmask
218  * modified again 7 sep 97 by Ghostwolf with code and ideas 
219  * stolen from comstud & Xorath.  All motd files are read into
220  * memory in read_motd() in s_conf.c
221  *
222  * When NODEFAULTMOTD is defined, then it is possible that
223  * sptr == NULL, which means that this function is called from
224  * register_user.
225  */
226 int ms_motd(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
227 {
228   struct tm *tm = &motd_tm;     /* Default: Most general case */
229   struct TRecord *ptr;
230   int count;
231   struct MotdItem *temp;
232
233 #ifdef NODEFAULTMOTD
234   int no_motd;
235
236   if (sptr)
237   {
238     no_motd = 0;
239 #endif
240     if (hunt_server(0, cptr, sptr, "%s%s " TOK_MOTD " %s", 1, parc,
241         parv) != HUNTED_ISME)
242       return 0;
243 #ifdef NODEFAULTMOTD
244   }
245   else
246   {
247     sptr = cptr;
248     no_motd = 1;
249   }
250 #endif
251
252   /*
253    * Find out if this is a remote query or if we have a T line for our hostname
254    */
255   if (IsServer(cptr))
256   {
257     tm = 0;                  /* Remote MOTD */
258     temp = rmotd;
259   }
260   else
261   {
262     for (ptr = tdata; ptr; ptr = ptr->next)
263     {
264       if (!match(ptr->hostmask, cptr->sockhost))
265         break;
266     }
267     if (ptr)
268     {
269       temp = ptr->tmotd;
270       tm = &ptr->tmotd_tm;
271     }
272     else
273       temp = motd;
274   }
275   if (temp == 0)
276   {
277     sendto_one(sptr, err_str(ERR_NOMOTD), me.name, parv[0]);
278     return 0;
279   }
280 #ifdef NODEFAULTMOTD
281   if (!no_motd)
282   {
283 #endif
284     if (tm)                     /* Not remote? */
285     {
286       sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
287       sendto_one(sptr, ":%s %d %s :- %d/%d/%d %d:%02d", me.name, RPL_MOTD,
288           parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year,
289           tm->tm_hour, tm->tm_min);
290       count = 100;
291     }
292     else
293       count = 3;
294     for (; temp; temp = temp->next)
295     {
296       sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0], temp->line);
297       if (--count == 0)
298         break;
299     }
300 #ifdef NODEFAULTMOTD
301   }
302   else
303   {
304     sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
305     sendto_one(sptr, ":%s %d %s :%s", me.name, RPL_MOTD, parv[0],
306         "\ 2Type /MOTD to read the AUP before continuing using this service.\ 2");
307     sendto_one(sptr,
308         ":%s %d %s :The message of the day was last changed: %d/%d/%d", me.name,
309         RPL_MOTD, parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
310   }
311 #endif
312   sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);
313   return 0;
314 }
315
316 #if 0
317 /*
318  * m_motd
319  *
320  * parv[0] - sender prefix
321  * parv[1] - servername
322  *
323  * modified 30 mar 1995 by flux (cmlambertus@ucdavis.edu)
324  * T line patch - display motd based on hostmask
325  * modified again 7 sep 97 by Ghostwolf with code and ideas 
326  * stolen from comstud & Xorath.  All motd files are read into
327  * memory in read_motd() in s_conf.c
328  *
329  * When NODEFAULTMOTD is defined, then it is possible that
330  * sptr == NULL, which means that this function is called from
331  * register_user.
332  */
333 int m_motd(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
334 {
335   struct tm *tm = &motd_tm;     /* Default: Most general case */
336   struct TRecord *ptr;
337   int count;
338   struct MotdItem *temp;
339
340 #ifdef NODEFAULTMOTD
341   int no_motd;
342
343   if (sptr)
344   {
345     no_motd = 0;
346 #endif
347     if (hunt_server(0, cptr, sptr, "%s%s " TOK_MOTD " %s", 1, parc,
348         parv) != HUNTED_ISME)
349       return 0;
350 #ifdef NODEFAULTMOTD
351   }
352   else
353   {
354     sptr = cptr;
355     no_motd = 1;
356   }
357 #endif
358
359   /*
360    * Find out if this is a remote query or if we have a T line for our hostname
361    */
362   if (IsServer(cptr))
363   {
364     tm = 0;                  /* Remote MOTD */
365     temp = rmotd;
366   }
367   else
368   {
369     for (ptr = tdata; ptr; ptr = ptr->next)
370     {
371       if (!match(ptr->hostmask, cptr->sockhost))
372         break;
373     }
374     if (ptr)
375     {
376       temp = ptr->tmotd;
377       tm = &ptr->tmotd_tm;
378     }
379     else
380       temp = motd;
381   }
382   if (temp == 0)
383   {
384     sendto_one(sptr, err_str(ERR_NOMOTD), me.name, parv[0]);
385     return 0;
386   }
387 #ifdef NODEFAULTMOTD
388   if (!no_motd)
389   {
390 #endif
391     if (tm)                     /* Not remote? */
392     {
393       sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
394       sendto_one(sptr, ":%s %d %s :- %d/%d/%d %d:%02d", me.name, RPL_MOTD,
395           parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year,
396           tm->tm_hour, tm->tm_min);
397       count = 100;
398     }
399     else
400       count = 3;
401     for (; temp; temp = temp->next)
402     {
403       sendto_one(sptr, rpl_str(RPL_MOTD), me.name, parv[0], temp->line);
404       if (--count == 0)
405         break;
406     }
407 #ifdef NODEFAULTMOTD
408   }
409   else
410   {
411     sendto_one(sptr, rpl_str(RPL_MOTDSTART), me.name, parv[0], me.name);
412     sendto_one(sptr, ":%s %d %s :%s", me.name, RPL_MOTD, parv[0],
413         "\ 2Type /MOTD to read the AUP before continuing using this service.\ 2");
414     sendto_one(sptr,
415         ":%s %d %s :The message of the day was last changed: %d/%d/%d", me.name,
416         RPL_MOTD, parv[0], tm->tm_mday, tm->tm_mon + 1, 1900 + tm->tm_year);
417   }
418 #endif
419   sendto_one(sptr, rpl_str(RPL_ENDOFMOTD), me.name, parv[0]);
420   return 0;
421 }
422 #endif /* 0 */
423