Author: Bleep <tomh@inxpress.net>
[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 = FindServer(server);
82   
83   if (!acptr) {
84     Debug((DEBUG_NOTICE, "Ignoring SQUIT to an unknown server"));
85     return 0;
86   }
87   
88   /* If they are squitting me, we reverse it */
89   if (IsMe(acptr)) {
90         cptr = acptr;
91         acptr = &me;
92   }
93         
94   timestamp = atoi(parv[2]);
95
96   /* If atoi(parv[2]) == 0 we must indeed squit !
97    * It will be our neighbour.
98    */
99   if ( timestamp != 0 && timestamp != acptr->serv->timestamp) {
100     Debug((DEBUG_NOTICE, "Ignoring SQUIT with the wrong timestamp"));
101     return 0;
102   }
103   
104   return exit_client(cptr, acptr, sptr, comment);
105 }
106
107 /*
108  *  mo_squit (oper)
109  *
110  *    parv[0] = sender prefix
111  *    parv[1] = server name
112  *    parv[2] = comment (optional)
113  *
114  */
115 int mo_squit(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
116 {
117   const char* server;
118   struct Client *acptr;
119   struct Client *acptr2;
120   char *comment;
121       
122   if (parc < 2) 
123     return need_more_params(sptr, "SQUIT");
124
125   if (parc < 3 || BadPtr(parv[2]))
126     comment = sptr->name;
127   else
128     comment = parv[2];
129
130   server = parv[1];
131   /*
132    * The following allows wild cards in SQUIT. Only usefull
133    * when the command is issued by an oper.
134    */
135   for (acptr = GlobalClientList; (acptr = next_client(acptr, server));
136       acptr = acptr->next) {
137     if (IsServer(acptr) || IsMe(acptr))
138       break;
139   }
140   
141   /* Not found? Bugger. */
142   if (!acptr || IsMe(acptr))
143     return send_error_to_client(sptr, ERR_NOSUCHSERVER, server);
144
145   /*
146    * Look for a matching server that is closer,
147    * that way we won't accidently squit two close
148    * servers like davis.* and davis-r.* when typing
149    * /SQUIT davis*
150    */
151   for (acptr2 = acptr->serv->up; acptr2 != &me;
152       acptr2 = acptr2->serv->up)
153     if (!match(server, acptr2->name))
154       acptr = acptr2;
155   
156   /* Disallow local opers to squit remote servers */
157   if (IsLocOp(sptr) && !MyConnect(acptr))
158     return send_error_to_client(sptr, ERR_NOPRIVILEGES);
159
160   return exit_client(cptr, acptr, sptr, comment);
161 }
162
163