|
|
|
// -*- Mode: c++-mode; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 2; -*-
|
|
|
|
//
|
|
|
|
// Copyright (C) 2004 Grzegorz Jaskiewicz <gj at pointblue.com.pl>
|
|
|
|
//
|
|
|
|
// gadudcc.cpp
|
|
|
|
//
|
|
|
|
// 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 option) 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
|
|
|
|
// 02111-1307, USA.
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/un.h>
|
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include "gadudccserver.h"
|
|
|
|
#include "gadudcc.h"
|
|
|
|
#include "gadudcctransaction.h"
|
|
|
|
#include "gaduaccount.h"
|
|
|
|
|
|
|
|
#include "libgadu.h"
|
|
|
|
|
|
|
|
#include <qsocketnotifier.h>
|
|
|
|
#include <qhostaddress.h>
|
|
|
|
#include <qmutex.h>
|
|
|
|
#include <qmap.h>
|
|
|
|
#include <qstring.h>
|
|
|
|
|
|
|
|
volatile unsigned int GaduDCC::referenceCount = 0;
|
|
|
|
|
|
|
|
GaduDCCServer* GaduDCC::dccServer = NULL;
|
|
|
|
|
|
|
|
static QMutex initmutex;
|
|
|
|
|
|
|
|
typedef QMap< unsigned int, GaduAccount* > gaduAccounts;
|
|
|
|
static gaduAccounts accounts;
|
|
|
|
|
|
|
|
GaduDCC::GaduDCC( QObject* parent, const char* name )
|
|
|
|
:QObject( parent, name )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GaduDCC::unregisterAccount()
|
|
|
|
{
|
|
|
|
return unregisterAccount( accountId );
|
|
|
|
}
|
|
|
|
|
|
|
|
GaduAccount*
|
|
|
|
GaduDCC::account( unsigned int uin )
|
|
|
|
{
|
|
|
|
return accounts[ uin ];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GaduDCC::unregisterAccount( unsigned int id )
|
|
|
|
{
|
|
|
|
initmutex.lock();
|
|
|
|
|
|
|
|
if ( id == 0 ) {
|
|
|
|
kdDebug(14100) << "ID nan" << endl;
|
|
|
|
initmutex.unlock();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !accounts.contains( id ) ) {
|
|
|
|
kdDebug(14100) << "attempt to unregister not registered account" << endl;
|
|
|
|
initmutex.unlock();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
accounts.remove( id );
|
|
|
|
|
|
|
|
if ( --referenceCount <= 0 ) {
|
|
|
|
kdDebug(14100) << "closing dcc socket" << endl;
|
|
|
|
referenceCount = 0;
|
|
|
|
if ( dccServer ) {
|
|
|
|
delete dccServer;
|
|
|
|
dccServer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
kdDebug(14100) << "reference count " << referenceCount << endl;
|
|
|
|
initmutex.unlock();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
GaduDCC::registerAccount( GaduAccount* account )
|
|
|
|
{
|
|
|
|
unsigned int aid;
|
|
|
|
|
|
|
|
if ( !account ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( account->accountId().isEmpty() ) {
|
|
|
|
kdDebug(14100) << "attempt to register account with empty ID" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
initmutex.lock();
|
|
|
|
|
|
|
|
aid = account->accountId().toInt();
|
|
|
|
|
|
|
|
if ( accounts.contains( aid ) ) {
|
|
|
|
kdDebug(14100) << "attempt to register already registered account" << endl;
|
|
|
|
initmutex.unlock();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
accountId = aid;
|
|
|
|
kdDebug( 14100 ) << " attempt to register " << accountId << endl;
|
|
|
|
|
|
|
|
accounts[ accountId ] = account;
|
|
|
|
|
|
|
|
referenceCount++;
|
|
|
|
|
|
|
|
if ( !dccServer) {
|
|
|
|
dccServer = new GaduDCCServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
connect( dccServer, SIGNAL( incoming( gg_dcc*, bool& ) ), SLOT( slotIncoming( gg_dcc*, bool& ) ) );
|
|
|
|
|
|
|
|
initmutex.unlock();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void
|
|
|
|
GaduDCC::slotIncoming( gg_dcc* incoming, bool& handled )
|
|
|
|
{
|
|
|
|
gg_dcc* newdcc;
|
|
|
|
GaduDCCTransaction* dt;
|
|
|
|
|
|
|
|
kdDebug( 14100 ) << "slotIncomming for UIN: " << incoming->uin << endl;
|
|
|
|
|
|
|
|
// no uin? I'm so sorry
|
|
|
|
// this screws file receiving (using kadu 0.4.x as peer) for me
|
|
|
|
// if ( !incoming->uin ) {
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
handled = true;
|
|
|
|
// TODO: limit number of connections per contact, or maybe even use parametr for that
|
|
|
|
newdcc = new gg_dcc;
|
|
|
|
memcpy( newdcc, incoming, sizeof( gg_dcc ) );
|
|
|
|
dt = new GaduDCCTransaction( this );
|
|
|
|
if ( dt->setupIncoming( newdcc ) == false ) {
|
|
|
|
// FIXME: write something to user, maybe, or not...
|
|
|
|
delete dt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GaduDCC::~GaduDCC()
|
|
|
|
{
|
|
|
|
if ( accounts.contains( accountId ) ) {
|
|
|
|
kdDebug( 14100 ) << "unregister account " << accountId << " in destructor " << endl;
|
|
|
|
unregisterAccount( accountId );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
GaduDCC::listeingPort()
|
|
|
|
{
|
|
|
|
if ( dccServer ) {
|
|
|
|
return dccServer->listeingPort();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "gadudcc.moc"
|