]>
Commit | Line | Data |
---|---|---|
7bec4aeb | 1 | /* whois.c */ |
2 | ||
3 | #include "miscreply.h" | |
7bec4aeb | 4 | #include "../irc/irc.h" |
5 | #include "../core/error.h" | |
6 | #include "../core/hooks.h" | |
a7697869 | 7 | #include "../server/server.h" |
7bec4aeb | 8 | |
9 | #include <string.h> | |
10 | ||
11 | ||
12 | ||
a7697869 | 13 | /* do whois |
7bec4aeb | 14 | * |
15 | */ | |
a7697869 | 16 | static void do_whois(char *sourcenum, nick *snick, nick *tnick) { |
17 | ||
18 | void *nicks[3]; /* nick array for whois channels hook */ | |
7bec4aeb | 19 | |
7bec4aeb | 20 | |
a7697869 | 21 | /* user |
22 | * | |
23 | * 311 RPL_WHOISUSER "source 311 target nick user host * :realname" | |
24 | * "irc.netsplit.net 311 foobar bar foo host.com * :foobar" | |
25 | */ | |
26 | /* sethost (usermode +h) */ | |
27 | if (IsSetHost(tnick)) { | |
28 | irc_send("%s 311 %s %s %s %s * :%s", getmynumeric(), sourcenum, tnick->nick, | |
29 | tnick->shident->content, tnick->sethost->content, tnick->realname->name->content); | |
30 | /* account and hiddenhost (usermode +rx) */ | |
31 | } else if (IsAccount(tnick) && IsHideHost(tnick)) { | |
32 | irc_send("%s 311 %s %s %s %s.%s * :%s", getmynumeric(), sourcenum, tnick->nick, | |
33 | tnick->ident, tnick->authname, HIS_HIDDENHOST, tnick->realname->name->content); | |
34 | /* not hidden */ | |
35 | } else { | |
36 | irc_send("%s 311 %s %s %s %s * :%s", getmynumeric(), sourcenum, tnick->nick, | |
37 | tnick->ident, tnick->host->name->content, tnick->realname->name->content); | |
38 | } | |
7bec4aeb | 39 | |
40 | ||
a7697869 | 41 | /* channels |
42 | * show channels only when | |
43 | * target user is not a service (usermode +k) AND | |
44 | * target user is not hidechan (usermode +n) | |
45 | * OR user WHOIS'ing himself | |
46 | */ | |
42d7af35 | 47 | if ((!IsService(tnick) && !IsHideChan(tnick) && canseeuser(snick, tnick)) || snick == tnick) { |
a7697869 | 48 | nicks[0] = (char *)snick; |
49 | nicks[1] = (char *)tnick; | |
50 | nicks[2] = sourcenum; | |
51 | triggerhook(HOOK_NICK_WHOISCHANNELS, nicks); | |
7bec4aeb | 52 | } |
53 | ||
7bec4aeb | 54 | |
a7697869 | 55 | /* server |
7bec4aeb | 56 | * |
a7697869 | 57 | * 312 RPL_WHOISSERVER "source 312 target nick server :description" |
58 | * "irc.netsplit.net 312 foobar barfoo *.netsplit.net :Netsplit Server" | |
7bec4aeb | 59 | */ |
a7697869 | 60 | /* show server and description when |
61 | * user WHOIS'ing himself, OR to an IRC Operator, OR when HIS_SERVER is 0 | |
62 | */ | |
63 | if (snick == tnick || IsOper(snick) || !HIS_SERVER) { | |
64 | irc_send("%s 312 %s %s %s :%s", getmynumeric(), sourcenum, tnick->nick, | |
65 | serverlist[homeserver(tnick->numeric)].name->content, | |
66 | serverlist[homeserver(tnick->numeric)].description->content); | |
67 | /* show HIS server and description */ | |
68 | } else { | |
69 | irc_send("%s 312 %s %s %s :%s", getmynumeric(), sourcenum, tnick->nick, | |
70 | HIS_SERVERNAME, | |
71 | HIS_SERVERDESC); | |
72 | } | |
7bec4aeb | 73 | |
7bec4aeb | 74 | |
a7697869 | 75 | /* target user is away */ |
76 | if ((tnick)->away) { | |
77 | /* | |
78 | * 301 RPL_AWAY "source 301 target nick :awaymsg" | |
79 | * "irc.netsplit.net 301 foobar barfoo :afk." | |
7bec4aeb | 80 | */ |
a7697869 | 81 | irc_send("%s 301 %s %s :%s", getmynumeric(), sourcenum, tnick->nick, tnick->away->content); |
82 | } | |
7bec4aeb | 83 | |
84 | ||
a7697869 | 85 | /* target user is an IRC Operator */ |
86 | if (IsOper(tnick)) { | |
87 | /* | |
88 | * 313 RPL_WHOISOPERATOR "source 313 target nick :is an IRC Operator" | |
89 | * "irc.netsplit.net 313 foobar barfoo :is an IRC Operator" | |
7bec4aeb | 90 | */ |
a7697869 | 91 | irc_send("%s 313 %s %s :is an IRC Operator", getmynumeric(), sourcenum, tnick->nick); |
7bec4aeb | 92 | |
a7697869 | 93 | /* source user is an IRC Operator, show opername if we have it */ |
94 | if (IsOper(snick) && (tnick->opername && strcmp(tnick->opername->content, "-"))) | |
95 | /* | |
96 | * 343 RPL_WHOISOPERNAME "source 343 target nick opername :is opered as" | |
97 | * "irc.netsplit.net 343 foobar barfoo fish :is opered as" | |
98 | * | |
99 | * note: snircd extension | |
100 | */ | |
101 | irc_send("%s 343 %s %s %s :is opered as", getmynumeric(), sourcenum, tnick->nick, tnick->opername->content); | |
102 | } | |
7bec4aeb | 103 | |
7bec4aeb | 104 | |
105 | ||
a7697869 | 106 | /* target user got an account (usermode +r) */ |
107 | if (IsAccount(tnick)) { | |
108 | /* | |
109 | * 330 RPL_WHOISACCOUNT "source 330 target nick account :is authed as" | |
110 | * "irc.netsplit.net 330 foobar barfoo fish :is authed as" | |
7bec4aeb | 111 | * |
a7697869 | 112 | * note: ircu shows "is logged in as" as text |
7bec4aeb | 113 | */ |
a7697869 | 114 | irc_send("%s 330 %s %s %s :is authed as", getmynumeric(), sourcenum, tnick->nick, tnick->authname); |
115 | } | |
7bec4aeb | 116 | |
7bec4aeb | 117 | |
118 | ||
a7697869 | 119 | /* target user got a sethost (usermode +h) or has a hiddenhost (usermode +rx) |
120 | * show real host to user WHOIS'ing himself and to an IRC Operator | |
121 | */ | |
122 | if ((snick == tnick || IsOper(snick)) && (IsSetHost(tnick) || (IsAccount(tnick) && IsHideHost(tnick)) )) { | |
123 | /* | |
124 | * 338 RPL_WHOISACTUALLY "source 338 target nick user@host IP :Actual user@host, Actual IP" | |
125 | * "irc.netsplit.net 338 foobar barfoo foobar@localhost 127.0.0.1 :Actual user@host, Actual IP" | |
126 | */ | |
127 | irc_send("%s 338 %s %s %s@%s %s :Actual user@host, Actual IP", getmynumeric(), sourcenum, tnick->nick, | |
fdcb5d66 | 128 | tnick->ident, tnick->host->name->content, IPtostr(tnick->ipaddress)); |
a7697869 | 129 | } |
7bec4aeb | 130 | |
131 | ||
132 | ||
a7697869 | 133 | /* my user, |
134 | * AND not a service (usermode +k), AND not hiding idle time (usermode +I) | |
135 | * show idle and signon time | |
136 | */ | |
137 | if (mylongnum == homeserver(tnick->numeric) && !IsService(tnick) && !IsHideIdle(tnick)) { | |
138 | /* | |
139 | * 317 RPL_WHOISIDLE "source 317 target nick idle signon :seconds idle, signon time" | |
140 | * "irc.netsplit.net 317 foobar barfoo 5 1084458353" | |
141 | */ | |
142 | irc_send("%s 317 %s %s %ld %ld :seconds idle, signon time", getmynumeric(), sourcenum, tnick->nick, | |
143 | (getnettime() - tnick->timestamp) % (((tnick->numeric + tnick->timestamp) % 983) + 7), tnick->timestamp); | |
144 | } | |
145 | } | |
7bec4aeb | 146 | |
147 | ||
148 | ||
a7697869 | 149 | /* handle remote whois request |
150 | * | |
151 | * <source numeric> WHOIS/W <target server numeric> <nick> | |
152 | * | |
153 | * cargv[0] = target server numeric | |
154 | * cargv[1] = nick as given by source | |
155 | * comma separated list of one or more nicks, may contain wildcards | |
156 | * ircu does not do wildcard matches for remote whois, we dont either | |
157 | * | |
158 | */ | |
159 | int handlewhoismsg(void *source, int cargc, char **cargv) { | |
7bec4aeb | 160 | |
a7697869 | 161 | nick *snick; /* struct nick for source nick */ |
162 | nick *tnick; /* struct nick for target nick */ | |
163 | char *sourcenum = (char *)source; /* source user numeric */ | |
164 | char nicks[BUFSIZE]; /* nick parameter */ | |
165 | char *nick; /* loop nick */ | |
7bec4aeb | 166 | |
a7697869 | 167 | /* check parameters */ |
168 | if (cargc < 2) { | |
169 | miscreply_needmoreparams(sourcenum, "WHOIS"); | |
170 | return CMD_OK; | |
171 | } | |
7bec4aeb | 172 | |
a7697869 | 173 | /* get the parameters */ |
174 | strcpy(nicks, cargv[1]); | |
7bec4aeb | 175 | |
a7697869 | 176 | /* find source user */ |
177 | if (!(snick = miscreply_finduser(sourcenum, "WHOIS"))) | |
178 | return CMD_OK; | |
7bec4aeb | 179 | |
a7697869 | 180 | /* go through the list of nicks */ |
181 | for (nick = strtok(nicks, ","); nick != NULL; nick = strtok(NULL, ",")) { | |
7bec4aeb | 182 | |
a7697869 | 183 | /* find the target */ |
184 | if (!(tnick = getnickbynick(nick))) { | |
185 | /* | |
186 | * 401 ERR_NOSUCHNICK "source 401 target nick :No such nick" | |
187 | * "irc.netsplit.net 391 foobar barfoo :No such nick" | |
7bec4aeb | 188 | */ |
a7697869 | 189 | irc_send("%s 401 %s %s :No such nick", getmynumeric(), sourcenum, nick); |
7bec4aeb | 190 | } |
a7697869 | 191 | |
192 | else | |
193 | do_whois(sourcenum, snick, tnick); | |
7bec4aeb | 194 | } |
195 | ||
196 | ||
197 | /* end of | |
198 | * | |
199 | * 318 RPL_ENDOFWHOIS "source 318 target nick :End of /WHOIS list." | |
200 | * "irc.netsplit.net 318 foobar barfoo :End of /WHOIS list." | |
201 | */ | |
a7697869 | 202 | irc_send("%s 318 %s %s :End of /WHOIS list.", getmynumeric(), sourcenum, cargv[1]); |
7bec4aeb | 203 | |
204 | return CMD_OK; | |
205 | } |