]> jfr.im git - irc/quakenet/newserv.git/blame - miscreply/whois.c
CHANSERV: better batcher error handling for expired accounts/accounts with no email.
[irc/quakenet/newserv.git] / miscreply / whois.c
CommitLineData
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 16static 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 */
159int 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}