summaryrefslogtreecommitdiff
path: root/src/cmd_whois.cpp
blob: d21c86202c366a54b525968bad9b0199d7a4552d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*       +------------------------------------+
 *       | Inspire Internet Relay Chat Daemon |
 *       +------------------------------------+
 *
 *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
 * See: http://www.inspircd.org/wiki/index.php/Credits
 *
 * This program is free but copyrighted software; see
 *            the file COPYING for details.
 *
 * ---------------------------------------------------
 */

#include "inspircd.h"
#include "configreader.h"
#include "users.h"
#include "modules.h"
#include "commands/cmd_whois.h"
#include "hashcomp.h"

void do_whois(InspIRCd* ServerInstance, userrec* user, userrec* dest,unsigned long signon, unsigned long idle, const char* nick)
{
	if (dest->Visibility && !dest->Visibility->VisibleTo(user))
	{
		ServerInstance->SendWhoisLine(user, dest, 401, "%s %s :No such nick/channel",user->nick, *nick ? nick : "*");
		ServerInstance->SendWhoisLine(user, dest, 318, "%s %s :End of /WHOIS list.",user->nick, *nick ? nick : "*");
		return;
	}

	if (dest->registered == REG_ALL)
	{
		ServerInstance->SendWhoisLine(user, dest, 311, "%s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname);
		if ((user == dest) || (*user->oper))
		{
			ServerInstance->SendWhoisLine(user, dest, 378, "%s %s :is connecting from %s@%s %s", user->nick, dest->nick, dest->ident, dest->host, dest->GetIPString());
		}

		std::string cl = dest->ChannelList(user);

		if (cl.length())
		{
			if (cl.length() > 400)
			{
				user->SplitChanList(dest,cl);
			}
			else
			{
				ServerInstance->SendWhoisLine(user, dest, 319, "%s %s :%s",user->nick, dest->nick, cl.c_str());
			}
		}
		if (*ServerInstance->Config->HideWhoisServer && !(*user->oper))
		{
			ServerInstance->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick, dest->nick, ServerInstance->Config->HideWhoisServer, ServerInstance->Config->Network);
		}
		else
		{
			ServerInstance->SendWhoisLine(user, dest, 312, "%s %s %s :%s",user->nick, dest->nick, dest->server, ServerInstance->GetServerDescription(dest->server).c_str());
		}

		if (*dest->awaymsg)
		{
			ServerInstance->SendWhoisLine(user, dest, 301, "%s %s :%s",user->nick, dest->nick, dest->awaymsg);
		}

		if (*dest->oper)
		{
			ServerInstance->SendWhoisLine(user, dest, 313, "%s %s :is %s %s on %s",user->nick, dest->nick, (strchr("AEIOUaeiou",*dest->oper) ? "an" : "a"),irc::Spacify(dest->oper), ServerInstance->Config->Network);
		}

		FOREACH_MOD(I_OnWhois,OnWhois(user,dest));

		/*
		 * We only send these if we've been provided them. That is, if hidewhois is turned off, and user is local, or
		 * if remote whois is queried, too. This is to keep the user hidden, and also since you can't reliably tell remote time. -- w00t
		 */
		if ((idle) || (signon))
		{
			ServerInstance->SendWhoisLine(user, dest, 317, "%s %s %d %d :seconds idle, signon time",user->nick, dest->nick, idle, signon);
		}

		ServerInstance->SendWhoisLine(user, dest, 318, "%s %s :End of /WHOIS list.",user->nick, dest->nick);
	}
	else
	{
		ServerInstance->SendWhoisLine(user, dest, 401, "%s %s :No such nick/channel",user->nick, *nick ? nick : "*");
		ServerInstance->SendWhoisLine(user, dest, 318, "%s %s :End of /WHOIS list.",user->nick, *nick ? nick : "*");
	}
}



extern "C" command_t* init_command(InspIRCd* Instance)
{
	return new cmd_whois(Instance);
}

CmdResult cmd_whois::Handle (const char** parameters, int pcnt, userrec *user)
{
	userrec *dest;
	unsigned long idle = 0, signon = 0;

	if (ServerInstance->Parser->LoopCall(user, this, parameters, pcnt, 0))
		return CMD_SUCCESS;

	dest = ServerInstance->FindNick(parameters[0]);

	if (dest)
	{
		/*
		 * Determine whether to show idletime. We show it if:
		 * If user is local and hidewhois is turned off, or
		 * param[0] == param[1].
		 *
		 * The assumption here (not a huge one) is that cmd_whois is only ever invoked
		 * remotely! Keep that in mind! -- w00t
		 */
		if ((IS_LOCAL(dest) && !*ServerInstance->Config->HideWhoisServer) || pcnt > 1)
		{
			if (pcnt > 1)
			{
				/*
				 * if it looks like a remote whois, make sure it is one.
				 * this stops things like /whois foo bar to get foo's
				 * idletime without a proper remote request. -- w00t
				 */
				if (!strcmp(parameters[0], parameters[1]))
				{
					/* this really is safe, we're only called for local users .. */
					idle = abs((dest->idle_lastmsg)-ServerInstance->Time());
					signon = dest->signon;
				}
			}
		}

		do_whois(this->ServerInstance, user,dest,signon,idle,parameters[0]);
	}
	else
	{
		/* no such nick/channel */
		user->WriteServ("401 %s %s :No such nick/channel",user->nick, *parameters[0] ? parameters[0] : "*");
		user->WriteServ("318 %s %s :End of /WHOIS list.",user->nick, *parameters[0] ? parameters[0] : "*");
		return CMD_FAILURE;
	}

	return CMD_SUCCESS;
}