ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_connect.c
Revision: 374
Committed: Sat Jan 14 17:57:18 2006 UTC (19 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 9360 byte(s)
Log Message:
- More m_connect cleanups, I also never liked the idea of temporarily modifying
  a connect item, so let's do this a bit different now.

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_connect.c: Connects to a remote IRC server.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "handlers.h"
27     #include "client.h"
28     #include "ircd.h"
29     #include "numeric.h"
30     #include "s_conf.h"
31     #include "s_serv.h"
32     #include "send.h"
33     #include "msg.h"
34     #include "parse.h"
35     #include "hash.h"
36     #include "modules.h"
37    
38 michael 348 static void mo_connect(struct Client *, struct Client *, int, char *[]);
39     static void ms_connect(struct Client *, struct Client *, int, char *[]);
40 adx 30
41     struct Message connect_msgtab = {
42     "CONNECT", 0, 0, 2, 0, MFLG_SLOW, 0,
43 michael 348 { m_unregistered, m_not_oper, ms_connect, m_ignore, mo_connect, m_ignore }
44 adx 30 };
45    
46     #ifndef STATIC_MODULES
47     void
48     _modinit(void)
49     {
50     mod_add_cmd(&connect_msgtab);
51     }
52    
53     void
54     _moddeinit(void)
55     {
56     mod_del_cmd(&connect_msgtab);
57     }
58    
59 knight 31 const char *_version = "$Revision$";
60 adx 30 #endif
61    
62 michael 348 /*! \brief CONNECT command handler (called for operators only)
63 adx 30 *
64 michael 348 * \param client_p Pointer to allocated Client struct with physical connection
65     * to this server, i.e. with an open socket connected.
66     * \param source_p Pointer to allocated Client struct from which the message
67     * originally comes from. This can be a local or remote client.
68     * \param parc Integer holding the number of supplied arguments.
69     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
70     * pointers.
71     * \note Valid arguments for this command are:
72     * - parv[0] = sender prefix
73     * - parv[1] = servername
74     * - parv[2] = port number
75     * - parv[3] = remote server
76 adx 30 */
77     static void
78 michael 374 mo_connect(struct Client *client_p, struct Client *source_p,
79     int parc, char *parv[])
80 adx 30 {
81 michael 374 int port = 0;
82 adx 30 struct ConfItem *conf = NULL;
83     struct AccessItem *aconf = NULL;
84 michael 374 struct Client *target_p = NULL;
85 adx 30
86     /* always privileged with handlers */
87     if (MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
88     {
89     sendto_one(source_p, form_str(ERR_NOPRIVS),
90     me.name, source_p->name, "connect");
91     return;
92     }
93    
94 michael 348 if (hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3,
95     parc, parv) != HUNTED_ISME)
96 adx 30 return;
97    
98     if (*parv[1] == '\0')
99     {
100     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
101     me.name, source_p->name, "CONNECT");
102     return;
103     }
104    
105     if ((target_p = find_server(parv[1])))
106     {
107     sendto_one(source_p,
108 michael 373 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
109 adx 30 me.name, source_p->name, parv[1], target_p->from->name);
110     return;
111     }
112    
113     /*
114 michael 373 * Try to find the name, then host, if both fail notify ops and bail
115 adx 30 */
116     if ((conf = find_matching_name_conf(SERVER_TYPE,
117 michael 373 parv[1], NULL, NULL, 0)) != NULL)
118 db 139 aconf = &conf->conf.AccessItem;
119 adx 30 else if ((conf = find_matching_name_conf(SERVER_TYPE,
120 michael 373 NULL, NULL, parv[1], 0)) != NULL)
121 db 139 aconf = &conf->conf.AccessItem;
122 adx 30
123     if (conf == NULL)
124     {
125     sendto_one(source_p,
126 michael 373 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
127     me.name, source_p->name, parv[1]);
128 adx 30 return;
129     }
130 michael 373
131     /*
132     * Get port number from user, if given. If not specified,
133     * use the default from configuration structure.
134 adx 30 */
135 michael 374 port = aconf->port;
136 adx 30
137     if (parc > 2 && !EmptyString(parv[2]))
138 michael 374 port = atoi(parv[2]);
139    
140     if (port <= 0 || port > 0xFFFF)
141 adx 30 {
142 michael 374 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal or missing port number",
143 adx 30 me.name, source_p->name);
144     return;
145     }
146    
147     if (find_servconn_in_progress(conf->name))
148     {
149     sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
150     "is already in progress.", me.name, source_p->name, conf->name);
151     return;
152     }
153    
154     /*
155     * Notify all operators about remote connect requests
156     */
157     ilog(L_TRACE, "CONNECT From %s : %s %s",
158     source_p->name, parv[1], parv[2] ? parv[2] : "");
159    
160 michael 373 /*
161     * At this point we should be calling connect_server with a valid
162     * connect{} and a valid port in the connect{}
163 adx 30 */
164 michael 374 if (serv_connect(aconf, source_p, port))
165 adx 30 {
166     if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
167     sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
168     me.name, source_p->name, aconf->host,
169 michael 374 conf->name, port);
170 adx 30 else
171     sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
172 michael 374 me.name, source_p->name, conf->name, port);
173 adx 30 }
174     else
175     {
176     sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
177 michael 374 me.name, source_p->name, conf->name, port);
178 adx 30 }
179    
180 michael 348 /*
181 michael 373 * Client is either connecting with all the data it needs or has been
182 adx 30 * destroyed
183     */
184     }
185    
186 michael 348 /*! \brief CONNECT command handler (called for remote clients only)
187 adx 30 *
188 michael 348 * \param client_p Pointer to allocated Client struct with physical connection
189     * to this server, i.e. with an open socket connected.
190     * \param source_p Pointer to allocated Client struct from which the message
191     * originally comes from. This can be a local or remote client.
192     * \param parc Integer holding the number of supplied arguments.
193     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
194     * pointers.
195     * \note Valid arguments for this command are:
196     * - parv[0] = sender prefix
197     * - parv[1] = servername
198     * - parv[2] = port number
199     * - parv[3] = remote server
200 adx 30 */
201     static void
202     ms_connect(struct Client *client_p, struct Client *source_p,
203     int parc, char *parv[])
204     {
205 michael 374 int port = 0;
206 adx 30 struct ConfItem *conf = NULL;
207     struct AccessItem *aconf = NULL;
208 michael 374 struct Client *target_p = NULL;
209 adx 30
210 michael 348 if (hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3,
211     parc, parv) != HUNTED_ISME)
212 adx 30 return;
213    
214     if (*parv[1] == '\0')
215     {
216     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
217     me.name, source_p->name, "CONNECT");
218     return;
219     }
220    
221     if ((target_p = find_server(parv[1])))
222     {
223     sendto_one(source_p,
224 michael 373 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
225 adx 30 me.name, source_p->name, parv[1], target_p->from->name);
226     return;
227     }
228    
229     /*
230 michael 373 * Try to find the name, then host, if both fail notify ops and bail
231 adx 30 */
232     if ((conf = find_matching_name_conf(SERVER_TYPE,
233 michael 373 parv[1], NULL, NULL, 0)) != NULL)
234 db 139 aconf = &conf->conf.AccessItem;
235 adx 30 else if ((conf = find_matching_name_conf(SERVER_TYPE,
236 michael 373 NULL, NULL, parv[1], 0)) != NULL)
237 db 139 aconf = &conf->conf.AccessItem;
238 adx 30
239     if (aconf == NULL)
240     {
241     sendto_one(source_p,
242 michael 373 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
243     me.name, source_p->name, parv[1]);
244 adx 30 return;
245     }
246    
247     assert(aconf != NULL);
248    
249 michael 373 /*
250     * Get port number from user, if given. If not specified,
251     * use the default from configuration structure.
252 adx 30 */
253 michael 374 port = aconf->port;
254 adx 30
255     if (parc > 2 && !EmptyString(parv[2]))
256     {
257     port = atoi(parv[2]);
258    
259 michael 374 /* if someone sends port 0, use the config port instead */
260     if (port == 0)
261 adx 30 port = aconf->port;
262     }
263 michael 374
264     if (port <= 0 || port > 0xFFFF)
265 adx 30 {
266 michael 374 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal or missing port number",
267 adx 30 me.name, source_p->name);
268     return;
269     }
270    
271     if (find_servconn_in_progress(conf->name))
272     {
273     sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
274     "is already in progress.", me.name, source_p->name, conf->name);
275     return;
276     }
277    
278     /*
279     * Notify all operators about remote connect requests
280     */
281     sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s",
282     parv[1], port, source_p->name);
283     sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
284     ":%s WALLOPS :Remote CONNECT %s %d from %s",
285     me.name, parv[1], port, source_p->name);
286    
287     ilog(L_TRACE, "CONNECT From %s : %s %d",
288     source_p->name, parv[1], port);
289    
290 michael 373 /*
291     * At this point we should be calling connect_server with a valid
292     * connect{} and a valid port in the connect{}
293 adx 30 */
294 michael 374 if (serv_connect(aconf, source_p, port))
295 adx 30 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
296 michael 374 me.name, source_p->name, conf->name, port);
297 adx 30 else
298     sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
299 michael 374 me.name, source_p->name, conf->name, port);
300 michael 348
301     /*
302 michael 373 * Client is either connecting with all the data it needs or has been
303 adx 30 * destroyed
304     */
305     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision