]>
Commit | Line | Data |
---|---|---|
7bec4aeb | 1 | /* trace.c */ |
2 | ||
3 | #include "miscreply.h" | |
7bec4aeb | 4 | #include "../core/error.h" |
5 | #include "../irc/irc.h" | |
6 | #include "../lib/irc_string.h" | |
7bec4aeb | 7 | #include "../server/server.h" |
8 | ||
9 | #include <string.h> | |
10 | ||
11 | ||
12 | ||
a7697869 | 13 | /* trace_user |
14 | * | |
7bec4aeb | 15 | */ |
a7697869 | 16 | static void trace_user(char *sourcenum, nick *tnick) { |
17 | if (IsOper(tnick)) { | |
18 | /* | |
19 | * 204 RPL_TRACEOPERATOR "source 204 target Oper class nick[user@IP] last_parse" | |
20 | * "irc.netsplit.net 204 foobar Oper barfoo[fish@127.0.0.1] 0" | |
21 | * | |
22 | * note: no info available on how long ago we last parsed something from this user -> 0 (not idle time) | |
23 | */ | |
24 | irc_send("%s 204 %s Oper opers %s[%s@%s] 0", getmynumeric(), sourcenum, tnick->nick, | |
25 | tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr)); | |
26 | } else { | |
27 | /* | |
28 | * 205 RPL_TRACEUSER "source 205 target User class nick[user@IP] last_parse" | |
29 | * "irc.netsplit.net 205 foobar User barfoo[fish@127.0.0.1] 0" | |
30 | */ | |
31 | irc_send("%s 205 %s User users %s[%s@%s] 0", getmynumeric(), sourcenum, tnick->nick, | |
32 | tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr)); | |
33 | } | |
34 | } | |
35 | ||
36 | ||
37 | ||
38 | /* trace_server | |
39 | * return number of matched servers | |
40 | */ | |
41 | static int trace_server(char *sourcenum, char *target, int doall) { | |
42 | ||
43 | /* do not show all and no match for my hub */ | |
44 | if (!doall && !match2strings(target, serverlist[myhub].name->content)) | |
45 | return 0; | |
46 | ||
47 | /* | |
48 | * 206 RPL_TRACESERVER "source 206 target Serv class NS NC server connected_by last_parse connected_for" | |
49 | * "irc.netsplit.net 206 foobar Server 2S 6C irc.netsplit.net *!user@host 34 92988" | |
50 | * | |
51 | * note: no info available on how many servers or clients are linked through this server link -> 0S 0C | |
52 | * no info available on who/what established the link, pretend it is by us -> *!*@myservername | |
53 | * no info available on how long ago we last parsed something from this link -> 0 | |
54 | * no info available on how long this server has been linked -> 0 | |
55 | */ | |
56 | irc_send("%s 206 %s Serv servers 0S 0C %s *!*@%s 0 0", getmynumeric(), sourcenum, | |
57 | serverlist[myhub].name->content, myserver->content); | |
58 | ||
59 | return 1; | |
60 | } | |
61 | ||
62 | ||
7bec4aeb | 63 | |
64 | /* handle remote trace request | |
65 | * | |
66 | * <source numeric> TRACE/TR <target> <target server numeric> | |
67 | * | |
68 | * cargv[0] = target | |
69 | * as given by source, can be a nick or a server (may contain wildcards) | |
70 | * cargv[1] = target server numeric | |
71 | * | |
72 | */ | |
73 | int handletracemsg(void *source, int cargc, char **cargv) { | |
74 | ||
a7697869 | 75 | nick *snick; /* struct nick for source nick */ |
76 | nick *tnick; /* struct nick for target nick */ | |
77 | nick **lnick; /* struct nick for looping local users */ | |
78 | int c; /* loop variable */ | |
79 | int opers = 0; /* number of operators */ | |
80 | int users = 0; /* number of users */ | |
81 | int servers = 0; /* number of servers */ | |
82 | int doall, wilds, dow; /* determine what to show */ | |
83 | char *sourcenum = (char *)source; /* source user numeric */ | |
84 | char *target; /* target parameter - as given by the source user */ | |
7bec4aeb | 85 | |
7bec4aeb | 86 | |
87 | /* check parameters */ | |
88 | if (cargc < 2) { | |
89 | miscreply_needmoreparams(sourcenum, "TRACE"); | |
90 | return CMD_OK; | |
91 | } | |
92 | ||
93 | /* get the parameters */ | |
94 | target = cargv[0]; | |
7bec4aeb | 95 | |
96 | /* find source user */ | |
97 | if (!(snick = miscreply_finduser(sourcenum, "TRACE"))) | |
98 | return CMD_OK; | |
99 | ||
a7697869 | 100 | /* doall, wilds, dow */ |
101 | doall = match2strings(target, myserver->content); | |
102 | wilds = strchr(target, '*') || strchr(target, '?'); | |
103 | dow = wilds || doall; | |
7bec4aeb | 104 | |
7bec4aeb | 105 | |
a7697869 | 106 | /* find target user */ |
107 | if ((tnick = getnickbynick(target))) { | |
108 | ||
109 | /* my user */ | |
110 | if (mylongnum == homeserver(tnick->numeric)) | |
111 | trace_user(sourcenum, tnick); | |
112 | } | |
113 | ||
114 | ||
115 | /* source user is an operator */ | |
116 | else if (IsOper(snick)) { | |
117 | ||
118 | /* show servers */ | |
119 | servers = trace_server(sourcenum, target, doall); | |
120 | ||
121 | /* do all or wilds */ | |
122 | if (dow) { | |
123 | ||
124 | /* loop over all local users */ | |
125 | lnick = servernicks[mylongnum]; | |
126 | for (c = 0; c < serverlist[mylongnum].maxusernum; c++) { | |
127 | ||
128 | if (lnick[c] == NULL) /* no user */ | |
7bec4aeb | 129 | continue; |
a7697869 | 130 | |
131 | /* target is invisible (mode +i), target is not an operator */ | |
132 | if (IsInvisible(lnick[c]) && dow && !IsOper(lnick[c])) | |
7bec4aeb | 133 | continue; |
a7697869 | 134 | |
135 | /* dont show all, do wildcards and no match */ | |
136 | if (!doall && wilds && !match2strings(target, lnick[c]->nick)) | |
7bec4aeb | 137 | continue; |
7bec4aeb | 138 | |
a7697869 | 139 | if (IsOper(lnick[c])) |
140 | opers++; | |
141 | else | |
142 | users++; | |
143 | trace_user(sourcenum, lnick[c]); | |
7bec4aeb | 144 | } |
a7697869 | 145 | /* |
146 | * class has no meaning here, | |
147 | * but showing the total count for users/opers/servers might be useful anyway | |
148 | * | |
149 | * 209 RPL_TRACECLASS "source 209 target Class class count" | |
150 | * "irc.netsplit.net 209 foobar Class users 2" | |
151 | */ | |
152 | if (users) | |
153 | irc_send("%s 209 %s Class users %d", getmynumeric(), sourcenum, users); | |
154 | if (opers) | |
155 | irc_send("%s 209 %s Class opers %d", getmynumeric(), sourcenum, opers); | |
156 | if (servers) | |
157 | irc_send("%s 209 %s Class servers %d", getmynumeric(), sourcenum, servers); | |
7bec4aeb | 158 | } |
159 | } | |
160 | ||
a7697869 | 161 | |
7bec4aeb | 162 | /* |
163 | * 262 RPL_TRACEEND "source 262 target :End of TRACE" | |
164 | * "irc.netsplit.net 262 foobar :End of TRACE" | |
165 | */ | |
a7697869 | 166 | irc_send("%s 262 %s :End of TRACE", getmynumeric(), sourcenum); |
7bec4aeb | 167 | |
168 | return CMD_OK; | |
169 | } |