Merged rev 838,888,890,894,899,900,902-904,926,934,963,984-989 from crox's branch:

- Changes to specfile
- define PATH_MAX and RTLD_LOCAL if not defines
- compile fixes
- SetFileName should not set m_iFD
- check for cygwin and do not use -fPIC
- replaced if ... elif with case in configure.in
- handle 437 reply code
- allow disabled channels
- use strerror() in CIRCSock::SockError()
- added GetUser() to CClient and CIRCSock
- added support for traffic accounting
- added names to timers


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@806 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2007-05-17 19:09:17 +00:00
parent 4f7b904651
commit b772e2664e
16 changed files with 168 additions and 21 deletions
+3 -1
View File
@@ -21,8 +21,10 @@ CChan::CChan(const CString& sName, CUser* pUser, bool bInConfig) {
m_bDetached = false;
m_uBufferCount = m_pUser->GetBufferCount();
m_bKeepBuffer = m_pUser->KeepBuffer();
m_bDisabled = false;
Reset();
}
CChan::~CChan() {
ClearNicks();
}
@@ -155,7 +157,7 @@ CString CChan::GetModeString() const {
}
}
return (sModes.empty()) ? sModes : ("+" + sModes + sArgs);
return sModes.empty() ? sModes : CString("+" + sModes + sArgs);
}
CString CChan::GetModeForNames() const {
+4
View File
@@ -111,6 +111,8 @@ public:
void SetDetached(bool b = true) { m_bDetached = b; }
void SetInConfig(bool b) { m_bInConfig = b; }
void SetCreationDate(unsigned long u) { m_ulCreationDate = u; }
void Disable() { m_bDisabled = true; }
void Enable() { m_bDisabled = false; }
// !Setters
// Getters
@@ -137,6 +139,7 @@ public:
bool IsDetached() const { return m_bDetached; }
bool InConfig() const { return m_bInConfig; }
unsigned long GetCreationDate() const { return m_ulCreationDate; }
bool IsDisabled() const { return m_bDisabled; }
// !Getters
private:
protected:
@@ -146,6 +149,7 @@ protected:
bool m_bKeepBuffer;
bool m_bAutoCycle;
bool m_bInConfig;
bool m_bDisabled;
CString m_sName;
CString m_sKey;
CString m_sCurKey;
+71 -1
View File
@@ -9,6 +9,17 @@
#include "DCCSock.h"
#include "Server.h"
CClient::~CClient() {
if (!m_spAuth.IsNull()) {
CClientAuth* pAuth = (CClientAuth*) &(*m_spAuth);
pAuth->SetClient(NULL);
}
if (m_pUser != NULL) {
m_pUser->AddBytesRead(GetBytesRead());
m_pUser->AddBytesWritten(GetBytesWritten());
}
}
void CClient::ReadLine(const CString& sData) {
CString sLine = sData;
@@ -765,6 +776,21 @@ void CClient::UserCommand(const CString& sLine) {
return;
}
}
} else if (sCommand.CaseCmp("ENABLECHAN") == 0) {
CString sChan = sLine.Token(1, true);
if (sChan.empty()) {
PutStatus("Usage: EnableChan <channel>");
} else {
CChan* pChan = m_pUser->FindChan(sChan);
if (!pChan) {
PutStatus("Channel [" + sChan + "] not found.");
return;
}
pChan->Enable();
PutStatus("Channel [" + sChan + "] enabled.");
}
} else if (sCommand.CaseCmp("LISTCHANS") == 0) {
if (m_pUser) {
const vector<CChan*>& vChans = m_pUser->GetChans();
@@ -794,7 +820,7 @@ void CClient::UserCommand(const CString& sLine) {
CChan* pChan = vChans[a];
Table.AddRow();
Table.SetCell("Name", pChan->GetPermStr() + pChan->GetName());
Table.SetCell("Status", ((vChans[a]->IsOn()) ? ((vChans[a]->IsDetached()) ? "Detached" : "Joined") : "Trying"));
Table.SetCell("Status", ((vChans[a]->IsOn()) ? ((vChans[a]->IsDetached()) ? "Detached" : "Joined") : ((vChans[a]->IsDisabled()) ? "Disabled" : "Trying")));
Table.SetCell("Conf", CString((pChan->InConfig()) ? "yes" : ""));
Table.SetCell("Buf", CString((pChan->KeepBuffer()) ? "*" : "") + CString(pChan->GetBufferCount()));
Table.SetCell("Modes", pChan->GetModeString());
@@ -1320,6 +1346,50 @@ void CClient::UserCommand(const CString& sLine) {
pChan->SetBufferCount(uLineCount);
PutStatus("BufferCount for [" + sChan + "] set to [" + CString(pChan->GetBufferCount()) + "]");
} else if (m_pUser->IsAdmin() && sCommand.CaseCmp("TRAFFIC") == 0) {
CZNC::Get().UpdateTrafficStats();
const map<CString, CUser*>& msUsers = CZNC::Get().GetUserMap();
CTable Table;
Table.AddColumn("Username");
Table.AddColumn("In");
Table.AddColumn("Out");
Table.AddColumn("Total");
unsigned long long users_total_in = 0;
unsigned long long users_total_out = 0;
for (map<CString, CUser*>::const_iterator it = msUsers.begin(); it != msUsers.end(); it++) {
Table.AddRow();
Table.SetCell("Username", it->first);
Table.SetCell("In", CString(it->second->BytesRead()));
Table.SetCell("Out", CString(it->second->BytesWritten()));
Table.SetCell("Total", CString(it->second->BytesRead() + it->second->BytesWritten()));
users_total_in += it->second->BytesRead();
users_total_out += it->second->BytesWritten();
}
Table.AddRow();
Table.SetCell("Username", "<Users>");
Table.SetCell("In", CString(users_total_in));
Table.SetCell("Out", CString(users_total_out));
Table.SetCell("Total", CString(users_total_in + users_total_out));
Table.AddRow();
Table.SetCell("Username", "<ZNC>");
Table.SetCell("In", CString(CZNC::Get().BytesRead()));
Table.SetCell("Out", CString(CZNC::Get().BytesWritten()));
Table.SetCell("Total", CString(CZNC::Get().BytesRead() + CZNC::Get().BytesWritten()));
Table.AddRow();
Table.SetCell("Username", "<Total>");
Table.SetCell("In", CString(users_total_in + CZNC::Get().BytesRead()));
Table.SetCell("Out", CString(users_total_out + CZNC::Get().BytesWritten()));
Table.SetCell("Total", CString(users_total_in + CZNC::Get().BytesRead() + users_total_out + CZNC::Get().BytesWritten()));
if (Table.size()) {
unsigned int uTableIdx = 0;
CString sLine;
while (Table.GetLine(uTableIdx++, sLine)) {
PutStatus(sLine);
}
}
} else {
PutStatus("Unknown command [" + sCommand + "] try 'Help'");
}
+2 -6
View File
@@ -67,12 +67,7 @@ public:
Init();
}
virtual ~CClient() {
if (!m_spAuth.IsNull()) {
CClientAuth* pAuth = (CClientAuth*) &(*m_spAuth);
pAuth->SetClient(NULL);
}
}
virtual ~CClient();
void Init() {
m_pUser = NULL;
@@ -120,6 +115,7 @@ public:
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
void SetNick(const CString& s);
CUser* GetUser() const { return m_pUser; }
private:
protected:
bool m_bAuthed;
+9 -1
View File
@@ -51,6 +51,8 @@ CIRCSock::~CIRCSock() {
PutIRC("QUIT :" + m_pUser->GetQuitMsg());
m_msChans.clear();
GetUser()->AddBytesRead(GetBytesRead());
GetUser()->AddBytesWritten(GetBytesWritten());
}
void CIRCSock::ReadLine(const CString& sData) {
@@ -156,6 +158,12 @@ void CIRCSock::ReadLine(const CString& sData) {
}
break;
case 437:
// :irc.server.net 437 * badnick :Nick/channel is temporarily unavailable
// :irc.server.net 437 mynick badnick :Nick/channel is temporarily unavailable
// :irc.server.net 437 mynick badnick :Cannot change nickname while banned on channel
if (m_pUser->IsChan(sRest.Token(0)) || sNick != "*")
break;
case 433: {
unsigned int uMax = GetMaxNickLen();
CString sBadNick = sRest.Token(0);
@@ -873,7 +881,7 @@ void CIRCSock::Disconnected() {
void CIRCSock::SockError(int iErrno) {
DEBUG_ONLY(cout << GetSockName() << " == SockError(" << iErrno << ")" << endl);
if (!m_pUser->IsBeingDeleted()) {
m_pUser->PutStatus("Disconnected from IRC. Reconnecting...");
m_pUser->PutStatus("Disconnected from IRC (" + CString(strerror(iErrno)) + "). Reconnecting...");
}
m_pUser->ClearRawBuffer();
m_pUser->ClearMotdBuffer();
+1
View File
@@ -66,6 +66,7 @@ public:
const CString& GetNick() const { return m_Nick.GetNick(); }
const CString& GetPass() const { return m_sPass; }
bool IsOrigNickPending() const { return m_bOrigNickPending; }
CUser* GetUser() const { return m_pUser; }
bool HasNamesx() const { return m_bNamesx; }
bool HasUHNames() const { return m_bUHNames; }
const set<unsigned char>& GetUserModes() const { return m_scUserModes; }
+5
View File
@@ -25,6 +25,11 @@ using std::set;
#endif
#endif
#ifndef RTLD_LOCAL
# define RTLD_LOCAL 0
# warning "your crap box doesnt define RTLD_LOCAL !?"
#endif
#define MODCONSTRUCTOR(CLASS) \
CLASS(void *pDLL, CUser* pUser, const CString& sModName) : CModule(pDLL, pUser, sModName)
#define MODULEDEFS(CLASS, DESCRIPTION) \
+1 -1
View File
@@ -36,5 +36,5 @@ bool CServer::IsSSL() const { return m_bSSL; }
bool CServer::IsIPV6() const { return m_bIPV6; }
CString CServer::GetString() const {
return m_sName + " " + CString(m_bSSL ? "+" : "") + CString(m_uPort) + CString(m_sPass.empty() ? CString("") : " " + m_sPass);
return m_sName + " " + CString(m_bSSL ? "+" : "") + CString(m_uPort) + CString(m_sPass.empty() ? "" : " " + m_sPass);
}
+3
View File
@@ -10,6 +10,7 @@ public:
CKeepNickTimer(CUser* pUser) : CCron() {
m_pUser = pUser;
m_uTrys = 0;
SetName("CKeepNickTimer::" + m_pUser->GetUserName());
Start(5);
}
virtual ~CKeepNickTimer() {}
@@ -37,6 +38,7 @@ class CMiscTimer : public CCron {
public:
CMiscTimer(CUser* pUser) : CCron() {
m_pUser = pUser;
SetName("CMiscTimer::" + m_pUser->GetUserName());
Start(30);
}
virtual ~CMiscTimer() {}
@@ -67,6 +69,7 @@ class CJoinTimer : public CCron {
public:
CJoinTimer(CUser* pUser) : CCron() {
m_pUser = pUser;
SetName("CJoinTimer::" + m_pUser->GetUserName());
Start(20);
}
virtual ~CJoinTimer() {}
+3 -1
View File
@@ -19,6 +19,8 @@ CUser::CUser(const CString& sUserName) {
m_sIdent = m_sCleanUserName;
m_sRealName = sUserName;
m_uServerIdx = 0;
m_uBytesRead = 0;
m_uBytesWritten = 0;
#ifdef _MODULES
m_pModules = new CModules;
#endif
@@ -615,7 +617,7 @@ CChan* CUser::FindChan(const CString& sName) const {
void CUser::JoinChans() {
for (unsigned int a = 0; a < m_vChans.size(); a++) {
CChan* pChan = m_vChans[a];
if (!pChan->IsOn()) {
if (!pChan->IsOn() && !pChan->IsDisabled()) {
PutIRC("JOIN " + pChan->GetName() + " " + pChan->GetKey());
}
}
+7
View File
@@ -106,6 +106,9 @@ public:
bool Clone(const CUser& User, CString& sErrorRet);
void BounceAllClients();
void AddBytesRead(unsigned long long u) { m_uBytesRead += u; }
void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; }
// Setters
void SetUserName(const CString& s);
void SetNick(const CString& s);
@@ -181,6 +184,8 @@ public:
bool IsBeingDeleted() const { return m_bBeingDeleted; }
bool HasServers() const { return m_vServers.size() > 0; }
float GetTimezoneOffset() const { return m_fTimezoneOffset; }
unsigned long long BytesRead() const { return m_uBytesRead; }
unsigned long long BytesWritten() const { return m_uBytesWritten; }
// !Getters
private:
protected:
@@ -235,6 +240,8 @@ protected:
set<CString> m_ssAllowedHosts;
unsigned int m_uServerIdx;
unsigned int m_uBufferCount;
unsigned long long m_uBytesRead;
unsigned long long m_uBytesWritten;
#ifdef _MODULES
CModules* m_pModules;
+17 -4
View File
@@ -2,9 +2,11 @@ dnl Keep the version number in sync with main.h!
AC_INIT([znc], [0.048])
AC_PROG_CXX
AC_CANONICAL_HOST
CXXFLAGS="-D_GNU_SOURCE"
INCLUDES=""
LIBS=""
function appendLib {
if test "$LIBS" != ""; then
LIBS="$LIBS $*"
@@ -37,16 +39,27 @@ function appendLD {
fi
}
if `echo $host_os | grep -i 'freebsd' >/dev/null 2>/dev/null`; then
case "${host_os}" in
freebsd*)
appendInc -I/usr/local/include
appendLib -L/usr/local/lib -lcompat
appendCXX -D__GNU_LIBRARY__
elif `echo $host_os | grep -i 'sol' >/dev/null 2>/dev/null`; then
;;
solaris*)
appendLib -lsocket -lnsl
ISSUN=1
fi
;;
cygwin)
ISCYGWIN=1
;;
esac
appendCXX -fPIC
# cygwin
# warning: -fPIC ignored for target (all code is position independent)
if test -z "$ISCYGWIN" ; then
appendCXX -fPIC
fi
AC_ARG_WITH( [openssl],
AC_HELP_STRING([--with-openssl=/path/to/openssl], []),
+4
View File
@@ -47,6 +47,10 @@ using std::cout;
using std::cerr;
using std::endl;
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#include "String.h"
#include "Csocket.h"
#include "Utils.h"
+23
View File
@@ -22,6 +22,8 @@ CZNC::CZNC() {
m_pISpoofLockFile = NULL;
m_uiConnectDelay = 30;
SetISpoofFormat(""); // Set ISpoofFormat to default
m_uBytesRead = 0;
m_uBytesWritten = 0;
}
CZNC::~CZNC() {
@@ -110,6 +112,8 @@ int CZNC::Loop() {
#ifdef _MODULES
pUser->DelModules();
#endif
AddBytesRead(pUser->BytesRead());
AddBytesWritten(pUser->BytesWritten());
delete pUser;
}
@@ -1303,3 +1307,22 @@ CZNC& CZNC::Get() {
return *pZNC;
}
void CZNC::UpdateTrafficStats() {
CSockManager* p = &m_Manager;
for (unsigned int a = 0; a < p->size(); a++) {
if ((*p)[a]->GetSockName().Left(5) == "IRC::") {
CIRCSock *i = (CIRCSock *)(*p)[a];
i->GetUser()->AddBytesRead((*p)[a]->GetBytesRead());
(*p)[a]->ResetBytesRead();
i->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten());
(*p)[a]->ResetBytesWritten();
} else if ((*p)[a]->GetSockName().Left(5) == "USR::") {
CClient *c = (CClient *)(*p)[a];
c->GetUser()->AddBytesRead((*p)[a]->GetBytesRead());
(*p)[a]->ResetBytesRead();
c->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten());
(*p)[a]->ResetBytesWritten();
}
}
}
+7
View File
@@ -106,6 +106,11 @@ public:
bool AddVHost(const CString& sHost);
bool RemVHost(const CString& sHost);
void Broadcast(const CString& sMessage, CUser* pUser = NULL);
void AddBytesRead(unsigned long long u) { m_uBytesRead += u; }
void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; }
unsigned long long BytesRead() const { return m_uBytesRead; }
unsigned long long BytesWritten() const { return m_uBytesWritten; }
void UpdateTrafficStats();
// Setters
void SetStatusPrefix(const CString& s) { m_sStatusPrefix = (s.empty()) ? "*" : s; }
@@ -179,6 +184,8 @@ protected:
#ifdef _MODULES
CGlobalModules* m_pModules;
#endif
unsigned long long m_uBytesRead;
unsigned long long m_uBytesWritten;
};
class CListener {
+8 -6
View File
@@ -1,22 +1,22 @@
Name: znc
Version: 0.046
Version: 0.048
Release: 1
Packager: imaginos@imaginos.net
Summary: znc
Summary: znc - an advanced IRC bouncer
License: GPL
Group: none
Group: Applications/Communications
URL: http://sourceforge.net/projects/znc/
BuildRequires: gcc >= 3.2
BuildRequires: openssl >= 0.9.7d
BuildRoot: /tmp/znc-TMP/
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Prefix: /usr
Source: znc-%{version}.tar.gz
Source: %{name}-%{version}.tar.gz
%description
ZNC is an IRC bounce with many advanced features like detaching, multiple users, per channel playback buffer, SSL, transparent DCC bouncing, and c++ module support to name a few.
%prep
%setup -n znc-%{version}
%setup -n %{name}-%{version}
%build
./configure --prefix=%{prefix}
@@ -30,5 +30,7 @@ make install DESTDIR=$RPM_BUILD_ROOT
%files
%doc AUTHORS
%doc docs/*.html docs/*.txt docs/*.pm
%{prefix}