ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/contrib/m_ltrace.c
Revision: 1011
Committed: Fri Sep 18 10:14:09 2009 UTC (14 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 9941 byte(s)
Log Message:
- move list manipulation routines from tools.c to list.c
- mem_frob() goes to memory.c
- sort out redundant/unneeded header includes

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

Properties

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