summaryrefslogtreecommitdiff
path: root/src/cmd_whois.cpp
blob: d86360df63ae7b5aa69788b424a422e0fbce5d32 (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
/*       +------------------------------------+
 *       | 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 hidewhois is turned off.
		 * spanningtree deals with 2 param whois, and remote users, so this is all we need to do.
		 *
		 * The assumption here (not a huge one) is that cmd_whois is only ever invoked
		 * remotely! Keep that in mind! -- w00t
		 */
		if (!*ServerInstance->Config->HideWhoisServer)
		{
			/* 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;
}