Author: Kev <klmitch@mit.edu>
[ircu2.10.12-pk.git] / ircd / m_squit.c
1 /*
2  * IRC - Internet Relay Chat, ircd/m_squit.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 #if 0
27 /*
28  * No need to include handlers.h here the signatures must match
29  * and we don't need to force a rebuild of all the handlers everytime
30  * we add a new one to the list. --Bleep
31  */
32 #include "handlers.h"
33 #endif /* 0 */
34 #include "client.h"
35 #include "hash.h"
36 #include "ircd.h"
37 #include "ircd_chattr.h"
38 #include "ircd_reply.h"
39 #include "ircd_string.h"
40 #include "numeric.h"
41 #include "numnicks.h"
42 #include "match.h"
43 #include "s_debug.h"
44 #include "s_misc.h"
45 #include "s_user.h"
46 #include "send.h"
47
48 #include <assert.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52
53 /*
54  *  ms_squit (server)
55  *
56  *    parv[0] = sender prefix
57  *    parv[1] = server name
58  *    parv[2] = timestamp
59  *    parv[parc-1] = comment
60  *
61  * No longer supports wildcards from servers. 
62  * No longer squits a server that gave us an malformed squit message.
63  *    - Isomer 1999-12-18
64  * 
65  */
66 int ms_squit(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
67 {
68   const char* server = parv[1];
69   struct Client *acptr;
70   time_t timestamp;
71   char *comment = 0;
72   
73   if (parc < 2) 
74     return need_more_params(sptr, "SQUIT");
75
76   comment = parv[parc-1];
77   
78   if (BadPtr(parv[parc - 1]))
79         comment=sptr->name;
80         
81   acptr = FindNServer(server);
82
83   if (!acptr)
84     acptr = FindServer(server);
85
86   if (!acptr) {
87     Debug((DEBUG_NOTICE, "Ignoring SQUIT to an unknown server"));
88     return 0;
89   }
90   
91   /* If they are squitting me, we reverse it */
92   if (IsMe(acptr)) {
93         cptr = acptr;
94         acptr = &me;
95   }
96         
97   timestamp = atoi(parv[2]);
98
99   /* If atoi(parv[2]) == 0 we must indeed squit !
100    * It will be our neighbour.
101    */
102   if ( timestamp != 0 && timestamp != acptr->serv->timestamp) {
103     Debug((DEBUG_NOTICE, "Ignoring SQUIT with the wrong timestamp"));
104     return 0;
105   }
106   
107   return exit_client(cptr, acptr, sptr, comment);
108 }
109
110 /*
111  *  mo_squit (oper)
112  *
113  *    parv[0] = sender prefix
114  *    parv[1] = server name
115  *    parv[2] = comment (optional)
116  *
117  */
118 int mo_squit(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
119 {
120   const char* server;
121   struct Client *acptr;
122   struct Client *acptr2;
123   char *comment;
124       
125   if (parc < 2) 
126     return need_more_params(sptr, "SQUIT");
127
128   if (parc < 3 || BadPtr(parv[2]))
129     comment = sptr->name;
130   else
131     comment = parv[2];
132
133   server = parv[1];
134   /*
135    * The following allows wild cards in SQUIT. Only usefull
136    * when the command is issued by an oper.
137    */
138   for (acptr = GlobalClientList; (acptr = next_client(acptr, server));
139       acptr = acptr->next) {
140     if (IsServer(acptr) || IsMe(acptr))
141       break;
142   }
143   
144   /* Not found? Bugger. */
145   if (!acptr || IsMe(acptr))
146     return send_reply(sptr, ERR_NOSUCHSERVER, server);
147
148   /*
149    * Look for a matching server that is closer,
150    * that way we won't accidently squit two close
151    * servers like davis.* and davis-r.* when typing
152    * /SQUIT davis*
153    */
154   for (acptr2 = acptr->serv->up; acptr2 != &me;
155       acptr2 = acptr2->serv->up)
156     if (!match(server, acptr2->name))
157       acptr = acptr2;
158   
159   /* Disallow local opers to squit remote servers */
160   if (IsLocOp(sptr) && !MyConnect(acptr))
161     return send_reply(sptr, ERR_NOPRIVILEGES);
162
163   return exit_client(cptr, acptr, sptr, comment);
164 }
165
166