forked from Efreak/ZNC-Modules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
whois.cpp
191 lines (172 loc) · 8.38 KB
/
whois.cpp
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
* Copyright (C) 2012 Efreak.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* I've aligned the version number with the version of ZNC it was last fixed
* to work with. If any other changes are made, update the version number to
* reflect it, please. This makes things easier for me; If someone else wants
* to take over maintenance, you're welcome to do so.
* -Efreak
*/
#include <znc/User.h>
#include <znc/IRCSock.h>
#include <znc/znc.h>
class CWhois : public CModule {
public:
MODCONSTRUCTOR(CWhois) {
m_bDev = false;
m_bReqAdmin = false;
m_bNumerics = true;
m_bServerName = false;
m_sServerName = "irc.znc.in";
}
virtual ~CWhois() {}
virtual bool OnLoad(const CString& sArgsStr, CString& sMessage) {
CString sArgs(sArgsStr);
while (sArgs.Left(1) == "-") {
CString sOpt = sArgs.Token(0);
sArgs = sArgs.Token(1, true);
if (sOpt.Equals("-REQADMIN")) {
m_bReqAdmin=true;
} else if (sOpt.Equals("-NONUMERICS")) {
m_bNumerics=false;
} else if (sOpt.Equals("-DEV")) {
m_bDev=true;
} else if (sOpt.Left(12).Equals("-SERVERNAME=")) {
m_bServerName=true;
m_sServerName=sOpt.Token(1,false,"=");
} else {
sMessage="Invalid Paramter specified: "+sOpt+". Valid parameters are: -reqadmin, -nonumerics, -dev, -servername=<name>";
return false;
}
}
return true;
}
virtual EModRet OnUserRaw(CString& sLine) {
if(sLine.Token(0).Equals("WHOIS")) {
CString sNick = sLine.Token(1);
if(sNick.Left(1)=="?") {
sNick = sNick.LeftChomp_n(1);
if (!m_pUser->IsAdmin() && m_bReqAdmin)
PutModule("Access denied");
else if(ZNCWhois(sNick)) return HALT;
}
} else if(sLine.Token(0).Equals("AWAY")) {
CString sReason = sLine.Token(1, true);
if(sReason.Left(1)==":") {
sReason = sReason.LeftChomp_n(1);
SetNV("Away"+m_pUser->GetUserName(),sReason);
}
}
return CONTINUE;
}
virtual void OnModCommand(const CString& sCommand) {
CString sCmd = sCommand.Token(0);
if (!m_pUser->IsAdmin()) {
PutModule("Access denied");
return;
}
PutModule("There are no commands yet");
}
private:
bool m_bDev;
bool m_bReqAdmin;
bool m_bNumerics;
bool m_bServerName;
CString m_sServerName;
bool ZNCWhois(CString& sUser) {
CUser *pUser = CZNC::Get().FindUser(sUser);
if(!pUser) {
PutModule("No such user!");
return false;
}
CString Username = pUser->GetUserName();
CString Nickname = pUser->GetNick();
CString Ident = pUser->GetIdent();
CString Server = (!m_pUser->IsAdmin() && m_bServerName ? m_sServerName : pUser->GetIRCServer()); //if whoiser isnt an admin, and the servername is defined, use it. otherwise grab the real server name.
CString VHost = pUser->GetBindHost();
CString RealName = pUser->GetRealName();
CString MyNick = m_pUser->GetNick();
bool Attached = pUser->IsUserAttached();
if(VHost=="") VHost = (m_bServerName ? m_sServerName : "irc.znc.in");
int SSL = 0; int total=0;
CString LastSeen = CString(time(NULL) - GetNV("LastSeen"+Username).ToInt());
CString Logon = CString(time(NULL) - GetNV("LastSeen"+Username).ToInt());
CString IP;
bool Away = pUser->IsIRCAway();
CString sAwayMsg = GetNV("Away"+pUser->GetUserName());
if(sAwayMsg != "") sAwayMsg = ": "+sAwayMsg;
vector<CClient*>& vClients = pUser->GetUserClients();
if (!vClients.empty()) {
for (unsigned int a = 0; a < vClients.size(); a++) {
total++;
if(vClients[a]->GetSSL()) SSL++;
}
}
if (!vClients.empty()) {
for (unsigned int a = 0; a < vClients.size(); a++) {
IP = IP + vClients[a]->GetRemoteIP() + " ";
}
}
CString rpl378 = ":irc.znc.in 378 " + MyNick + " ?" + Username + " :is connecting from *@";
CString rpl311 = ":irc.znc.in 311 " + MyNick + " ?" + Username + " " + Ident + " " + VHost + " " + " * :" + RealName;
CString rpl379 = ":irc.znc.in 379 " + MyNick + " ?" + Username + " :is using modes" +
(pUser->IsUserAttached() ? " +Attached" : " -Attached") + (pUser->IsIRCConnected() ? " +IRCConnected" : " -IRCConnected") +
(pUser->DenyLoadMod() ? " +DenyLoadMod" : " -DenyLoadMod") + (pUser->MultiClients() ? " +MultiClients" : " -MultiClients") +
(pUser->KeepBuffer() ? " +KeepBuffer" : " -KeepBuffer") + (!pUser->HasServers() ? " -HasServers":"") +
(!pUser->GetIRCConnectEnabled() ? " -IRCConnectEnabled":"");
CString rpl671;
if(SSL==1 && total==1) rpl671 = ":irc.znc.in 671 " + MyNick + " ?" + Username + " :is using a Secure Connection";
else rpl671 = ":irc.znc.in 671 " + MyNick + " ?" + Username + " :is using " + (CString)SSL + " Secure Connections out of " + (CString)total + " total connections";
CString rpl312 = ":irc.znc.in 312 " + MyNick + " ?" + Username + " " + Server + " :" + Username + " is" + (Attached ? " " : " \x02not\x02 ") +
"attached to " + (m_bServerName ? m_sServerName : "ZNC");
CString rpl301 = ":irc.znc.in 301 " + MyNick + " ?" + Username + " :?" + Username + " is away";
CString rpl313 = ":irc.znc.in 313 " + MyNick + " ?" + Username + " :is a ZNC Admin";
CString rpl317 = ":irc.znc.in 317 " + MyNick + " ?" + Username + " " + LastSeen + " " + Logon + " :seconds idle, signon time";
CString rpl318 = ":irc.znc.in 318 " + MyNick + " ?" + Username + " :End of /WHOIS list";
if(m_bDev || !m_bNumerics) {
PutModule(rpl311);
if(m_pUser->IsAdmin()) PutModule(rpl379);
if(m_pUser->IsAdmin()) PutModule(rpl378);
if(SSL>0) PutModule(rpl671);
if(Away)PutModule(rpl301);
PutModule(rpl312);
if(pUser->IsAdmin()) PutModule(rpl313);
PutModule(rpl318);
} if (m_bNumerics) { //not an else because of m_bDev
PutUser(rpl311); //rpl_whoisuser. Since we're on a bouncer, use ?Username!ident@VHost instead of nick@ident@host
if(m_pUser->IsAdmin()) PutUser(rpl379); //rpl_whoismodes. tell admins what options said user has (candcc, etc)
if(m_pUser->IsAdmin()) PutUser(rpl378); //rpl_whoishost. tell admins what host said user has
if(SSL>0) PutUser(rpl671); //rpl_ssl (?). is the user connected to ZNC via ssl?
if(Away)PutUser(rpl301); //rpl_away. is said user away?
PutUser(rpl312); //rpl_whoisserver. give the server the user is connected to. we don't know how to get the tagline, so lets just say we're connected via znc.
if(pUser->IsAdmin()) PutUser(rpl313); //rpl_whoisoperator. Is the user an admin on znc?
PutUser(rpl317); //rpl_whoisidle. tells the client the amount of time user has been idle, as well as the amt of time the client has been connected
PutUser(rpl318); //rpl_endofwhois. tells the client the whois data is done (why?)
}
return true;
}
virtual EModRet OnUserCTCP (CString &sTarget, CString &sMessage){ if(sTarget!=m_pUser->GetNick()) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL)));} return CONTINUE;}
virtual EModRet OnUserAction (CString &sTarget, CString &sMessage){ if(sTarget!=m_pUser->GetNick()) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL)));} return CONTINUE;}
virtual EModRet OnUserMsg (CString &sTarget, CString &sMessage){ if(sTarget!=m_pUser->GetNick()) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL)));} return CONTINUE;}
virtual EModRet OnUserNotice (CString &sTarget, CString &sMessage){ if(sTarget!=m_pUser->GetNick()) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL)));} return CONTINUE;}
virtual EModRet OnUserJoin (CString &sChannel, CString &sKey) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL))); return CONTINUE;}
virtual EModRet OnUserPart (CString &sChannel, CString &sMessage){ SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL))); return CONTINUE;}
virtual EModRet OnUserTopic (CString &sChannel, CString &sTopic) { SetNV("LastSeen"+m_pUser->GetUserName(),CString(time(NULL))); return CONTINUE;}
virtual void OnClientLogin () {SetNV("Login"+m_pUser->GetUserName(),CString(time(NULL)));}
virtual void OnClientDisconnect () {SetNV("Login"+m_pUser->GetUserName(),CString(time(NULL)));}
virtual EModRet OnAddUser(CUser& User, CString& sErrorRet) {
SetNV("LastSeen"+User.GetUserName(),CString(time(NULL)));
SetNV( "Login" + User.GetUserName(),CString(time(NULL)));
return CONTINUE;
}
};
template<> void TModInfo<CWhois>(CModInfo& Info) {
Info.SetWikiPage("whois");
Info.SetHasArgs(true);
Info.SetArgsHelpText("There are no arguments.");
}
GLOBALMODULEDEFS(CWhois, "Whois BNC users, with extra info for admin. Version 0.202")