ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/contrib/m_ltrace.c
Revision: 889
Committed: Thu Nov 1 12:59:05 2007 UTC (18 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 10371 byte(s)
Log Message:
- Got rid of Serv.dep_users and Serv.dep_servers

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_ltrace.c: Traces a path to a client/server.
4 *
5 * Copyright (C) 2002 Hybrid Development Team
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 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "handlers.h"
27 #include "tools.h"
28 #include "hook.h"
29 #include "client.h"
30 #include "common.h"
31 #include "hash.h"
32 #include "irc_string.h"
33 #include "ircd.h"
34 #include "numeric.h"
35 #include "fdlist.h"
36 #include "s_bsd.h"
37 #include "s_serv.h"
38 #include "s_conf.h"
39 #include "send.h"
40 #include "msg.h"
41 #include "parse.h"
42 #include "modules.h"
43 #include "irc_getnameinfo.h"
44
45 static void do_ltrace(struct Client *, int, char **);
46 static void m_ltrace(struct Client *, struct Client *, int, char **);
47 static void mo_ltrace(struct Client *, struct Client *, int, char **);
48
49 struct Message ltrace_msgtab = {
50 "LTRACE", 0, 0, 0, 0, MFLG_SLOW, 0,
51 {m_unregistered, m_ltrace, mo_ltrace, m_ignore, mo_ltrace, m_ignore}
52 };
53
54 #ifndef STATIC_MODULES
55 const char *_version = "$Revision$";
56 static struct Callback *ltrace_cb;
57
58 static void *
59 va_ltrace(va_list args)
60 {
61 struct Client *source_p = va_arg(args, struct Client *);
62 int parc = va_arg(args, int);
63 char **parv = va_arg(args, char **);
64
65 do_ltrace(source_p, parc, parv);
66 return NULL;
67 }
68
69 void
70 _modinit(void)
71 {
72 ltrace_cb = register_callback("doing_ltrace", va_ltrace);
73 mod_add_cmd(&ltrace_msgtab);
74 }
75
76 void
77 _moddeinit(void)
78 {
79 mod_del_cmd(&ltrace_msgtab);
80 uninstall_hook(ltrace_cb, va_ltrace);
81 }
82 #endif
83
84 static void report_this_status(struct Client *, struct Client *, int);
85
86 static void
87 trace_get_dependent(int *const server,
88 int *const client, const struct Client *target_p)
89 {
90 const dlink_node *ptr = NULL;
91
92 (*server)++;
93 (*client) += dlink_list_length(&target_p->serv->client_list);
94
95 DLINK_FOREACH(ptr, target_p->serv->server_list.head)
96 trace_get_dependent(server, client, ptr->data);
97 }
98
99 /*
100 * m_ltrace()
101 *
102 * parv[0] = sender prefix
103 * parv[1] = target client/server to trace
104 */
105 static void
106 m_ltrace(struct Client *client_p, struct Client *source_p,
107 int parc, char *parv[])
108 {
109 char *tname;
110
111 if (parc > 1)
112 tname = parv[1];
113 else
114 tname = me.name;
115 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
116 me.name, parv[0], tname);
117 }
118
119 /*
120 * do_ltrace
121 */
122 static void
123 do_ltrace(struct Client *source_p, int parc, char **parv)
124 {
125 struct Client *target_p = NULL;
126 int doall;
127 int wilds, dow;
128 dlink_node *ptr;
129 char *looking_for = parv[0];
130 char *tname = parc > 1 ? parv[1] : me.name;
131
132 switch (hunt_server(source_p->from, source_p, ":%s LTRACE :%s", 1,parc,parv))
133 {
134 case HUNTED_PASS: /* note: gets here only if parv[1] exists */
135 {
136 struct Client *ac2ptr = NULL;
137
138 if ((ac2ptr = find_client(tname)) == NULL)
139 DLINK_FOREACH(ptr, global_client_list.head)
140 {
141 ac2ptr = ptr->data;
142
143 if (match(tname, ac2ptr->name) || match(ac2ptr->name, tname))
144 break;
145 else
146 ac2ptr = NULL;
147 }
148
149 if (ac2ptr != NULL)
150 sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for,
151 ircd_version, tname, ac2ptr->from->name);
152 else
153 sendto_one(source_p, form_str(RPL_TRACELINK), me.name, looking_for,
154 ircd_version, tname, "ac2ptr_is_NULL!!");
155 return;
156 }
157 case HUNTED_ISME:
158 break;
159 default:
160 return;
161 }
162
163 doall = (parv[1] && (parc > 1)) ? match(tname, me.name): TRUE;
164 wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
165 dow = wilds || doall;
166
167 /* lusers cant issue ltrace.. */
168 if (!dow)
169 {
170 const char* name;
171 const char* class_name;
172 char ipaddr[HOSTIPLEN];
173
174 target_p = find_client(tname);
175
176 if (target_p && IsClient(target_p))
177 {
178 name = get_client_name(target_p, HIDE_IP);
179 /* Should this be sockhost? - stu */
180 irc_getnameinfo((struct sockaddr*)&target_p->localClient->ip,
181 target_p->localClient->ip.ss_len, ipaddr,
182 HOSTIPLEN, NULL, 0, NI_NUMERICHOST);
183 class_name = get_client_class(target_p);
184
185 if (IsOper(target_p))
186 {
187 if (ConfigFileEntry.hide_spoof_ips)
188 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
189 me.name, source_p->name, class_name, name,
190 (IsIPSpoof(target_p) ? "255.255.255.255" : ipaddr),
191 CurrentTime - target_p->lasttime,
192 CurrentTime - target_p->localClient->last);
193 else
194 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
195 me.name, source_p->name, class_name, name,
196 (IsIPSpoof(target_p) ? "255.255.255.255" : ipaddr),
197 CurrentTime - target_p->lasttime,
198 CurrentTime - target_p->localClient->last);
199 }
200 }
201
202 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
203 me.name, source_p->name, tname);
204 return;
205 }
206
207 /* report all opers */
208 DLINK_FOREACH(ptr, local_client_list.head)
209 {
210 target_p = ptr->data;
211
212 if (!IsOper(target_p))
213 continue;
214
215 if (!doall && wilds && !match(tname, target_p->name))
216 continue;
217
218 if (!dow && irccmp(tname, target_p->name))
219 continue;
220
221 report_this_status(source_p, target_p, dow);
222 }
223
224 /* report all servers */
225 DLINK_FOREACH(ptr, serv_list.head)
226 {
227 target_p = ptr->data;
228
229 if (!doall && wilds && !match(tname, target_p->name))
230 continue;
231 if (!dow && irccmp(tname, target_p->name))
232 continue;
233
234 report_this_status(source_p, target_p, dow);
235 }
236
237 sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0], tname);
238 }
239
240 /*
241 * mo_ltrace
242 * parv[0] = sender prefix
243 * parv[1] = servername
244 */
245 static void
246 mo_ltrace(struct Client *client_p, struct Client *source_p,
247 int parc, char *parv[])
248 {
249 if (!IsOper(source_p))
250 {
251 sendto_one(source_p, form_str(RPL_ENDOFTRACE), me.name, parv[0],
252 parc > 1 ? parv[1] : me.name);
253 return;
254 }
255
256 if (parc > 2)
257 if (hunt_server(client_p, source_p, ":%s LTRACE %s :%s", 2, parc, parv))
258 return;
259
260 #ifdef STATIC_MODULES
261 do_ltrace(source_p, parc, parv);
262 #else
263 execute_callback(ltrace_cb, source_p, parc, parv);
264 #endif
265 }
266
267 /*
268 * report_this_status
269 *
270 * inputs - pointer to client to report to
271 * - pointer to client to report about
272 * output - counter of number of hits
273 * side effects - NONE
274 */
275 static void
276 report_this_status(struct Client *source_p, struct Client *target_p,
277 int dow)
278 {
279 const char *name = NULL;
280 const char *class_name = NULL;
281 char ip[HOSTIPLEN];
282
283 /* Should this be sockhost? - stu */
284 irc_getnameinfo((struct sockaddr *)&target_p->localClient->ip,
285 target_p->localClient->ip.ss_len, ip,
286 HOSTIPLEN, NULL, 0, NI_NUMERICHOST);
287
288 name = get_client_name(target_p, HIDE_IP);
289 class_name = get_client_class(target_p);
290
291 switch (target_p->status)
292 {
293 case STAT_CONNECTING:
294 sendto_one(source_p, form_str(RPL_TRACECONNECTING), me.name,
295 source_p->name, class_name,
296 IsAdmin(source_p) ? name : target_p->name);
297 break;
298
299 case STAT_HANDSHAKE:
300 sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE), me.name,
301 source_p->name, class_name,
302 IsAdmin(source_p) ? name : target_p->name);
303 break;
304
305 case STAT_CLIENT:
306 if (IsAdmin(target_p))
307 {
308 if (ConfigFileEntry.hide_spoof_ips)
309 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
310 me.name, source_p->name, class_name, name,
311 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
312 CurrentTime - target_p->lasttime,
313 CurrentTime - target_p->localClient->last);
314 else
315 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
316 me.name, source_p->name, class_name, name,
317 IsAdmin(source_p) ? ip :
318 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
319 CurrentTime - target_p->lasttime,
320 CurrentTime - target_p->localClient->last);
321 }
322 else if (IsOper(target_p))
323 {
324 if (ConfigFileEntry.hide_spoof_ips)
325 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
326 me.name, source_p->name, class_name, name,
327 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
328 CurrentTime - target_p->lasttime,
329 CurrentTime - target_p->localClient->last);
330 else
331 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
332 me.name, source_p->name, class_name, name,
333 (IsIPSpoof(target_p) ? "255.255.255.255" : ip),
334 CurrentTime - target_p->lasttime,
335 CurrentTime - target_p->localClient->last);
336 }
337 break;
338
339 case STAT_SERVER:
340 {
341 int clients = 0;
342 int servers = 0;
343
344 trace_get_dependent(&servers, &clients, target_p);
345
346 if (!IsAdmin(source_p))
347 name = get_client_name(target_p, MASK_IP);
348
349 sendto_one(source_p, form_str(RPL_TRACESERVER),
350 me.name, source_p->name, class_name, servers,
351 clients, name, *(target_p->serv->by) ?
352 target_p->serv->by : "*", "*",
353 me.name, CurrentTime - target_p->lasttime);
354 break;
355 }
356
357 case STAT_ME:
358 case STAT_UNKNOWN:
359 break;
360
361 default: /* ...we actually shouldn't come here... --msa */
362 sendto_one(source_p, form_str(RPL_TRACENEWTYPE), me.name,
363 source_p->name, name);
364 break;
365 }
366 }

Properties

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