|
|
|
//=================================================================================================
|
|
|
|
//
|
|
|
|
// File : kvi_regusersdb.cpp
|
|
|
|
// Creation date : Sat Sep 09 2000 15:46:12 by Szymon Stefanek
|
|
|
|
//
|
|
|
|
// This file is part of the KVirc irc client distribution
|
|
|
|
// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
|
|
|
|
//
|
|
|
|
// This program is FREE software. You can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
|
|
|
// as published by the Free Software Foundation; either version 2
|
|
|
|
// of the License, or (at your opinion) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
//
|
|
|
|
//=================================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
#define __KVILIB__
|
|
|
|
|
|
|
|
#include "kvi_debug.h"
|
|
|
|
|
|
|
|
#define _KVI_REGUSERDB_CPP_
|
|
|
|
#include "kvi_regusersdb.h"
|
|
|
|
|
|
|
|
#include "kvi_config.h"
|
|
|
|
#include "kvi_locale.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
@doc: registered_users
|
|
|
|
@title:
|
|
|
|
Registered users
|
|
|
|
@type:
|
|
|
|
generic
|
|
|
|
@short:
|
|
|
|
Registration of users in KVIrc
|
|
|
|
@keyterms:
|
|
|
|
registered users, registration mask, registered user properties,
|
|
|
|
user properties, notify property, avatar property
|
|
|
|
@body:
|
|
|
|
[big]Introduction[/big][br]
|
|
|
|
The "registered user database" is basically a set of users with associated
|
|
|
|
[doc:irc_masks]irc-masks[/doc] and properties.[br]
|
|
|
|
It is used to recognize users on IRC and associate properties to them.[br]
|
|
|
|
This works more or less like the IRC ban list, K-Line list, or invite list.[br]
|
|
|
|
[big]User entry[/big][br]
|
|
|
|
A registered user database entry is identified by an [b]unique[/b] name.[br]
|
|
|
|
It may be the nickname of the user that you want to match, or the real name (if you know it)
|
|
|
|
or any other string (even with spaces). The name is an "internal identifier" for the user entry:
|
|
|
|
each name maps to a single entry and each entry has a single name.[br]
|
|
|
|
Each entry has a set of registration [doc:irc_masks]irc-masks[/doc]: these masks
|
|
|
|
are used to recognize the user on irc.[br]
|
|
|
|
[br]
|
|
|
|
[big]Registration masks[/big][br]
|
|
|
|
The masks have the common IRC mask format: [b]<nick>!<user>@<host>[/b][br]
|
|
|
|
The masks may contain '*' and '?' wildcards that match any portion of text.[br]
|
|
|
|
[b]*!*@*[/b][br]
|
|
|
|
[b]Pragma!*@*[/b][br]
|
|
|
|
[b]*!~daemon@*[/b][br]
|
|
|
|
[b]Pragma!*daemon@*.it[/b][br]
|
|
|
|
[b]Pragma!?daemon@some*.it[/b][br]
|
|
|
|
[b]Pragma!~daemon@some.host.it[/b][br]
|
|
|
|
Are examples of valid registration masks.[br]
|
|
|
|
The masks with wildcards can actually match more than a single user.[br]
|
|
|
|
For example the mask *!root@*.host.com will match all the users
|
|
|
|
having root as username and coming from the host.com domain.[br]
|
|
|
|
For this reason putting wildcards in nicknames could become a problem
|
|
|
|
if not used carefully (but may also be used to achieve interesting tricks).[br]
|
|
|
|
If you don't use wildcards in nicknames you are sure that
|
|
|
|
in a single irc connection , a mask will always refer to a single user.[br]
|
|
|
|
You will commonly use the following format:[br]
|
|
|
|
<nick>!*<username>@*.<host>.<top>[br]
|
|
|
|
or[br]
|
|
|
|
<nick>!*<username>@<number>.<number>.<number>.*[br]
|
|
|
|
In this way you can be 95% sure that the mask will really match the correct user.[br]
|
|
|
|
[br]
|
|
|
|
[big]Example of registration and lookups[/big]
|
|
|
|
Assume that you want to registere a friend of yours: Derek Riggs.[br]
|
|
|
|
Derek often uses "Eddie" as his nickname
|
|
|
|
"stranger" as username and has a dial-up connection that makes his IP address appear as
|
|
|
|
<variable-number>.somewhere.in.time.org.[br]
|
|
|
|
You will add an entry with name "Derek Riggs" and a registration mask like the following:
|
|
|
|
Eddie!stranger@*.somewhere.in.time.org.[br]
|
|
|
|
If the IRC servers keep adding strange characters ([doc:irc_masks]prefixes[/doc]) at the beginning of his username you may use
|
|
|
|
Eddie!*stranger@*.somewhere.in.time.org.[br]
|
|
|
|
If Eddie also often connects from the wasted.years.org domain and gets 'eddie' as username there, you might add a second registration mask as follows:
|
|
|
|
Eddie!*eddie@*.wasted.years.org.[br]
|
|
|
|
An alternative could be use only one mask with *.org as domain and allow any username (Eddie!*@*.org) but this
|
|
|
|
could become dangerous since it could match the users that you don't want to.[br]
|
|
|
|
On the other hand, if you dislike the users with the nickname Eddie that come from .org
|
|
|
|
and you're implementing an auto-kick system, the correct mask to register is "Eddie!*@*.org".[br]
|
|
|
|
[br]
|
|
|
|
KVirc ties to be smart , and always find the most correct match for an user:
|
|
|
|
If you have two masks registered: Pragma!*xor@*.myisp.it and *!*@*.myisp.it,
|
|
|
|
kvirc will match Pragma!~xor@233-dyn.myisp.it with the first one even if the second
|
|
|
|
one matches too; the firs one is a best match.[br]
|
|
|
|
[br]
|
|
|
|
[big]Properties[/big][br]
|
|
|
|
A registered user has an (eventually empty) set of properties
|
|
|
|
defined by name/value pairs. (In versions prior to 3.0.0 flags were used instead,
|
|
|
|
but revealed to be insufficient).[br]
|
|
|
|
KVirc recognizes some of these proprietes and associates semantic actions to it; other properties
|
|
|
|
are left for scripting extension. Property names are case insensitive.[br]
|
|
|
|
One of the recognized properties is the "[doc:notify_list]notify[/doc]" property.
|
|
|
|
When an user is found to have this property set to a special value
|
|
|
|
KVIrc will attempt to track the user presence on IRC.
|
|
|
|
Another one is the [doc:avatar]avatar[/doc] property. Its value should be the
|
|
|
|
name of the "default" [doc:avatar]avatar image file[/doc] for the specified user.[br]
|
|
|
|
The "ignore" property should be set to "1" (or "true") for users that have to be ignored (:D).[br]
|
|
|
|
[br]
|
|
|
|
[big]The interface to the database[/big][br]
|
|
|
|
The [module:reguser]reguser module[/module] is the interface to the "registered users database".[br]
|
|
|
|
It provides a set of commands for adding and removing masks and manipulating properties.[br]
|
|
|
|
*/
|
|
|
|
|
|
|
|
//============================================================================================================
|
|
|
|
//
|
|
|
|
// KviRegisteredMask
|
|
|
|
//
|
|
|
|
|
|
|
|
KVILIB_API KviRegisteredUserDataBase* g_pRegisteredUserDataBase = 0;
|
|
|
|
|
|
|
|
KviRegisteredMask::KviRegisteredMask(KviRegisteredUser * u,KviIrcMask * m)
|
|
|
|
{
|
|
|
|
m_pUser = u;
|
|
|
|
m_pMask = m;
|
|
|
|
m_iMaskNonWildChars = m_pMask->nonWildChars();
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================================================
|
|
|
|
//
|
|
|
|
// KviRegisteredUser
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
KviRegisteredUser::KviRegisteredUser(const TQString & name)
|
|
|
|
{
|
|
|
|
m_iIgnoreFlags =0;
|
|
|
|
m_bIgnoreEnabled=false;
|
|
|
|
m_szName = name;
|
|
|
|
m_pPropertyDict = 0;
|
|
|
|
m_pMaskList = new KviPointerList<KviIrcMask>;
|
|
|
|
m_pMaskList->setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUser::~KviRegisteredUser()
|
|
|
|
{
|
|
|
|
if(m_pPropertyDict)delete m_pPropertyDict;
|
|
|
|
delete m_pMaskList;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::isIgnoreEnabledFor(IgnoreFlags flag)
|
|
|
|
{
|
|
|
|
if(!m_bIgnoreEnabled) return false;
|
|
|
|
return m_iIgnoreFlags & flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviIrcMask * KviRegisteredUser::findMask(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
for(KviIrcMask * m = m_pMaskList->first();m;m = m_pMaskList->next())
|
|
|
|
{
|
|
|
|
if(*m == mask)return m;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::addMask(KviIrcMask * mask)
|
|
|
|
{
|
|
|
|
if(findMask(*mask))
|
|
|
|
{
|
|
|
|
delete mask;
|
|
|
|
mask = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_pMaskList->append(mask);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::removeMask(KviIrcMask * mask)
|
|
|
|
{
|
|
|
|
if(!mask)return false;
|
|
|
|
return m_pMaskList->removeRef(mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::matches(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
for(KviIrcMask * m = m_pMaskList->first();m;m = m_pMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->matches(mask))return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::matchesFixed(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
for(KviIrcMask * m = m_pMaskList->first();m;m = m_pMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->matchesFixed(mask))return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::matchesFixed(const TQString & nick,const TQString & user,const TQString & host)
|
|
|
|
{
|
|
|
|
for(KviIrcMask * m = m_pMaskList->first();m;m = m_pMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->matchesFixed(nick,user,host))return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviRegisteredUser::setProperty(const TQString &name,bool value)
|
|
|
|
{
|
|
|
|
setProperty(name,value ? TQString("true") : TQString("false"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviRegisteredUser::setProperty(const TQString & name,const TQString & value)
|
|
|
|
{
|
|
|
|
if(!value.isEmpty())
|
|
|
|
{
|
|
|
|
if(!m_pPropertyDict)
|
|
|
|
{
|
|
|
|
m_pPropertyDict = new KviPointerHashTable<TQString,TQString>(7,false);
|
|
|
|
m_pPropertyDict->setAutoDelete(true);
|
|
|
|
}
|
|
|
|
#ifdef COMPILE_USE_QT4
|
|
|
|
TQString * val = new TQString(value.trimmed());
|
|
|
|
#else
|
|
|
|
TQString * val = new TQString(value.stripWhiteSpace());
|
|
|
|
#endif
|
|
|
|
if(!val->isEmpty())
|
|
|
|
{
|
|
|
|
m_pPropertyDict->replace(name,val);
|
|
|
|
} else {
|
|
|
|
delete val;
|
|
|
|
val = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(m_pPropertyDict)m_pPropertyDict->remove(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::getProperty(const TQString & name,TQString &value)
|
|
|
|
{
|
|
|
|
if(!m_pPropertyDict)return false;
|
|
|
|
if(name.isEmpty()) return false;
|
|
|
|
TQString * pValue = m_pPropertyDict->find(name);
|
|
|
|
if(pValue)value = *pValue;
|
|
|
|
else return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQString & KviRegisteredUser::getProperty(const TQString & name)
|
|
|
|
{
|
|
|
|
if(!m_pPropertyDict)return KviTQString::empty;
|
|
|
|
if(name.isEmpty())return KviTQString::empty;
|
|
|
|
TQString * pValue = m_pPropertyDict->find(name);
|
|
|
|
if(pValue)return *pValue;
|
|
|
|
return KviTQString::empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUser::getBoolProperty(const TQString & name,bool def)
|
|
|
|
{
|
|
|
|
if(!m_pPropertyDict)return def;
|
|
|
|
if(name.isEmpty()) return def;
|
|
|
|
TQString * pValue = m_pPropertyDict->find(name);
|
|
|
|
if(pValue)
|
|
|
|
{
|
|
|
|
// be flexible , allow more "true" values (pragma)
|
|
|
|
if(KviTQString::equalCS(*pValue,"1"))return true;
|
|
|
|
if(KviTQString::equalCI(*pValue,"true"))return true;
|
|
|
|
if(KviTQString::equalCI(*pValue,"yes"))return true;
|
|
|
|
//if(KviTQString::equalCI(*pValue,"yeah"))return true;
|
|
|
|
//if(KviTQString::equalCI(*pValue,"sure"))return true;
|
|
|
|
//if(KviTQString::equalCI(*pValue,"sureashell"))return true;
|
|
|
|
}
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================================================
|
|
|
|
//
|
|
|
|
// KviRegisteredUserGroup
|
|
|
|
//
|
|
|
|
|
|
|
|
KviRegisteredUserGroup::KviRegisteredUserGroup(const TQString &name)
|
|
|
|
{
|
|
|
|
setName(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUserGroup::~KviRegisteredUserGroup()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//============================================================================================================
|
|
|
|
//
|
|
|
|
// KviRegisteredUserDb
|
|
|
|
//
|
|
|
|
|
|
|
|
KviRegisteredUserDataBase::KviRegisteredUserDataBase()
|
|
|
|
{
|
|
|
|
m_pUserDict = new KviPointerHashTable<TQString,KviRegisteredUser>(31,false); // do not copy keys
|
|
|
|
m_pUserDict->setAutoDelete(true);
|
|
|
|
|
|
|
|
m_pWildMaskList = new KviRegisteredMaskList;
|
|
|
|
m_pWildMaskList->setAutoDelete(true);
|
|
|
|
|
|
|
|
m_pMaskDict = new KviPointerHashTable<TQString,KviRegisteredMaskList>(49,false); // copy keys here!
|
|
|
|
m_pMaskDict->setAutoDelete(true);
|
|
|
|
|
|
|
|
m_pGroupDict = new KviPointerHashTable<TQString,KviRegisteredUserGroup>(5,false); // copy keys here!
|
|
|
|
m_pGroupDict->setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUserDataBase::~KviRegisteredUserDataBase()
|
|
|
|
{
|
|
|
|
emit(databaseCleared());
|
|
|
|
delete m_pUserDict;
|
|
|
|
delete m_pWildMaskList;
|
|
|
|
delete m_pMaskDict;
|
|
|
|
delete m_pGroupDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::addUser(const TQString & name)
|
|
|
|
{
|
|
|
|
if(name.isEmpty()) return false;
|
|
|
|
if(m_pUserDict->find(name))return 0;
|
|
|
|
KviRegisteredUser * u = new KviRegisteredUser(name);
|
|
|
|
m_pUserDict->replace(u->name(),u); //u->name() because we're NOT copying keys!
|
|
|
|
emit(userAdded(name));
|
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUserGroup * KviRegisteredUserDataBase::addGroup(const TQString & name)
|
|
|
|
{
|
|
|
|
if(name.isEmpty()) return false;
|
|
|
|
if(m_pGroupDict->find(name))return 0;
|
|
|
|
KviRegisteredUserGroup * pGroup = new KviRegisteredUserGroup(name);
|
|
|
|
m_pGroupDict->replace(pGroup->name(),pGroup); //u->name() because we're NOT copying keys!
|
|
|
|
return pGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::getUser(const TQString & name)
|
|
|
|
{
|
|
|
|
if(name.isEmpty()) return 0;
|
|
|
|
KviRegisteredUser * u = m_pUserDict->find(name);
|
|
|
|
if(!u)
|
|
|
|
{
|
|
|
|
u = new KviRegisteredUser(name);
|
|
|
|
m_pUserDict->replace(u->name(),u); //u->name() because we're NOT copying keys!
|
|
|
|
}
|
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void append_mask_to_list(KviRegisteredMaskList *l,KviRegisteredUser *u,KviIrcMask *mask)
|
|
|
|
{
|
|
|
|
KviRegisteredMask * newMask = new KviRegisteredMask(u,mask);
|
|
|
|
int idx = 0;
|
|
|
|
for(KviRegisteredMask * m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(m->nonWildChars() < newMask->nonWildChars())
|
|
|
|
{
|
|
|
|
l->insert(idx,newMask);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
l->append(newMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::addMask(KviRegisteredUser * u,KviIrcMask * mask)
|
|
|
|
{
|
|
|
|
if(!u || !mask) return 0;
|
|
|
|
__range_valid(u == m_pUserDict->find(u->name()));
|
|
|
|
|
|
|
|
KviRegisteredMaskList * l;
|
|
|
|
if(mask->hasWildNick())
|
|
|
|
{
|
|
|
|
for(KviRegisteredMask * m = m_pWildMaskList->first();m;m = m_pWildMaskList->next())
|
|
|
|
{
|
|
|
|
if(*(m->mask()) == *mask)
|
|
|
|
{
|
|
|
|
delete mask;
|
|
|
|
mask = 0;
|
|
|
|
return m->user();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found ...ok... add it
|
|
|
|
// masks with more info go first in the list
|
|
|
|
l = m_pWildMaskList;
|
|
|
|
} else {
|
|
|
|
l = m_pMaskDict->find(mask->nick());
|
|
|
|
if(l)
|
|
|
|
{
|
|
|
|
// FIXME: #warning "Here we could compare the host and username only: nick matches for sure"
|
|
|
|
for(KviRegisteredMask * m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(*(m->mask()) == *mask)
|
|
|
|
{
|
|
|
|
delete mask;
|
|
|
|
mask = 0;
|
|
|
|
return m->user();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found ...ok... add it
|
|
|
|
} else {
|
|
|
|
// not found ...ok... add it
|
|
|
|
// this is the first mask in the list
|
|
|
|
l = new KviRegisteredMaskList;
|
|
|
|
l->setAutoDelete(true);
|
|
|
|
if(!u->addMask(mask))
|
|
|
|
{
|
|
|
|
debug(" Ops...got an incoherent regusers action...recovered ?");
|
|
|
|
delete l;
|
|
|
|
l = 0;
|
|
|
|
} else {
|
|
|
|
append_mask_to_list(l,u,mask);
|
|
|
|
m_pMaskDict->insert(mask->nick(),l);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Ok...add it
|
|
|
|
if(!u->addMask(mask))
|
|
|
|
{
|
|
|
|
debug("ops...got an incoherent regusers action...recovered ?");
|
|
|
|
return 0; // ops...already there ?
|
|
|
|
}
|
|
|
|
append_mask_to_list(l,u,mask);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviRegisteredUserDataBase::copyFrom(KviRegisteredUserDataBase * db)
|
|
|
|
{
|
|
|
|
m_pUserDict->clear();
|
|
|
|
m_pWildMaskList->clear();
|
|
|
|
m_pMaskDict->clear();
|
|
|
|
m_pGroupDict->clear();
|
|
|
|
emit(databaseCleared());
|
|
|
|
|
|
|
|
KviPointerHashTableIterator<TQString,KviRegisteredUser> it(*(db->m_pUserDict));
|
|
|
|
|
|
|
|
while(KviRegisteredUser * theCur = it.current())
|
|
|
|
{
|
|
|
|
KviRegisteredUser * u = getUser(theCur->name());
|
|
|
|
// copy masks
|
|
|
|
KviPointerList<KviIrcMask> * l = theCur->maskList();
|
|
|
|
for(KviIrcMask * m=l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
KviIrcMask * m2 = new KviIrcMask(*m);
|
|
|
|
addMask(u,m2);
|
|
|
|
}
|
|
|
|
// copy properties
|
|
|
|
KviPointerHashTable<TQString,TQString> * pd = theCur->propertyDict();
|
|
|
|
if(pd)
|
|
|
|
{
|
|
|
|
KviPointerHashTableIterator<TQString,TQString> pdi(*pd);
|
|
|
|
while(pdi.current())
|
|
|
|
{
|
|
|
|
u->setProperty(pdi.currentKey(),*(pdi.current()));
|
|
|
|
++pdi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
u->m_iIgnoreFlags=theCur->m_iIgnoreFlags;
|
|
|
|
u->m_bIgnoreEnabled=theCur->m_bIgnoreEnabled;
|
|
|
|
u->setGroup(theCur->group());
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviPointerHashTableIterator<TQString,KviRegisteredUserGroup> git(*db->m_pGroupDict);
|
|
|
|
while(git.current())
|
|
|
|
{
|
|
|
|
addGroup(git.currentKey());
|
|
|
|
++git;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool KviRegisteredUserDataBase::removeUser(const TQString & name)
|
|
|
|
{
|
|
|
|
if(name.isEmpty()) return false;
|
|
|
|
KviRegisteredUser * u = m_pUserDict->find(name);
|
|
|
|
if(!u)return false;
|
|
|
|
while(KviIrcMask * mask = u->maskList()->first())
|
|
|
|
{
|
|
|
|
if(!removeMaskByPointer(mask))
|
|
|
|
debug("Ops... removeMaskByPointer(%s) failed ?",KviTQString::toUtf8(name).data());
|
|
|
|
}
|
|
|
|
emit(userRemoved(name));
|
|
|
|
m_pUserDict->remove(name);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool KviRegisteredUserDataBase::removeGroup(const TQString & name)
|
|
|
|
{
|
|
|
|
if(name.isEmpty()) return false;
|
|
|
|
m_pGroupDict->remove(name);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUserDataBase::removeMask(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
// find the mask pointer
|
|
|
|
KviRegisteredMask * m = findExactMask(mask);
|
|
|
|
// and remove it
|
|
|
|
if(m){
|
|
|
|
if(removeMaskByPointer(m->mask()))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KviRegisteredUserDataBase::removeMaskByPointer(KviIrcMask * mask)
|
|
|
|
{
|
|
|
|
if(!mask) return 0;
|
|
|
|
if(mask->hasWildNick())
|
|
|
|
{
|
|
|
|
// remove from the wild list
|
|
|
|
for(KviRegisteredMask * m = m_pWildMaskList->first();m;m = m_pWildMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->mask() == mask)
|
|
|
|
{
|
|
|
|
// ok..got it, remove from the list and from the user struct (user struct deletes it!)
|
|
|
|
emit(userChanged(mask->nick()));
|
|
|
|
m->user()->removeMask(mask); // this one deletes m->mask()
|
|
|
|
m_pWildMaskList->removeRef(m); // this one deletes m
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found ...opz :)
|
|
|
|
} else {
|
|
|
|
KviRegisteredMaskList * l = m_pMaskDict->find(mask->nick());
|
|
|
|
if(l)
|
|
|
|
{
|
|
|
|
// FIXME: #warning "Here we could compare the host and username only: nick matches for sure"
|
|
|
|
for(KviRegisteredMask * m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(m->mask() == mask)
|
|
|
|
{
|
|
|
|
TQString nick = mask->nick();
|
|
|
|
emit(userChanged(nick));
|
|
|
|
m->user()->removeMask(mask); // this one deletes m->mask() (or mask)
|
|
|
|
l->removeRef(m); // this one deletes m
|
|
|
|
if(l->count() == 0)m_pMaskDict->remove(nick);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found ...opz
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found...
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::findMatchingUser(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
// first lookup the nickname in the maskDict
|
|
|
|
KviRegisteredMaskList * l = m_pMaskDict->find(mask.nick());
|
|
|
|
if(l)
|
|
|
|
{
|
|
|
|
for(KviRegisteredMask *m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(m->mask()->matchesFixed(0,mask.user(),mask.host()))return m->user();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found....lookup the wild ones
|
|
|
|
for(KviRegisteredMask * m = m_pWildMaskList->first();m;m = m_pWildMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->mask()->matchesFixed(mask))return m->user();
|
|
|
|
}
|
|
|
|
return 0; // no match at all
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::findMatchingUser(const TQString & nick,const TQString &user,const TQString & host)
|
|
|
|
{
|
|
|
|
KviRegisteredMask * m = findMatchingMask(nick,user,host);
|
|
|
|
if(m)return m->user();
|
|
|
|
return 0; // no match at all
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredMask * KviRegisteredUserDataBase::findMatchingMask(const TQString & nick,const TQString &user,const TQString & host)
|
|
|
|
{
|
|
|
|
// first lookup the nickname in the maskDict
|
|
|
|
if(nick.isEmpty()) return false;
|
|
|
|
KviRegisteredMaskList * l = m_pMaskDict->find(nick);
|
|
|
|
if(l)
|
|
|
|
{
|
|
|
|
for(KviRegisteredMask *m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(m->mask()->matchesFixed(nick,user,host))return m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found....lookup the wild ones
|
|
|
|
for(KviRegisteredMask * m = m_pWildMaskList->first();m;m = m_pWildMaskList->next())
|
|
|
|
{
|
|
|
|
if(m->mask()->matchesFixed(nick,user,host))return m;
|
|
|
|
}
|
|
|
|
return 0; // no match at all
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredUser * KviRegisteredUserDataBase::findUserWithMask(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
KviRegisteredMask * m = findExactMask(mask);
|
|
|
|
if(m)return m->user();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviRegisteredMask * KviRegisteredUserDataBase::findExactMask(const KviIrcMask &mask)
|
|
|
|
{
|
|
|
|
// first lookup the nickname in the maskDict
|
|
|
|
if(mask.nick()=="") return 0;
|
|
|
|
KviRegisteredMaskList * l = m_pMaskDict->find(mask.nick());
|
|
|
|
if(l)
|
|
|
|
{
|
|
|
|
for(KviRegisteredMask *m = l->first();m;m = l->next())
|
|
|
|
{
|
|
|
|
if(*(m->mask()) == mask)return m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// not found....lookup the wild ones
|
|
|
|
for(KviRegisteredMask * m = m_pWildMaskList->first();m;m = m_pWildMaskList->next())
|
|
|
|
{
|
|
|
|
if(*(m->mask()) == mask)return m;
|
|
|
|
}
|
|
|
|
return 0; // no match at all
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
bool KviRegisteredUserDataBase::isIgnoredUser(const TQString & nick,const TQString & user,const TQString & host)
|
|
|
|
{
|
|
|
|
KviRegisteredUser * u = findMatchingUser(nick,user,host);
|
|
|
|
if(u)return u->getBoolProperty("IGNORE");
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
void KviRegisteredUserDataBase::load(const TQString & filename)
|
|
|
|
{
|
|
|
|
TQString szCurrent;
|
|
|
|
KviConfig cfg(filename,KviConfig::Read);
|
|
|
|
|
|
|
|
KviConfigIterator it(*cfg.dict());
|
|
|
|
while(it.current())
|
|
|
|
{
|
|
|
|
cfg.setGroup(it.currentKey());
|
|
|
|
szCurrent=it.currentKey();
|
|
|
|
if(KviTQString::equalCSN("#Group ",szCurrent,7))
|
|
|
|
{
|
|
|
|
szCurrent.remove(0,7);
|
|
|
|
addGroup(szCurrent);
|
|
|
|
} else {
|
|
|
|
KviRegisteredUser * u = addUser(szCurrent);
|
|
|
|
|
|
|
|
if(u)
|
|
|
|
{
|
|
|
|
u->setIgnoreEnabled(cfg.readBoolEntry("IgnoreEnabled",false));
|
|
|
|
u->setIgnoreFlags(cfg.readIntEntry("IgnoreFlags",0));
|
|
|
|
KviConfigGroupIterator sdi(*(it.current()));
|
|
|
|
while(sdi.current())
|
|
|
|
{
|
|
|
|
TQString tmp = sdi.currentKey();
|
|
|
|
if(KviTQString::equalCSN("prop_",tmp,5))
|
|
|
|
{
|
|
|
|
tmp.remove(0,5);
|
|
|
|
u->setProperty(tmp,*(sdi.current()));
|
|
|
|
} else if(KviTQString::equalCSN("mask_",tmp,5))
|
|
|
|
{
|
|
|
|
KviIrcMask * mask = new KviIrcMask(*(sdi.current()));
|
|
|
|
addMask(u,mask);
|
|
|
|
} else if(KviTQString::equalCI(tmp,"Group"))
|
|
|
|
{
|
|
|
|
u->setGroup(*(sdi.current()));
|
|
|
|
}
|
|
|
|
++sdi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
if(!m_pGroupDict->find(__tr("Default")))
|
|
|
|
addGroup(__tr("Default"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KviRegisteredUserDataBase::save(const TQString & filename)
|
|
|
|
{
|
|
|
|
KviConfig cfg(filename,KviConfig::Write);
|
|
|
|
cfg.clear();
|
|
|
|
cfg.preserveEmptyGroups(true);
|
|
|
|
|
|
|
|
KviPointerHashTableIterator<TQString,KviRegisteredUser> it(*m_pUserDict);
|
|
|
|
|
|
|
|
while(it.current())
|
|
|
|
{
|
|
|
|
cfg.setGroup(it.current()->name());
|
|
|
|
// Write properties
|
|
|
|
cfg.writeEntry("IgnoreEnabled",it.current()->ignoreEnagled());
|
|
|
|
cfg.writeEntry("IgnoreFlags",it.current()->ignoreFlags());
|
|
|
|
if(it.current()->propertyDict())
|
|
|
|
{
|
|
|
|
KviPointerHashTableIterator<TQString,TQString> pit(*(it.current()->propertyDict()));
|
|
|
|
while(pit.current())
|
|
|
|
{
|
|
|
|
TQString tmp = "prop_";
|
|
|
|
tmp.append(pit.currentKey());
|
|
|
|
cfg.writeEntry(tmp,*(pit.current()));
|
|
|
|
++pit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write masks
|
|
|
|
int idx = 0;
|
|
|
|
for(KviIrcMask * m = it.current()->maskList()->first();m;m = it.current()->maskList()->next())
|
|
|
|
{
|
|
|
|
TQString tmp;
|
|
|
|
KviTQString::sprintf(tmp,"mask_%d",idx);
|
|
|
|
TQString mask;
|
|
|
|
m->mask(mask,KviIrcMask::NickUserHost);
|
|
|
|
cfg.writeEntry(tmp,mask);
|
|
|
|
++idx;
|
|
|
|
}
|
|
|
|
cfg.writeEntry("Group",it.current()->group());
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
KviPointerHashTableIterator<TQString,KviRegisteredUserGroup> git(*m_pGroupDict);
|
|
|
|
TQString szTmp;
|
|
|
|
while(git.current())
|
|
|
|
{
|
|
|
|
KviTQString::sprintf(szTmp,"#Group %Q",&(git.current()->name()));
|
|
|
|
cfg.setGroup(szTmp);
|
|
|
|
++git;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|