initial commit
This commit is contained in:
commit
9d20827c46
2469 changed files with 470994 additions and 0 deletions
32
iris-legacy/cutestuff/cutestuff.pri
Normal file
32
iris-legacy/cutestuff/cutestuff.pri
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
INCLUDEPATH += $$PWD/util $$PWD/network
|
||||
DEPENDPATH += $$PWD/util $$PWD/network
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/util/bytestream.h \
|
||||
$$PWD/network/bsocket.h \
|
||||
$$PWD/network/httpconnect.h \
|
||||
$$PWD/network/httppoll.h \
|
||||
$$PWD/network/socks.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/util/bytestream.cpp \
|
||||
$$PWD/network/bsocket.cpp \
|
||||
$$PWD/network/httpconnect.cpp \
|
||||
$$PWD/network/httppoll.cpp \
|
||||
$$PWD/network/socks.cpp
|
||||
|
||||
!irisnet {
|
||||
INCLUDEPATH += $$PWD/legacy
|
||||
HEADERS += \
|
||||
$$PWD/legacy/safedelete.h \
|
||||
$$PWD/legacy/ndns.h \
|
||||
$$PWD/legacy/srvresolver.h \
|
||||
$$PWD/legacy/servsock.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/legacy/safedelete.cpp \
|
||||
$$PWD/legacy/ndns.cpp \
|
||||
$$PWD/legacy/srvresolver.cpp \
|
||||
$$PWD/legacy/servsock.cpp
|
||||
}
|
||||
|
||||
393
iris-legacy/cutestuff/legacy/ndns.cpp
Normal file
393
iris-legacy/cutestuff/legacy/ndns.cpp
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/*
|
||||
* ndns.cpp - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
//! \class NDns ndns.h
|
||||
//! \brief Simple DNS resolution using native system calls
|
||||
//!
|
||||
//! This class is to be used when Qt's QDns is not good enough. Because QDns
|
||||
//! does not use threads, it cannot make a system call asyncronously. Thus,
|
||||
//! QDns tries to imitate the behavior of each platform's native behavior, and
|
||||
//! generally falls short.
|
||||
//!
|
||||
//! NDns uses a thread to make the system call happen in the background. This
|
||||
//! gives your program native DNS behavior, at the cost of requiring threads
|
||||
//! to build.
|
||||
//!
|
||||
//! \code
|
||||
//! #include "ndns.h"
|
||||
//!
|
||||
//! ...
|
||||
//!
|
||||
//! NDns dns;
|
||||
//! dns.resolve("psi.affinix.com");
|
||||
//!
|
||||
//! // The class will emit the resultsReady() signal when the resolution
|
||||
//! // is finished. You may then retrieve the results:
|
||||
//!
|
||||
//! QHostAddress ip_address = dns.result();
|
||||
//!
|
||||
//! // or if you want to get the IP address as a string:
|
||||
//!
|
||||
//! QString ip_address = dns.resultString();
|
||||
//! \endcode
|
||||
|
||||
#include "ndns.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <q3socketdevice.h>
|
||||
#include <q3ptrlist.h>
|
||||
#include <qeventloop.h>
|
||||
//Added by qt3to4:
|
||||
#include <QCustomEvent>
|
||||
#include <QEvent>
|
||||
#include <Q3CString>
|
||||
#include <QPointer>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "psilogger.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//! \if _hide_doc_
|
||||
class NDnsWorker : public QThread
|
||||
{
|
||||
public:
|
||||
NDnsWorker(QObject *, const Q3CString &);
|
||||
~NDnsWorker();
|
||||
|
||||
bool success;
|
||||
bool cancelled;
|
||||
QHostAddress addr;
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
Q3CString host;
|
||||
};
|
||||
//! \endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDnsManager
|
||||
//----------------------------------------------------------------------------
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
static QMutex *workerMutex = 0;
|
||||
static QMutex *workerCancelled = 0;
|
||||
#endif
|
||||
#endif
|
||||
static NDnsManager *manager_instance = 0;
|
||||
bool winsock_init = false;
|
||||
|
||||
class NDnsManager::Item
|
||||
{
|
||||
public:
|
||||
NDns *ndns;
|
||||
NDnsWorker *worker;
|
||||
};
|
||||
|
||||
class NDnsManager::Private
|
||||
{
|
||||
public:
|
||||
Item *find(const NDns *n)
|
||||
{
|
||||
Q3PtrListIterator<Item> it(list);
|
||||
for(Item *i; (i = it.current()); ++it) {
|
||||
if(i->ndns == n)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Item *find(const NDnsWorker *w)
|
||||
{
|
||||
Q3PtrListIterator<Item> it(list);
|
||||
for(Item *i; (i = it.current()); ++it) {
|
||||
if(i->worker == w)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Q3PtrList<Item> list;
|
||||
};
|
||||
|
||||
NDnsManager::NDnsManager()
|
||||
: QObject(QCoreApplication::instance())
|
||||
{
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
workerMutex = new QMutex;
|
||||
workerCancelled = new QMutex;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
if(!winsock_init) {
|
||||
winsock_init = true;
|
||||
Q3SocketDevice *sd = new Q3SocketDevice;
|
||||
delete sd;
|
||||
}
|
||||
#endif
|
||||
|
||||
d = new Private;
|
||||
d->list.setAutoDelete(true);
|
||||
|
||||
connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), SLOT(app_aboutToQuit()));
|
||||
}
|
||||
|
||||
NDnsManager::~NDnsManager()
|
||||
{
|
||||
delete d;
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
delete workerMutex;
|
||||
workerMutex = 0;
|
||||
delete workerCancelled;
|
||||
workerCancelled = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void NDnsManager::resolve(NDns *self, const QString &name)
|
||||
{
|
||||
Item *i = new Item;
|
||||
i->ndns = self;
|
||||
i->worker = new NDnsWorker(this, name.utf8());
|
||||
connect(i->worker, SIGNAL(finished()), SLOT(workerFinished()));
|
||||
d->list.append(i);
|
||||
|
||||
i->worker->start();
|
||||
}
|
||||
|
||||
void NDnsManager::stop(NDns *self)
|
||||
{
|
||||
Item *i = d->find(self);
|
||||
if(!i)
|
||||
return;
|
||||
// disassociate
|
||||
i->ndns = 0;
|
||||
|
||||
#ifndef HAVE_GETHOSTBYNAME_R
|
||||
#ifndef Q_WS_WIN
|
||||
// cancel
|
||||
workerCancelled->lock();
|
||||
i->worker->cancelled = true;
|
||||
workerCancelled->unlock();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
d->list.removeRef(i);
|
||||
}
|
||||
|
||||
bool NDnsManager::isBusy(const NDns *self) const
|
||||
{
|
||||
Item *i = d->find(self);
|
||||
return (i ? true: false);
|
||||
}
|
||||
|
||||
void NDnsManager::workerFinished()
|
||||
{
|
||||
NDnsWorker* worker = dynamic_cast<NDnsWorker*>(sender());
|
||||
Q_ASSERT(worker);
|
||||
if (!worker)
|
||||
return;
|
||||
worker->wait(); // ensure that the thread is terminated
|
||||
|
||||
Item *i = d->find(worker);
|
||||
if(i) {
|
||||
QHostAddress addr = i->worker->addr;
|
||||
QPointer<NDns> ndns = i->ndns;
|
||||
d->list.removeRef(i);
|
||||
|
||||
// nuke manager if no longer needed (code that follows MUST BE SAFE!)
|
||||
tryDestroy();
|
||||
|
||||
// requestor still around?
|
||||
if(ndns) {
|
||||
ndns->finished(addr);
|
||||
}
|
||||
}
|
||||
|
||||
worker->deleteLater();
|
||||
}
|
||||
|
||||
void NDnsManager::tryDestroy()
|
||||
{
|
||||
// mblsha: NDnsManager is now singleton
|
||||
#if 0
|
||||
if(d->list.isEmpty()) {
|
||||
manager_instance = 0;
|
||||
deleteLater();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NDnsManager::app_aboutToQuit()
|
||||
{
|
||||
// mblsha: NDnsManager is now singleton
|
||||
#if 0
|
||||
while(man) {
|
||||
QCoreApplication::instance()->processEvents(QEventLoop::WaitForMoreEvents);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDns
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//! \fn void NDns::resultsReady()
|
||||
//! This signal is emitted when the DNS resolution succeeds or fails.
|
||||
|
||||
//!
|
||||
//! Constructs an NDns object with parent \a parent.
|
||||
NDns::NDns(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
//! Destroys the object and frees allocated resources.
|
||||
NDns::~NDns()
|
||||
{
|
||||
stop();
|
||||
PsiLogger::instance()->log(QString("%1 NDns::~NDns()").arg(LOG_THIS));
|
||||
}
|
||||
|
||||
//!
|
||||
//! Resolves hostname \a host (eg. psi.affinix.com)
|
||||
void NDns::resolve(const QString &host)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::resolve(%2)").arg(LOG_THIS).arg(host));
|
||||
stop();
|
||||
if(!manager_instance)
|
||||
manager_instance = new NDnsManager;
|
||||
manager_instance->resolve(this, host);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Cancels the lookup action.
|
||||
//! \note This will not stop the underlying system call, which must finish before the next lookup will proceed.
|
||||
void NDns::stop()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::stop()").arg(LOG_THIS));
|
||||
if(manager_instance)
|
||||
manager_instance->stop(this);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as QHostAddress. This will be a Null QHostAddress if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QHostAddress NDns::result() const
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as a string. This will be an empty string if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QString NDns::resultString() const
|
||||
{
|
||||
if (addr.isNull())
|
||||
return QString();
|
||||
else
|
||||
return addr.toString();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns TRUE if busy resolving a hostname.
|
||||
bool NDns::isBusy() const
|
||||
{
|
||||
if(!manager_instance)
|
||||
return false;
|
||||
return manager_instance->isBusy(this);
|
||||
}
|
||||
|
||||
void NDns::finished(const QHostAddress &a)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 NDns::finished(%2)").arg(LOG_THIS).arg(a.toString()));
|
||||
addr = a;
|
||||
resultsReady();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDnsWorker
|
||||
//----------------------------------------------------------------------------
|
||||
NDnsWorker::NDnsWorker(QObject *_par, const Q3CString &_host)
|
||||
: QThread(_par)
|
||||
{
|
||||
success = cancelled = false;
|
||||
host = _host.copy(); // do we need this to avoid sharing across threads?
|
||||
}
|
||||
|
||||
NDnsWorker::~NDnsWorker()
|
||||
{
|
||||
}
|
||||
|
||||
void NDnsWorker::run()
|
||||
{
|
||||
hostent *h = 0;
|
||||
|
||||
#ifdef HAVE_GETHOSTBYNAME_R
|
||||
hostent buf;
|
||||
char char_buf[1024];
|
||||
int err;
|
||||
gethostbyname_r(host.data(), &buf, char_buf, sizeof(char_buf), &h, &err);
|
||||
#else
|
||||
#ifndef Q_WS_WIN
|
||||
// lock for gethostbyname
|
||||
QMutexLocker locker(workerMutex);
|
||||
|
||||
// check for cancel
|
||||
workerCancelled->lock();
|
||||
bool cancel = cancelled;
|
||||
workerCancelled->unlock();
|
||||
|
||||
if(!cancel)
|
||||
#endif
|
||||
h = gethostbyname(host.data());
|
||||
#endif
|
||||
|
||||
// FIXME: not ipv6 clean, currently.
|
||||
if(!h || h->h_addrtype != AF_INET) {
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
in_addr a = *((struct in_addr *)h->h_addr_list[0]);
|
||||
addr.setAddress(ntohl(a.s_addr));
|
||||
success = true;
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
90
iris-legacy/cutestuff/legacy/ndns.h
Normal file
90
iris-legacy/cutestuff/legacy/ndns.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* ndns.h - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_NDNS_H
|
||||
#define CS_NDNS_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <q3cstring.h>
|
||||
#include <qthread.h>
|
||||
#include <qmutex.h>
|
||||
#include <qhostaddress.h>
|
||||
//Added by qt3to4:
|
||||
#include <QEvent>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class NDnsWorker;
|
||||
class NDnsManager;
|
||||
|
||||
class NDns : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NDns(QObject *parent=0);
|
||||
~NDns();
|
||||
|
||||
void resolve(const QString &);
|
||||
void stop();
|
||||
bool isBusy() const;
|
||||
|
||||
QHostAddress result() const;
|
||||
QString resultString() const;
|
||||
|
||||
signals:
|
||||
void resultsReady();
|
||||
|
||||
private:
|
||||
QHostAddress addr;
|
||||
|
||||
friend class NDnsManager;
|
||||
void finished(const QHostAddress &);
|
||||
};
|
||||
|
||||
class NDnsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~NDnsManager();
|
||||
class Item;
|
||||
|
||||
//! \if _hide_doc_
|
||||
protected slots:
|
||||
void workerFinished();
|
||||
//! \endif
|
||||
|
||||
private slots:
|
||||
void app_aboutToQuit();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
friend class NDns;
|
||||
NDnsManager();
|
||||
void resolve(NDns *self, const QString &name);
|
||||
void stop(NDns *self);
|
||||
bool isBusy(const NDns *self) const;
|
||||
void tryDestroy();
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
111
iris-legacy/cutestuff/legacy/safedelete.cpp
Normal file
111
iris-legacy/cutestuff/legacy/safedelete.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#include "safedelete.h"
|
||||
|
||||
#include <qtimer.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDelete
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDelete::SafeDelete()
|
||||
{
|
||||
lock = 0;
|
||||
}
|
||||
|
||||
SafeDelete::~SafeDelete()
|
||||
{
|
||||
if(lock)
|
||||
lock->dying();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteLater(QObject *o)
|
||||
{
|
||||
if(!lock)
|
||||
deleteSingle(o);
|
||||
else
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDelete::unlock()
|
||||
{
|
||||
lock = 0;
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteAll()
|
||||
{
|
||||
if(list.isEmpty())
|
||||
return;
|
||||
|
||||
QObjectList::Iterator it = list.begin();
|
||||
for(QObjectList::Iterator it = list.begin(); it != list.end(); ++it)
|
||||
deleteSingle(*it);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteSingle(QObject *o)
|
||||
{
|
||||
o->deleteLater();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLock
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLock::SafeDeleteLock(SafeDelete *sd)
|
||||
{
|
||||
own = false;
|
||||
if(!sd->lock) {
|
||||
_sd = sd;
|
||||
_sd->lock = this;
|
||||
}
|
||||
else
|
||||
_sd = 0;
|
||||
}
|
||||
|
||||
SafeDeleteLock::~SafeDeleteLock()
|
||||
{
|
||||
if(_sd) {
|
||||
_sd->unlock();
|
||||
if(own)
|
||||
delete _sd;
|
||||
}
|
||||
}
|
||||
|
||||
void SafeDeleteLock::dying()
|
||||
{
|
||||
_sd = new SafeDelete(*_sd);
|
||||
own = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLater
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLater *SafeDeleteLater::self = 0;
|
||||
|
||||
SafeDeleteLater *SafeDeleteLater::ensureExists()
|
||||
{
|
||||
if(!self)
|
||||
new SafeDeleteLater();
|
||||
return self;
|
||||
}
|
||||
|
||||
SafeDeleteLater::SafeDeleteLater()
|
||||
{
|
||||
self = this;
|
||||
QTimer::singleShot(0, this, SLOT(explode()));
|
||||
}
|
||||
|
||||
SafeDeleteLater::~SafeDeleteLater()
|
||||
{
|
||||
while (!list.isEmpty())
|
||||
delete list.takeFirst();
|
||||
self = 0;
|
||||
}
|
||||
|
||||
void SafeDeleteLater::deleteItLater(QObject *o)
|
||||
{
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDeleteLater::explode()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
60
iris-legacy/cutestuff/legacy/safedelete.h
Normal file
60
iris-legacy/cutestuff/legacy/safedelete.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef SAFEDELETE_H
|
||||
#define SAFEDELETE_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qobject.h>
|
||||
|
||||
class SafeDelete;
|
||||
class SafeDeleteLock
|
||||
{
|
||||
public:
|
||||
SafeDeleteLock(SafeDelete *sd);
|
||||
~SafeDeleteLock();
|
||||
|
||||
private:
|
||||
SafeDelete *_sd;
|
||||
bool own;
|
||||
friend class SafeDelete;
|
||||
void dying();
|
||||
};
|
||||
|
||||
class SafeDelete
|
||||
{
|
||||
public:
|
||||
SafeDelete();
|
||||
~SafeDelete();
|
||||
|
||||
void deleteLater(QObject *o);
|
||||
|
||||
// same as QObject::deleteLater()
|
||||
static void deleteSingle(QObject *o);
|
||||
|
||||
private:
|
||||
QObjectList list;
|
||||
void deleteAll();
|
||||
|
||||
friend class SafeDeleteLock;
|
||||
SafeDeleteLock *lock;
|
||||
void unlock();
|
||||
};
|
||||
|
||||
class SafeDeleteLater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SafeDeleteLater *ensureExists();
|
||||
void deleteItLater(QObject *o);
|
||||
|
||||
private slots:
|
||||
void explode();
|
||||
|
||||
private:
|
||||
SafeDeleteLater();
|
||||
~SafeDeleteLater();
|
||||
|
||||
QObjectList list;
|
||||
friend class SafeDelete;
|
||||
static SafeDeleteLater *self;
|
||||
};
|
||||
|
||||
#endif
|
||||
111
iris-legacy/cutestuff/legacy/servsock.cpp
Normal file
111
iris-legacy/cutestuff/legacy/servsock.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* servsock.cpp - simple wrapper to QServerSocket
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "servsock.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSock
|
||||
//----------------------------------------------------------------------------
|
||||
class ServSock::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
ServSockSignal *serv;
|
||||
};
|
||||
|
||||
ServSock::ServSock(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
ServSock::~ServSock()
|
||||
{
|
||||
stop();
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool ServSock::isActive() const
|
||||
{
|
||||
return (d->serv ? true: false);
|
||||
}
|
||||
|
||||
bool ServSock::listen(quint16 port)
|
||||
{
|
||||
stop();
|
||||
|
||||
d->serv = new ServSockSignal(this);
|
||||
if(!d->serv->listen(QHostAddress::Any, port)) {
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
return false;
|
||||
}
|
||||
connect(d->serv, SIGNAL(connectionReady(int)), SLOT(sss_connectionReady(int)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServSock::stop()
|
||||
{
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
int ServSock::port() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverPort();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
QHostAddress ServSock::address() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
void ServSock::sss_connectionReady(int s)
|
||||
{
|
||||
connectionReady(s);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSockSignal
|
||||
//----------------------------------------------------------------------------
|
||||
ServSockSignal::ServSockSignal(QObject *parent)
|
||||
:QTcpServer(parent)
|
||||
{
|
||||
setMaxPendingConnections(16);
|
||||
}
|
||||
|
||||
void ServSockSignal::incomingConnection(int socketDescriptor)
|
||||
{
|
||||
connectionReady(socketDescriptor);
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
68
iris-legacy/cutestuff/legacy/servsock.h
Normal file
68
iris-legacy/cutestuff/legacy/servsock.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* servsock.h - simple wrapper to QServerSocket
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SERVSOCK_H
|
||||
#define CS_SERVSOCK_H
|
||||
|
||||
#include <QTcpServer>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class ServSock : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServSock(QObject *parent=0);
|
||||
~ServSock();
|
||||
|
||||
bool isActive() const;
|
||||
bool listen(quint16 port);
|
||||
void stop();
|
||||
int port() const;
|
||||
QHostAddress address() const;
|
||||
|
||||
signals:
|
||||
void connectionReady(int);
|
||||
|
||||
private slots:
|
||||
void sss_connectionReady(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
class ServSockSignal : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServSockSignal(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void connectionReady(int);
|
||||
|
||||
protected:
|
||||
// reimplemented
|
||||
void incomingConnection(int socketDescriptor);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
313
iris-legacy/cutestuff/legacy/srvresolver.cpp
Normal file
313
iris-legacy/cutestuff/legacy/srvresolver.cpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* srvresolver.cpp - class to simplify SRV lookups
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srvresolver.h"
|
||||
|
||||
#include <q3cstring.h>
|
||||
#include <qtimer.h>
|
||||
#include <q3dns.h>
|
||||
//Added by qt3to4:
|
||||
#include <QList>
|
||||
#include <QtAlgorithms>
|
||||
#include "safedelete.h"
|
||||
#include "psilogger.h"
|
||||
|
||||
#ifndef NO_NDNS
|
||||
#include "ndns.h"
|
||||
#endif
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
bool serverLessThan(const Q3Dns::Server &s1, const Q3Dns::Server &s2)
|
||||
{
|
||||
int a = s1.priority;
|
||||
int b = s2.priority;
|
||||
int j = s1.weight;
|
||||
int k = s2.weight;
|
||||
return a < b || (a == b && j < k);
|
||||
}
|
||||
|
||||
static void sortSRVList(QList<Q3Dns::Server> &list)
|
||||
{
|
||||
qStableSort(list.begin(), list.end(), serverLessThan);
|
||||
}
|
||||
|
||||
class SrvResolver::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
Q3Dns *qdns;
|
||||
#ifndef NO_NDNS
|
||||
NDns ndns;
|
||||
#endif
|
||||
|
||||
bool failed;
|
||||
QHostAddress resultAddress;
|
||||
Q_UINT16 resultPort;
|
||||
|
||||
bool srvonly;
|
||||
QString srv;
|
||||
QList<Q3Dns::Server> servers;
|
||||
bool aaaa;
|
||||
|
||||
QTimer t;
|
||||
SafeDelete sd;
|
||||
};
|
||||
|
||||
SrvResolver::SrvResolver(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
d->qdns = 0;
|
||||
|
||||
#ifndef NO_NDNS
|
||||
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
#endif
|
||||
connect(&d->t, SIGNAL(timeout()), SLOT(t_timeout()));
|
||||
stop();
|
||||
}
|
||||
|
||||
SrvResolver::~SrvResolver()
|
||||
{
|
||||
stop();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("SrvResolver::resolve(%1, %2, %3, %4)").arg(server).arg(type).arg(proto).arg(srvOnly));
|
||||
stop();
|
||||
|
||||
d->failed = false;
|
||||
d->srvonly = srvOnly;
|
||||
d->srv = QString("_") + type + "._" + proto + '.' + server;
|
||||
d->t.start(15000, true);
|
||||
d->qdns = new Q3Dns;
|
||||
connect(d->qdns, SIGNAL(resultsReady()), SLOT(qdns_done()));
|
||||
d->qdns->setRecordType(Q3Dns::Srv);
|
||||
d->qdns->setLabel(d->srv);
|
||||
}
|
||||
|
||||
void SrvResolver::resolve(const QString &server, const QString &type, const QString &proto)
|
||||
{
|
||||
resolve(server, type, proto, false);
|
||||
}
|
||||
|
||||
void SrvResolver::resolveSrvOnly(const QString &server, const QString &type, const QString &proto)
|
||||
{
|
||||
resolve(server, type, proto, true);
|
||||
}
|
||||
|
||||
void SrvResolver::next()
|
||||
{
|
||||
if(d->servers.isEmpty())
|
||||
return;
|
||||
|
||||
tryNext();
|
||||
}
|
||||
|
||||
void SrvResolver::stop()
|
||||
{
|
||||
if(d->t.isActive())
|
||||
d->t.stop();
|
||||
if(d->qdns) {
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
}
|
||||
#ifndef NO_NDNS
|
||||
if(d->ndns.isBusy())
|
||||
d->ndns.stop();
|
||||
#endif
|
||||
d->resultAddress = QHostAddress();
|
||||
d->resultPort = 0;
|
||||
d->servers.clear();
|
||||
d->srv = "";
|
||||
d->failed = true;
|
||||
}
|
||||
|
||||
bool SrvResolver::isBusy() const
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
if(d->qdns || d->ndns.isBusy())
|
||||
#else
|
||||
if(d->qdns)
|
||||
#endif
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<Q3Dns::Server> SrvResolver::servers() const
|
||||
{
|
||||
return d->servers;
|
||||
}
|
||||
|
||||
bool SrvResolver::failed() const
|
||||
{
|
||||
return d->failed;
|
||||
}
|
||||
|
||||
QHostAddress SrvResolver::resultAddress() const
|
||||
{
|
||||
return d->resultAddress;
|
||||
}
|
||||
|
||||
Q_UINT16 SrvResolver::resultPort() const
|
||||
{
|
||||
return d->resultPort;
|
||||
}
|
||||
|
||||
void SrvResolver::tryNext()
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::tryNext() d->ndns.resolve(%2)").arg(d->srv).arg(d->servers.first().name));
|
||||
d->ndns.resolve(d->servers.first().name);
|
||||
#else
|
||||
d->qdns = new Q3Dns;
|
||||
connect(d->qdns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
if(d->aaaa)
|
||||
d->qdns->setRecordType(Q3Dns::Aaaa); // IPv6
|
||||
else
|
||||
d->qdns->setRecordType(Q3Dns::A); // IPv4
|
||||
d->qdns->setLabel(d->servers.first().name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SrvResolver::qdns_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::qdns_done() d->qdns = %2; d->qdns->isWorking() = %3; d->qdns->servers().count() = %4").arg(d->srv).arg((long)d->qdns).arg(d->qdns ? d->qdns->isWorking() : 0).arg(d->qdns ? d->qdns->servers().count() : 0));
|
||||
if(!d->qdns)
|
||||
return;
|
||||
|
||||
// apparently we sometimes get this signal even though the results aren't ready
|
||||
if(d->qdns->isWorking())
|
||||
return;
|
||||
d->t.stop();
|
||||
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
// grab the server list and destroy the qdns object
|
||||
QList<Q3Dns::Server> list;
|
||||
if(d->qdns->recordType() == Q3Dns::Srv)
|
||||
list = d->qdns->servers();
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
|
||||
if(list.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
sortSRVList(list);
|
||||
d->servers = list;
|
||||
|
||||
if(d->srvonly)
|
||||
resultsReady();
|
||||
else {
|
||||
// kick it off
|
||||
d->aaaa = true;
|
||||
tryNext();
|
||||
}
|
||||
}
|
||||
|
||||
void SrvResolver::ndns_done()
|
||||
{
|
||||
#ifndef NO_NDNS
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
QHostAddress r = d->ndns.result();
|
||||
int port = d->servers.first().port;
|
||||
d->servers.remove(d->servers.begin());
|
||||
|
||||
PsiLogger::instance()->log(QString("SrvResolver(%1)::ndns_done() r.isNull = %2, r = %3, port = %4").arg(d->srv).arg(r.isNull()).arg(r.toString()).arg(port));
|
||||
|
||||
if(!r.isNull()) {
|
||||
d->resultAddress = r;
|
||||
d->resultPort = port;
|
||||
resultsReady();
|
||||
}
|
||||
else {
|
||||
// failed? bail if last one
|
||||
if(d->servers.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise try the next
|
||||
tryNext();
|
||||
}
|
||||
#else
|
||||
if(!d->qdns)
|
||||
return;
|
||||
|
||||
// apparently we sometimes get this signal even though the results aren't ready
|
||||
if(d->qdns->isWorking())
|
||||
return;
|
||||
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
// grab the address list and destroy the qdns object
|
||||
QList<QHostAddress> list;
|
||||
if(d->qdns->recordType() == Q3Dns::A || d->qdns->recordType() == Q3Dns::Aaaa)
|
||||
list = d->qdns->addresses();
|
||||
d->qdns->disconnect(this);
|
||||
d->sd.deleteLater(d->qdns);
|
||||
d->qdns = 0;
|
||||
|
||||
if(!list.isEmpty()) {
|
||||
int port = d->servers.first().port;
|
||||
d->servers.remove(d->servers.begin());
|
||||
d->aaaa = true;
|
||||
|
||||
d->resultAddress = list.first();
|
||||
d->resultPort = port;
|
||||
resultsReady();
|
||||
}
|
||||
else {
|
||||
if(!d->aaaa)
|
||||
d->servers.remove(d->servers.begin());
|
||||
d->aaaa = !d->aaaa;
|
||||
|
||||
// failed? bail if last one
|
||||
if(d->servers.isEmpty()) {
|
||||
stop();
|
||||
resultsReady();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise try the next
|
||||
tryNext();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SrvResolver::t_timeout()
|
||||
{
|
||||
SafeDeleteLock s(&d->sd);
|
||||
|
||||
stop();
|
||||
resultsReady();
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
66
iris-legacy/cutestuff/legacy/srvresolver.h
Normal file
66
iris-legacy/cutestuff/legacy/srvresolver.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* srvresolver.h - class to simplify SRV lookups
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SRVRESOLVER_H
|
||||
#define CS_SRVRESOLVER_H
|
||||
|
||||
#include <QList>
|
||||
#include <q3dns.h>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class SrvResolver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SrvResolver(QObject *parent=0);
|
||||
~SrvResolver();
|
||||
|
||||
void resolve(const QString &server, const QString &type, const QString &proto);
|
||||
void resolveSrvOnly(const QString &server, const QString &type, const QString &proto);
|
||||
void next();
|
||||
void stop();
|
||||
bool isBusy() const;
|
||||
|
||||
QList<Q3Dns::Server> servers() const;
|
||||
|
||||
bool failed() const;
|
||||
QHostAddress resultAddress() const;
|
||||
Q_UINT16 resultPort() const;
|
||||
|
||||
signals:
|
||||
void resultsReady();
|
||||
|
||||
private slots:
|
||||
void qdns_done();
|
||||
void ndns_done();
|
||||
void t_timeout();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void tryNext();
|
||||
void resolve(const QString &server, const QString &type, const QString &proto, bool srvOnly);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
474
iris-legacy/cutestuff/network/bsocket.cpp
Normal file
474
iris-legacy/cutestuff/network/bsocket.cpp
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* bsocket.cpp - QSocket wrapper based on Bytestream with SRV DNS support
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "bsocket.h"
|
||||
|
||||
//#include "safedelete.h"
|
||||
#ifndef NO_NDNS
|
||||
#include "ndns.h"
|
||||
#endif
|
||||
#include "srvresolver.h"
|
||||
|
||||
//#define BS_DEBUG
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define READBUFSIZE 65536
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
#include "psilogger.h"
|
||||
|
||||
class QTcpSocketSignalRelay : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QTcpSocketSignalRelay(QTcpSocket *sock, QObject *parent = 0)
|
||||
:QObject(parent)
|
||||
{
|
||||
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
|
||||
connect(sock, SIGNAL(hostFound()), SLOT(sock_hostFound()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(connected()), SLOT(sock_connected()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)), Qt::QueuedConnection);
|
||||
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
signals:
|
||||
void hostFound();
|
||||
void connected();
|
||||
void disconnected();
|
||||
void readyRead();
|
||||
void bytesWritten(qint64);
|
||||
void error(QAbstractSocket::SocketError);
|
||||
|
||||
public slots:
|
||||
void sock_hostFound()
|
||||
{
|
||||
emit hostFound();
|
||||
}
|
||||
|
||||
void sock_connected()
|
||||
{
|
||||
emit connected();
|
||||
}
|
||||
|
||||
void sock_disconnected()
|
||||
{
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void sock_readyRead()
|
||||
{
|
||||
emit readyRead();
|
||||
}
|
||||
|
||||
void sock_bytesWritten(qint64 x)
|
||||
{
|
||||
emit bytesWritten(x);
|
||||
}
|
||||
|
||||
void sock_error(QAbstractSocket::SocketError x)
|
||||
{
|
||||
emit error(x);
|
||||
}
|
||||
};
|
||||
|
||||
class BSocket::Private
|
||||
{
|
||||
public:
|
||||
Private()
|
||||
{
|
||||
qsock = 0;
|
||||
qsock_relay = 0;
|
||||
}
|
||||
|
||||
QTcpSocket *qsock;
|
||||
QTcpSocketSignalRelay *qsock_relay;
|
||||
int state;
|
||||
|
||||
#ifndef NO_NDNS
|
||||
NDns ndns;
|
||||
#endif
|
||||
SrvResolver srv;
|
||||
QString host;
|
||||
int port;
|
||||
//SafeDelete sd;
|
||||
};
|
||||
|
||||
BSocket::BSocket(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
#ifndef NO_NDNS
|
||||
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
|
||||
#endif
|
||||
connect(&d->srv, SIGNAL(resultsReady()), SLOT(srv_done()));
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
BSocket::~BSocket()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::~BSocket()").arg(LOG_THIS));
|
||||
}
|
||||
|
||||
void BSocket::reset(bool clear)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::reset()").arg(LOG_THIS));
|
||||
|
||||
if(d->qsock) {
|
||||
delete d->qsock_relay;
|
||||
d->qsock_relay = 0;
|
||||
|
||||
/*d->qsock->disconnect(this);
|
||||
|
||||
if(!clear && d->qsock->isOpen() && d->qsock->isValid()) {*/
|
||||
// move remaining into the local queue
|
||||
QByteArray block(d->qsock->bytesAvailable(), 0);
|
||||
d->qsock->read(block.data(), block.size());
|
||||
appendRead(block);
|
||||
//}
|
||||
|
||||
//d->sd.deleteLater(d->qsock);
|
||||
// delete d->qsock;
|
||||
d->qsock->deleteLater();
|
||||
d->qsock = 0;
|
||||
}
|
||||
else {
|
||||
if(clear)
|
||||
clearReadBuffer();
|
||||
}
|
||||
|
||||
if(d->srv.isBusy())
|
||||
d->srv.stop();
|
||||
#ifndef NO_NDNS
|
||||
if(d->ndns.isBusy())
|
||||
d->ndns.stop();
|
||||
#endif
|
||||
d->state = Idle;
|
||||
}
|
||||
|
||||
void BSocket::ensureSocket()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::ensureSocket()").arg(LOG_THIS));
|
||||
if(!d->qsock) {
|
||||
d->qsock = new QTcpSocket;
|
||||
#if QT_VERSION >= 0x030200
|
||||
d->qsock->setReadBufferSize(READBUFSIZE);
|
||||
#endif
|
||||
d->qsock_relay = new QTcpSocketSignalRelay(d->qsock);
|
||||
connect(d->qsock_relay, SIGNAL(hostFound()), SLOT(qs_hostFound()));
|
||||
connect(d->qsock_relay, SIGNAL(connected()), SLOT(qs_connected()));
|
||||
connect(d->qsock_relay, SIGNAL(disconnected()), SLOT(qs_closed()));
|
||||
connect(d->qsock_relay, SIGNAL(readyRead()), SLOT(qs_readyRead()));
|
||||
connect(d->qsock_relay, SIGNAL(bytesWritten(qint64)), SLOT(qs_bytesWritten(qint64)));
|
||||
connect(d->qsock_relay, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(qs_error(QAbstractSocket::SocketError)));
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::connectToHost(const QString &host, quint16 port)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::connectToHost(%2, %3)").arg(LOG_THIS).arg(host).arg(port));
|
||||
reset(true);
|
||||
d->host = host;
|
||||
d->port = port;
|
||||
#ifdef NO_NDNS
|
||||
d->state = Connecting;
|
||||
do_connect();
|
||||
#else
|
||||
d->state = HostLookup;
|
||||
d->ndns.resolve(d->host);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSocket::connectToServer(const QString &srv, const QString &type)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::connectToServer(%2, %3)").arg(LOG_THIS).arg(srv).arg(type));
|
||||
reset(true);
|
||||
d->state = HostLookup;
|
||||
d->srv.resolve(srv, type, "tcp");
|
||||
}
|
||||
|
||||
int BSocket::socket() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->socketDescriptor();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void BSocket::setSocket(int s)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::setSocket(%2)").arg(LOG_THIS).arg(s));
|
||||
reset(true);
|
||||
ensureSocket();
|
||||
d->state = Connected;
|
||||
d->qsock->setSocketDescriptor(s);
|
||||
}
|
||||
|
||||
int BSocket::state() const
|
||||
{
|
||||
return d->state;
|
||||
}
|
||||
|
||||
bool BSocket::isOpen() const
|
||||
{
|
||||
if(d->state == Connected)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void BSocket::close()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::close()").arg(LOG_THIS));
|
||||
if(d->state == Idle)
|
||||
return;
|
||||
|
||||
if(d->qsock) {
|
||||
d->qsock->close();
|
||||
d->state = Closing;
|
||||
if(d->qsock->bytesToWrite() == 0)
|
||||
reset();
|
||||
}
|
||||
else {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::write(const QByteArray &a)
|
||||
{
|
||||
if(d->state != Connected)
|
||||
return;
|
||||
#ifdef BS_DEBUG
|
||||
QString s = QString::fromUtf8(a);
|
||||
fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), s.latin1());
|
||||
#endif
|
||||
d->qsock->write(a.data(), a.size());
|
||||
}
|
||||
|
||||
QByteArray BSocket::read(int bytes)
|
||||
{
|
||||
QByteArray block;
|
||||
if(d->qsock) {
|
||||
int max = bytesAvailable();
|
||||
if(bytes <= 0 || bytes > max)
|
||||
bytes = max;
|
||||
block.resize(bytes);
|
||||
d->qsock->read(block.data(), block.size());
|
||||
}
|
||||
else
|
||||
block = ByteStream::read(bytes);
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
QString s = QString::fromUtf8(block);
|
||||
fprintf(stderr, "BSocket: read [%d]: {%s}\n", block.size(), s.latin1());
|
||||
#endif
|
||||
return block;
|
||||
}
|
||||
|
||||
int BSocket::bytesAvailable() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->bytesAvailable();
|
||||
else
|
||||
return ByteStream::bytesAvailable();
|
||||
}
|
||||
|
||||
int BSocket::bytesToWrite() const
|
||||
{
|
||||
if(!d->qsock)
|
||||
return 0;
|
||||
return d->qsock->bytesToWrite();
|
||||
}
|
||||
|
||||
QHostAddress BSocket::address() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->localAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
quint16 BSocket::port() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->localPort();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
QHostAddress BSocket::peerAddress() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->peerAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
quint16 BSocket::peerPort() const
|
||||
{
|
||||
if(d->qsock)
|
||||
return d->qsock->peerPort();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BSocket::srv_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::srv_done()").arg(LOG_THIS));
|
||||
if(d->srv.failed()) {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error resolving hostname.\n");
|
||||
#endif
|
||||
error(ErrHostNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
d->host = d->srv.resultAddress().toString();
|
||||
d->port = d->srv.resultPort();
|
||||
do_connect();
|
||||
//QTimer::singleShot(0, this, SLOT(do_connect()));
|
||||
//hostFound();
|
||||
}
|
||||
|
||||
void BSocket::ndns_done()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::ndns_done()").arg(LOG_THIS));
|
||||
#ifndef NO_NDNS
|
||||
if(!d->ndns.result().isNull()) {
|
||||
d->host = d->ndns.resultString();
|
||||
d->state = Connecting;
|
||||
do_connect();
|
||||
//QTimer::singleShot(0, this, SLOT(do_connect()));
|
||||
//hostFound();
|
||||
}
|
||||
else {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error resolving hostname.\n");
|
||||
#endif
|
||||
error(ErrHostNotFound);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BSocket::do_connect()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::do_connect()").arg(LOG_THIS));
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connecting to %s:%d\n", d->host.latin1(), d->port);
|
||||
#endif
|
||||
ensureSocket();
|
||||
d->qsock->connectToHost(d->host, d->port);
|
||||
}
|
||||
|
||||
void BSocket::qs_hostFound()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_hostFound()").arg(LOG_THIS));
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
}
|
||||
|
||||
void BSocket::qs_connected()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_connected()").arg(LOG_THIS));
|
||||
d->state = Connected;
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connected.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
connected();
|
||||
}
|
||||
|
||||
void BSocket::qs_closed()
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_closed()").arg(LOG_THIS));
|
||||
if(d->state == Closing)
|
||||
{
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Delayed Close Finished.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void BSocket::qs_readyRead()
|
||||
{
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
readyRead();
|
||||
}
|
||||
|
||||
void BSocket::qs_bytesWritten(qint64 x64)
|
||||
{
|
||||
int x = x64;
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: BytesWritten [%d].\n", x);
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
bytesWritten(x);
|
||||
}
|
||||
|
||||
void BSocket::qs_error(QAbstractSocket::SocketError x)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("%1 BSocket::qs_error(%2)").arg(LOG_THIS).arg(x));
|
||||
if(x == QTcpSocket::RemoteHostClosedError) {
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Connection Closed.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
reset();
|
||||
connectionClosed();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BS_DEBUG
|
||||
fprintf(stderr, "BSocket: Error.\n");
|
||||
#endif
|
||||
//SafeDeleteLock s(&d->sd);
|
||||
|
||||
// connection error during SRV host connect? try next
|
||||
if(d->state == HostLookup && (x == QTcpSocket::ConnectionRefusedError || x == QTcpSocket::HostNotFoundError)) {
|
||||
d->srv.next();
|
||||
return;
|
||||
}
|
||||
|
||||
reset();
|
||||
if(x == QTcpSocket::ConnectionRefusedError)
|
||||
error(ErrConnectionRefused);
|
||||
else if(x == QTcpSocket::HostNotFoundError)
|
||||
error(ErrHostNotFound);
|
||||
else
|
||||
error(ErrRead);
|
||||
}
|
||||
|
||||
#include "bsocket.moc"
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
90
iris-legacy/cutestuff/network/bsocket.h
Normal file
90
iris-legacy/cutestuff/network/bsocket.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* bsocket.h - QSocket wrapper based on Bytestream with SRV DNS support
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_BSOCKET_H
|
||||
#define CS_BSOCKET_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
class QString;
|
||||
class QObject;
|
||||
class QByteArray;
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class BSocket : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound };
|
||||
enum State { Idle, HostLookup, Connecting, Connected, Closing };
|
||||
BSocket(QObject *parent=0);
|
||||
~BSocket();
|
||||
|
||||
void connectToHost(const QString &host, quint16 port);
|
||||
void connectToServer(const QString &srv, const QString &type);
|
||||
int socket() const;
|
||||
void setSocket(int);
|
||||
int state() const;
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
// local
|
||||
QHostAddress address() const;
|
||||
quint16 port() const;
|
||||
|
||||
// remote
|
||||
QHostAddress peerAddress() const;
|
||||
quint16 peerPort() const;
|
||||
|
||||
signals:
|
||||
void hostFound();
|
||||
void connected();
|
||||
|
||||
private slots:
|
||||
void qs_hostFound();
|
||||
void qs_connected();
|
||||
void qs_closed();
|
||||
void qs_readyRead();
|
||||
void qs_bytesWritten(qint64);
|
||||
void qs_error(QAbstractSocket::SocketError);
|
||||
void srv_done();
|
||||
void ndns_done();
|
||||
void do_connect();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
void ensureSocket();
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
363
iris-legacy/cutestuff/network/httpconnect.cpp
Normal file
363
iris-legacy/cutestuff/network/httpconnect.cpp
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* httpconnect.cpp - HTTP "CONNECT" proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "httpconnect.h"
|
||||
|
||||
#include <qstringlist.h>
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
#include "bsocket.h"
|
||||
#include <QtCrypto>
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
static QString extractLine(QByteArray *buf, bool *found)
|
||||
{
|
||||
// Scan for newline
|
||||
int index = buf->indexOf ("\r\n");
|
||||
if (index == -1) {
|
||||
// Newline not found
|
||||
if (found)
|
||||
*found = false;
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
// Found newline
|
||||
QString s = QString::fromAscii(buf->left(index));
|
||||
buf->remove(0, index + 2);
|
||||
|
||||
if (found)
|
||||
*found = true;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg)
|
||||
{
|
||||
int n = line.find(' ');
|
||||
if(n == -1)
|
||||
return false;
|
||||
if(proto)
|
||||
*proto = line.mid(0, n);
|
||||
++n;
|
||||
int n2 = line.find(' ', n);
|
||||
if(n2 == -1)
|
||||
return false;
|
||||
if(code)
|
||||
*code = line.mid(n, n2-n).toInt();
|
||||
n = n2+1;
|
||||
if(msg)
|
||||
*msg = line.mid(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
class HttpConnect::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
BSocket sock;
|
||||
QString host;
|
||||
int port;
|
||||
QString user, pass;
|
||||
QString real_host;
|
||||
int real_port;
|
||||
|
||||
QByteArray recvBuf;
|
||||
|
||||
bool inHeader;
|
||||
QStringList headerLines;
|
||||
|
||||
int toWrite;
|
||||
bool active;
|
||||
};
|
||||
|
||||
HttpConnect::HttpConnect(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||
connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||
connect(&d->sock, SIGNAL(delayedCloseFinished()), SLOT(sock_delayedCloseFinished()));
|
||||
connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||
connect(&d->sock, SIGNAL(bytesWritten(int)), SLOT(sock_bytesWritten(int)));
|
||||
connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpConnect::~HttpConnect()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpConnect::reset(bool clear)
|
||||
{
|
||||
if(d->sock.state() != BSocket::Idle)
|
||||
d->sock.close();
|
||||
if(clear) {
|
||||
clearReadBuffer();
|
||||
d->recvBuf.resize(0);
|
||||
}
|
||||
d->active = false;
|
||||
}
|
||||
|
||||
void HttpConnect::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
void HttpConnect::connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
d->host = proxyHost;
|
||||
d->port = proxyPort;
|
||||
d->real_host = host;
|
||||
d->real_port = port;
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: Connecting to %s:%d", proxyHost.latin1(), proxyPort);
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
d->sock.connectToHost(d->host, d->port);
|
||||
}
|
||||
|
||||
bool HttpConnect::isOpen() const
|
||||
{
|
||||
return d->active;
|
||||
}
|
||||
|
||||
void HttpConnect::close()
|
||||
{
|
||||
d->sock.close();
|
||||
if(d->sock.bytesToWrite() == 0)
|
||||
reset();
|
||||
}
|
||||
|
||||
void HttpConnect::write(const QByteArray &buf)
|
||||
{
|
||||
if(d->active)
|
||||
d->sock.write(buf);
|
||||
}
|
||||
|
||||
QByteArray HttpConnect::read(int bytes)
|
||||
{
|
||||
return ByteStream::read(bytes);
|
||||
}
|
||||
|
||||
int HttpConnect::bytesAvailable() const
|
||||
{
|
||||
return ByteStream::bytesAvailable();
|
||||
}
|
||||
|
||||
int HttpConnect::bytesToWrite() const
|
||||
{
|
||||
if(d->active)
|
||||
return d->sock.bytesToWrite();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HttpConnect::sock_connected()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: Connected\n");
|
||||
#endif
|
||||
d->inHeader = true;
|
||||
d->headerLines.clear();
|
||||
|
||||
// connected, now send the request
|
||||
QString s;
|
||||
s += QString("CONNECT ") + d->real_host + ':' + QString::number(d->real_port) + " HTTP/1.0\r\n";
|
||||
if(!d->user.isEmpty()) {
|
||||
QString str = d->user + ':' + d->pass;
|
||||
s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
|
||||
}
|
||||
s += "Pragma: no-cache\r\n";
|
||||
s += "\r\n";
|
||||
|
||||
Q3CString cs = s.utf8();
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
d->toWrite = block.size();
|
||||
d->sock.write(block);
|
||||
}
|
||||
|
||||
void HttpConnect::sock_connectionClosed()
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
connectionClosed();
|
||||
}
|
||||
else {
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_delayedCloseFinished()
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_readyRead()
|
||||
{
|
||||
QByteArray block = d->sock.read();
|
||||
|
||||
if(!d->active) {
|
||||
ByteStream::appendArray(&d->recvBuf, block);
|
||||
|
||||
if(d->inHeader) {
|
||||
// grab available lines
|
||||
while(1) {
|
||||
bool found;
|
||||
QString line = extractLine(&d->recvBuf, &found);
|
||||
if(!found)
|
||||
break;
|
||||
if(line.isEmpty()) {
|
||||
d->inHeader = false;
|
||||
break;
|
||||
}
|
||||
d->headerLines += line;
|
||||
}
|
||||
|
||||
// done with grabbing the header?
|
||||
if(!d->inHeader) {
|
||||
QString str = d->headerLines.first();
|
||||
d->headerLines.remove(d->headerLines.begin());
|
||||
|
||||
QString proto;
|
||||
int code;
|
||||
QString msg;
|
||||
if(!extractMainHeader(str, &proto, &code, &msg)) {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: invalid header!\n");
|
||||
#endif
|
||||
reset(true);
|
||||
error(ErrProxyNeg);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1());
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it)
|
||||
fprintf(stderr, "HttpConnect: * [%s]\n", (*it).latin1());
|
||||
#endif
|
||||
}
|
||||
|
||||
if(code == 200) { // OK
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: << Success >>\n");
|
||||
#endif
|
||||
d->active = true;
|
||||
connected();
|
||||
|
||||
if(!d->recvBuf.isEmpty()) {
|
||||
appendRead(d->recvBuf);
|
||||
d->recvBuf.resize(0);
|
||||
readyRead();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
QString errStr;
|
||||
if(code == 407) { // Authentication failed
|
||||
err = ErrProxyAuth;
|
||||
errStr = tr("Authentication failed");
|
||||
}
|
||||
else if(code == 404) { // Host not found
|
||||
err = ErrHostNotFound;
|
||||
errStr = tr("Host not found");
|
||||
}
|
||||
else if(code == 403) { // Access denied
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Access denied");
|
||||
}
|
||||
else if(code == 503) { // Connection refused
|
||||
err = ErrConnectionRefused;
|
||||
errStr = tr("Connection refused");
|
||||
}
|
||||
else { // invalid reply
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Invalid reply");
|
||||
}
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpConnect: << Error >> [%s]\n", errStr.latin1());
|
||||
#endif
|
||||
reset(true);
|
||||
error(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
appendRead(block);
|
||||
readyRead();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpConnect::sock_bytesWritten(int x)
|
||||
{
|
||||
if(d->toWrite > 0) {
|
||||
int size = x;
|
||||
if(d->toWrite < x)
|
||||
size = d->toWrite;
|
||||
d->toWrite -= size;
|
||||
x -= size;
|
||||
}
|
||||
|
||||
if(d->active && x > 0)
|
||||
bytesWritten(x);
|
||||
}
|
||||
|
||||
void HttpConnect::sock_error(int x)
|
||||
{
|
||||
if(d->active) {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
}
|
||||
else {
|
||||
reset(true);
|
||||
if(x == BSocket::ErrHostNotFound)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrConnectionRefused)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrRead)
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
67
iris-legacy/cutestuff/network/httpconnect.h
Normal file
67
iris-legacy/cutestuff/network/httpconnect.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* httpconnect.h - HTTP "CONNECT" proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_HTTPCONNECT_H
|
||||
#define CS_HTTPCONNECT_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class HttpConnect : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpConnect(QObject *parent=0);
|
||||
~HttpConnect();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_delayedCloseFinished();
|
||||
void sock_readyRead();
|
||||
void sock_bytesWritten(int);
|
||||
void sock_error(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
666
iris-legacy/cutestuff/network/httppoll.cpp
Normal file
666
iris-legacy/cutestuff/network/httppoll.cpp
Normal file
|
|
@ -0,0 +1,666 @@
|
|||
/*
|
||||
* httppoll.cpp - HTTP polling proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "httppoll.h"
|
||||
|
||||
#include <qstringlist.h>
|
||||
#include <q3url.h>
|
||||
#include <qtimer.h>
|
||||
#include <qpointer.h>
|
||||
#include <QtCrypto>
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
#include <stdlib.h>
|
||||
#include "bsocket.h"
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define POLL_KEYS 64
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
static QByteArray randomArray(int size)
|
||||
{
|
||||
QByteArray a(size);
|
||||
for(int n = 0; n < size; ++n)
|
||||
a[n] = (char)(256.0*rand()/(RAND_MAX+1.0));
|
||||
return a;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HttpPoll
|
||||
//----------------------------------------------------------------------------
|
||||
static QString hpk(int n, const QString &s)
|
||||
{
|
||||
if(n == 0)
|
||||
return s;
|
||||
else
|
||||
return QCA::Base64().arrayToString( QCA::Hash("sha1").hash( Q3CString(hpk(n - 1, s).latin1()) ).toByteArray() );
|
||||
}
|
||||
|
||||
class HttpPoll::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
HttpProxyPost http;
|
||||
QString host;
|
||||
int port;
|
||||
QString user, pass;
|
||||
QString url;
|
||||
bool use_proxy;
|
||||
|
||||
QByteArray out;
|
||||
|
||||
int state;
|
||||
bool closing;
|
||||
QString ident;
|
||||
|
||||
QTimer *t;
|
||||
|
||||
QString key[POLL_KEYS];
|
||||
int key_n;
|
||||
|
||||
int polltime;
|
||||
};
|
||||
|
||||
HttpPoll::HttpPoll(QObject *parent)
|
||||
:ByteStream(parent)
|
||||
{
|
||||
d = new Private;
|
||||
|
||||
d->polltime = 30;
|
||||
d->t = new QTimer;
|
||||
connect(d->t, SIGNAL(timeout()), SLOT(do_sync()));
|
||||
|
||||
connect(&d->http, SIGNAL(result()), SLOT(http_result()));
|
||||
connect(&d->http, SIGNAL(error(int)), SLOT(http_error(int)));
|
||||
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpPoll::~HttpPoll()
|
||||
{
|
||||
reset(true);
|
||||
delete d->t;
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpPoll::reset(bool clear)
|
||||
{
|
||||
if(d->http.isActive())
|
||||
d->http.stop();
|
||||
if(clear)
|
||||
clearReadBuffer();
|
||||
clearWriteBuffer();
|
||||
d->out.resize(0);
|
||||
d->state = 0;
|
||||
d->closing = false;
|
||||
d->t->stop();
|
||||
}
|
||||
|
||||
void HttpPoll::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
void HttpPoll::connectToUrl(const QString &url)
|
||||
{
|
||||
connectToHost("", 0, url);
|
||||
}
|
||||
|
||||
void HttpPoll::connectToHost(const QString &proxyHost, int proxyPort, const QString &url)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
// using proxy?
|
||||
if(!proxyHost.isEmpty()) {
|
||||
d->host = proxyHost;
|
||||
d->port = proxyPort;
|
||||
d->url = url;
|
||||
d->use_proxy = true;
|
||||
}
|
||||
else {
|
||||
Q3Url u = url;
|
||||
d->host = u.host();
|
||||
if(u.hasPort())
|
||||
d->port = u.port();
|
||||
else
|
||||
d->port = 80;
|
||||
d->url = u.encodedPathAndQuery();
|
||||
d->use_proxy = false;
|
||||
}
|
||||
|
||||
resetKey();
|
||||
bool last;
|
||||
QString key = getKey(&last);
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpPoll: Connecting to %s:%d [%s]", d->host.latin1(), d->port, d->url.latin1());
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
QPointer<QObject> self = this;
|
||||
syncStarted();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
d->state = 1;
|
||||
d->http.setAuth(d->user, d->pass);
|
||||
d->http.post(d->host, d->port, d->url, makePacket("0", key, "", QByteArray()), d->use_proxy);
|
||||
}
|
||||
|
||||
QByteArray HttpPoll::makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block)
|
||||
{
|
||||
QString str = ident;
|
||||
if(!key.isEmpty()) {
|
||||
str += ';';
|
||||
str += key;
|
||||
}
|
||||
if(!newkey.isEmpty()) {
|
||||
str += ';';
|
||||
str += newkey;
|
||||
}
|
||||
str += ',';
|
||||
Q3CString cs = str.latin1();
|
||||
int len = cs.length();
|
||||
|
||||
QByteArray a(len + block.size());
|
||||
memcpy(a.data(), cs.data(), len);
|
||||
memcpy(a.data() + len, block.data(), block.size());
|
||||
return a;
|
||||
}
|
||||
|
||||
int HttpPoll::pollInterval() const
|
||||
{
|
||||
return d->polltime;
|
||||
}
|
||||
|
||||
void HttpPoll::setPollInterval(int seconds)
|
||||
{
|
||||
d->polltime = seconds;
|
||||
}
|
||||
|
||||
bool HttpPoll::isOpen() const
|
||||
{
|
||||
return (d->state == 2 ? true: false);
|
||||
}
|
||||
|
||||
void HttpPoll::close()
|
||||
{
|
||||
if(d->state == 0 || d->closing)
|
||||
return;
|
||||
|
||||
if(bytesToWrite() == 0)
|
||||
reset();
|
||||
else
|
||||
d->closing = true;
|
||||
}
|
||||
|
||||
void HttpPoll::http_result()
|
||||
{
|
||||
// check for death :)
|
||||
QPointer<QObject> self = this;
|
||||
syncFinished();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
// get id and packet
|
||||
QString id;
|
||||
QString cookie = d->http.getHeader("Set-Cookie");
|
||||
int n = cookie.find("ID=");
|
||||
if(n == -1) {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
return;
|
||||
}
|
||||
n += 3;
|
||||
int n2 = cookie.find(';', n);
|
||||
if(n2 != -1)
|
||||
id = cookie.mid(n, n2-n);
|
||||
else
|
||||
id = cookie.mid(n);
|
||||
QByteArray block = d->http.body();
|
||||
|
||||
// session error?
|
||||
if(id.right(2) == ":0") {
|
||||
if(id == "0:0" && d->state == 2) {
|
||||
reset();
|
||||
connectionClosed();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
reset();
|
||||
error(ErrRead);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d->ident = id;
|
||||
bool justNowConnected = false;
|
||||
if(d->state == 1) {
|
||||
d->state = 2;
|
||||
justNowConnected = true;
|
||||
}
|
||||
|
||||
// sync up again soon
|
||||
if(bytesToWrite() > 0 || !d->closing)
|
||||
d->t->start(d->polltime * 1000, true);
|
||||
|
||||
// connecting
|
||||
if(justNowConnected) {
|
||||
connected();
|
||||
}
|
||||
else {
|
||||
if(!d->out.isEmpty()) {
|
||||
int x = d->out.size();
|
||||
d->out.resize(0);
|
||||
takeWrite(x);
|
||||
bytesWritten(x);
|
||||
}
|
||||
}
|
||||
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(!block.isEmpty()) {
|
||||
appendRead(block);
|
||||
readyRead();
|
||||
}
|
||||
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(bytesToWrite() > 0) {
|
||||
do_sync();
|
||||
}
|
||||
else {
|
||||
if(d->closing) {
|
||||
reset();
|
||||
delayedCloseFinished();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpPoll::http_error(int x)
|
||||
{
|
||||
reset();
|
||||
if(x == HttpProxyPost::ErrConnectionRefused)
|
||||
error(ErrConnectionRefused);
|
||||
else if(x == HttpProxyPost::ErrHostNotFound)
|
||||
error(ErrHostNotFound);
|
||||
else if(x == HttpProxyPost::ErrSocket)
|
||||
error(ErrRead);
|
||||
else if(x == HttpProxyPost::ErrProxyConnect)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == HttpProxyPost::ErrProxyNeg)
|
||||
error(ErrProxyNeg);
|
||||
else if(x == HttpProxyPost::ErrProxyAuth)
|
||||
error(ErrProxyAuth);
|
||||
}
|
||||
|
||||
int HttpPoll::tryWrite()
|
||||
{
|
||||
if(!d->http.isActive())
|
||||
do_sync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HttpPoll::do_sync()
|
||||
{
|
||||
if(d->http.isActive())
|
||||
return;
|
||||
|
||||
d->t->stop();
|
||||
d->out = takeWrite(0, false);
|
||||
|
||||
bool last;
|
||||
QString key = getKey(&last);
|
||||
QString newkey;
|
||||
if(last) {
|
||||
resetKey();
|
||||
newkey = getKey(&last);
|
||||
}
|
||||
|
||||
QPointer<QObject> self = this;
|
||||
syncStarted();
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
d->http.post(d->host, d->port, d->url, makePacket(d->ident, key, newkey, d->out), d->use_proxy);
|
||||
}
|
||||
|
||||
void HttpPoll::resetKey()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpPoll: reset key!\n");
|
||||
#endif
|
||||
QByteArray a = randomArray(64);
|
||||
QString str = QString::fromLatin1(a.data(), a.size());
|
||||
|
||||
d->key_n = POLL_KEYS;
|
||||
for(int n = 0; n < POLL_KEYS; ++n)
|
||||
d->key[n] = hpk(n+1, str);
|
||||
}
|
||||
|
||||
const QString & HttpPoll::getKey(bool *last)
|
||||
{
|
||||
*last = false;
|
||||
--(d->key_n);
|
||||
if(d->key_n == 0)
|
||||
*last = true;
|
||||
return d->key[d->key_n];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// HttpProxyPost
|
||||
//----------------------------------------------------------------------------
|
||||
static QString extractLine(QByteArray *buf, bool *found)
|
||||
{
|
||||
// scan for newline
|
||||
int n;
|
||||
for(n = 0; n < (int)buf->size()-1; ++n) {
|
||||
if(buf->at(n) == '\r' && buf->at(n+1) == '\n') {
|
||||
//Q3CString cstr;
|
||||
//cstr.resize(n+1);
|
||||
QByteArray cstr;
|
||||
cstr.resize(n);
|
||||
memcpy(cstr.data(), buf->data(), n);
|
||||
n += 2; // hack off CR/LF
|
||||
|
||||
memmove(buf->data(), buf->data() + n, buf->size() - n);
|
||||
buf->resize(buf->size() - n);
|
||||
QString s = QString::fromUtf8(cstr);
|
||||
|
||||
if(found)
|
||||
*found = true;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
*found = false;
|
||||
return "";
|
||||
}
|
||||
|
||||
static bool extractMainHeader(const QString &line, QString *proto, int *code, QString *msg)
|
||||
{
|
||||
int n = line.find(' ');
|
||||
if(n == -1)
|
||||
return false;
|
||||
if(proto)
|
||||
*proto = line.mid(0, n);
|
||||
++n;
|
||||
int n2 = line.find(' ', n);
|
||||
if(n2 == -1)
|
||||
return false;
|
||||
if(code)
|
||||
*code = line.mid(n, n2-n).toInt();
|
||||
n = n2+1;
|
||||
if(msg)
|
||||
*msg = line.mid(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
class HttpProxyPost::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
BSocket sock;
|
||||
QByteArray postdata, recvBuf, body;
|
||||
QString url;
|
||||
QString user, pass;
|
||||
bool inHeader;
|
||||
QStringList headerLines;
|
||||
bool asProxy;
|
||||
QString host;
|
||||
};
|
||||
|
||||
HttpProxyPost::HttpProxyPost(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
connect(&d->sock, SIGNAL(connected()), SLOT(sock_connected()));
|
||||
connect(&d->sock, SIGNAL(connectionClosed()), SLOT(sock_connectionClosed()));
|
||||
connect(&d->sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
|
||||
connect(&d->sock, SIGNAL(error(int)), SLOT(sock_error(int)));
|
||||
reset(true);
|
||||
}
|
||||
|
||||
HttpProxyPost::~HttpProxyPost()
|
||||
{
|
||||
reset(true);
|
||||
delete d;
|
||||
}
|
||||
|
||||
void HttpProxyPost::reset(bool clear)
|
||||
{
|
||||
if(d->sock.state() != BSocket::Idle)
|
||||
d->sock.close();
|
||||
d->recvBuf.resize(0);
|
||||
if(clear)
|
||||
d->body.resize(0);
|
||||
}
|
||||
|
||||
void HttpProxyPost::setAuth(const QString &user, const QString &pass)
|
||||
{
|
||||
d->user = user;
|
||||
d->pass = pass;
|
||||
}
|
||||
|
||||
bool HttpProxyPost::isActive() const
|
||||
{
|
||||
return (d->sock.state() == BSocket::Idle ? false: true);
|
||||
}
|
||||
|
||||
void HttpProxyPost::post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy)
|
||||
{
|
||||
reset(true);
|
||||
|
||||
d->host = proxyHost;
|
||||
d->url = url;
|
||||
d->postdata = data;
|
||||
d->asProxy = asProxy;
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: Connecting to %s:%d", proxyHost.latin1(), proxyPort);
|
||||
if(d->user.isEmpty())
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", auth {%s,%s}\n", d->user.latin1(), d->pass.latin1());
|
||||
#endif
|
||||
d->sock.connectToHost(proxyHost, proxyPort);
|
||||
}
|
||||
|
||||
void HttpProxyPost::stop()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
QByteArray HttpProxyPost::body() const
|
||||
{
|
||||
return d->body;
|
||||
}
|
||||
|
||||
QString HttpProxyPost::getHeader(const QString &var) const
|
||||
{
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it) {
|
||||
const QString &s = *it;
|
||||
int n = s.find(": ");
|
||||
if(n == -1)
|
||||
continue;
|
||||
QString v = s.mid(0, n);
|
||||
if(v == var)
|
||||
return s.mid(n+2);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_connected()
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: Connected\n");
|
||||
#endif
|
||||
d->inHeader = true;
|
||||
d->headerLines.clear();
|
||||
|
||||
Q3Url u = d->url;
|
||||
|
||||
// connected, now send the request
|
||||
QString s;
|
||||
s += QString("POST ") + d->url + " HTTP/1.0\r\n";
|
||||
if(d->asProxy) {
|
||||
if(!d->user.isEmpty()) {
|
||||
QString str = d->user + ':' + d->pass;
|
||||
s += QString("Proxy-Authorization: Basic ") + QCA::Base64().encodeString(str) + "\r\n";
|
||||
}
|
||||
s += "Pragma: no-cache\r\n";
|
||||
s += QString("Host: ") + u.host() + "\r\n";
|
||||
}
|
||||
else {
|
||||
s += QString("Host: ") + d->host + "\r\n";
|
||||
}
|
||||
s += "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
s += QString("Content-Length: ") + QString::number(d->postdata.size()) + "\r\n";
|
||||
s += "\r\n";
|
||||
|
||||
// write request
|
||||
Q3CString cs = s.utf8();
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
d->sock.write(block);
|
||||
|
||||
// write postdata
|
||||
d->sock.write(d->postdata);
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_connectionClosed()
|
||||
{
|
||||
d->body = d->recvBuf;
|
||||
reset();
|
||||
result();
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_readyRead()
|
||||
{
|
||||
QByteArray block = d->sock.read();
|
||||
ByteStream::appendArray(&d->recvBuf, block);
|
||||
|
||||
if(d->inHeader) {
|
||||
// grab available lines
|
||||
while(1) {
|
||||
bool found;
|
||||
QString line = extractLine(&d->recvBuf, &found);
|
||||
if(!found)
|
||||
break;
|
||||
if(line.isEmpty()) {
|
||||
d->inHeader = false;
|
||||
break;
|
||||
}
|
||||
d->headerLines += line;
|
||||
}
|
||||
|
||||
// done with grabbing the header?
|
||||
if(!d->inHeader) {
|
||||
QString str = d->headerLines.first();
|
||||
d->headerLines.remove(d->headerLines.begin());
|
||||
|
||||
QString proto;
|
||||
int code;
|
||||
QString msg;
|
||||
if(!extractMainHeader(str, &proto, &code, &msg)) {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: invalid header!\n");
|
||||
#endif
|
||||
reset(true);
|
||||
error(ErrProxyNeg);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: header proto=[%s] code=[%d] msg=[%s]\n", proto.latin1(), code, msg.latin1());
|
||||
for(QStringList::ConstIterator it = d->headerLines.begin(); it != d->headerLines.end(); ++it)
|
||||
fprintf(stderr, "HttpProxyPost: * [%s]\n", (*it).latin1());
|
||||
#endif
|
||||
}
|
||||
|
||||
if(code == 200) { // OK
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: << Success >>\n");
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
int err;
|
||||
QString errStr;
|
||||
if(code == 407) { // Authentication failed
|
||||
err = ErrProxyAuth;
|
||||
errStr = tr("Authentication failed");
|
||||
}
|
||||
else if(code == 404) { // Host not found
|
||||
err = ErrHostNotFound;
|
||||
errStr = tr("Host not found");
|
||||
}
|
||||
else if(code == 403) { // Access denied
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Access denied");
|
||||
}
|
||||
else if(code == 503) { // Connection refused
|
||||
err = ErrConnectionRefused;
|
||||
errStr = tr("Connection refused");
|
||||
}
|
||||
else { // invalid reply
|
||||
err = ErrProxyNeg;
|
||||
errStr = tr("Invalid reply");
|
||||
}
|
||||
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: << Error >> [%s]\n", errStr.latin1());
|
||||
#endif
|
||||
reset(true);
|
||||
error(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpProxyPost::sock_error(int x)
|
||||
{
|
||||
#ifdef PROX_DEBUG
|
||||
fprintf(stderr, "HttpProxyPost: socket error: %d\n", x);
|
||||
#endif
|
||||
reset(true);
|
||||
if(x == BSocket::ErrHostNotFound)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrConnectionRefused)
|
||||
error(ErrProxyConnect);
|
||||
else if(x == BSocket::ErrRead)
|
||||
error(ErrProxyNeg);
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
104
iris-legacy/cutestuff/network/httppoll.h
Normal file
104
iris-legacy/cutestuff/network/httppoll.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* httppoll.h - HTTP polling proxy
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_HTTPPOLL_H
|
||||
#define CS_HTTPPOLL_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class HttpPoll : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpPoll(QObject *parent=0);
|
||||
~HttpPoll();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToUrl(const QString &url);
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &url);
|
||||
|
||||
int pollInterval() const;
|
||||
void setPollInterval(int seconds);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void syncStarted();
|
||||
void syncFinished();
|
||||
|
||||
protected:
|
||||
int tryWrite();
|
||||
|
||||
private slots:
|
||||
void http_result();
|
||||
void http_error(int);
|
||||
void do_sync();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
QByteArray makePacket(const QString &ident, const QString &key, const QString &newkey, const QByteArray &block);
|
||||
void resetKey();
|
||||
const QString & getKey(bool *);
|
||||
};
|
||||
|
||||
class HttpProxyPost : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused, ErrHostNotFound, ErrSocket, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
HttpProxyPost(QObject *parent=0);
|
||||
~HttpProxyPost();
|
||||
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
bool isActive() const;
|
||||
void post(const QString &proxyHost, int proxyPort, const QString &url, const QByteArray &data, bool asProxy=true);
|
||||
void stop();
|
||||
QByteArray body() const;
|
||||
QString getHeader(const QString &) const;
|
||||
|
||||
signals:
|
||||
void result();
|
||||
void error(int);
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_readyRead();
|
||||
void sock_error(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool clear=false);
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
1231
iris-legacy/cutestuff/network/socks.cpp
Normal file
1231
iris-legacy/cutestuff/network/socks.cpp
Normal file
File diff suppressed because it is too large
Load diff
160
iris-legacy/cutestuff/network/socks.h
Normal file
160
iris-legacy/cutestuff/network/socks.h
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* socks.h - SOCKS5 TCP proxy client/server
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_SOCKS_H
|
||||
#define CS_SOCKS_H
|
||||
|
||||
#include "bytestream.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class QHostAddress;
|
||||
class SocksClient;
|
||||
class SocksServer;
|
||||
|
||||
class SocksUDP : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~SocksUDP();
|
||||
|
||||
void change(const QString &host, int port);
|
||||
void write(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void packetReady(const QByteArray &data);
|
||||
|
||||
private slots:
|
||||
void sn_activated(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
friend class SocksClient;
|
||||
SocksUDP(SocksClient *sc, const QString &host, int port, const QHostAddress &routeAddr, int routePort);
|
||||
};
|
||||
|
||||
class SocksClient : public ByteStream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused = ErrCustom, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth };
|
||||
enum Method { AuthNone=0x0001, AuthUsername=0x0002 };
|
||||
enum Request { ReqConnect, ReqUDPAssociate };
|
||||
SocksClient(QObject *parent=0);
|
||||
SocksClient(int, QObject *parent=0);
|
||||
~SocksClient();
|
||||
|
||||
bool isIncoming() const;
|
||||
|
||||
// outgoing
|
||||
void setAuth(const QString &user, const QString &pass="");
|
||||
void connectToHost(const QString &proxyHost, int proxyPort, const QString &host, int port, bool udpMode=false);
|
||||
|
||||
// incoming
|
||||
void chooseMethod(int);
|
||||
void authGrant(bool);
|
||||
void requestDeny();
|
||||
void grantConnect();
|
||||
void grantUDPAssociate(const QString &relayHost, int relayPort);
|
||||
|
||||
// from ByteStream
|
||||
bool isOpen() const;
|
||||
void close();
|
||||
void write(const QByteArray &);
|
||||
QByteArray read(int bytes=0);
|
||||
int bytesAvailable() const;
|
||||
int bytesToWrite() const;
|
||||
|
||||
// remote address
|
||||
QHostAddress peerAddress() const;
|
||||
Q_UINT16 peerPort() const;
|
||||
|
||||
// udp
|
||||
QString udpAddress() const;
|
||||
Q_UINT16 udpPort() const;
|
||||
SocksUDP *createUDP(const QString &host, int port, const QHostAddress &routeAddr, int routePort);
|
||||
|
||||
signals:
|
||||
// outgoing
|
||||
void connected();
|
||||
|
||||
// incoming
|
||||
void incomingMethods(int);
|
||||
void incomingAuth(const QString &user, const QString &pass);
|
||||
void incomingConnectRequest(const QString &host, int port);
|
||||
void incomingUDPAssociateRequest();
|
||||
|
||||
private slots:
|
||||
void sock_connected();
|
||||
void sock_connectionClosed();
|
||||
void sock_delayedCloseFinished();
|
||||
void sock_readyRead();
|
||||
void sock_bytesWritten(int);
|
||||
void sock_error(int);
|
||||
void serve();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void init();
|
||||
void reset(bool clear=false);
|
||||
void do_request();
|
||||
void processOutgoing(const QByteArray &);
|
||||
void processIncoming(const QByteArray &);
|
||||
void continueIncoming();
|
||||
void writeData(const QByteArray &a);
|
||||
};
|
||||
|
||||
class SocksServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocksServer(QObject *parent=0);
|
||||
~SocksServer();
|
||||
|
||||
bool isActive() const;
|
||||
bool listen(Q_UINT16 port, bool udp=false);
|
||||
void stop();
|
||||
int port() const;
|
||||
QHostAddress address() const;
|
||||
SocksClient *takeIncoming();
|
||||
|
||||
void writeUDP(const QHostAddress &addr, int port, const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void incomingReady();
|
||||
void incomingUDP(const QString &host, int port, const QHostAddress &addr, int sourcePort, const QByteArray &data);
|
||||
|
||||
private slots:
|
||||
void connectionReady(int);
|
||||
void connectionError();
|
||||
void sn_activated(int);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
269
iris-legacy/cutestuff/util/bytestream.cpp
Normal file
269
iris-legacy/cutestuff/util/bytestream.cpp
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* bytestream.cpp - base class for bytestreams
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bytestream.h"
|
||||
//Added by qt3to4:
|
||||
#include <Q3CString>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//! \class ByteStream bytestream.h
|
||||
//! \brief Base class for "bytestreams"
|
||||
//!
|
||||
//! This class provides a basic framework for a "bytestream", here defined
|
||||
//! as a bi-directional, asynchronous pipe of data. It can be used to create
|
||||
//! several different kinds of bytestream-applications, such as a console or
|
||||
//! TCP connection, or something more abstract like a security layer or tunnel,
|
||||
//! all with the same interface. The provided functions make creating such
|
||||
//! classes simpler. ByteStream is a pure-virtual class, so you do not use it
|
||||
//! on its own, but instead through a subclass such as \a BSocket.
|
||||
//!
|
||||
//! The signals connectionClosed(), delayedCloseFinished(), readyRead(),
|
||||
//! bytesWritten(), and error() serve the exact same function as those from
|
||||
//! <A HREF="http://doc.trolltech.com/3.1/qsocket.html">QSocket</A>.
|
||||
//!
|
||||
//! The simplest way to create a ByteStream is to reimplement isOpen(), close(),
|
||||
//! and tryWrite(). Call appendRead() whenever you want to make data available for
|
||||
//! reading. ByteStream will take care of the buffers with regards to the caller,
|
||||
//! and will call tryWrite() when the write buffer gains data. It will be your
|
||||
//! job to call tryWrite() whenever it is acceptable to write more data to
|
||||
//! the underlying system.
|
||||
//!
|
||||
//! If you need more advanced control, reimplement read(), write(), bytesAvailable(),
|
||||
//! and/or bytesToWrite() as necessary.
|
||||
//!
|
||||
//! Use appendRead(), appendWrite(), takeRead(), and takeWrite() to modify the
|
||||
//! buffers. If you have more advanced requirements, the buffers can be accessed
|
||||
//! directly with readBuf() and writeBuf().
|
||||
//!
|
||||
//! Also available are the static convenience functions ByteStream::appendArray()
|
||||
//! and ByteStream::takeArray(), which make dealing with byte queues very easy.
|
||||
|
||||
class ByteStream::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
QByteArray readBuf, writeBuf;
|
||||
};
|
||||
|
||||
//!
|
||||
//! Constructs a ByteStream object with parent \a parent.
|
||||
ByteStream::ByteStream(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Destroys the object and frees allocated resources.
|
||||
ByteStream::~ByteStream()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns TRUE if the stream is open, meaning that you can write to it.
|
||||
bool ByteStream::isOpen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Closes the stream. If there is data in the write buffer then it will be
|
||||
//! written before actually closing the stream. Once all data has been written,
|
||||
//! the delayedCloseFinished() signal will be emitted.
|
||||
//! \sa delayedCloseFinished()
|
||||
void ByteStream::close()
|
||||
{
|
||||
}
|
||||
|
||||
//!
|
||||
//! Writes array \a a to the stream.
|
||||
void ByteStream::write(const QByteArray &a)
|
||||
{
|
||||
if(!isOpen())
|
||||
return;
|
||||
|
||||
bool doWrite = bytesToWrite() == 0 ? true: false;
|
||||
appendWrite(a);
|
||||
if(doWrite)
|
||||
tryWrite();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Reads bytes \a bytes of data from the stream and returns them as an array. If \a bytes is 0, then
|
||||
//! \a read will return all available data.
|
||||
QByteArray ByteStream::read(int bytes)
|
||||
{
|
||||
return takeRead(bytes);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the number of bytes available for reading.
|
||||
int ByteStream::bytesAvailable() const
|
||||
{
|
||||
return d->readBuf.size();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the number of bytes that are waiting to be written.
|
||||
int ByteStream::bytesToWrite() const
|
||||
{
|
||||
return d->writeBuf.size();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Writes string \a cs to the stream.
|
||||
void ByteStream::write(const Q3CString &cs)
|
||||
{
|
||||
QByteArray block(cs.length());
|
||||
memcpy(block.data(), cs.data(), block.size());
|
||||
write(block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Clears the read buffer.
|
||||
void ByteStream::clearReadBuffer()
|
||||
{
|
||||
d->readBuf.resize(0);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Clears the write buffer.
|
||||
void ByteStream::clearWriteBuffer()
|
||||
{
|
||||
d->writeBuf.resize(0);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Appends \a block to the end of the read buffer.
|
||||
void ByteStream::appendRead(const QByteArray &block)
|
||||
{
|
||||
appendArray(&d->readBuf, block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Appends \a block to the end of the write buffer.
|
||||
void ByteStream::appendWrite(const QByteArray &block)
|
||||
{
|
||||
appendArray(&d->writeBuf, block);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the read buffer.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeRead(int size, bool del)
|
||||
{
|
||||
return takeArray(&d->readBuf, size, del);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the write buffer.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeWrite(int size, bool del)
|
||||
{
|
||||
return takeArray(&d->writeBuf, size, del);
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns a reference to the read buffer.
|
||||
QByteArray & ByteStream::readBuf()
|
||||
{
|
||||
return d->readBuf;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns a reference to the write buffer.
|
||||
QByteArray & ByteStream::writeBuf()
|
||||
{
|
||||
return d->writeBuf;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Attempts to try and write some bytes from the write buffer, and returns the number
|
||||
//! successfully written or -1 on error. The default implementation returns -1.
|
||||
int ByteStream::tryWrite()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Append array \a b to the end of the array pointed to by \a a.
|
||||
void ByteStream::appendArray(QByteArray *a, const QByteArray &b)
|
||||
{
|
||||
int oldsize = a->size();
|
||||
a->resize(oldsize + b.size());
|
||||
memcpy(a->data() + oldsize, b.data(), b.size());
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns \a size bytes from the start of the array pointed to by \a from.
|
||||
//! If \a size is 0, then all available data will be returned.
|
||||
//! If \a del is TRUE, then the bytes are also removed.
|
||||
QByteArray ByteStream::takeArray(QByteArray *from, int size, bool del)
|
||||
{
|
||||
QByteArray a;
|
||||
if(size == 0) {
|
||||
a = *from;
|
||||
if(del)
|
||||
from->resize(0);
|
||||
}
|
||||
else {
|
||||
if(size > (int)from->size())
|
||||
size = from->size();
|
||||
a.resize(size);
|
||||
char *r = from->data();
|
||||
memcpy(a.data(), r, size);
|
||||
if(del) {
|
||||
int newsize = from->size()-size;
|
||||
memmove(r, r+size, newsize);
|
||||
from->resize(newsize);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
void connectionClosed();
|
||||
void delayedCloseFinished();
|
||||
void readyRead();
|
||||
void bytesWritten(int);
|
||||
void error(int);
|
||||
|
||||
//! \fn void ByteStream::connectionClosed()
|
||||
//! This signal is emitted when the remote end of the stream closes.
|
||||
|
||||
//! \fn void ByteStream::delayedCloseFinished()
|
||||
//! This signal is emitted when all pending data has been written to the stream
|
||||
//! after an attempt to close.
|
||||
|
||||
//! \fn void ByteStream::readyRead()
|
||||
//! This signal is emitted when data is available to be read.
|
||||
|
||||
//! \fn void ByteStream::bytesWritten(int x);
|
||||
//! This signal is emitted when data has been successfully written to the stream.
|
||||
//! \a x is the number of bytes written.
|
||||
|
||||
//! \fn void ByteStream::error(int code)
|
||||
//! This signal is emitted when an error occurs in the stream. The reason for
|
||||
//! error is indicated by \a code.
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
78
iris-legacy/cutestuff/util/bytestream.h
Normal file
78
iris-legacy/cutestuff/util/bytestream.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* bytestream.h - base class for bytestreams
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_BYTESTREAM_H
|
||||
#define CS_BYTESTREAM_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <q3cstring.h>
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
// CS_EXPORT_BEGIN
|
||||
class ByteStream : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrRead, ErrWrite, ErrCustom = 10 };
|
||||
ByteStream(QObject *parent=0);
|
||||
virtual ~ByteStream()=0;
|
||||
|
||||
virtual bool isOpen() const;
|
||||
virtual void close();
|
||||
virtual void write(const QByteArray &);
|
||||
virtual QByteArray read(int bytes=0);
|
||||
virtual int bytesAvailable() const;
|
||||
virtual int bytesToWrite() const;
|
||||
|
||||
void write(const Q3CString &);
|
||||
|
||||
static void appendArray(QByteArray *a, const QByteArray &b);
|
||||
static QByteArray takeArray(QByteArray *from, int size=0, bool del=true);
|
||||
|
||||
signals:
|
||||
void connectionClosed();
|
||||
void delayedCloseFinished();
|
||||
void readyRead();
|
||||
void bytesWritten(int);
|
||||
void error(int);
|
||||
|
||||
protected:
|
||||
void clearReadBuffer();
|
||||
void clearWriteBuffer();
|
||||
void appendRead(const QByteArray &);
|
||||
void appendWrite(const QByteArray &);
|
||||
QByteArray takeRead(int size=0, bool del=true);
|
||||
QByteArray takeWrite(int size=0, bool del=true);
|
||||
QByteArray & readBuf();
|
||||
QByteArray & writeBuf();
|
||||
virtual int tryWrite();
|
||||
|
||||
private:
|
||||
//! \if _hide_doc_
|
||||
class Private;
|
||||
Private *d;
|
||||
//! \endif
|
||||
};
|
||||
// CS_EXPORT_END
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
504
iris-legacy/iris/COPYING
Normal file
504
iris-legacy/iris/COPYING
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
18
iris-legacy/iris/TODO
Normal file
18
iris-legacy/iris/TODO
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
- Stream::id(), Stream::lang()
|
||||
- whitespace pings (but disable when using http poll)
|
||||
- make stanza error conditions work for both 1.0 and old
|
||||
|
||||
- xmpp-im (messages, roster, subscriptions, presence, privacy)
|
||||
- document xmpp-core
|
||||
- provide complete support for xmpp-core. this means all functionality from
|
||||
the draft, and noting behavior issues (like IQ semantics) in the
|
||||
library documentation.
|
||||
|
||||
- SASL "EXTERNAL" w/ client certificate
|
||||
- SASL "ANONYMOUS" ?
|
||||
|
||||
credits:
|
||||
MD5 algorithm by Peter Deutsch (Aladdin Enterprises)
|
||||
|
||||
- s5b: support multiple streamhosts in proxy reply
|
||||
|
||||
609
iris-legacy/iris/example/conntest/configure
vendored
Normal file
609
iris-legacy/iris/example/conntest/configure
vendored
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
#!/bin/sh
|
||||
|
||||
show_usage() {
|
||||
cat <<EOT
|
||||
Usage: ./configure [OPTION]...
|
||||
|
||||
This script creates necessary configuration files to build/install.
|
||||
|
||||
Main options:
|
||||
--prefix=[path] Base path for build/install. Default: /usr/local
|
||||
--bindir=[path] Directory for binaries. Default: PREFIX/bin
|
||||
--qtdir=[path] Directory where Qt is installed.
|
||||
--debug Enable debug output.
|
||||
--help This help text.
|
||||
|
||||
EOT
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--prefix=*)
|
||||
PREFIX="${1#--prefix=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
--bindir=*)
|
||||
BINDIR="${1#--bindir=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
--qtdir=*)
|
||||
QTDIR="${1#--qtdir=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
--debug)
|
||||
QC_DEBUG="Y"
|
||||
shift
|
||||
;;
|
||||
--help) show_usage; exit ;;
|
||||
*) show_usage; exit ;;
|
||||
esac
|
||||
done
|
||||
|
||||
PREFIX=${PREFIX:-/usr/local}
|
||||
BINDIR=${BINDIR:-$PREFIX/bin}
|
||||
|
||||
echo "Configuring Iris Conntest ..."
|
||||
|
||||
if [ "$QC_DEBUG" = "Y" ]; then
|
||||
echo
|
||||
echo PREFIX=$PREFIX
|
||||
echo BINDIR=$BINDIR
|
||||
echo QTDIR=$QTDIR
|
||||
echo
|
||||
fi
|
||||
|
||||
printf "Verifying Qt 3.x Multithreaded (MT) build environment ... "
|
||||
|
||||
if [ -z "$QTDIR" ]; then
|
||||
if [ "$QC_DEBUG" = "Y" ]; then
|
||||
echo \$QTDIR not set... trying to find Qt manually
|
||||
fi
|
||||
for p in /usr/lib/qt /usr/share/qt /usr/share/qt3 /usr/local/lib/qt /usr/local/share/qt /usr/lib/qt3 /usr/local/lib/qt3 /usr/X11R6/share/qt /usr/qt/3 ; do
|
||||
if [ -d "$p/mkspecs" ]; then
|
||||
QTDIR=$p
|
||||
break;
|
||||
fi;
|
||||
done
|
||||
if [ -z "$QTDIR" ]; then
|
||||
echo fail
|
||||
echo
|
||||
echo "Unable to find Qt 'mkspecs'. Perhaps you need to"
|
||||
echo "install the Qt 3 development utilities. You may download"
|
||||
echo "them either from the vendor of your operating system"
|
||||
echo "or from http://www.trolltech.com/"
|
||||
echo
|
||||
echo "If you're sure you have the Qt development utilities"
|
||||
echo "installed, you might try using the --qtdir option."
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
if [ ! -x "$QTDIR/bin/moc" ]; then
|
||||
m=`which moc 2>/dev/null`
|
||||
if [ ! -x "$m" ]; then
|
||||
echo fail
|
||||
echo
|
||||
echo "We found Qt in $QTDIR, but we were unable to locate"
|
||||
echo "the moc utility. It was not found in $QTDIR/bin"
|
||||
echo "nor in PATH. This seems to be a very unusual setup."
|
||||
echo "You might try using the --qtdir option."
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
qtpre=`echo $m | awk '{ n = index($0, "/bin/moc"); if (!n) { exit 1; } print substr($0, 0, n-1); exit 0; }' 2>/dev/null`
|
||||
ret="$?"
|
||||
if [ "$ret" != "0" ]; then
|
||||
echo fail
|
||||
echo
|
||||
echo "We found Qt in $QTDIR, but the location of moc"
|
||||
echo "($m) is not suitable for use with this build system."
|
||||
echo "This is a VERY unusual and likely-broken setup. You"
|
||||
echo "should contact the maintainer of your Qt package."
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
QTDIR=$qtpre
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$QTDIR/bin/qmake" ]; then
|
||||
if [ "$QC_DEBUG" = "Y" ]; then
|
||||
echo Warning: qmake not in \$QTDIR/bin/qmake
|
||||
echo trying to find it in \$PATH
|
||||
fi
|
||||
qm=`which qmake 2>/dev/null`
|
||||
if [ -x "$qm" ]; then
|
||||
if [ "$QC_DEBUG" = "Y" ]; then
|
||||
echo qmake found in $qm
|
||||
fi
|
||||
else
|
||||
echo fail
|
||||
echo
|
||||
echo Sorry, you seem to have a very unusual setup,
|
||||
echo or I missdetected \$QTDIR=$QTDIR
|
||||
echo
|
||||
echo Please set \$QTDIR manually and make sure that
|
||||
echo \$QTDIR/bin/qmake exists.
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
else
|
||||
qm=$QTDIR/bin/qmake
|
||||
fi
|
||||
|
||||
gen_files() {
|
||||
cat >$1/modules.cpp <<EOT
|
||||
|
||||
EOT
|
||||
cat >$1/modules_new.cpp <<EOT
|
||||
|
||||
EOT
|
||||
cat >$1/conf.cpp <<EOT
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<qstring.h>
|
||||
#include<qdict.h>
|
||||
#include<qptrlist.h>
|
||||
#include<qfileinfo.h>
|
||||
#include<qfile.h>
|
||||
#include<qdir.h>
|
||||
#include<qstringlist.h>
|
||||
#include<qobject.h>
|
||||
|
||||
class MocTestObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MocTestObject() {}
|
||||
};
|
||||
|
||||
class Conf;
|
||||
|
||||
class ConfObj
|
||||
{
|
||||
public:
|
||||
ConfObj(Conf *c);
|
||||
virtual ~ConfObj();
|
||||
|
||||
virtual QString name() const=0;
|
||||
virtual QString shortname() const=0;
|
||||
virtual QString checkString() const;
|
||||
virtual QString resultString() const;
|
||||
virtual bool exec()=0;
|
||||
|
||||
Conf *conf;
|
||||
bool required;
|
||||
bool disabled;
|
||||
};
|
||||
|
||||
typedef QPtrList<ConfObj> ConfObjList;
|
||||
typedef QPtrListIterator<ConfObj> ConfObjListIt;
|
||||
|
||||
class Conf
|
||||
{
|
||||
public:
|
||||
Conf() : vars(17)
|
||||
{
|
||||
list.setAutoDelete(true);
|
||||
vars.setAutoDelete(true);
|
||||
|
||||
vars.insert("QMAKE_INCDIR_X11", new QString(X11_INC));
|
||||
vars.insert("QMAKE_LIBDIR_X11", new QString(X11_LIBDIR));
|
||||
vars.insert("QMAKE_LIBS_X11", new QString(X11_LIB));
|
||||
vars.insert("QMAKE_CC", new QString(CC));
|
||||
|
||||
do_debug = false;
|
||||
done_debug = false;
|
||||
}
|
||||
|
||||
~Conf()
|
||||
{
|
||||
}
|
||||
|
||||
void added(ConfObj *o)
|
||||
{
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
QString getenv(const QString &var)
|
||||
{
|
||||
char *p = ::getenv(var.latin1());
|
||||
if(!p)
|
||||
return QString::null;
|
||||
return QString(p);
|
||||
}
|
||||
|
||||
void debug(const QString &s)
|
||||
{
|
||||
if(do_debug) {
|
||||
if(!done_debug)
|
||||
printf("\n");
|
||||
done_debug = true;
|
||||
printf(" * %s\n", s.latin1());
|
||||
}
|
||||
}
|
||||
|
||||
bool exec()
|
||||
{
|
||||
if(getenv("QC_DEBUG") == "Y")
|
||||
do_debug = true;
|
||||
|
||||
ConfObjListIt it(list);
|
||||
for(ConfObj *o; (o = it.current()); ++it) {
|
||||
// if this was a disabled-by-default option, check if it was enabled
|
||||
if(o->disabled) {
|
||||
QString v = QString("QC_ENABLE_") + o->shortname();
|
||||
if(getenv(v) != "Y")
|
||||
continue;
|
||||
}
|
||||
// and the opposite?
|
||||
else {
|
||||
QString v = QString("QC_DISABLE_") + o->shortname();
|
||||
if(getenv(v) == "Y")
|
||||
continue;
|
||||
}
|
||||
|
||||
QString check = o->checkString();
|
||||
if(check.isEmpty())
|
||||
check = QString("Checking for %1 ...").arg(o->name());
|
||||
printf("%s", check.latin1());
|
||||
fflush(stdout);
|
||||
|
||||
done_debug = false;
|
||||
bool ok = o->exec();
|
||||
|
||||
QString result = o->resultString();
|
||||
if(result.isEmpty()) {
|
||||
if(ok)
|
||||
result = "yes";
|
||||
else
|
||||
result = "no";
|
||||
}
|
||||
if(done_debug)
|
||||
printf(" -> %s\n", result.latin1());
|
||||
else
|
||||
printf(" %s\n", result.latin1());
|
||||
|
||||
if(!ok && o->required) {
|
||||
printf("\nError: need %s!\n", o->name().latin1());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const QString & qvar(const QString &s)
|
||||
{
|
||||
QString *p = vars.find(s);
|
||||
if(p)
|
||||
return *p;
|
||||
else
|
||||
return blank;
|
||||
}
|
||||
|
||||
QString expandIncludes(const QString &inc)
|
||||
{
|
||||
return QString("-I") + inc;
|
||||
}
|
||||
|
||||
QString expandLibs(const QString &lib)
|
||||
{
|
||||
return QString("-L") + lib;
|
||||
}
|
||||
|
||||
int doCommand(const QString &s)
|
||||
{
|
||||
debug(QString("[%1]").arg(s));
|
||||
QString fullcmd;
|
||||
if(do_debug)
|
||||
fullcmd = s;
|
||||
else
|
||||
fullcmd = s + " 1>/dev/null 2>/dev/null";
|
||||
int r = system(fullcmd.latin1());
|
||||
debug(QString("returned: %1").arg(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
bool doCompileAndLink(const QString &filedata, const QString &flags, int *retcode=0)
|
||||
{
|
||||
QDir dir(".");
|
||||
QString fname = "atest.c";
|
||||
QString out = "atest";
|
||||
QFile f(fname);
|
||||
QCString cs = filedata.latin1();
|
||||
if(!f.open(IO_WriteOnly | IO_Truncate)) {
|
||||
debug("unable to open atest.c for writing");
|
||||
return false;
|
||||
}
|
||||
if(f.writeBlock(cs.data(), cs.length()) == -1) {
|
||||
debug("error writing to atest.c");
|
||||
return false;
|
||||
}
|
||||
f.close();
|
||||
|
||||
debug(QString("Wrote atest.c:\n%1").arg(filedata));
|
||||
|
||||
QString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out;
|
||||
if(!flags.isEmpty()) {
|
||||
str += ' ';
|
||||
str += flags;
|
||||
}
|
||||
|
||||
int r = doCommand(str);
|
||||
if(r == 0 && retcode)
|
||||
*retcode = doCommand(QString("./") + out);
|
||||
dir.remove(fname);
|
||||
dir.remove(out);
|
||||
if(r != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkHeader(const QString &path, const QString &h)
|
||||
{
|
||||
QFileInfo fi(path + '/' + h);
|
||||
if(fi.exists())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findHeader(const QString &h, const QStringList &ext, QString *inc)
|
||||
{
|
||||
if(checkHeader("/usr/include", h)) {
|
||||
*inc = "";
|
||||
return true;
|
||||
}
|
||||
QStringList dirs;
|
||||
dirs += "/usr/local/include";
|
||||
dirs += ext;
|
||||
for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
|
||||
if(checkHeader(*it, h)) {
|
||||
*inc = *it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkLibrary(const QString &path, const QString &name)
|
||||
{
|
||||
QString str =
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" return 0;\n"
|
||||
"}\n";
|
||||
|
||||
QString extra;
|
||||
if(!path.isEmpty())
|
||||
extra += QString("-L") + path + ' ';
|
||||
extra += QString("-l") + name;
|
||||
if(!doCompileAndLink(str, extra))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool findLibrary(const QString &name, QString *lib)
|
||||
{
|
||||
if(checkLibrary("", name)) {
|
||||
*lib = "";
|
||||
return true;
|
||||
}
|
||||
if(checkLibrary("/usr/local/lib", name)) {
|
||||
*lib = "/usr/local/lib";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void addDefine(const QString &str)
|
||||
{
|
||||
if(DEFINES.isEmpty())
|
||||
DEFINES = str;
|
||||
else
|
||||
DEFINES += QString(" ") + str;
|
||||
debug(QString("DEFINES += %1").arg(str));
|
||||
}
|
||||
|
||||
void addLib(const QString &str)
|
||||
{
|
||||
if(LIBS.isEmpty())
|
||||
LIBS = str;
|
||||
else
|
||||
LIBS += QString(" ") + str;
|
||||
debug(QString("LIBS += %1").arg(str));
|
||||
}
|
||||
|
||||
void addIncludePath(const QString &str)
|
||||
{
|
||||
if(INCLUDEPATH.isEmpty())
|
||||
INCLUDEPATH = str;
|
||||
else
|
||||
INCLUDEPATH += QString(" ") + str;
|
||||
debug(QString("INCLUDEPATH += %1").arg(str));
|
||||
}
|
||||
|
||||
void addExtra(const QString &str)
|
||||
{
|
||||
extra += str + '\n';
|
||||
debug(QString("extra += %1").arg(str));
|
||||
}
|
||||
|
||||
QString DEFINES;
|
||||
QString INCLUDEPATH;
|
||||
QString LIBS;
|
||||
QString extra;
|
||||
|
||||
private:
|
||||
ConfObjList list;
|
||||
QDict<QString> vars;
|
||||
QString blank;
|
||||
bool do_debug, done_debug;
|
||||
};
|
||||
|
||||
ConfObj::ConfObj(Conf *c)
|
||||
{
|
||||
conf = c;
|
||||
conf->added(this);
|
||||
required = false;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
ConfObj::~ConfObj()
|
||||
{
|
||||
}
|
||||
|
||||
QString ConfObj::checkString() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ConfObj::resultString() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
#include"modules.cpp"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// main
|
||||
//----------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
Conf *conf = new Conf;
|
||||
ConfObj *o;
|
||||
o = 0;
|
||||
#include"modules_new.cpp"
|
||||
|
||||
printf("ok\n");
|
||||
bool success = false;
|
||||
if(conf->exec()) {
|
||||
QFile f("conf.pri");
|
||||
if(!f.open(IO_WriteOnly | IO_Truncate)) {
|
||||
printf("Error writing %s\n", f.name().latin1());
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString str;
|
||||
str += "# qconf\n";
|
||||
str += "QT_PATH_PLUGINS = " + QString(qInstallPathPlugins()) + '\n';
|
||||
if(!conf->DEFINES.isEmpty())
|
||||
str += "DEFINES += " + conf->DEFINES + '\n';
|
||||
if(!conf->INCLUDEPATH.isEmpty())
|
||||
str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n';
|
||||
if(!conf->LIBS.isEmpty())
|
||||
str += "LIBS += " + conf->LIBS + '\n';
|
||||
if(!conf->extra.isEmpty())
|
||||
str += conf->extra;
|
||||
str += '\n';
|
||||
|
||||
char *p = getenv("BINDIR");
|
||||
if(p) {
|
||||
str += QString("target.path = ") + p + '\n';
|
||||
str += "INSTALLS += target\n";
|
||||
}
|
||||
|
||||
QCString cs = str.latin1();
|
||||
f.writeBlock(cs.data(), cs.length());
|
||||
f.close();
|
||||
success = true;
|
||||
}
|
||||
delete conf;
|
||||
|
||||
if(success)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include"conf.moc"
|
||||
|
||||
|
||||
EOT
|
||||
cat >$1/conf.pro <<EOT
|
||||
TEMPLATE = app
|
||||
CONFIG += qt x11 thread console
|
||||
TARGET = conf
|
||||
|
||||
DEFINES += X11_INC='"\$\$QMAKE_INCDIR_X11"'
|
||||
DEFINES += X11_LIBDIR='"\$\$QMAKE_LIBDIR_X11"'
|
||||
DEFINES += X11_LIB='"\$\$QMAKE_LIBS_X11"'
|
||||
DEFINES += CC='"\$\$QMAKE_CC"'
|
||||
|
||||
SOURCES += conf.cpp
|
||||
|
||||
EOT
|
||||
}
|
||||
|
||||
export PREFIX
|
||||
export BINDIR
|
||||
export QTDIR
|
||||
export QC_DEBUG
|
||||
rm -rf .qconftemp
|
||||
(
|
||||
mkdir .qconftemp
|
||||
gen_files .qconftemp
|
||||
cd .qconftemp
|
||||
$qm conf.pro >/dev/null
|
||||
QTDIR=$QTDIR make clean >/dev/null 2>&1
|
||||
QTDIR=$QTDIR make >../conf.log 2>&1
|
||||
)
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
rm -rf .qconftemp
|
||||
echo fail
|
||||
echo
|
||||
echo "There was an error compiling 'conf'. Be sure you have a proper"
|
||||
echo "Qt 3.x Multithreaded (MT) build environment set up. This"
|
||||
echo "means not just Qt, but also a C++ compiler, the 'make' command,"
|
||||
echo "and any other packages necessary to compile C++ programs."
|
||||
echo "See conf.log for details."
|
||||
if [ ! -f "$QTDIR/lib/libqt-mt.so.3" ]; then
|
||||
echo
|
||||
echo "One possible reason is that you don't have"
|
||||
echo "libqt-mt.so.3 installed in $QTDIR/lib/."
|
||||
fi
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
.qconftemp/conf
|
||||
ret="$?"
|
||||
if [ "$ret" = "1" ]; then
|
||||
rm -rf .qconftemp
|
||||
echo
|
||||
exit 1;
|
||||
else
|
||||
if [ "$ret" != "0" ]; then
|
||||
rm -rf .qconftemp
|
||||
echo fail
|
||||
echo
|
||||
echo Unexpected error launching 'conf'
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
rm -rf .qconftemp
|
||||
|
||||
if [ -x "./qcextra" ]; then
|
||||
./qcextra
|
||||
fi
|
||||
# run qmake
|
||||
$qm conntest.pro
|
||||
if [ "$?" != "0" ]; then
|
||||
echo
|
||||
exit 1;
|
||||
fi
|
||||
cat >Makefile.tmp <<EOT
|
||||
export QTDIR = $QTDIR
|
||||
export PATH = $QTDIR/bin:$PATH
|
||||
EOT
|
||||
cat Makefile >> Makefile.tmp
|
||||
rm -f Makefile
|
||||
cp -f Makefile.tmp Makefile
|
||||
rm -f Makefile.tmp
|
||||
|
||||
echo
|
||||
echo Good, your configure finished. Now run \'make\'.
|
||||
echo
|
||||
578
iris-legacy/iris/example/conntest/conntest.cpp
Normal file
578
iris-legacy/iris/example/conntest/conntest.cpp
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
#include <qapplication.h>
|
||||
#include "bconsole.h"
|
||||
#include <QtCrypto>
|
||||
#include "xmpp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define ROOTCERT_PATH "/usr/local/share/psi/certs/rootcert.xml"
|
||||
|
||||
QCA::Cert readCertXml(const QDomElement &e)
|
||||
{
|
||||
QCA::Cert cert;
|
||||
// there should be one child data tag
|
||||
QDomElement data = e.elementsByTagName("data").item(0).toElement();
|
||||
if(!data.isNull())
|
||||
cert.fromDER(Base64::stringToArray(data.text()));
|
||||
return cert;
|
||||
}
|
||||
|
||||
QPtrList<QCA::Cert> getRootCerts(const QString &store)
|
||||
{
|
||||
QPtrList<QCA::Cert> list;
|
||||
|
||||
// open the Psi rootcerts file
|
||||
QFile f(store);
|
||||
if(!f.open(IO_ReadOnly)) {
|
||||
printf("unable to open %s\n", f.name().latin1());
|
||||
return list;
|
||||
}
|
||||
QDomDocument doc;
|
||||
doc.setContent(&f);
|
||||
f.close();
|
||||
|
||||
QDomElement base = doc.documentElement();
|
||||
if(base.tagName() != "store") {
|
||||
printf("wrong format of %s\n", f.name().latin1());
|
||||
return list;
|
||||
}
|
||||
QDomNodeList cl = base.elementsByTagName("certificate");
|
||||
if(cl.count() == 0) {
|
||||
printf("no certs found in %s\n", f.name().latin1());
|
||||
return list;
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
for(int n = 0; n < (int)cl.count(); ++n) {
|
||||
QCA::Cert *cert = new QCA::Cert(readCertXml(cl.item(n).toElement()));
|
||||
if(cert->isNull()) {
|
||||
printf("error reading cert\n");
|
||||
delete cert;
|
||||
continue;
|
||||
}
|
||||
|
||||
++num;
|
||||
list.append(cert);
|
||||
}
|
||||
printf("imported %d root certs\n", num);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static QString prompt(const QString &s)
|
||||
{
|
||||
printf("* %s ", s.latin1());
|
||||
fflush(stdout);
|
||||
char line[256];
|
||||
fgets(line, 255, stdin);
|
||||
QString result = line;
|
||||
if(result[result.length()-1] == '\n')
|
||||
result.truncate(result.length()-1);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void showCertInfo(const QCA::Cert &cert)
|
||||
{
|
||||
fprintf(stderr, "-- Cert --\n");
|
||||
fprintf(stderr, " CN: %s\n", cert.subject()["CN"].latin1());
|
||||
fprintf(stderr, " Valid from: %s, until %s\n",
|
||||
cert.notBefore().toString().latin1(),
|
||||
cert.notAfter().toString().latin1());
|
||||
fprintf(stderr, " PEM:\n%s\n", cert.toPEM().latin1());
|
||||
}
|
||||
|
||||
static QString resultToString(int result)
|
||||
{
|
||||
QString s;
|
||||
switch(result) {
|
||||
case QCA::TLS::NoCert:
|
||||
s = QObject::tr("No certificate presented.");
|
||||
break;
|
||||
case QCA::TLS::Valid:
|
||||
break;
|
||||
case QCA::TLS::HostMismatch:
|
||||
s = QObject::tr("Hostname mismatch.");
|
||||
break;
|
||||
case QCA::TLS::Rejected:
|
||||
s = QObject::tr("Root CA rejects the specified purpose.");
|
||||
break;
|
||||
case QCA::TLS::Untrusted:
|
||||
s = QObject::tr("Not trusted for the specified purpose.");
|
||||
break;
|
||||
case QCA::TLS::SignatureFailed:
|
||||
s = QObject::tr("Invalid signature.");
|
||||
break;
|
||||
case QCA::TLS::InvalidCA:
|
||||
s = QObject::tr("Invalid CA certificate.");
|
||||
break;
|
||||
case QCA::TLS::InvalidPurpose:
|
||||
s = QObject::tr("Invalid certificate purpose.");
|
||||
break;
|
||||
case QCA::TLS::SelfSigned:
|
||||
s = QObject::tr("Certificate is self-signed.");
|
||||
break;
|
||||
case QCA::TLS::Revoked:
|
||||
s = QObject::tr("Certificate has been revoked.");
|
||||
break;
|
||||
case QCA::TLS::PathLengthExceeded:
|
||||
s = QObject::tr("Maximum cert chain length exceeded.");
|
||||
break;
|
||||
case QCA::TLS::Expired:
|
||||
s = QObject::tr("Certificate has expired.");
|
||||
break;
|
||||
case QCA::TLS::Unknown:
|
||||
default:
|
||||
s = QObject::tr("General validation error.");
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
class App : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XMPP::AdvancedConnector *conn;
|
||||
QCA::TLS *tls;
|
||||
XMPP::QCATLSHandler *tlsHandler;
|
||||
XMPP::ClientStream *stream;
|
||||
BConsole *c;
|
||||
XMPP::Jid jid;
|
||||
QPtrList<QCA::Cert> rootCerts;
|
||||
|
||||
App(const XMPP::Jid &_jid, const XMPP::AdvancedConnector::Proxy &proxy, const QString &host, int port, bool opt_ssl, bool opt_probe)
|
||||
:QObject(0)
|
||||
{
|
||||
c = 0;
|
||||
jid = _jid;
|
||||
|
||||
// Connector
|
||||
conn = new XMPP::AdvancedConnector;
|
||||
conn->setProxy(proxy);
|
||||
if(!host.isEmpty())
|
||||
conn->setOptHostPort(host, port);
|
||||
conn->setOptProbe(opt_probe);
|
||||
conn->setOptSSL(opt_ssl);
|
||||
|
||||
// TLSHandler
|
||||
tls = 0;
|
||||
tlsHandler = 0;
|
||||
rootCerts.setAutoDelete(true);
|
||||
if(QCA::isSupported(QCA::CAP_TLS)) {
|
||||
rootCerts = getRootCerts(ROOTCERT_PATH);
|
||||
tls = new QCA::TLS;
|
||||
tls->setCertificateStore(rootCerts);
|
||||
tlsHandler = new XMPP::QCATLSHandler(tls);
|
||||
connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken()));
|
||||
}
|
||||
|
||||
// Stream
|
||||
stream = new XMPP::ClientStream(conn, tlsHandler);
|
||||
connect(stream, SIGNAL(connected()), SLOT(cs_connected()));
|
||||
connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated()));
|
||||
connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool)));
|
||||
connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated()));
|
||||
connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed()));
|
||||
connect(stream, SIGNAL(readyRead()), SLOT(cs_readyRead()));
|
||||
connect(stream, SIGNAL(stanzaWritten()), SLOT(cs_stanzaWritten()));
|
||||
connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int)));
|
||||
connect(stream, SIGNAL(error(int)), SLOT(cs_error(int)));
|
||||
|
||||
fprintf(stderr, "conntest: Connecting ...\n");
|
||||
stream->setSSFRange(0, 256);
|
||||
stream->connectToServer(jid);
|
||||
}
|
||||
|
||||
~App()
|
||||
{
|
||||
delete stream;
|
||||
delete tls; // this destroys the TLSHandler also
|
||||
delete conn;
|
||||
delete c;
|
||||
}
|
||||
|
||||
signals:
|
||||
void quit();
|
||||
|
||||
private slots:
|
||||
void tls_handshaken()
|
||||
{
|
||||
QCA::Cert cert = tls->peerCertificate();
|
||||
int vr = tls->certificateValidityResult();
|
||||
|
||||
fprintf(stderr, "conntest: Successful TLS handshake.\n");
|
||||
if(!cert.isNull())
|
||||
showCertInfo(cert);
|
||||
if(vr == QCA::TLS::Valid)
|
||||
fprintf(stderr, "conntest: Valid certificate.\n");
|
||||
else
|
||||
fprintf(stderr, "conntest: Invalid certificate: %s\n", resultToString(vr).latin1());
|
||||
|
||||
tlsHandler->continueAfterHandshake();
|
||||
}
|
||||
|
||||
void cs_connected()
|
||||
{
|
||||
fprintf(stderr, "conntest: Connected\n");
|
||||
}
|
||||
|
||||
void cs_securityLayerActivated()
|
||||
{
|
||||
fprintf(stderr, "conntest: Security layer activated (%s)\n", tls->isHandshaken() ? "TLS": "SASL");
|
||||
}
|
||||
|
||||
void cs_needAuthParams(bool user, bool pass, bool realm)
|
||||
{
|
||||
fprintf(stderr, "conntest: need auth params -");
|
||||
if(user)
|
||||
fprintf(stderr, " (user)");
|
||||
if(pass)
|
||||
fprintf(stderr, " (pass)");
|
||||
if(realm)
|
||||
fprintf(stderr, " (realm)");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if(user)
|
||||
stream->setUsername(jid.node());
|
||||
if(pass)
|
||||
stream->setPassword(prompt("Password (not hidden!) :"));
|
||||
stream->continueAfterParams();
|
||||
}
|
||||
|
||||
void cs_authenticated()
|
||||
{
|
||||
fprintf(stderr, "conntest: <<< Authenticated >>>\n");
|
||||
|
||||
// console
|
||||
c = new BConsole;
|
||||
connect(c, SIGNAL(connectionClosed()), SLOT(con_connectionClosed()));
|
||||
connect(c, SIGNAL(readyRead()), SLOT(con_readyRead()));
|
||||
}
|
||||
|
||||
void cs_connectionClosed()
|
||||
{
|
||||
fprintf(stderr, "conntest: Disconnected by peer\n");
|
||||
quit();
|
||||
}
|
||||
|
||||
void cs_readyRead()
|
||||
{
|
||||
for(XMPP::Stanza s; !(s = stream->read()).isNull();) {
|
||||
QString str = s.toString();
|
||||
printf("%s\n", str.local8Bit().data());
|
||||
}
|
||||
}
|
||||
|
||||
void cs_stanzaWritten()
|
||||
{
|
||||
fprintf(stderr, "conntest: Stanza written\n");
|
||||
}
|
||||
|
||||
void cs_warning(int warn)
|
||||
{
|
||||
if(warn == XMPP::ClientStream::WarnOldVersion) {
|
||||
fprintf(stderr, "conntest: Warning: pre-1.0 protocol server\n");
|
||||
}
|
||||
else if(warn == XMPP::ClientStream::WarnNoTLS) {
|
||||
fprintf(stderr, "conntest: Warning: TLS not available!\n");
|
||||
}
|
||||
stream->continueAfterWarning();
|
||||
}
|
||||
|
||||
void cs_error(int err)
|
||||
{
|
||||
if(err == XMPP::ClientStream::ErrParse) {
|
||||
fprintf(stderr, "conntest: XML parsing error\n");
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrProtocol) {
|
||||
fprintf(stderr, "conntest: XMPP protocol error\n");
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrStream) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::Stream::GenericStreamError)
|
||||
s = "generic stream error";
|
||||
else if(x == XMPP::ClientStream::Conflict)
|
||||
s = "conflict (remote login replacing this one)";
|
||||
else if(x == XMPP::ClientStream::ConnectionTimeout)
|
||||
s = "timed out from inactivity";
|
||||
else if(x == XMPP::ClientStream::InternalServerError)
|
||||
s = "internal server error";
|
||||
else if(x == XMPP::ClientStream::InvalidXml)
|
||||
s = "invalid XML";
|
||||
else if(x == XMPP::ClientStream::PolicyViolation)
|
||||
s = "policy violation. go to jail!";
|
||||
else if(x == XMPP::ClientStream::ResourceConstraint)
|
||||
s = "server out of resources";
|
||||
else if(x == XMPP::ClientStream::SystemShutdown)
|
||||
s = "system is shutting down NOW";
|
||||
fprintf(stderr, "conntest: XMPP stream error: %s\n", s.latin1());
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrConnection) {
|
||||
int x = conn->errorCode();
|
||||
QString s;
|
||||
if(x == XMPP::AdvancedConnector::ErrConnectionRefused)
|
||||
s = "unable to connect to server";
|
||||
else if(x == XMPP::AdvancedConnector::ErrHostNotFound)
|
||||
s = "host not found";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyConnect)
|
||||
s = "proxy connect";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyNeg)
|
||||
s = "proxy negotiating";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyAuth)
|
||||
s = "proxy authorization";
|
||||
else if(x == XMPP::AdvancedConnector::ErrStream)
|
||||
s = "stream error";
|
||||
fprintf(stderr, "conntest: connection error: %s\n", s.latin1());
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrNeg) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::HostGone)
|
||||
s = "host no longer hosted";
|
||||
else if(x == XMPP::ClientStream::HostUnknown)
|
||||
s = "host unknown";
|
||||
else if(x == XMPP::ClientStream::RemoteConnectionFailed)
|
||||
s = "a required remote connection failed";
|
||||
else if(x == XMPP::ClientStream::SeeOtherHost)
|
||||
s = QString("see other host: [%1]").arg(stream->errorText());
|
||||
else if(x == XMPP::ClientStream::UnsupportedVersion)
|
||||
s = "server does not support proper xmpp version";
|
||||
fprintf(stderr, "conntest: stream negotiation error: %s\n", s.latin1());
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrTLS) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::TLSStart)
|
||||
s = "server rejected STARTTLS";
|
||||
else if(x == XMPP::ClientStream::TLSFail) {
|
||||
int t = tlsHandler->tlsError();
|
||||
if(t == QCA::TLS::ErrHandshake)
|
||||
s = "TLS handshake error";
|
||||
else
|
||||
s = "broken security layer (TLS)";
|
||||
}
|
||||
fprintf(stderr, "conntest: %s\n", s.latin1());
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrAuth) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::GenericAuthError)
|
||||
s = "unable to login";
|
||||
else if(x == XMPP::ClientStream::NoMech)
|
||||
s = "no appropriate auth mechanism available for given security settings";
|
||||
else if(x == XMPP::ClientStream::BadProto)
|
||||
s = "bad server response";
|
||||
else if(x == XMPP::ClientStream::BadServ)
|
||||
s = "server failed mutual authentication";
|
||||
else if(x == XMPP::ClientStream::EncryptionRequired)
|
||||
s = "encryption required for chosen SASL mechanism";
|
||||
else if(x == XMPP::ClientStream::InvalidAuthzid)
|
||||
s = "invalid authzid";
|
||||
else if(x == XMPP::ClientStream::InvalidMech)
|
||||
s = "invalid SASL mechanism";
|
||||
else if(x == XMPP::ClientStream::InvalidRealm)
|
||||
s = "invalid realm";
|
||||
else if(x == XMPP::ClientStream::MechTooWeak)
|
||||
s = "SASL mechanism too weak for authzid";
|
||||
else if(x == XMPP::ClientStream::NotAuthorized)
|
||||
s = "not authorized";
|
||||
else if(x == XMPP::ClientStream::TemporaryAuthFailure)
|
||||
s = "temporary auth failure";
|
||||
fprintf(stderr, "conntest: auth error: %s\n", s.latin1());
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrSecurityLayer)
|
||||
fprintf(stderr, "conntest: broken security layer (SASL)\n");
|
||||
quit();
|
||||
}
|
||||
|
||||
void con_connectionClosed()
|
||||
{
|
||||
fprintf(stderr, "conntest: Closing.\n");
|
||||
stream->close();
|
||||
quit();
|
||||
}
|
||||
|
||||
void con_readyRead()
|
||||
{
|
||||
QByteArray a = c->read();
|
||||
QCString cs;
|
||||
cs.resize(a.size()+1);
|
||||
memcpy(cs.data(), a.data(), a.size());
|
||||
QString s = QString::fromLocal8Bit(cs);
|
||||
stream->writeDirect(s);
|
||||
}
|
||||
};
|
||||
|
||||
#include "conntest.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv, false);
|
||||
|
||||
if(argc < 2) {
|
||||
printf("usage: conntest [options] [jid]\n");
|
||||
printf(" Options:\n");
|
||||
printf(" --host=host:port\n");
|
||||
printf(" --sslhost=host:port\n");
|
||||
printf(" --probe\n");
|
||||
printf(" --proxy=[https|poll|socks],host:port,url\n");
|
||||
printf(" --proxy-auth=user,pass\n");
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool have_tls = QCA::isSupported(QCA::CAP_TLS);
|
||||
|
||||
XMPP::Jid jid;
|
||||
XMPP::AdvancedConnector::Proxy proxy;
|
||||
QString host;
|
||||
int port = 0;
|
||||
bool opt_ssl = false;
|
||||
bool opt_probe = false;
|
||||
|
||||
for(int at = 1; at < argc; ++at) {
|
||||
QString s = argv[at];
|
||||
|
||||
// is it an option?
|
||||
if(s.left(2) == "--") {
|
||||
QString name;
|
||||
QStringList args;
|
||||
int n = s.find('=', 2);
|
||||
if(n != -1) {
|
||||
name = s.mid(2, n-2);
|
||||
++n;
|
||||
args = QStringList::split(',', s.mid(n), true);
|
||||
}
|
||||
else {
|
||||
name = s.mid(2);
|
||||
args.clear();
|
||||
}
|
||||
|
||||
// eat the arg
|
||||
--argc;
|
||||
for(int x = at; x < argc; ++x)
|
||||
argv[x] = argv[x+1];
|
||||
--at; // don't advance
|
||||
|
||||
// process option
|
||||
if(name == "proxy") {
|
||||
QString proxy_host;
|
||||
int proxy_port = 0;
|
||||
QString type = args[0];
|
||||
QString s = args[1];
|
||||
int n = s.find(':');
|
||||
if(n == -1) {
|
||||
if(type != "poll") {
|
||||
printf("Invalid host:port for proxy\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
proxy_host = s.mid(0, n);
|
||||
++n;
|
||||
proxy_port = s.mid(n).toInt();
|
||||
}
|
||||
|
||||
if(type == "https") {
|
||||
proxy.setHttpConnect(proxy_host, proxy_port);
|
||||
}
|
||||
else if(type == "poll") {
|
||||
if(args.count() < 3) {
|
||||
printf("poll needs more args\n");
|
||||
return 0;
|
||||
}
|
||||
QString proxy_url = args[2];
|
||||
proxy.setHttpPoll(proxy_host, proxy_port, proxy_url);
|
||||
}
|
||||
else if(type == "socks") {
|
||||
proxy.setSocks(proxy_host, proxy_port);
|
||||
}
|
||||
else {
|
||||
printf("No such proxy type '%s'\n", type.latin1());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(name == "proxy-auth") {
|
||||
proxy.setUserPass(args[0], args[1]);
|
||||
}
|
||||
else if(name == "host") {
|
||||
QString s = args[0];
|
||||
int n = s.find(':');
|
||||
if(n == -1) {
|
||||
printf("Invalid host:port for host\n");
|
||||
return 0;
|
||||
}
|
||||
host = s.mid(0, n);
|
||||
++n;
|
||||
port = s.mid(n).toInt();
|
||||
}
|
||||
else if(name == "sslhost") {
|
||||
QString s = args[0];
|
||||
int n = s.find(':');
|
||||
if(n == -1) {
|
||||
printf("Invalid host:port for host\n");
|
||||
return 0;
|
||||
}
|
||||
host = s.mid(0, n);
|
||||
++n;
|
||||
port = s.mid(n).toInt();
|
||||
opt_ssl = true;
|
||||
}
|
||||
else if(name == "probe") {
|
||||
opt_probe = true;
|
||||
}
|
||||
else {
|
||||
printf("Unknown option '%s'\n", name.latin1());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(argc < 2) {
|
||||
printf("No host specified!\n");
|
||||
return 0;
|
||||
}
|
||||
jid = argv[1];
|
||||
|
||||
if((opt_ssl || opt_probe) && !have_tls) {
|
||||
printf("TLS not supported, so the sslhost and probe options are not allowed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("JID: %s\n", jid.full().latin1());
|
||||
if(proxy.type() != XMPP::AdvancedConnector::Proxy::None) {
|
||||
printf("Proxy: ");
|
||||
if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpConnect)
|
||||
printf("HttpConnect (%s:%d)", proxy.host().latin1(), proxy.port());
|
||||
else if(proxy.type() == XMPP::AdvancedConnector::Proxy::HttpPoll) {
|
||||
printf("HttpPoll {%s}", proxy.url().latin1());
|
||||
if(!proxy.host().isEmpty()) {
|
||||
printf(" (%s:%d)", proxy.host().latin1(), proxy.port());
|
||||
}
|
||||
}
|
||||
else if(proxy.type() == XMPP::AdvancedConnector::Proxy::Socks)
|
||||
printf("Socks (%s:%d)", proxy.host().latin1(), proxy.port());
|
||||
printf("\n");
|
||||
}
|
||||
if(proxy.type() != XMPP::AdvancedConnector::Proxy::HttpPoll) {
|
||||
if(!host.isEmpty()) {
|
||||
printf("Host: %s:%d", host.latin1(), port);
|
||||
if(opt_ssl)
|
||||
printf(" (ssl)");
|
||||
printf("\n");
|
||||
}
|
||||
else {
|
||||
if(opt_probe)
|
||||
printf("Probe active\n");
|
||||
}
|
||||
}
|
||||
printf("----------\n");
|
||||
|
||||
App *a = new App(jid, proxy, host, port, opt_ssl, opt_probe);
|
||||
QObject::connect(a, SIGNAL(quit()), &app, SLOT(quit()));
|
||||
app.exec();
|
||||
delete a;
|
||||
|
||||
return 0;
|
||||
}
|
||||
15
iris-legacy/iris/example/conntest/conntest.pro
Normal file
15
iris-legacy/iris/example/conntest/conntest.pro
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += qt thread console
|
||||
TARGET = conntest
|
||||
QT += qt3support network xml
|
||||
|
||||
# Dependencies
|
||||
CONFIG += crypto
|
||||
include(../../../cutestuff/cutestuff.pri)
|
||||
include(../../iris.pri)
|
||||
irisnet {
|
||||
include(../../irisnet/irisnet.pri)
|
||||
}
|
||||
|
||||
SOURCES += conntest.cpp
|
||||
|
||||
4
iris-legacy/iris/example/conntest/conntest.qc
Normal file
4
iris-legacy/iris/example/conntest/conntest.qc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<qconf>
|
||||
<name>Iris Conntest</name>
|
||||
<profile>conntest.pro</profile>
|
||||
</qconf>
|
||||
30
iris-legacy/iris/example/conntest/prepare
Normal file
30
iris-legacy/iris/example/conntest/prepare
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh
|
||||
|
||||
CS_BASE=../../../cutestuff
|
||||
QCA_BASE=../../../qca
|
||||
IRIS_BASE=../..
|
||||
|
||||
# import cutestuff
|
||||
mkdir cutestuff
|
||||
cp -a $CS_BASE/util cutestuff
|
||||
cp -a $CS_BASE/network cutestuff
|
||||
|
||||
# import qca
|
||||
mkdir qca
|
||||
cp -a $QCA_BASE/src/* qca
|
||||
|
||||
# import iris
|
||||
mkdir iris
|
||||
cp -a $IRIS_BASE/libidn iris
|
||||
cp -a $IRIS_BASE/libidn.pri iris
|
||||
cp -a $IRIS_BASE/include iris
|
||||
cp -a $IRIS_BASE/xmpp-core iris
|
||||
cp -a $IRIS_BASE/xmpp-im iris
|
||||
cp -a $IRIS_BASE/jabber iris
|
||||
cp -a $IRIS_BASE/iris.pri iris
|
||||
|
||||
# other stuff
|
||||
cp -a $IRIS_BASE/cs.pri .
|
||||
cp -a $IRIS_BASE/example/example.pri .
|
||||
cp -a $IRIS_BASE/COPYING .
|
||||
|
||||
217
iris-legacy/iris/example/server/server.cpp
Normal file
217
iris-legacy/iris/example/server/server.cpp
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
#include <qapplication.h>
|
||||
#include <qsocket.h>
|
||||
#include <qserversocket.h>
|
||||
#include <qvaluelist.h>
|
||||
#include <qtimer.h>
|
||||
#include <qca.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "bsocket.h"
|
||||
#include "xmpp.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
char pemdata_cert[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDbjCCAtegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhzELMAkGA1UEBhMCVVMx\n"
|
||||
"EzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNVBAcTBklydmluZTEYMBYGA1UEChMP\n"
|
||||
"RXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqGSIb3\n"
|
||||
"DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTAeFw0wMzA3MjQwNzMwMDBaFw0wMzA4\n"
|
||||
"MjMwNzMwMDBaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEP\n"
|
||||
"MA0GA1UEBxMGSXJ2aW5lMRgwFgYDVQQKEw9FeGFtcGxlIENvbXBhbnkxFDASBgNV\n"
|
||||
"BAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\n"
|
||||
"Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCobzCF268K2sRp473gvBTT\n"
|
||||
"4AgSL1kjeF8N57vxS1P8zWrWMXNs4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwW\n"
|
||||
"WZToesxebu3m9VeA8dqWyOaUMjoxAcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8m\n"
|
||||
"a+AAPByfTORbzpSTmXAQAwIDAQABo4HnMIHkMB0GA1UdDgQWBBTvFierzLmmYMq0\n"
|
||||
"cB/+5rK1bNR56zCBtAYDVR0jBIGsMIGpgBTvFierzLmmYMq0cB/+5rK1bNR566GB\n"
|
||||
"jaSBijCBhzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExDzANBgNV\n"
|
||||
"BAcTBklydmluZTEYMBYGA1UEChMPRXhhbXBsZSBDb21wYW55MRQwEgYDVQQDEwtl\n"
|
||||
"eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbYIB\n"
|
||||
"ADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGqGhXf7xNOnYNtFO7gz\n"
|
||||
"K6RdZGHFI5q1DAEz4hhNBC9uElh32XGX4wN7giz3zLC8v9icL/W4ff/K5NDfv3Gf\n"
|
||||
"gQe/+Wo9Be3H3ul6uwPPFnx4+PIOF2a5TW99H9smyxWdNjnFtcUte4al3RszcMWG\n"
|
||||
"x3iqsWosGtj6F+ridmKoqKLu\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
char pemdata_privkey[] =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIICXAIBAAKBgQCobzCF268K2sRp473gvBTT4AgSL1kjeF8N57vxS1P8zWrWMXNs\n"
|
||||
"4LuH0NRZmKTajeboy0br8xw+smIy3AbaKAwWWZToesxebu3m9VeA8dqWyOaUMjox\n"
|
||||
"AcgVYesgVaMpjRe7fcWdJnX1wJoVVPuIcO8ma+AAPByfTORbzpSTmXAQAwIDAQAB\n"
|
||||
"AoGAP83u+aYghuIcaWhmM03MLf69z/WztKYSi/fu0BcS977w67bL3MC9CVPoPRB/\n"
|
||||
"0nLSt/jZIuRzHKUCYfXLerSU7v0oXDTy6GPzWMh/oXIrpF0tYNbwWF7LSq2O2gGZ\n"
|
||||
"XtA9MSmUNNJaKzQQeXjqdVFOY8A0Pho+k2KByBiCi+ChkcECQQDRUuyX0+PKJtA2\n"
|
||||
"M36BOTFpy61BAv+JRlXUnHuevOfQWl6NR6YGygqCyH1sWtP1sa9S4wWys3DFH+5A\n"
|
||||
"DkuAqk7zAkEAzf4eUH2hp5CIMsXH+WpIzKj09oY1it2CAKjVq4rUELf8iXvmGoFl\n"
|
||||
"000spua4MjHNUYm7LR0QaKesKrMyGZUesQJAL8aLdYPJI+SD9Tr/jqLtIkZ4frQe\n"
|
||||
"eshw4pvsoyheiHF3zyshO791crAr4EVCx3sMlxB1xnmqLXPCPyCEHxO//QJBAIBY\n"
|
||||
"IYkjDZJ6ofGIe1UyXJNvfdkPu9J+ut4wU5jjEcgs6mK62J6RGuFxhy2iOQfFMdjo\n"
|
||||
"yL+OCUg7mDCun7uCxrECQAtSvnLOFMjO5qExRjFtwi+b1rcSekd3Osk/izyRFSzg\n"
|
||||
"Or+AL56/EKfiogNnFipgaXIbb/xj785Cob6v96XoW1I=\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
QCA::Cert *cert;
|
||||
QCA::RSAKey *privkey;
|
||||
|
||||
using namespace XMPP;
|
||||
|
||||
int id_num = 0;
|
||||
|
||||
class Session : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Session(const QString &host, const QString &defRealm, ByteStream *bs) : QObject(0)
|
||||
{
|
||||
id = id_num++;
|
||||
|
||||
tls = new QCA::TLS;
|
||||
tls->setCertificate(*cert, *privkey);
|
||||
|
||||
cs = new ClientStream(host, defRealm, bs, tls);
|
||||
connect(cs, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed()));
|
||||
connect(cs, SIGNAL(error(int)), SLOT(cs_error(int)));
|
||||
}
|
||||
|
||||
~Session()
|
||||
{
|
||||
delete cs;
|
||||
delete tls;
|
||||
printf("[%d]: deleted\n", id);
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
printf("[%d]: New session!\n", id);
|
||||
cs->accept();
|
||||
}
|
||||
|
||||
signals:
|
||||
void done();
|
||||
|
||||
private slots:
|
||||
void cs_connectionClosed()
|
||||
{
|
||||
printf("[%d]: Connection closed by peer\n", id);
|
||||
done();
|
||||
}
|
||||
|
||||
void cs_error(int)
|
||||
{
|
||||
printf("[%d]: Error\n", id);
|
||||
done();
|
||||
}
|
||||
|
||||
private:
|
||||
int id;
|
||||
ClientStream *cs;
|
||||
QCA::TLS *tls;
|
||||
};
|
||||
|
||||
class ServerTest : public QServerSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum { Idle, Handshaking, Active, Closing };
|
||||
|
||||
ServerTest(const QString &_host, int _port) : QServerSocket(_port), host(_host), port(_port)
|
||||
{
|
||||
cert = new QCA::Cert;
|
||||
privkey = new QCA::RSAKey;
|
||||
|
||||
cert->fromPEM(pemdata_cert);
|
||||
privkey->fromPEM(pemdata_privkey);
|
||||
|
||||
list.setAutoDelete(true);
|
||||
}
|
||||
|
||||
~ServerTest()
|
||||
{
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
char buf[256];
|
||||
int r = gethostname(buf, sizeof(buf)-1);
|
||||
if(r == -1) {
|
||||
printf("Error getting hostname!\n");
|
||||
QTimer::singleShot(0, this, SIGNAL(quit()));
|
||||
return;
|
||||
}
|
||||
QString myhostname = buf;
|
||||
|
||||
realm = myhostname;
|
||||
if(host.isEmpty())
|
||||
host = myhostname;
|
||||
|
||||
if(cert->isNull() || privkey->isNull()) {
|
||||
printf("Error loading cert and/or private key!\n");
|
||||
QTimer::singleShot(0, this, SIGNAL(quit()));
|
||||
return;
|
||||
}
|
||||
if(!ok()) {
|
||||
printf("Error binding to port %d!\n", port);
|
||||
QTimer::singleShot(0, this, SIGNAL(quit()));
|
||||
return;
|
||||
}
|
||||
printf("Listening on %s:%d ...\n", host.latin1(), port);
|
||||
}
|
||||
|
||||
void newConnection(int s)
|
||||
{
|
||||
BSocket *bs = new BSocket;
|
||||
bs->setSocket(s);
|
||||
Session *sess = new Session(host, realm, bs);
|
||||
list.append(sess);
|
||||
connect(sess, SIGNAL(done()), SLOT(sess_done()));
|
||||
sess->start();
|
||||
}
|
||||
|
||||
signals:
|
||||
void quit();
|
||||
|
||||
private slots:
|
||||
void sess_done()
|
||||
{
|
||||
Session *sess = (Session *)sender();
|
||||
list.removeRef(sess);
|
||||
}
|
||||
|
||||
private:
|
||||
QString host, realm;
|
||||
int port;
|
||||
QPtrList<Session> list;
|
||||
};
|
||||
|
||||
#include "server.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv, false);
|
||||
QString host = argc > 1 ? QString(argv[1]) : QString();
|
||||
int port = argc > 2 ? QString(argv[2]).toInt() : 5222;
|
||||
|
||||
if(!QCA::isSupported(QCA::CAP_TLS)) {
|
||||
printf("TLS not supported!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!QCA::isSupported(QCA::CAP_SASL)) {
|
||||
printf("SASL not supported!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
ServerTest *s = new ServerTest(host, port);
|
||||
QObject::connect(s, SIGNAL(quit()), &app, SLOT(quit()));
|
||||
s->start();
|
||||
app.exec();
|
||||
delete s;
|
||||
|
||||
// clean up
|
||||
QCA::unloadAllPlugins();
|
||||
|
||||
return 0;
|
||||
}
|
||||
15
iris-legacy/iris/example/server/server.pro
Normal file
15
iris-legacy/iris/example/server/server.pro
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += qt thread console
|
||||
TARGET = server
|
||||
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = .obj
|
||||
UI_DIR = .ui
|
||||
|
||||
include(../xmpptest/iris.pri)
|
||||
|
||||
SOURCES += server.cpp
|
||||
|
||||
# gentoo hack?
|
||||
LIBS += -lcrypto
|
||||
|
||||
470
iris-legacy/iris/example/xmpptest/ui_test.ui
Normal file
470
iris-legacy/iris/example/xmpptest/ui_test.ui
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
<ui version="4.0" stdsetdef="1" >
|
||||
<author></author>
|
||||
<comment></comment>
|
||||
<exportmacro></exportmacro>
|
||||
<class>TestUI</class>
|
||||
<widget class="QDialog" name="TestUI" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>652</width>
|
||||
<height>591</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form1</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tb_main" >
|
||||
<widget class="QWidget" name="tab" >
|
||||
<attribute name="title" >
|
||||
<string>Core</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="Q3GroupBox" name="gb_server" >
|
||||
<property name="title" >
|
||||
<string>Server</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel1" >
|
||||
<property name="text" >
|
||||
<string>Full JID:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="le_jid" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel5_2" >
|
||||
<property name="text" >
|
||||
<string>User (if needed):</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="le_user" >
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel7_2" >
|
||||
<property name="text" >
|
||||
<string>Pass:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="le_pass" >
|
||||
<property name="echoMode" >
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QCheckBox" name="ck_ssl" >
|
||||
<property name="text" >
|
||||
<string>SSL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="1" row="2" column="1" colspan="2" >
|
||||
<widget class="QComboBox" name="cb_proxy" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>HTTP(S)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>SOCKS5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>HTTP Polling</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="lb_host" >
|
||||
<property name="text" >
|
||||
<string>Host:Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="1" row="0" column="0" colspan="3" >
|
||||
<widget class="QCheckBox" name="ck_probe" >
|
||||
<property name="text" >
|
||||
<string>Legacy SSL probe</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="textLabel4" >
|
||||
<property name="text" >
|
||||
<string>Proxy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="le_host" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Q3GroupBox" name="gb_proxy" >
|
||||
<property name="title" >
|
||||
<string>Proxy Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="textLabel2_2" >
|
||||
<property name="text" >
|
||||
<string>Host:Port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="1" row="0" column="1" colspan="3" >
|
||||
<widget class="QLineEdit" name="le_proxyhost" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="textLabel5" >
|
||||
<property name="text" >
|
||||
<string>User/Pass:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="le_proxyuser" />
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QLabel" name="textLabel7" >
|
||||
<property name="text" >
|
||||
<string>/</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<widget class="QLineEdit" name="le_proxypass" >
|
||||
<property name="echoMode" >
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="lb_proxyurl" >
|
||||
<property name="text" >
|
||||
<string>Polling URL:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="1" row="2" column="1" colspan="3" >
|
||||
<widget class="QLineEdit" name="le_proxyurl" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Q3GroupBox" name="gb_security" >
|
||||
<property name="title" >
|
||||
<string>Security Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ck_plain" >
|
||||
<property name="text" >
|
||||
<string>Allow plaintext login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ck_mutual" >
|
||||
<property name="text" >
|
||||
<string>Require mutual authentication</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel1_2" >
|
||||
<property name="text" >
|
||||
<string>SASL SSF min/max:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sb_ssfmin" />
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel2" >
|
||||
<property name="text" >
|
||||
<string>/</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sb_ssfmax" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_go" >
|
||||
<property name="text" >
|
||||
<string>&Connect</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Alt+C</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer5" >
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>130</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Horizontal</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_about" >
|
||||
<property name="text" >
|
||||
<string>&About</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer3_2" >
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Q3GroupBox" name="groupBox3" >
|
||||
<property name="title" >
|
||||
<string>Quick XML >></string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel8" >
|
||||
<property name="text" >
|
||||
<string>To:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="le_to" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_im" >
|
||||
<property name="text" >
|
||||
<string>&IM Session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_msg" >
|
||||
<property name="text" >
|
||||
<string>&Message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_iqv" >
|
||||
<property name="text" >
|
||||
<string>IQ &Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab" >
|
||||
<attribute name="title" >
|
||||
<string>IM</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="Q3TextEdit" name="te_log" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="wrapPolicy" >
|
||||
<enum>AtWordOrDocumentBoundary</enum>
|
||||
</property>
|
||||
<property name="readOnly" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Q3TextEdit" name="te_input" >
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>32767</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="spacer3" >
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>Expanding</enum>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Horizontal</enum>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_send" >
|
||||
<property name="text" >
|
||||
<string>&Send</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<string>Alt+S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11" />
|
||||
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
|
||||
<tabstops>
|
||||
<tabstop>le_jid</tabstop>
|
||||
<tabstop>le_user</tabstop>
|
||||
<tabstop>le_pass</tabstop>
|
||||
<tabstop>ck_probe</tabstop>
|
||||
<tabstop>le_host</tabstop>
|
||||
<tabstop>ck_ssl</tabstop>
|
||||
<tabstop>cb_proxy</tabstop>
|
||||
<tabstop>le_proxyhost</tabstop>
|
||||
<tabstop>le_proxyuser</tabstop>
|
||||
<tabstop>le_proxypass</tabstop>
|
||||
<tabstop>le_proxyurl</tabstop>
|
||||
<tabstop>ck_plain</tabstop>
|
||||
<tabstop>ck_mutual</tabstop>
|
||||
<tabstop>sb_ssfmin</tabstop>
|
||||
<tabstop>sb_ssfmax</tabstop>
|
||||
<tabstop>pb_go</tabstop>
|
||||
<tabstop>pb_about</tabstop>
|
||||
<tabstop>le_to</tabstop>
|
||||
<tabstop>pb_im</tabstop>
|
||||
<tabstop>pb_msg</tabstop>
|
||||
<tabstop>pb_iqv</tabstop>
|
||||
<tabstop>te_input</tabstop>
|
||||
<tabstop>pb_send</tabstop>
|
||||
<tabstop>te_log</tabstop>
|
||||
</tabstops>
|
||||
</ui>
|
||||
916
iris-legacy/iris/example/xmpptest/xmpptest.cpp
Normal file
916
iris-legacy/iris/example/xmpptest/xmpptest.cpp
Normal file
|
|
@ -0,0 +1,916 @@
|
|||
#include <qapplication.h>
|
||||
#include <q3textedit.h>
|
||||
#include <q3groupbox.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qlabel.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <q3textedit.h>
|
||||
#include <qcombobox.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qmessagebox.h>
|
||||
#include <qinputdialog.h>
|
||||
#include <qspinbox.h>
|
||||
#include <qtimer.h>
|
||||
#include <qmenubar.h>
|
||||
#include <q3popupmenu.h>
|
||||
#include <qtabwidget.h>
|
||||
#include <qca.h>
|
||||
//Added by qt3to4:
|
||||
#include <Q3PtrList>
|
||||
#include <QList>
|
||||
//#include <iris/xmpp.h>
|
||||
#include "xmpp.h"
|
||||
#include "im.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ui_ui_test.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define AppName "xmpptest"
|
||||
|
||||
static QString plain2rich(const QString &plain)
|
||||
{
|
||||
QString rich;
|
||||
int col = 0;
|
||||
|
||||
for(int i = 0; i < (int)plain.length(); ++i) {
|
||||
if(plain[i] == '\n') {
|
||||
rich += "<br>";
|
||||
col = 0;
|
||||
}
|
||||
else if(plain[i] == '\t') {
|
||||
rich += QChar::nbsp;
|
||||
while(col % 4) {
|
||||
rich += QChar::nbsp;
|
||||
++col;
|
||||
}
|
||||
}
|
||||
else if(plain[i].isSpace()) {
|
||||
if(i > 0 && plain[i-1] == ' ')
|
||||
rich += QChar::nbsp;
|
||||
else
|
||||
rich += ' ';
|
||||
}
|
||||
else if(plain[i] == '<')
|
||||
rich += "<";
|
||||
else if(plain[i] == '>')
|
||||
rich += ">";
|
||||
else if(plain[i] == '\"')
|
||||
rich += """;
|
||||
else if(plain[i] == '\'')
|
||||
rich += "'";
|
||||
else if(plain[i] == '&')
|
||||
rich += "&";
|
||||
else
|
||||
rich += plain[i];
|
||||
++col;
|
||||
}
|
||||
|
||||
return rich;
|
||||
}
|
||||
|
||||
/*static void showCertInfo(const QCA::Cert &cert)
|
||||
{
|
||||
fprintf(stderr, "-- Cert --\n");
|
||||
fprintf(stderr, " CN: %s\n", cert.subject()["CN"].latin1());
|
||||
fprintf(stderr, " Valid from: %s, until %s\n",
|
||||
cert.notBefore().toString().latin1(),
|
||||
cert.notAfter().toString().latin1());
|
||||
fprintf(stderr, " PEM:\n%s\n", cert.toPEM().latin1());
|
||||
}*/
|
||||
|
||||
static QString resultToString(int result)
|
||||
{
|
||||
QString s;
|
||||
switch(result) {
|
||||
case QCA::TLS::NoCertificate:
|
||||
s = QObject::tr("No certificate presented.");
|
||||
break;
|
||||
case QCA::TLS::Valid:
|
||||
break;
|
||||
case QCA::TLS::HostMismatch:
|
||||
s = QObject::tr("Hostname mismatch.");
|
||||
break;
|
||||
case QCA::TLS::InvalidCertificate:
|
||||
s = QObject::tr("Invalid Certificate.");
|
||||
break;
|
||||
// TODO: Inspect why
|
||||
// case QCA::TLS::Untrusted:
|
||||
// s = QObject::tr("Not trusted for the specified purpose.");
|
||||
// break;
|
||||
// case QCA::TLS::SignatureFailed:
|
||||
// s = QObject::tr("Invalid signature.");
|
||||
// break;
|
||||
// case QCA::TLS::InvalidCA:
|
||||
// s = QObject::tr("Invalid CA certificate.");
|
||||
// break;
|
||||
// case QCA::TLS::InvalidPurpose:
|
||||
// s = QObject::tr("Invalid certificate purpose.");
|
||||
// break;
|
||||
// case QCA::TLS::SelfSigned:
|
||||
// s = QObject::tr("Certificate is self-signed.");
|
||||
// break;
|
||||
// case QCA::TLS::Revoked:
|
||||
// s = QObject::tr("Certificate has been revoked.");
|
||||
// break;
|
||||
// case QCA::TLS::PathLengthExceeded:
|
||||
// s = QObject::tr("Maximum cert chain length exceeded.");
|
||||
// break;
|
||||
// case QCA::TLS::Expired:
|
||||
// s = QObject::tr("Certificate has expired.");
|
||||
// break;
|
||||
// case QCA::TLS::Unknown:
|
||||
default:
|
||||
s = QObject::tr("General validation error.");
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
class TestDebug : public XMPP::Debug
|
||||
{
|
||||
public:
|
||||
void msg(const QString &);
|
||||
void outgoingTag(const QString &);
|
||||
void incomingTag(const QString &);
|
||||
void outgoingXml(const QDomElement &);
|
||||
void incomingXml(const QDomElement &);
|
||||
};
|
||||
|
||||
class TestDlg : public QDialog, public Ui::TestUI
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool active, connected;
|
||||
XMPP::AdvancedConnector *conn;
|
||||
QCA::TLS *tls;
|
||||
XMPP::QCATLSHandler *tlsHandler;
|
||||
XMPP::ClientStream *stream;
|
||||
XMPP::Jid jid;
|
||||
|
||||
TestDlg(QWidget *parent=0) : QDialog(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
setWindowTitle(tr("XMPP Test"));
|
||||
|
||||
connect(ck_probe, SIGNAL(toggled(bool)), SLOT(probe_toggled(bool)));
|
||||
connect(cb_proxy, SIGNAL(activated(int)), SLOT(proxy_activated(int)));
|
||||
connect(pb_go, SIGNAL(clicked()), SLOT(go()));
|
||||
connect(pb_send, SIGNAL(clicked()), SLOT(send()));
|
||||
connect(pb_im, SIGNAL(clicked()), SLOT(sc_im()));
|
||||
connect(pb_msg, SIGNAL(clicked()), SLOT(sc_msg()));
|
||||
connect(pb_iqv, SIGNAL(clicked()), SLOT(sc_iqv()));
|
||||
connect(pb_about, SIGNAL(clicked()), SLOT(about()));
|
||||
|
||||
sb_ssfmin->setMinValue(0);
|
||||
sb_ssfmin->setMaxValue(256);
|
||||
sb_ssfmax->setMinValue(0);
|
||||
sb_ssfmax->setMaxValue(256);
|
||||
|
||||
pb_send->setEnabled(false);
|
||||
proxy_activated(0);
|
||||
ck_probe->setChecked(true);
|
||||
ck_mutual->setChecked(false);
|
||||
pb_go->setText(tr("&Connect"));
|
||||
|
||||
//le_jid->setText("psitest@jabberd.jabberstudio.org/Test");
|
||||
//ck_probe->setChecked(false);
|
||||
//le_host->setText("jabberd.jabberstudio.org:15222");
|
||||
//ck_mutual->setChecked(false);
|
||||
//le_jid->setText("sasltest@e.jabber.ru/Test");
|
||||
//le_jid->setText("psitest@jabber.cz/Test");
|
||||
//le_pass->setText("psitest");
|
||||
//cb_proxy->setCurrentItem(3);
|
||||
//le_proxyurl->setText("http://connect.jabber.cz/");
|
||||
|
||||
// setup xmpp
|
||||
conn = new XMPP::AdvancedConnector;
|
||||
connect(conn, SIGNAL(srvLookup(const QString &)), SLOT(conn_srvLookup(const QString &)));
|
||||
connect(conn, SIGNAL(srvResult(bool)), SLOT(conn_srvResult(bool)));
|
||||
connect(conn, SIGNAL(httpSyncStarted()), SLOT(conn_httpSyncStarted()));
|
||||
connect(conn, SIGNAL(httpSyncFinished()), SLOT(conn_httpSyncFinished()));
|
||||
|
||||
if(QCA::isSupported("tls")) {
|
||||
tls = new QCA::TLS;
|
||||
tlsHandler = new XMPP::QCATLSHandler(tls);
|
||||
tlsHandler->setXMPPCertCheck(true);
|
||||
connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken()));
|
||||
}
|
||||
else {
|
||||
tls = 0;
|
||||
tlsHandler = 0;
|
||||
}
|
||||
|
||||
stream = new XMPP::ClientStream(conn, tlsHandler);
|
||||
//stream->setOldOnly(true);
|
||||
connect(stream, SIGNAL(connected()), SLOT(cs_connected()));
|
||||
connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated(int)));
|
||||
connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool)));
|
||||
connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated()));
|
||||
connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed()));
|
||||
connect(stream, SIGNAL(delayedCloseFinished()), SLOT(cs_delayedCloseFinished()));
|
||||
connect(stream, SIGNAL(readyRead()), SLOT(cs_readyRead()));
|
||||
connect(stream, SIGNAL(stanzaWritten()), SLOT(cs_stanzaWritten()));
|
||||
connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int)));
|
||||
connect(stream, SIGNAL(error(int)), SLOT(cs_error(int)));
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(adjustLayout()));
|
||||
|
||||
le_jid->setFocus();
|
||||
active = false;
|
||||
connected = false;
|
||||
}
|
||||
|
||||
~TestDlg()
|
||||
{
|
||||
delete stream;
|
||||
delete tls; // this destroys the TLSHandler also
|
||||
delete conn;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void adjustLayout()
|
||||
{
|
||||
tb_main->setFixedWidth(tb_main->minimumSizeHint().width());
|
||||
resize(minimumSizeHint());
|
||||
show();
|
||||
}
|
||||
|
||||
void about()
|
||||
{
|
||||
QMessageBox::about(this, tr("About %1").arg(AppName), tr(
|
||||
"%1 v1.0\n"
|
||||
"\n"
|
||||
"Utility to demonstrate the Iris XMPP library.\n"
|
||||
"\n"
|
||||
"Currently supports:\n"
|
||||
" draft-ietf-xmpp-core-21\n"
|
||||
" JEP-0025\n"
|
||||
"\n"
|
||||
"Copyright (C) 2003 Justin Karneges").arg(AppName));
|
||||
}
|
||||
|
||||
void probe_toggled(bool)
|
||||
{
|
||||
setHostState();
|
||||
}
|
||||
|
||||
void proxy_activated(int x)
|
||||
{
|
||||
bool ok = (x != 0);
|
||||
bool okpoll = (x == 3);
|
||||
gb_proxy->setEnabled(ok);
|
||||
lb_proxyurl->setEnabled(okpoll);
|
||||
le_proxyurl->setEnabled(okpoll);
|
||||
ck_probe->setEnabled(!okpoll);
|
||||
setHostState();
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
pb_send->setEnabled(false);
|
||||
pb_go->setEnabled(true);
|
||||
pb_go->setText(tr("&Connect"));
|
||||
pb_go->setFocus();
|
||||
gb_server->setEnabled(true);
|
||||
active = false;
|
||||
connected = false;
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
if(active)
|
||||
return;
|
||||
|
||||
jid = XMPP::Jid(le_jid->text());
|
||||
if(jid.domain().isEmpty() || jid.node().isEmpty() || jid.resource().isEmpty()) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Please enter the Full JID to connect with."));
|
||||
return;
|
||||
}
|
||||
|
||||
int p = cb_proxy->currentItem();
|
||||
XMPP::AdvancedConnector::Proxy proxy;
|
||||
if(p > 0) {
|
||||
QString s = le_proxyhost->text();
|
||||
QString url = le_proxyurl->text();
|
||||
if(p != 3 && s.isEmpty()) {
|
||||
QMessageBox::information(this, tr("Error"), tr("You must specify a host:port for the proxy."));
|
||||
return;
|
||||
}
|
||||
if(p == 3 && s.isEmpty() && url.isEmpty()) {
|
||||
QMessageBox::information(this, tr("Error"), tr("You must at least enter a URL to use http poll."));
|
||||
return;
|
||||
}
|
||||
QString host;
|
||||
int port = 0;
|
||||
if(!s.isEmpty()) {
|
||||
int n = s.find(':');
|
||||
if(n == -1) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Please enter the proxy host in the form 'host:port'."));
|
||||
return;
|
||||
}
|
||||
host = s.mid(0, n);
|
||||
port = s.mid(n+1).toInt();
|
||||
}
|
||||
if(p == 1)
|
||||
proxy.setHttpConnect(host, port);
|
||||
else if(p == 2)
|
||||
proxy.setSocks(host, port);
|
||||
else if(p == 3) {
|
||||
proxy.setHttpPoll(host, port, url);
|
||||
proxy.setPollInterval(2); // fast during login
|
||||
}
|
||||
proxy.setUserPass(le_proxyuser->text(), le_proxypass->text());
|
||||
}
|
||||
bool probe = (p != 3 && ck_probe->isChecked());
|
||||
bool useHost = (!probe && !le_host->text().isEmpty());
|
||||
QString host;
|
||||
int port = 0;
|
||||
bool ssl = false;
|
||||
if(useHost) {
|
||||
QString s = le_host->text();
|
||||
int n = s.find(':');
|
||||
if(n == -1) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Please enter the host in the form 'host:port'."));
|
||||
return;
|
||||
}
|
||||
host = s.mid(0, n);
|
||||
port = s.mid(n+1).toInt();
|
||||
|
||||
if(ck_ssl->isChecked())
|
||||
ssl = true;
|
||||
}
|
||||
if(sb_ssfmin->value() > sb_ssfmax->value()) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Error: SSF Min is greater than SSF Max."));
|
||||
return;
|
||||
}
|
||||
|
||||
if((probe || ssl) && !tls) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Error: TLS not available. Disable any TLS options."));
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare
|
||||
conn->setProxy(proxy);
|
||||
if(useHost)
|
||||
conn->setOptHostPort(host, port);
|
||||
else
|
||||
conn->setOptHostPort("", 0);
|
||||
conn->setOptProbe(probe);
|
||||
conn->setOptSSL(ssl);
|
||||
|
||||
if(tls) {
|
||||
tls->setTrustedCertificates(QCA::systemStore());
|
||||
}
|
||||
|
||||
stream->setNoopTime(55000); // every 55 seconds
|
||||
stream->setAllowPlain(ck_plain->isChecked() ? XMPP::ClientStream::AllowPlain : XMPP::ClientStream::NoAllowPlain);
|
||||
stream->setRequireMutualAuth(ck_mutual->isChecked());
|
||||
stream->setSSFRange(sb_ssfmin->value(), sb_ssfmax->value());
|
||||
//stream->setOldOnly(true);
|
||||
stream->setCompress(true);
|
||||
|
||||
gb_server->setEnabled(false);
|
||||
pb_go->setText(tr("&Disconnect"));
|
||||
pb_go->setFocus();
|
||||
active = true;
|
||||
|
||||
appendSysMsg("Connecting...");
|
||||
stream->connectToServer(jid);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if(!active)
|
||||
return;
|
||||
|
||||
if(connected) {
|
||||
pb_go->setEnabled(false);
|
||||
appendSysMsg("Disconnecting...");
|
||||
stream->close();
|
||||
}
|
||||
else {
|
||||
stream->close();
|
||||
appendSysMsg("Disconnected");
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
void go()
|
||||
{
|
||||
if(active)
|
||||
stop();
|
||||
else
|
||||
start();
|
||||
}
|
||||
|
||||
void send()
|
||||
{
|
||||
if(te_input->text().isEmpty())
|
||||
return;
|
||||
|
||||
// construct a "temporary" document to parse the input
|
||||
QString str = "<stream xmlns=\"jabber:client\">\n";
|
||||
str += te_input->text() + '\n';
|
||||
str += "</stream>";
|
||||
|
||||
QDomDocument doc;
|
||||
QString errMsg;
|
||||
int errLine, errCol;
|
||||
if(!doc.setContent(str, true, &errMsg, &errLine, &errCol)) {
|
||||
int lines = QStringList::split('\n', str, true).count();
|
||||
--errLine; // skip the first line
|
||||
if(errLine == lines-1) {
|
||||
errLine = lines-2;
|
||||
errCol = te_input->paragraphLength(errLine-1)+1;
|
||||
errMsg = "incomplete input";
|
||||
}
|
||||
te_input->setCursorPosition(errLine-1, errCol-1);
|
||||
QMessageBox::information(this, tr("Error"), tr("Bad XML input (%1,%2): %3\nPlease correct and try again.").arg(errCol).arg(errLine).arg(errMsg));
|
||||
return;
|
||||
}
|
||||
QDomElement e = doc.firstChild().toElement();
|
||||
|
||||
int num = 0;
|
||||
QDomNodeList nl = e.childNodes();
|
||||
QList<XMPP::Stanza> stanzaList;
|
||||
for(uint x = 0; x < nl.count(); ++x) {
|
||||
QDomNode n = nl.item(x);
|
||||
if(n.isElement()) {
|
||||
QDomElement e = n.toElement();
|
||||
XMPP::Stanza s = stream->createStanza(e);
|
||||
if(s.isNull()) {
|
||||
QMessageBox::information(this, tr("Error"), tr("Bad Stanza '%1'. Must be 'message', 'presence', or 'iq'").arg(e.tagName()));
|
||||
return;
|
||||
}
|
||||
stanzaList += s;
|
||||
++num;
|
||||
}
|
||||
}
|
||||
if(num == 0) {
|
||||
QMessageBox::information(this, tr("Error"), tr("You must enter at least one stanza!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// out the door
|
||||
for(QList<XMPP::Stanza>::ConstIterator it = stanzaList.begin(); it != stanzaList.end(); ++it) {
|
||||
appendXmlOut(XMPP::Stream::xmlToString((*it).element(), true));
|
||||
stream->write(*it);
|
||||
}
|
||||
|
||||
te_input->setText("");
|
||||
}
|
||||
|
||||
void sc_im()
|
||||
{
|
||||
/*XMPP::Message m("justin@andbit.net/Psi");
|
||||
m.setSubject("Hi");
|
||||
m.setBody("I send you this in order to have your advice.");
|
||||
m.setBody("Escucha lechuga!", "es");
|
||||
XMPP::Stanza stanza = m.toStanza(stream);
|
||||
QString str = stanza.toString();
|
||||
printf("[%s]\n", str.latin1());
|
||||
|
||||
XMPP::Message n;
|
||||
n.fromStanza(stanza);
|
||||
printf("subject: [%s]\n", n.subject().latin1());
|
||||
printf("body: [%s]\n", n.body().latin1());
|
||||
printf("body-es: [%s]\n", n.body("es").latin1());*/
|
||||
|
||||
QString s;
|
||||
s += "<iq type='set' id='sess_1'>\n";
|
||||
s += " <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>\n";
|
||||
s += "</iq>";
|
||||
te_input->setText(s);
|
||||
te_input->setFocus();
|
||||
}
|
||||
|
||||
void sc_msg()
|
||||
{
|
||||
QString to = le_to->text();
|
||||
QString s;
|
||||
if(!to.isEmpty())
|
||||
s += QString("<message to=\"%1\">\n").arg(to);
|
||||
else
|
||||
s += QString("<message to=\"\">\n");
|
||||
s += " <body>hello world</body>\n";
|
||||
s += "</message>";
|
||||
te_input->setText(s);
|
||||
if(!to.isEmpty()) {
|
||||
te_input->setCursorPosition(1, 7);
|
||||
te_input->setSelection(1, 7, 1, 18);
|
||||
}
|
||||
else
|
||||
te_input->setCursorPosition(0, 13);
|
||||
te_input->setFocus();
|
||||
}
|
||||
|
||||
void sc_iqv()
|
||||
{
|
||||
QString to = le_to->text();
|
||||
QString s;
|
||||
if(!to.isEmpty())
|
||||
s += QString("<iq to=\"%1\" type=\"get\" id=\"abcde\">\n").arg(to);
|
||||
else
|
||||
s += QString("<iq to=\"\" type=\"get\" id=\"abcde\">\n");
|
||||
s += " <query xmlns=\"jabber:iq:version\"/>\n";
|
||||
s += "</iq>";
|
||||
te_input->setText(s);
|
||||
if(!to.isEmpty()) {
|
||||
te_input->setCursorPosition(0, 8);
|
||||
te_input->setSelection(0, 8, 0, 8 + to.length());
|
||||
}
|
||||
else
|
||||
te_input->setCursorPosition(0, 8);
|
||||
te_input->setFocus();
|
||||
}
|
||||
|
||||
void conn_srvLookup(const QString &server)
|
||||
{
|
||||
appendLibMsg(QString("SRV lookup on [%1]").arg(server));
|
||||
}
|
||||
|
||||
void conn_srvResult(bool b)
|
||||
{
|
||||
if(b)
|
||||
appendLibMsg("SRV lookup success!");
|
||||
else
|
||||
appendLibMsg("SRV lookup failed");
|
||||
}
|
||||
|
||||
void conn_httpSyncStarted()
|
||||
{
|
||||
appendLibMsg("HttpPoll: syncing");
|
||||
}
|
||||
|
||||
void conn_httpSyncFinished()
|
||||
{
|
||||
appendLibMsg("HttpPoll: done");
|
||||
}
|
||||
|
||||
void tls_handshaken()
|
||||
{
|
||||
//QCA::Certificate cert = tls->peerCertificate();
|
||||
int vr = tls->peerIdentityResult();
|
||||
if (vr == QCA::TLS::Valid && !tlsHandler->certMatchesHostname()) vr = QCA::TLS::HostMismatch;
|
||||
|
||||
appendSysMsg("Successful TLS handshake.");
|
||||
if(vr == QCA::TLS::Valid)
|
||||
appendSysMsg("Valid certificate.");
|
||||
else {
|
||||
appendSysMsg(QString("Invalid certificate: %1").arg(resultToString(vr)), Qt::red);
|
||||
appendSysMsg("Continuing anyway");
|
||||
}
|
||||
|
||||
tlsHandler->continueAfterHandshake();
|
||||
}
|
||||
|
||||
void cs_connected()
|
||||
{
|
||||
QString s = "Connected";
|
||||
if(conn->havePeerAddress())
|
||||
s += QString(" (%1:%2)").arg(conn->peerAddress().toString()).arg(conn->peerPort());
|
||||
if(conn->useSSL())
|
||||
s += " [ssl]";
|
||||
appendSysMsg(s);
|
||||
}
|
||||
|
||||
void cs_securityLayerActivated(int type)
|
||||
{
|
||||
appendSysMsg(QString("Security layer activated (%1)").arg((type == XMPP::ClientStream::LayerTLS) ? "TLS": "SASL"));
|
||||
}
|
||||
|
||||
void cs_needAuthParams(bool user, bool pass, bool realm)
|
||||
{
|
||||
QString s = "Need auth parameters -";
|
||||
if(user)
|
||||
s += " (Username)";
|
||||
if(pass)
|
||||
s += " (Password)";
|
||||
if(realm)
|
||||
s += " (Realm)";
|
||||
appendSysMsg(s);
|
||||
|
||||
if(user) {
|
||||
if(!le_user->text().isEmpty())
|
||||
stream->setUsername(le_user->text());
|
||||
else
|
||||
stream->setUsername(jid.node());
|
||||
}
|
||||
if(pass) {
|
||||
if(!le_pass->text().isEmpty())
|
||||
stream->setPassword(le_pass->text());
|
||||
else {
|
||||
conn->changePollInterval(10); // slow down during prompt
|
||||
bool ok;
|
||||
QString s = QInputDialog::getText(tr("Password"), tr("Enter the password for %1").arg(jid.full()), QLineEdit::Password, QString::null, &ok, this);
|
||||
if(!ok) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
stream->setPassword(s);
|
||||
|
||||
conn->changePollInterval(2); // resume speed
|
||||
}
|
||||
}
|
||||
if(realm)
|
||||
stream->setRealm(jid.domain());
|
||||
|
||||
stream->continueAfterParams();
|
||||
}
|
||||
|
||||
void cs_authenticated()
|
||||
{
|
||||
connected = true;
|
||||
pb_send->setEnabled(true);
|
||||
conn->changePollInterval(10); // slow down after login
|
||||
appendSysMsg("Authenticated");
|
||||
}
|
||||
|
||||
void cs_connectionClosed()
|
||||
{
|
||||
appendSysMsg("Disconnected by peer");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void cs_delayedCloseFinished()
|
||||
{
|
||||
appendSysMsg("Disconnected");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void cs_readyRead()
|
||||
{
|
||||
while(stream->stanzaAvailable()) {
|
||||
XMPP::Stanza s = stream->read();
|
||||
appendXmlIn(XMPP::Stream::xmlToString(s.element(), true));
|
||||
}
|
||||
}
|
||||
|
||||
void cs_stanzaWritten()
|
||||
{
|
||||
appendSysMsg("Stanza sent");
|
||||
}
|
||||
|
||||
void cs_warning(int warn)
|
||||
{
|
||||
if(warn == XMPP::ClientStream::WarnOldVersion) {
|
||||
appendSysMsg("Warning: pre-1.0 protocol server", Qt::red);
|
||||
}
|
||||
else if(warn == XMPP::ClientStream::WarnNoTLS) {
|
||||
appendSysMsg("Warning: TLS not available!", Qt::red);
|
||||
}
|
||||
stream->continueAfterWarning();
|
||||
}
|
||||
|
||||
void cs_error(int err)
|
||||
{
|
||||
if(err == XMPP::ClientStream::ErrParse) {
|
||||
appendErrMsg("XML parsing error");
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrProtocol) {
|
||||
appendErrMsg("XMPP protocol error");
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrStream) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::Stream::GenericStreamError)
|
||||
s = "generic stream error";
|
||||
else if(x == XMPP::ClientStream::Conflict)
|
||||
s = "conflict (remote login replacing this one)";
|
||||
else if(x == XMPP::ClientStream::ConnectionTimeout)
|
||||
s = "timed out from inactivity";
|
||||
else if(x == XMPP::ClientStream::InternalServerError)
|
||||
s = "internal server error";
|
||||
else if(x == XMPP::ClientStream::InvalidFrom)
|
||||
s = "invalid from address";
|
||||
else if(x == XMPP::ClientStream::InvalidXml)
|
||||
s = "invalid XML";
|
||||
else if(x == XMPP::ClientStream::PolicyViolation)
|
||||
s = "policy violation. go to jail!";
|
||||
else if(x == XMPP::ClientStream::ResourceConstraint)
|
||||
s = "server out of resources";
|
||||
else if(x == XMPP::ClientStream::SystemShutdown)
|
||||
s = "system is shutting down NOW";
|
||||
appendErrMsg(QString("XMPP stream error: %1").arg(s));
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrConnection) {
|
||||
int x = conn->errorCode();
|
||||
QString s;
|
||||
if(x == XMPP::AdvancedConnector::ErrConnectionRefused)
|
||||
s = "unable to connect to server";
|
||||
else if(x == XMPP::AdvancedConnector::ErrHostNotFound)
|
||||
s = "host not found";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyConnect)
|
||||
s = "proxy connect";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyNeg)
|
||||
s = "proxy negotiating";
|
||||
else if(x == XMPP::AdvancedConnector::ErrProxyAuth)
|
||||
s = "proxy authorization";
|
||||
else if(x == XMPP::AdvancedConnector::ErrStream)
|
||||
s = "stream error";
|
||||
appendErrMsg(QString("Connection error: %1").arg(s));
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrNeg) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::HostGone)
|
||||
s = "host no longer hosted";
|
||||
else if(x == XMPP::ClientStream::HostUnknown)
|
||||
s = "host unknown";
|
||||
else if(x == XMPP::ClientStream::RemoteConnectionFailed)
|
||||
s = "a required remote connection failed";
|
||||
else if(x == XMPP::ClientStream::SeeOtherHost)
|
||||
s = QString("see other host: [%1]").arg(stream->errorText());
|
||||
else if(x == XMPP::ClientStream::UnsupportedVersion)
|
||||
s = "server does not support proper xmpp version";
|
||||
appendErrMsg(QString("Stream negotiation error: %1").arg(s));
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrTLS) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::TLSStart)
|
||||
s = "server rejected STARTTLS";
|
||||
else if(x == XMPP::ClientStream::TLSFail) {
|
||||
int t = tlsHandler->tlsError();
|
||||
if(t == QCA::TLS::ErrorHandshake)
|
||||
s = "TLS handshake error";
|
||||
else
|
||||
s = "broken security layer (TLS)";
|
||||
}
|
||||
appendErrMsg(s);
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrAuth) {
|
||||
int x = stream->errorCondition();
|
||||
QString s;
|
||||
if(x == XMPP::ClientStream::GenericAuthError)
|
||||
s = "unable to login";
|
||||
else if(x == XMPP::ClientStream::NoMech)
|
||||
s = "no appropriate auth mechanism available for given security settings";
|
||||
else if(x == XMPP::ClientStream::BadProto)
|
||||
s = "bad server response";
|
||||
else if(x == XMPP::ClientStream::BadServ)
|
||||
s = "server failed mutual authentication";
|
||||
else if(x == XMPP::ClientStream::EncryptionRequired)
|
||||
s = "encryption required for chosen SASL mechanism";
|
||||
else if(x == XMPP::ClientStream::InvalidAuthzid)
|
||||
s = "invalid authzid";
|
||||
else if(x == XMPP::ClientStream::InvalidMech)
|
||||
s = "invalid SASL mechanism";
|
||||
else if(x == XMPP::ClientStream::InvalidRealm)
|
||||
s = "invalid realm";
|
||||
else if(x == XMPP::ClientStream::MechTooWeak)
|
||||
s = "SASL mechanism too weak for authzid";
|
||||
else if(x == XMPP::ClientStream::NotAuthorized)
|
||||
s = "not authorized";
|
||||
else if(x == XMPP::ClientStream::TemporaryAuthFailure)
|
||||
s = "temporary auth failure";
|
||||
appendErrMsg(QString("Auth error: %1").arg(s));
|
||||
}
|
||||
else if(err == XMPP::ClientStream::ErrSecurityLayer)
|
||||
appendErrMsg("Broken security layer (SASL)");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private:
|
||||
void setHostState()
|
||||
{
|
||||
bool ok = false;
|
||||
if(!ck_probe->isChecked() && cb_proxy->currentItem() != 3)
|
||||
ok = true;
|
||||
lb_host->setEnabled(ok);
|
||||
le_host->setEnabled(ok);
|
||||
ck_ssl->setEnabled(ok);
|
||||
}
|
||||
|
||||
void appendSysMsg(const QString &s, const QColor &_c=QColor())
|
||||
{
|
||||
QString str;
|
||||
QColor c;
|
||||
if(_c.isValid())
|
||||
c = _c;
|
||||
else
|
||||
c = Qt::blue;
|
||||
|
||||
if(c.isValid())
|
||||
str += QString("<font color=\"%1\">").arg(c.name());
|
||||
str += QString("*** %1").arg(s);
|
||||
if(c.isValid())
|
||||
str += QString("</font>");
|
||||
te_log->append(str);
|
||||
}
|
||||
|
||||
public:
|
||||
void appendLibMsg(const QString &s)
|
||||
{
|
||||
appendSysMsg(s, Qt::magenta);
|
||||
}
|
||||
|
||||
void appendErrMsg(const QString &s)
|
||||
{
|
||||
appendSysMsg(s, Qt::red);
|
||||
}
|
||||
|
||||
void appendXmlOut(const QString &s)
|
||||
{
|
||||
QStringList lines = QStringList::split('\n', s, true);
|
||||
QString str;
|
||||
bool first = true;
|
||||
for(QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it) {
|
||||
if(!first)
|
||||
str += "<br>";
|
||||
str += QString("<font color=\"%1\">%2</font>").arg(QColor(Qt::darkGreen).name()).arg(plain2rich(*it));
|
||||
first = false;
|
||||
}
|
||||
te_log->append(str);
|
||||
}
|
||||
|
||||
void appendXmlIn(const QString &s)
|
||||
{
|
||||
QStringList lines = QStringList::split('\n', s, true);
|
||||
QString str;
|
||||
bool first = true;
|
||||
for(QStringList::ConstIterator it = lines.begin(); it != lines.end(); ++it) {
|
||||
if(!first)
|
||||
str += "<br>";
|
||||
str += QString("<font color=\"%1\">%2</font>").arg(QColor(Qt::darkBlue).name()).arg(plain2rich(*it));
|
||||
first = false;
|
||||
}
|
||||
te_log->append(str);
|
||||
}
|
||||
};
|
||||
|
||||
TestDlg *td_glob = 0;
|
||||
|
||||
void TestDebug::msg(const QString &s)
|
||||
{
|
||||
if(td_glob)
|
||||
td_glob->appendLibMsg(s);
|
||||
}
|
||||
|
||||
void TestDebug::outgoingTag(const QString &s)
|
||||
{
|
||||
if(td_glob)
|
||||
td_glob->appendXmlOut(s);
|
||||
}
|
||||
|
||||
void TestDebug::incomingTag(const QString &s)
|
||||
{
|
||||
if(td_glob)
|
||||
td_glob->appendXmlIn(s);
|
||||
}
|
||||
|
||||
void TestDebug::outgoingXml(const QDomElement &e)
|
||||
{
|
||||
QString out = XMPP::Stream::xmlToString(e, true);
|
||||
if(td_glob)
|
||||
td_glob->appendXmlOut(out);
|
||||
}
|
||||
|
||||
void TestDebug::incomingXml(const QDomElement &e)
|
||||
{
|
||||
QString out = XMPP::Stream::xmlToString(e, true);
|
||||
if(td_glob)
|
||||
td_glob->appendXmlIn(out);
|
||||
}
|
||||
|
||||
#include "xmpptest.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCA::Initializer init;
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
QApplication::addLibraryPath(".");
|
||||
putenv("SASL_PATH=.\\sasl");
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// seed the random number generator (needed at least for HttpPoll)
|
||||
srand(time(NULL));
|
||||
|
||||
TestDlg *w = new TestDlg(0);
|
||||
td_glob = w;
|
||||
TestDebug *td = new TestDebug;
|
||||
XMPP::setDebug(td);
|
||||
QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
|
||||
app.exec();
|
||||
XMPP::setDebug(0);
|
||||
delete td;
|
||||
delete w;
|
||||
|
||||
// we need this for a clean exit
|
||||
QCA::unloadAllPlugins();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef QCA_STATIC
|
||||
#include <QtPlugin>
|
||||
#ifdef HAVE_OPENSSL
|
||||
Q_IMPORT_PLUGIN(qca_openssl)
|
||||
#endif
|
||||
#endif
|
||||
41
iris-legacy/iris/example/xmpptest/xmpptest.pro
Normal file
41
iris-legacy/iris/example/xmpptest/xmpptest.pro
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += thread
|
||||
CONFIG -= app_bundle
|
||||
TARGET = xmpptest
|
||||
QT += xml network qt3support
|
||||
DEFINES += QT_STATICPLUGIN
|
||||
|
||||
MOC_DIR = .moc
|
||||
OBJECTS_DIR = .obj
|
||||
UI_DIR = .ui
|
||||
|
||||
#DEFINES += CS_XMPP
|
||||
DEFINES += XMPP_DEBUG
|
||||
|
||||
# Dependencies
|
||||
include(../../../conf.pri)
|
||||
windows:include(../../../conf_windows.pri)
|
||||
|
||||
!qca-static {
|
||||
CONFIG += crypto
|
||||
}
|
||||
qca-static {
|
||||
# QCA
|
||||
DEFINES += QCA_STATIC
|
||||
include(../../../third-party/qca/qca.pri)
|
||||
|
||||
# QCA-OpenSSL
|
||||
contains(DEFINES, HAVE_OPENSSL) {
|
||||
include(../../../third-party/qca/qca-openssl.pri)
|
||||
}
|
||||
}
|
||||
|
||||
include(../../../cutestuff/cutestuff.pri)
|
||||
include(../../iris.pri)
|
||||
irisnet {
|
||||
include(../../irisnet/irisnet.pri)
|
||||
}
|
||||
|
||||
SOURCES += xmpptest.cpp
|
||||
INTERFACES += ui_test.ui
|
||||
|
||||
133
iris-legacy/iris/include/im.h
Normal file
133
iris-legacy/iris/include/im.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* im.h - XMPP "IM" library API
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_IM_H
|
||||
#define XMPP_IM_H
|
||||
|
||||
#include <qdatetime.h>
|
||||
//Added by qt3to4:
|
||||
#include <QList>
|
||||
|
||||
#include "xmpp.h"
|
||||
#include "xmpp_jid.h"
|
||||
#include "xmpp_muc.h"
|
||||
#include "xmpp_message.h"
|
||||
#include "xmpp_chatstate.h"
|
||||
#include "xmpp_status.h"
|
||||
#include "xmpp_htmlelement.h"
|
||||
#include "xmpp_features.h"
|
||||
#include "xmpp_httpauthrequest.h"
|
||||
#include "xmpp_url.h"
|
||||
#include "xmpp_task.h"
|
||||
#include "xmpp_resource.h"
|
||||
#include "xmpp_resourcelist.h"
|
||||
#include "xmpp_roster.h"
|
||||
#include "xmpp_rosteritem.h"
|
||||
#include "xmpp_liverosteritem.h"
|
||||
#include "xmpp_liveroster.h"
|
||||
#include "xmpp_rosterx.h"
|
||||
#include "xmpp_xdata.h"
|
||||
#include "xmpp_discoitem.h"
|
||||
#include "xmpp_agentitem.h"
|
||||
#include "xmpp_client.h"
|
||||
#include "xmpp_address.h"
|
||||
#include "xmpp_pubsubitem.h"
|
||||
#include "xmpp_pubsubretraction.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
typedef QMap<QString, QString> StringMap;
|
||||
|
||||
typedef QList<AgentItem> AgentList;
|
||||
typedef QList<DiscoItem> DiscoList;
|
||||
|
||||
class FormField
|
||||
{
|
||||
public:
|
||||
enum { username, nick, password, name, first, last, email, address, city, state, zip, phone, url, date, misc };
|
||||
FormField(const QString &type="", const QString &value="");
|
||||
~FormField();
|
||||
|
||||
int type() const;
|
||||
QString fieldName() const;
|
||||
QString realName() const;
|
||||
bool isSecret() const;
|
||||
const QString & value() const;
|
||||
void setType(int);
|
||||
bool setType(const QString &);
|
||||
void setValue(const QString &);
|
||||
|
||||
private:
|
||||
int tagNameToType(const QString &) const;
|
||||
QString typeToTagName(int) const;
|
||||
|
||||
int v_type;
|
||||
QString v_value;
|
||||
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
class Form : public QList<FormField>
|
||||
{
|
||||
public:
|
||||
Form(const Jid &j="");
|
||||
~Form();
|
||||
|
||||
Jid jid() const;
|
||||
QString instructions() const;
|
||||
QString key() const;
|
||||
void setJid(const Jid &);
|
||||
void setInstructions(const QString &);
|
||||
void setKey(const QString &);
|
||||
|
||||
private:
|
||||
Jid v_jid;
|
||||
QString v_instructions, v_key;
|
||||
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
class SearchResult
|
||||
{
|
||||
public:
|
||||
SearchResult(const Jid &jid="");
|
||||
~SearchResult();
|
||||
|
||||
const Jid & jid() const;
|
||||
const QString & nick() const;
|
||||
const QString & first() const;
|
||||
const QString & last() const;
|
||||
const QString & email() const;
|
||||
|
||||
void setJid(const Jid &);
|
||||
void setNick(const QString &);
|
||||
void setFirst(const QString &);
|
||||
void setLast(const QString &);
|
||||
void setEmail(const QString &);
|
||||
|
||||
private:
|
||||
Jid v_jid;
|
||||
QString v_nick, v_first, v_last, v_email;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
235
iris-legacy/iris/include/xmpp.h
Normal file
235
iris-legacy/iris/include/xmpp.h
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* xmpp.h - XMPP "core" library API
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_H
|
||||
#define XMPP_H
|
||||
|
||||
#include <QPair>
|
||||
#include <qobject.h>
|
||||
#include <qstring.h>
|
||||
#include <qhostaddress.h>
|
||||
#include <qstring.h>
|
||||
#include <q3cstring.h>
|
||||
#include <qxml.h>
|
||||
#include <qdom.h>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
#include "xmpp_stanza.h"
|
||||
#include "xmpp_stream.h"
|
||||
#include "xmpp_clientstream.h"
|
||||
|
||||
namespace QCA
|
||||
{
|
||||
class TLS;
|
||||
};
|
||||
|
||||
#ifndef CS_XMPP
|
||||
class ByteStream;
|
||||
#endif
|
||||
|
||||
#include <QtCrypto> // For QCA::SASL::Params
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
// CS_IMPORT_BEGIN cutestuff/bytestream.h
|
||||
#ifdef CS_XMPP
|
||||
class ByteStream;
|
||||
#endif
|
||||
// CS_IMPORT_END
|
||||
|
||||
class Debug
|
||||
{
|
||||
public:
|
||||
virtual ~Debug();
|
||||
|
||||
virtual void msg(const QString &)=0;
|
||||
virtual void outgoingTag(const QString &)=0;
|
||||
virtual void incomingTag(const QString &)=0;
|
||||
virtual void outgoingXml(const QDomElement &)=0;
|
||||
virtual void incomingXml(const QDomElement &)=0;
|
||||
};
|
||||
|
||||
void setDebug(Debug *);
|
||||
|
||||
class Connector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Connector(QObject *parent=0);
|
||||
virtual ~Connector();
|
||||
|
||||
virtual void connectToServer(const QString &server)=0;
|
||||
virtual ByteStream *stream() const=0;
|
||||
virtual void done()=0;
|
||||
|
||||
bool useSSL() const;
|
||||
bool havePeerAddress() const;
|
||||
QHostAddress peerAddress() const;
|
||||
Q_UINT16 peerPort() const;
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void error();
|
||||
|
||||
protected:
|
||||
void setUseSSL(bool b);
|
||||
void setPeerAddressNone();
|
||||
void setPeerAddress(const QHostAddress &addr, Q_UINT16 port);
|
||||
|
||||
private:
|
||||
bool ssl;
|
||||
bool haveaddr;
|
||||
QHostAddress addr;
|
||||
Q_UINT16 port;
|
||||
};
|
||||
|
||||
class AdvancedConnector : public Connector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrConnectionRefused, ErrHostNotFound, ErrProxyConnect, ErrProxyNeg, ErrProxyAuth, ErrStream };
|
||||
AdvancedConnector(QObject *parent=0);
|
||||
virtual ~AdvancedConnector();
|
||||
|
||||
class Proxy
|
||||
{
|
||||
public:
|
||||
enum { None, HttpConnect, HttpPoll, Socks };
|
||||
Proxy();
|
||||
~Proxy();
|
||||
|
||||
int type() const;
|
||||
QString host() const;
|
||||
Q_UINT16 port() const;
|
||||
QString url() const;
|
||||
QString user() const;
|
||||
QString pass() const;
|
||||
int pollInterval() const;
|
||||
|
||||
void setHttpConnect(const QString &host, Q_UINT16 port);
|
||||
void setHttpPoll(const QString &host, Q_UINT16 port, const QString &url);
|
||||
void setSocks(const QString &host, Q_UINT16 port);
|
||||
void setUserPass(const QString &user, const QString &pass);
|
||||
void setPollInterval(int secs);
|
||||
|
||||
private:
|
||||
int t;
|
||||
QString v_host, v_url;
|
||||
Q_UINT16 v_port;
|
||||
QString v_user, v_pass;
|
||||
int v_poll;
|
||||
};
|
||||
|
||||
void setProxy(const Proxy &proxy);
|
||||
void setOptHostPort(const QString &host, Q_UINT16 port);
|
||||
void setOptProbe(bool);
|
||||
void setOptSSL(bool);
|
||||
|
||||
void changePollInterval(int secs);
|
||||
|
||||
void connectToServer(const QString &server);
|
||||
ByteStream *stream() const;
|
||||
void done();
|
||||
|
||||
int errorCode() const;
|
||||
|
||||
signals:
|
||||
void srvLookup(const QString &server);
|
||||
void srvResult(bool success);
|
||||
void httpSyncStarted();
|
||||
void httpSyncFinished();
|
||||
|
||||
private slots:
|
||||
void dns_done();
|
||||
void srv_done();
|
||||
void bs_connected();
|
||||
void bs_error(int);
|
||||
void http_syncStarted();
|
||||
void http_syncFinished();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void cleanup();
|
||||
void do_resolve();
|
||||
void do_connect();
|
||||
void tryNextSrv();
|
||||
};
|
||||
|
||||
class TLSHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TLSHandler(QObject *parent=0);
|
||||
virtual ~TLSHandler();
|
||||
|
||||
virtual void reset()=0;
|
||||
virtual void startClient(const QString &host)=0;
|
||||
virtual void write(const QByteArray &a)=0;
|
||||
virtual void writeIncoming(const QByteArray &a)=0;
|
||||
|
||||
signals:
|
||||
void success();
|
||||
void fail();
|
||||
void closed();
|
||||
void readyRead(const QByteArray &a);
|
||||
void readyReadOutgoing(const QByteArray &a, int plainBytes);
|
||||
};
|
||||
|
||||
class QCATLSHandler : public TLSHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCATLSHandler(QCA::TLS *parent);
|
||||
~QCATLSHandler();
|
||||
|
||||
QCA::TLS *tls() const;
|
||||
int tlsError() const;
|
||||
|
||||
void setXMPPCertCheck(bool enable);
|
||||
bool XMPPCertCheck();
|
||||
bool certMatchesHostname();
|
||||
|
||||
void reset();
|
||||
void startClient(const QString &host);
|
||||
void write(const QByteArray &a);
|
||||
void writeIncoming(const QByteArray &a);
|
||||
|
||||
signals:
|
||||
void tlsHandshaken();
|
||||
|
||||
public slots:
|
||||
void continueAfterHandshake();
|
||||
|
||||
private slots:
|
||||
void tls_handshaken();
|
||||
void tls_readyRead();
|
||||
void tls_readyReadOutgoing();
|
||||
void tls_closed();
|
||||
void tls_error();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
66
iris-legacy/iris/include/xmpp_address.h
Normal file
66
iris-legacy/iris/include/xmpp_address.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_ADDRESS_H
|
||||
#define XMPP_ADDRESS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
|
||||
class QDomElement;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Address
|
||||
{
|
||||
public:
|
||||
typedef enum { Unknown, To, Cc, Bcc, ReplyTo, ReplyRoom, NoReply, OriginalFrom, OriginalTo } Type;
|
||||
|
||||
Address(Type type = Unknown, const Jid& jid = Jid());
|
||||
Address(const QDomElement&);
|
||||
|
||||
const Jid& jid() const;
|
||||
const QString& uri() const;
|
||||
const QString& node() const;
|
||||
const QString& desc() const;
|
||||
bool delivered() const;
|
||||
Type type() const;
|
||||
|
||||
QDomElement toXml(Stanza&) const;
|
||||
void fromXml(const QDomElement& t);
|
||||
|
||||
void setJid(const Jid &);
|
||||
void setUri(const QString &);
|
||||
void setNode(const QString &);
|
||||
void setDesc(const QString &);
|
||||
void setDelivered(bool);
|
||||
void setType(Type);
|
||||
|
||||
private:
|
||||
Jid v_jid;
|
||||
QString v_uri, v_node, v_desc;
|
||||
bool v_delivered;
|
||||
Type v_type;
|
||||
};
|
||||
|
||||
typedef QList<Address> AddressList;
|
||||
};
|
||||
|
||||
#endif
|
||||
55
iris-legacy/iris/include/xmpp_agentitem.h
Normal file
55
iris-legacy/iris/include/xmpp_agentitem.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* xmpp_agentitem.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_AGENTITEM
|
||||
#define XMPP_AGENTITEM
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
#include "xmpp_features.h"
|
||||
|
||||
namespace XMPP {
|
||||
class AgentItem
|
||||
{
|
||||
public:
|
||||
AgentItem() { }
|
||||
|
||||
const Jid & jid() const { return v_jid; }
|
||||
const QString & name() const { return v_name; }
|
||||
const QString & category() const { return v_category; }
|
||||
const QString & type() const { return v_type; }
|
||||
const Features & features() const { return v_features; }
|
||||
|
||||
void setJid(const Jid &j) { v_jid = j; }
|
||||
void setName(const QString &n) { v_name = n; }
|
||||
void setCategory(const QString &c) { v_category = c; }
|
||||
void setType(const QString &t) { v_type = t; }
|
||||
void setFeatures(const Features &f) { v_features = f; }
|
||||
|
||||
private:
|
||||
Jid v_jid;
|
||||
QString v_name, v_category, v_type;
|
||||
Features v_features;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
34
iris-legacy/iris/include/xmpp_chatstate.h
Normal file
34
iris-legacy/iris/include/xmpp_chatstate.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_CHATSTATE
|
||||
#define XMPP_CHATSTATE
|
||||
|
||||
namespace XMPP {
|
||||
typedef enum {
|
||||
StateNone,
|
||||
StateActive,
|
||||
StateComposing,
|
||||
StatePaused,
|
||||
StateInactive,
|
||||
StateGone
|
||||
} ChatState;
|
||||
}
|
||||
|
||||
#endif
|
||||
193
iris-legacy/iris/include/xmpp_client.h
Normal file
193
iris-legacy/iris/include/xmpp_client.h
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_CLIENT_H
|
||||
#define XMPP_CLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
#include "xmpp_status.h"
|
||||
#include "xmpp_discoitem.h"
|
||||
|
||||
class QString;
|
||||
class QDomElement;
|
||||
class QDomDocument;
|
||||
namespace XMPP {
|
||||
class ClientStream;
|
||||
class Features;
|
||||
class FileTransferManager;
|
||||
class IBBManager;
|
||||
class JidLinkManager;
|
||||
class LiveRoster;
|
||||
class LiveRosterItem;
|
||||
class Message;
|
||||
class Resource;
|
||||
class ResourceList;
|
||||
class Roster;
|
||||
class RosterItem;
|
||||
class S5BManager;
|
||||
class Stream;
|
||||
class Task;
|
||||
}
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Client : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Client(QObject *parent=0);
|
||||
~Client();
|
||||
|
||||
bool isActive() const;
|
||||
void connectToServer(ClientStream *s, const Jid &j, bool auth=true);
|
||||
void start(const QString &host, const QString &user, const QString &pass, const QString &resource);
|
||||
void close(bool fast=false);
|
||||
|
||||
Stream & stream();
|
||||
QString streamBaseNS() const;
|
||||
const LiveRoster & roster() const;
|
||||
const ResourceList & resourceList() const;
|
||||
|
||||
void send(const QDomElement &);
|
||||
void send(const QString &);
|
||||
|
||||
QString host() const;
|
||||
QString user() const;
|
||||
QString pass() const;
|
||||
QString resource() const;
|
||||
Jid jid() const;
|
||||
|
||||
void rosterRequest();
|
||||
void sendMessage(const Message &);
|
||||
void sendSubscription(const Jid &, const QString &, const QString& nick = QString());
|
||||
void setPresence(const Status &);
|
||||
|
||||
void debug(const QString &);
|
||||
QString genUniqueId();
|
||||
Task *rootTask();
|
||||
QDomDocument *doc() const;
|
||||
|
||||
QString OSName() const;
|
||||
QString timeZone() const;
|
||||
int timeZoneOffset() const;
|
||||
QString clientName() const;
|
||||
QString clientVersion() const;
|
||||
QString capsNode() const;
|
||||
QString capsVersion() const;
|
||||
QString capsExt() const;
|
||||
|
||||
void setOSName(const QString &);
|
||||
void setTimeZone(const QString &, int);
|
||||
void setClientName(const QString &);
|
||||
void setClientVersion(const QString &);
|
||||
void setCapsNode(const QString &);
|
||||
void setCapsVersion(const QString &);
|
||||
|
||||
void setIdentity(DiscoItem::Identity);
|
||||
DiscoItem::Identity identity();
|
||||
|
||||
void setFeatures(const Features& f);
|
||||
const Features& features() const;
|
||||
|
||||
void addExtension(const QString& ext, const Features& f);
|
||||
void removeExtension(const QString& ext);
|
||||
const Features& extension(const QString& ext) const;
|
||||
QStringList extensions() const;
|
||||
|
||||
S5BManager *s5bManager() const;
|
||||
IBBManager *ibbManager() const;
|
||||
JidLinkManager *jidLinkManager() const;
|
||||
|
||||
void setFileTransferEnabled(bool b);
|
||||
FileTransferManager *fileTransferManager() const;
|
||||
|
||||
QString groupChatPassword(const QString& host, const QString& room) const;
|
||||
bool groupChatJoin(const QString &host, const QString &room, const QString &nick, const QString& password = QString(), int maxchars = -1, int maxstanzas = -1, int seconds = -1, const Status& = Status());
|
||||
void groupChatSetStatus(const QString &host, const QString &room, const Status &);
|
||||
void groupChatChangeNick(const QString &host, const QString &room, const QString &nick, const Status &);
|
||||
void groupChatLeave(const QString &host, const QString &room);
|
||||
|
||||
signals:
|
||||
void activated();
|
||||
void disconnected();
|
||||
//void authFinished(bool, int, const QString &);
|
||||
void rosterRequestFinished(bool, int, const QString &);
|
||||
void rosterItemAdded(const RosterItem &);
|
||||
void rosterItemUpdated(const RosterItem &);
|
||||
void rosterItemRemoved(const RosterItem &);
|
||||
void resourceAvailable(const Jid &, const Resource &);
|
||||
void resourceUnavailable(const Jid &, const Resource &);
|
||||
void presenceError(const Jid &, int, const QString &);
|
||||
void subscription(const Jid &, const QString &, const QString &);
|
||||
void messageReceived(const Message &);
|
||||
void debugText(const QString &);
|
||||
void xmlIncoming(const QString &);
|
||||
void xmlOutgoing(const QString &);
|
||||
void groupChatJoined(const Jid &);
|
||||
void groupChatLeft(const Jid &);
|
||||
void groupChatPresence(const Jid &, const Status &);
|
||||
void groupChatError(const Jid &, int, const QString &);
|
||||
|
||||
void incomingJidLink();
|
||||
|
||||
void beginImportRoster();
|
||||
void endImportRoster();
|
||||
|
||||
private slots:
|
||||
//void streamConnected();
|
||||
//void streamHandshaken();
|
||||
//void streamError(const StreamError &);
|
||||
//void streamSSLCertificateReady(const QSSLCert &);
|
||||
//void streamCloseFinished();
|
||||
void streamError(int);
|
||||
void streamReadyRead();
|
||||
void streamIncomingXml(const QString &);
|
||||
void streamOutgoingXml(const QString &);
|
||||
|
||||
void slotRosterRequestFinished();
|
||||
|
||||
// basic daemons
|
||||
void ppSubscription(const Jid &, const QString &, const QString&);
|
||||
void ppPresence(const Jid &, const Status &);
|
||||
void pmMessage(const Message &);
|
||||
void prRoster(const Roster &);
|
||||
|
||||
void s5b_incomingReady();
|
||||
void ibb_incomingReady();
|
||||
|
||||
public:
|
||||
class GroupChat;
|
||||
private:
|
||||
void cleanup();
|
||||
void distribute(const QDomElement &);
|
||||
void importRoster(const Roster &);
|
||||
void importRosterItem(const RosterItem &);
|
||||
void updateSelfPresence(const Jid &, const Status &);
|
||||
void updatePresence(LiveRosterItem *, const Jid &, const Status &);
|
||||
|
||||
class ClientPrivate;
|
||||
ClientPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
202
iris-legacy/iris/include/xmpp_clientstream.h
Normal file
202
iris-legacy/iris/include/xmpp_clientstream.h
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_CLIENTSTREAM_H
|
||||
#define XMPP_CLIENTSTREAM_H
|
||||
|
||||
#include <QtCrypto>
|
||||
|
||||
#include "xmpp_stream.h"
|
||||
|
||||
class QByteArray;
|
||||
class QString;
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
class QObject;
|
||||
class ByteStream;
|
||||
class QHostAddress;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class TLSHandler;
|
||||
class Connector;
|
||||
|
||||
class ClientStream : public Stream
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error {
|
||||
ErrConnection = ErrCustom, // Connection error, ask Connector-subclass what's up
|
||||
ErrNeg, // Negotiation error, see condition
|
||||
ErrTLS, // TLS error, see condition
|
||||
ErrAuth, // Auth error, see condition
|
||||
ErrSecurityLayer, // broken SASL security layer
|
||||
ErrBind // Resource binding error
|
||||
};
|
||||
enum Warning {
|
||||
WarnOldVersion, // server uses older XMPP/Jabber "0.9" protocol
|
||||
WarnNoTLS // there is no chance for TLS at this point
|
||||
};
|
||||
enum NegCond {
|
||||
HostGone, // host no longer hosted
|
||||
HostUnknown, // unknown host
|
||||
RemoteConnectionFailed, // unable to connect to a required remote resource
|
||||
SeeOtherHost, // a 'redirect', see errorText() for other host
|
||||
UnsupportedVersion // unsupported XMPP version
|
||||
};
|
||||
enum TLSCond {
|
||||
TLSStart, // server rejected STARTTLS
|
||||
TLSFail // TLS failed, ask TLSHandler-subclass what's up
|
||||
};
|
||||
enum SecurityLayer {
|
||||
LayerTLS,
|
||||
LayerSASL
|
||||
};
|
||||
enum AuthCond {
|
||||
GenericAuthError, // all-purpose "can't login" error
|
||||
NoMech, // No appropriate auth mech available
|
||||
BadProto, // Bad SASL auth protocol
|
||||
BadServ, // Server failed mutual auth
|
||||
EncryptionRequired, // can't use mech without TLS
|
||||
InvalidAuthzid, // bad input JID
|
||||
InvalidMech, // bad mechanism
|
||||
InvalidRealm, // bad realm
|
||||
MechTooWeak, // can't use mech with this authzid
|
||||
NotAuthorized, // bad user, bad password, bad creditials
|
||||
TemporaryAuthFailure // please try again later!
|
||||
};
|
||||
enum BindCond {
|
||||
BindNotAllowed, // not allowed to bind a resource
|
||||
BindConflict // resource in-use
|
||||
};
|
||||
enum AllowPlainType {
|
||||
NoAllowPlain,
|
||||
AllowPlain,
|
||||
AllowPlainOverTLS
|
||||
};
|
||||
|
||||
ClientStream(Connector *conn, TLSHandler *tlsHandler=0, QObject *parent=0);
|
||||
ClientStream(const QString &host, const QString &defRealm, ByteStream *bs, QCA::TLS *tls=0, QObject *parent=0); // server
|
||||
~ClientStream();
|
||||
|
||||
Jid jid() const;
|
||||
void connectToServer(const Jid &jid, bool auth=true);
|
||||
void accept(); // server
|
||||
bool isActive() const;
|
||||
bool isAuthenticated() const;
|
||||
|
||||
// login params
|
||||
void setUsername(const QString &s);
|
||||
void setPassword(const QString &s);
|
||||
void setRealm(const QString &s);
|
||||
void setAuthzid(const QString &s);
|
||||
void continueAfterParams();
|
||||
|
||||
// SASL information
|
||||
QString saslMechanism() const;
|
||||
int saslSSF() const;
|
||||
|
||||
// binding
|
||||
void setResourceBinding(bool);
|
||||
|
||||
// Language
|
||||
void setLang(const QString&);
|
||||
|
||||
// security options (old protocol only uses the first !)
|
||||
void setAllowPlain(AllowPlainType);
|
||||
#ifdef YAPSI
|
||||
void setAllowXFacebookPlatform(bool);
|
||||
#endif
|
||||
void setRequireMutualAuth(bool);
|
||||
void setSSFRange(int low, int high);
|
||||
void setOldOnly(bool);
|
||||
void setSASLMechanism(const QString &s);
|
||||
void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
|
||||
|
||||
// Compression
|
||||
void setCompress(bool);
|
||||
|
||||
// reimplemented
|
||||
QDomDocument & doc() const;
|
||||
QString baseNS() const;
|
||||
bool old() const;
|
||||
|
||||
void close();
|
||||
bool stanzaAvailable() const;
|
||||
Stanza read();
|
||||
void write(const Stanza &s);
|
||||
|
||||
int errorCondition() const;
|
||||
QString errorText() const;
|
||||
QDomElement errorAppSpec() const;
|
||||
|
||||
// extra
|
||||
void writeDirect(const QString &s);
|
||||
void setNoopTime(int mills);
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void securityLayerActivated(int);
|
||||
void needAuthParams(bool user, bool pass, bool realm);
|
||||
void authenticated();
|
||||
void warning(int);
|
||||
void incomingXml(const QString &s);
|
||||
void outgoingXml(const QString &s);
|
||||
|
||||
public slots:
|
||||
void continueAfterWarning();
|
||||
|
||||
private slots:
|
||||
void cr_connected();
|
||||
void cr_error();
|
||||
|
||||
void bs_connectionClosed();
|
||||
void bs_delayedCloseFinished();
|
||||
void bs_error(int); // server only
|
||||
|
||||
void ss_readyRead();
|
||||
void ss_bytesWritten(int);
|
||||
void ss_tlsHandshaken();
|
||||
void ss_tlsClosed();
|
||||
void ss_error(int);
|
||||
|
||||
void sasl_clientFirstStep(bool, const QByteArray&);
|
||||
void sasl_nextStep(const QByteArray &stepData);
|
||||
void sasl_needParams(const QCA::SASL::Params&);
|
||||
void sasl_authCheck(const QString &user, const QString &authzid);
|
||||
void sasl_authenticated();
|
||||
void sasl_error();
|
||||
|
||||
void doNoop();
|
||||
void doReadyRead();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
|
||||
void reset(bool all=false);
|
||||
void processNext();
|
||||
int convertedSASLCond() const;
|
||||
bool handleNeed();
|
||||
void handleError();
|
||||
void srvProcessNext();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
86
iris-legacy/iris/include/xmpp_discoitem.h
Normal file
86
iris-legacy/iris/include/xmpp_discoitem.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* xmpp_discoitem.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_DISCOITEM
|
||||
#define XMPP_DISCOITEM
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
#include "xmpp_features.h"
|
||||
#include "xmpp_agentitem.h"
|
||||
|
||||
namespace XMPP {
|
||||
class DiscoItem
|
||||
{
|
||||
public:
|
||||
DiscoItem();
|
||||
~DiscoItem();
|
||||
|
||||
const Jid &jid() const;
|
||||
const QString &node() const;
|
||||
const QString &name() const;
|
||||
|
||||
void setJid(const Jid &);
|
||||
void setName(const QString &);
|
||||
void setNode(const QString &);
|
||||
|
||||
enum Action {
|
||||
None = 0,
|
||||
Remove,
|
||||
Update
|
||||
};
|
||||
|
||||
Action action() const;
|
||||
void setAction(Action);
|
||||
|
||||
const Features &features() const;
|
||||
void setFeatures(const Features &);
|
||||
|
||||
struct Identity
|
||||
{
|
||||
QString category;
|
||||
QString name;
|
||||
QString type;
|
||||
};
|
||||
|
||||
typedef QList<Identity> Identities;
|
||||
|
||||
const Identities &identities() const;
|
||||
void setIdentities(const Identities &);
|
||||
|
||||
// some useful helper functions
|
||||
static Action string2action(QString s);
|
||||
static QString action2string(Action a);
|
||||
|
||||
DiscoItem & operator= (const DiscoItem &);
|
||||
DiscoItem(const DiscoItem &);
|
||||
|
||||
operator AgentItem() const { return toAgentItem(); }
|
||||
AgentItem toAgentItem() const;
|
||||
void fromAgentItem(const AgentItem &);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
88
iris-legacy/iris/include/xmpp_features.h
Normal file
88
iris-legacy/iris/include/xmpp_features.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* xmpp_features.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_FEATURES_H
|
||||
#define XMPP_FEATURES_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Features
|
||||
{
|
||||
public:
|
||||
Features();
|
||||
Features(const QStringList &);
|
||||
Features(const QString &);
|
||||
~Features();
|
||||
|
||||
QStringList list() const; // actual featurelist
|
||||
void setList(const QStringList &);
|
||||
void addFeature(const QString&);
|
||||
|
||||
// features
|
||||
bool canRegister() const;
|
||||
bool canSearch() const;
|
||||
bool canMulticast() const;
|
||||
bool canGroupchat() const;
|
||||
bool canVoice() const;
|
||||
bool canDisco() const;
|
||||
bool canChatState() const;
|
||||
bool canCommand() const;
|
||||
bool isGateway() const;
|
||||
bool haveVCard() const;
|
||||
bool canMessageReceipts() const;
|
||||
|
||||
enum FeatureID {
|
||||
FID_Invalid = -1,
|
||||
FID_None,
|
||||
FID_Register,
|
||||
FID_Search,
|
||||
FID_Groupchat,
|
||||
FID_Disco,
|
||||
FID_Gateway,
|
||||
FID_VCard,
|
||||
FID_AHCommand,
|
||||
|
||||
// private Psi actions
|
||||
FID_Add
|
||||
};
|
||||
|
||||
// useful functions
|
||||
bool test(const QString &) const;
|
||||
bool test(const QStringList &) const;
|
||||
|
||||
QString name() const;
|
||||
static QString name(long id);
|
||||
static QString name(const QString &feature);
|
||||
|
||||
long id() const;
|
||||
static long id(const QString &feature);
|
||||
static QString feature(long id);
|
||||
|
||||
class FeatureName;
|
||||
private:
|
||||
QStringList _list;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
46
iris-legacy/iris/include/xmpp_htmlelement.h
Normal file
46
iris-legacy/iris/include/xmpp_htmlelement.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_HTMLELEMENT_H
|
||||
#define XMPP_HTMLELEMENT_H
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class HTMLElement
|
||||
{
|
||||
public:
|
||||
HTMLElement();
|
||||
HTMLElement(const QDomElement &body);
|
||||
|
||||
void setBody(const QDomElement &body);
|
||||
const QDomElement& body() const;
|
||||
QString toString(const QString &rootTagName = "body") const;
|
||||
QString text() const;
|
||||
|
||||
private:
|
||||
QDomDocument doc_;
|
||||
QDomElement body_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
57
iris-legacy/iris/include/xmpp_httpauthrequest.h
Normal file
57
iris-legacy/iris/include/xmpp_httpauthrequest.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Maciek Niedzielski
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_AUTHREQUEST_H
|
||||
#define XMPP_AUTHREQUEST_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QDomElement;
|
||||
class QDomDocument;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class HttpAuthRequest
|
||||
{
|
||||
public:
|
||||
HttpAuthRequest(const QString &m, const QString &u, const QString &i);
|
||||
HttpAuthRequest(const QString &m = "", const QString &u = "");
|
||||
HttpAuthRequest(const QDomElement &);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
void setMethod(const QString&);
|
||||
void setUrl(const QString&);
|
||||
void setId(const QString&);
|
||||
QString method() const;
|
||||
QString url() const;
|
||||
QString id() const;
|
||||
bool hasId() const;
|
||||
|
||||
QDomElement toXml(QDomDocument &) const;
|
||||
bool fromXml(const QDomElement &);
|
||||
|
||||
static Stanza::Error denyError;
|
||||
private:
|
||||
QString method_, url_, id_;
|
||||
bool hasId_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
83
iris-legacy/iris/include/xmpp_jid.h
Normal file
83
iris-legacy/iris/include/xmpp_jid.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* xmpp_jid.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_JID_H
|
||||
#define XMPP_JID_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Jid
|
||||
{
|
||||
public:
|
||||
Jid();
|
||||
~Jid();
|
||||
|
||||
Jid(const QString &s);
|
||||
Jid(const char *s);
|
||||
Jid & operator=(const QString &s);
|
||||
Jid & operator=(const char *s);
|
||||
|
||||
bool operator==(const Jid& other) const;
|
||||
|
||||
void set(const QString &s);
|
||||
void set(const QString &domain, const QString &node, const QString &resource="");
|
||||
|
||||
void setDomain(const QString &s);
|
||||
void setNode(const QString &s);
|
||||
void setResource(const QString &s);
|
||||
|
||||
bool isNull() const { return null; }
|
||||
const QString & domain() const { return d; }
|
||||
const QString & node() const { return n; }
|
||||
const QString & resource() const { return r; }
|
||||
const QString & bare() const { return b; }
|
||||
const QString & full() const { return f; }
|
||||
|
||||
Jid withNode(const QString &s) const;
|
||||
Jid withResource(const QString &s) const;
|
||||
|
||||
bool isValid() const;
|
||||
bool isEmpty() const;
|
||||
bool compare(const Jid &a, bool compareRes=true) const;
|
||||
|
||||
static bool validDomain(const QString &s, QString *norm=0);
|
||||
static bool validNode(const QString &s, QString *norm=0);
|
||||
static bool validResource(const QString &s, QString *norm=0);
|
||||
|
||||
// TODO: kill these later
|
||||
const QString & host() const { return d; }
|
||||
const QString & user() const { return n; }
|
||||
const QString & userHost() const { return b; }
|
||||
|
||||
private:
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
QString f, b, d, n, r;
|
||||
bool valid, null;
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: doesn't seem to have any effect at all on gcc 4.2.3 / linux
|
||||
uint qHash(const XMPP::Jid& jid);
|
||||
|
||||
#endif
|
||||
43
iris-legacy/iris/include/xmpp_liveroster.h
Normal file
43
iris-legacy/iris/include/xmpp_liveroster.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_LIVEROSTER_H
|
||||
#define XMPP_LIVEROSTER_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "xmpp_liverosteritem.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Jid;
|
||||
|
||||
class LiveRoster : public QList<LiveRosterItem>
|
||||
{
|
||||
public:
|
||||
LiveRoster();
|
||||
~LiveRoster();
|
||||
|
||||
void flagAllForDelete();
|
||||
LiveRoster::Iterator find(const Jid &, bool compareRes=true);
|
||||
LiveRoster::ConstIterator find(const Jid &, bool compareRes=true) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
58
iris-legacy/iris/include/xmpp_liverosteritem.h
Normal file
58
iris-legacy/iris/include/xmpp_liverosteritem.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_LIVEROSTERITEM_H
|
||||
#define XMPP_LIVEROSTERITEM_H
|
||||
|
||||
#include "xmpp_status.h"
|
||||
#include "xmpp_resourcelist.h"
|
||||
#include "xmpp_rosteritem.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class LiveRosterItem : public RosterItem
|
||||
{
|
||||
public:
|
||||
LiveRosterItem(const Jid &j="");
|
||||
LiveRosterItem(const RosterItem &);
|
||||
~LiveRosterItem();
|
||||
|
||||
void setRosterItem(const RosterItem &);
|
||||
|
||||
ResourceList & resourceList();
|
||||
ResourceList::Iterator priority();
|
||||
|
||||
const ResourceList & resourceList() const;
|
||||
ResourceList::ConstIterator priority() const;
|
||||
|
||||
bool isAvailable() const;
|
||||
const Status & lastUnavailableStatus() const;
|
||||
bool flagForDelete() const;
|
||||
|
||||
void setLastUnavailableStatus(const Status &);
|
||||
void setFlagForDelete(bool);
|
||||
|
||||
private:
|
||||
ResourceList v_resourceList;
|
||||
Status v_lastUnavailableStatus;
|
||||
bool v_flagForDelete;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
189
iris-legacy/iris/include/xmpp_message.h
Normal file
189
iris-legacy/iris/include/xmpp_message.h
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_MESSAGE_H
|
||||
#define XMPP_MESSAGE_H
|
||||
|
||||
#include "xmpp_stanza.h"
|
||||
#include "xmpp_url.h"
|
||||
#include "xmpp_chatstate.h"
|
||||
#include "xmpp_receipts.h"
|
||||
#include "xmpp_address.h"
|
||||
#include "xmpp_rosterx.h"
|
||||
#include "xmpp_muc.h"
|
||||
|
||||
class QString;
|
||||
class QDateTime;
|
||||
#ifdef YAPSI
|
||||
class YaLastMail;
|
||||
#endif
|
||||
|
||||
namespace XMPP {
|
||||
class Jid;
|
||||
class PubSubItem;
|
||||
class PubSubRetraction;
|
||||
class HTMLElement;
|
||||
class HttpAuthRequest;
|
||||
class XData;
|
||||
|
||||
typedef enum { OfflineEvent, DeliveredEvent, DisplayedEvent,
|
||||
ComposingEvent, CancelEvent } MsgEvent;
|
||||
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
Message(const Jid &to="");
|
||||
Message(const Message &from);
|
||||
Message & operator=(const Message &from);
|
||||
~Message();
|
||||
|
||||
Jid to() const;
|
||||
Jid from() const;
|
||||
QString id() const;
|
||||
QString type() const;
|
||||
QString lang() const;
|
||||
QString subject(const QString &lang="") const;
|
||||
QString body(const QString &lang="") const;
|
||||
QString thread() const;
|
||||
Stanza::Error error() const;
|
||||
|
||||
void setTo(const Jid &j);
|
||||
void setFrom(const Jid &j);
|
||||
void setId(const QString &s);
|
||||
void setType(const QString &s);
|
||||
void setLang(const QString &s);
|
||||
void setSubject(const QString &s, const QString &lang="");
|
||||
void setBody(const QString &s, const QString &lang="");
|
||||
void setThread(const QString &s, bool send = false);
|
||||
void setError(const Stanza::Error &err);
|
||||
|
||||
// JEP-0060
|
||||
const QString& pubsubNode() const;
|
||||
const QList<PubSubItem>& pubsubItems() const;
|
||||
const QList<PubSubRetraction>& pubsubRetractions() const;
|
||||
|
||||
// JEP-0091
|
||||
QDateTime timeStamp() const;
|
||||
void setTimeStamp(const QDateTime &ts, bool send = false);
|
||||
|
||||
// JEP-0071
|
||||
HTMLElement html(const QString &lang="") const;
|
||||
void setHTML(const HTMLElement &s, const QString &lang="");
|
||||
bool containsHTML() const;
|
||||
|
||||
// JEP-0066
|
||||
UrlList urlList() const;
|
||||
void urlAdd(const Url &u);
|
||||
void urlsClear();
|
||||
void setUrlList(const UrlList &list);
|
||||
|
||||
// JEP-0022
|
||||
QString eventId() const;
|
||||
void setEventId(const QString& id);
|
||||
bool containsEvents() const;
|
||||
bool containsEvent(MsgEvent e) const;
|
||||
void addEvent(MsgEvent e);
|
||||
|
||||
// JEP-0085
|
||||
ChatState chatState() const;
|
||||
void setChatState(ChatState);
|
||||
|
||||
// XEP-0184
|
||||
MessageReceipt messageReceipt() const;
|
||||
void setMessageReceipt(MessageReceipt);
|
||||
|
||||
// JEP-0027
|
||||
QString xencrypted() const;
|
||||
void setXEncrypted(const QString &s);
|
||||
|
||||
// JEP-0033
|
||||
AddressList addresses() const;
|
||||
AddressList findAddresses(Address::Type t) const;
|
||||
void addAddress(const Address &a);
|
||||
void clearAddresses();
|
||||
void setAddresses(const AddressList &list);
|
||||
|
||||
// JEP-144
|
||||
const RosterExchangeItems& rosterExchangeItems() const;
|
||||
void setRosterExchangeItems(const RosterExchangeItems&);
|
||||
|
||||
// JEP-172
|
||||
void setNick(const QString&);
|
||||
const QString& nick() const;
|
||||
|
||||
// JEP-0070
|
||||
void setHttpAuthRequest(const HttpAuthRequest&);
|
||||
HttpAuthRequest httpAuthRequest() const;
|
||||
|
||||
// JEP-0004
|
||||
void setForm(const XData&);
|
||||
const XData& getForm() const;
|
||||
|
||||
// JEP-xxxx Whiteboarding
|
||||
void setWhiteboard(const QDomElement&);
|
||||
const QDomElement& whiteboard() const;
|
||||
|
||||
// MUC
|
||||
void setMUCStatus(int);
|
||||
bool hasMUCStatus() const;
|
||||
int mucStatus() const;
|
||||
void addMUCInvite(const MUCInvite&);
|
||||
const QList<MUCInvite>& mucInvites() const;
|
||||
void setMUCDecline(const MUCDecline&);
|
||||
const MUCDecline& mucDecline() const;
|
||||
const QString& mucPassword() const;
|
||||
void setMUCPassword(const QString&);
|
||||
|
||||
// Obsolete invitation
|
||||
QString invite() const;
|
||||
void setInvite(const QString &s);
|
||||
|
||||
// for compatibility. delete me later
|
||||
bool spooled() const;
|
||||
void setSpooled(bool);
|
||||
bool wasEncrypted() const;
|
||||
void setWasEncrypted(bool);
|
||||
|
||||
Stanza toStanza(Stream *stream) const;
|
||||
bool fromStanza(const Stanza &s, int tzoffset);
|
||||
|
||||
#ifdef YAPSI
|
||||
const YaLastMail& lastMailNotify() const;
|
||||
void setLastMailNotify(const YaLastMail& lastMailNotify);
|
||||
int spamFlag() const;
|
||||
|
||||
QString twin() const;
|
||||
void setTwin(const QString& twin);
|
||||
|
||||
QString yaMessageId() const;
|
||||
void setYaMessageId(const QString& yaMessageId);
|
||||
|
||||
int yaFlags() const;
|
||||
void setYaFlags(int flags);
|
||||
#endif
|
||||
|
||||
const QDomElement& getExtension(const QString& ns) const;
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
137
iris-legacy/iris/include/xmpp_muc.h
Normal file
137
iris-legacy/iris/include/xmpp_muc.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* xmpp_muc.h
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_MUC_H
|
||||
#define XMPP_MUC_H
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QString>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class MUCItem
|
||||
{
|
||||
public:
|
||||
enum Affiliation { UnknownAffiliation, Outcast, NoAffiliation, Member, Admin, Owner };
|
||||
enum Role { UnknownRole, NoRole, Visitor, Participant, Moderator };
|
||||
|
||||
MUCItem(Role = UnknownRole, Affiliation = UnknownAffiliation);
|
||||
MUCItem(const QDomElement&);
|
||||
|
||||
void setNick(const QString&);
|
||||
void setJid(const Jid&);
|
||||
void setAffiliation(Affiliation);
|
||||
void setRole(Role);
|
||||
void setActor(const Jid&);
|
||||
void setReason(const QString&);
|
||||
|
||||
const QString& nick() const;
|
||||
const Jid& jid() const;
|
||||
Affiliation affiliation() const;
|
||||
Role role() const;
|
||||
const Jid& actor() const;
|
||||
const QString& reason() const;
|
||||
|
||||
void fromXml(const QDomElement&);
|
||||
QDomElement toXml(QDomDocument&);
|
||||
|
||||
bool operator==(const MUCItem& o);
|
||||
|
||||
private:
|
||||
QString nick_;
|
||||
Jid jid_, actor_;
|
||||
Affiliation affiliation_;
|
||||
Role role_;
|
||||
QString reason_;
|
||||
};
|
||||
|
||||
class MUCInvite
|
||||
{
|
||||
public:
|
||||
MUCInvite();
|
||||
MUCInvite(const QDomElement&);
|
||||
MUCInvite(const Jid& to, const QString& reason = QString());
|
||||
|
||||
const Jid& to() const;
|
||||
void setTo(const Jid&);
|
||||
const Jid& from() const;
|
||||
void setFrom(const Jid&);
|
||||
const QString& reason() const;
|
||||
void setReason(const QString&);
|
||||
bool cont() const;
|
||||
void setCont(bool);
|
||||
|
||||
|
||||
void fromXml(const QDomElement&);
|
||||
QDomElement toXml(QDomDocument&) const;
|
||||
bool isNull() const;
|
||||
|
||||
private:
|
||||
Jid to_, from_;
|
||||
QString reason_, password_;
|
||||
bool cont_;
|
||||
};
|
||||
|
||||
class MUCDecline
|
||||
{
|
||||
public:
|
||||
MUCDecline();
|
||||
MUCDecline(const Jid& to, const QString& reason);
|
||||
MUCDecline(const QDomElement&);
|
||||
|
||||
const Jid& to() const;
|
||||
void setTo(const Jid&);
|
||||
const Jid& from() const;
|
||||
void setFrom(const Jid&);
|
||||
const QString& reason() const;
|
||||
void setReason(const QString&);
|
||||
|
||||
void fromXml(const QDomElement&);
|
||||
QDomElement toXml(QDomDocument&) const;
|
||||
bool isNull() const;
|
||||
|
||||
private:
|
||||
Jid to_, from_;
|
||||
QString reason_;
|
||||
};
|
||||
|
||||
class MUCDestroy
|
||||
{
|
||||
public:
|
||||
MUCDestroy();
|
||||
MUCDestroy(const QDomElement&);
|
||||
|
||||
const Jid& jid() const;
|
||||
void setJid(const Jid&);
|
||||
const QString& reason() const;
|
||||
void setReason(const QString&);
|
||||
|
||||
void fromXml(const QDomElement&);
|
||||
QDomElement toXml(QDomDocument&) const;
|
||||
|
||||
private:
|
||||
Jid jid_;
|
||||
QString reason_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
42
iris-legacy/iris/include/xmpp_pubsubitem.h
Normal file
42
iris-legacy/iris/include/xmpp_pubsubitem.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_PUBSUBITEM_H
|
||||
#define XMPP_PUBSUBITEM_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDomElement>
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class PubSubItem
|
||||
{
|
||||
public:
|
||||
PubSubItem();
|
||||
PubSubItem(const QString& id, const QDomElement& payload);
|
||||
const QString& id() const;
|
||||
const QDomElement& payload() const;
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
QDomElement payload_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
41
iris-legacy/iris/include/xmpp_pubsubretraction.h
Normal file
41
iris-legacy/iris/include/xmpp_pubsubretraction.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_PUBSUBRETRACTION_H
|
||||
#define XMPP_PUBSUBRETRACTION_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDomElement>
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
|
||||
class PubSubRetraction
|
||||
{
|
||||
public:
|
||||
PubSubRetraction();
|
||||
PubSubRetraction(const QString& id);
|
||||
const QString& id() const;
|
||||
|
||||
private:
|
||||
QString id_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
32
iris-legacy/iris/include/xmpp_receipts.h
Normal file
32
iris-legacy/iris/include/xmpp_receipts.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* xmpp_receipts.h - XEP-0184 support helper file
|
||||
* Copyright (C) 2007 Michail Pishchagin
|
||||
*
|
||||
* 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_RECEIPTS_H
|
||||
#define XMPP_RECEIPTS_H
|
||||
|
||||
namespace XMPP {
|
||||
typedef enum {
|
||||
ReceiptNone,
|
||||
ReceiptRequest,
|
||||
ReceiptReceived
|
||||
} MessageReceipt;
|
||||
}
|
||||
|
||||
#endif
|
||||
48
iris-legacy/iris/include/xmpp_resource.h
Normal file
48
iris-legacy/iris/include/xmpp_resource.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_RESOURCE_H
|
||||
#define XMPP_RESOURCE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "xmpp_status.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Resource
|
||||
{
|
||||
public:
|
||||
Resource(const QString &name="", const Status &s=Status());
|
||||
~Resource();
|
||||
|
||||
const QString & name() const;
|
||||
int priority() const;
|
||||
const Status & status() const;
|
||||
|
||||
void setName(const QString &);
|
||||
void setStatus(const Status &);
|
||||
|
||||
private:
|
||||
QString v_name;
|
||||
Status v_status;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
45
iris-legacy/iris/include/xmpp_resourcelist.h
Normal file
45
iris-legacy/iris/include/xmpp_resourcelist.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_RESOURCELIST_H
|
||||
#define XMPP_RESOURCELIST_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "xmpp_resource.h"
|
||||
|
||||
class QString;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class ResourceList : public QList<Resource>
|
||||
{
|
||||
public:
|
||||
ResourceList();
|
||||
~ResourceList();
|
||||
|
||||
ResourceList::Iterator find(const QString &);
|
||||
ResourceList::Iterator priority();
|
||||
|
||||
ResourceList::ConstIterator find(const QString &) const;
|
||||
ResourceList::ConstIterator priority() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
47
iris-legacy/iris/include/xmpp_roster.h
Normal file
47
iris-legacy/iris/include/xmpp_roster.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_ROSTER_H
|
||||
#define XMPP_ROSTER_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "xmpp_rosteritem.h"
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Jid;
|
||||
class Roster : public QList<RosterItem>
|
||||
{
|
||||
public:
|
||||
Roster();
|
||||
~Roster();
|
||||
|
||||
Roster::Iterator find(const Jid &);
|
||||
Roster::ConstIterator find(const Jid &) const;
|
||||
|
||||
private:
|
||||
class RosterPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
82
iris-legacy/iris/include/xmpp_rosteritem.h
Normal file
82
iris-legacy/iris/include/xmpp_rosteritem.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_ROSTERITEM_H
|
||||
#define XMPP_ROSTERITEM_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Subscription
|
||||
{
|
||||
public:
|
||||
enum SubType { None, To, From, Both, Remove };
|
||||
|
||||
Subscription(SubType type=None);
|
||||
|
||||
int type() const;
|
||||
|
||||
QString toString() const;
|
||||
bool fromString(const QString &);
|
||||
|
||||
private:
|
||||
SubType value;
|
||||
};
|
||||
|
||||
class RosterItem
|
||||
{
|
||||
public:
|
||||
RosterItem(const Jid &jid="");
|
||||
virtual ~RosterItem();
|
||||
|
||||
const Jid & jid() const;
|
||||
const QString & name() const;
|
||||
const QStringList & groups() const;
|
||||
const Subscription & subscription() const;
|
||||
const QString & ask() const;
|
||||
bool isPush() const;
|
||||
bool inGroup(const QString &) const;
|
||||
|
||||
virtual void setJid(const Jid &);
|
||||
void setName(const QString &);
|
||||
void setGroups(const QStringList &);
|
||||
void setSubscription(const Subscription &);
|
||||
void setAsk(const QString &);
|
||||
void setIsPush(bool);
|
||||
bool addGroup(const QString &);
|
||||
bool removeGroup(const QString &);
|
||||
|
||||
QDomElement toXml(QDomDocument *) const;
|
||||
bool fromXml(const QDomElement &);
|
||||
|
||||
private:
|
||||
Jid v_jid;
|
||||
QString v_name;
|
||||
QStringList v_groups;
|
||||
Subscription v_subscription;
|
||||
QString v_ask;
|
||||
bool v_push;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
66
iris-legacy/iris/include/xmpp_rosterx.h
Normal file
66
iris-legacy/iris/include/xmpp_rosterx.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* rosterexchangeitem.h
|
||||
* Copyright (C) 2003 Remko Troncon
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_ROSTERX_H
|
||||
#define XMPP_ROSTERX_H
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "xmpp_jid.h"
|
||||
|
||||
class QDomElement;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Stanza;
|
||||
|
||||
class RosterExchangeItem
|
||||
{
|
||||
public:
|
||||
enum Action { Add, Delete, Modify };
|
||||
|
||||
RosterExchangeItem(const Jid& jid, const QString& name = "", const QStringList& groups = QStringList(), Action = Add);
|
||||
RosterExchangeItem(const QDomElement&);
|
||||
|
||||
const Jid& jid() const;
|
||||
Action action() const;
|
||||
const QString& name() const;
|
||||
const QStringList& groups() const;
|
||||
bool isNull() const;
|
||||
|
||||
void setJid(const Jid&);
|
||||
void setAction(Action);
|
||||
void setName(const QString&);
|
||||
void setGroups(const QStringList&);
|
||||
|
||||
QDomElement toXml(Stanza&) const;
|
||||
void fromXml(const QDomElement&);
|
||||
|
||||
private:
|
||||
Jid jid_;
|
||||
QString name_;
|
||||
QStringList groups_;
|
||||
Action action_;
|
||||
};
|
||||
typedef QList<RosterExchangeItem> RosterExchangeItems;
|
||||
}
|
||||
|
||||
#endif
|
||||
138
iris-legacy/iris/include/xmpp_stanza.h
Normal file
138
iris-legacy/iris/include/xmpp_stanza.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_STANZA_H
|
||||
#define XMPP_STANZA_H
|
||||
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
#include <QDomElement>
|
||||
|
||||
class QDomDocument;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Jid;
|
||||
class Stream;
|
||||
|
||||
class Stanza
|
||||
{
|
||||
public:
|
||||
enum Kind { Message, Presence, IQ };
|
||||
|
||||
Stanza();
|
||||
Stanza(const Stanza &from);
|
||||
Stanza & operator=(const Stanza &from);
|
||||
virtual ~Stanza();
|
||||
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
enum ErrorType { Cancel = 1, Continue, Modify, Auth, Wait };
|
||||
enum ErrorCond
|
||||
{
|
||||
BadRequest = 1,
|
||||
Conflict,
|
||||
FeatureNotImplemented,
|
||||
Forbidden,
|
||||
Gone,
|
||||
InternalServerError,
|
||||
ItemNotFound,
|
||||
JidMalformed,
|
||||
NotAcceptable,
|
||||
NotAllowed,
|
||||
NotAuthorized,
|
||||
PaymentRequired,
|
||||
RecipientUnavailable,
|
||||
Redirect,
|
||||
RegistrationRequired,
|
||||
RemoteServerNotFound,
|
||||
RemoteServerTimeout,
|
||||
ResourceConstraint,
|
||||
ServiceUnavailable,
|
||||
SubscriptionRequired,
|
||||
UndefinedCondition,
|
||||
UnexpectedRequest
|
||||
};
|
||||
|
||||
Error(int type=Cancel, int condition=UndefinedCondition, const QString &text="", const QDomElement &appSpec=QDomElement());
|
||||
|
||||
int type;
|
||||
int condition;
|
||||
QString text;
|
||||
QDomElement appSpec;
|
||||
|
||||
int code() const;
|
||||
bool fromCode(int code);
|
||||
|
||||
QPair<QString, QString> description() const;
|
||||
|
||||
QDomElement toXml(QDomDocument &doc, const QString &baseNS) const;
|
||||
bool fromXml(const QDomElement &e, const QString &baseNS);
|
||||
private:
|
||||
class Private;
|
||||
int originalCode;
|
||||
|
||||
};
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
QDomElement element() const;
|
||||
QString toString() const;
|
||||
|
||||
QDomDocument & doc() const;
|
||||
QString baseNS() const;
|
||||
QDomElement createElement(const QString &ns, const QString &tagName);
|
||||
QDomElement createTextElement(const QString &ns, const QString &tagName, const QString &text);
|
||||
void appendChild(const QDomElement &e);
|
||||
|
||||
Kind kind() const;
|
||||
void setKind(Kind k);
|
||||
|
||||
Jid to() const;
|
||||
Jid from() const;
|
||||
QString id() const;
|
||||
QString type() const;
|
||||
QString lang() const;
|
||||
|
||||
void setTo(const Jid &j);
|
||||
void setFrom(const Jid &j);
|
||||
void setId(const QString &id);
|
||||
void setType(const QString &type);
|
||||
void setLang(const QString &lang);
|
||||
|
||||
#ifdef YAPSI
|
||||
void setAttribute(const QString& name, const QString& value);
|
||||
#endif
|
||||
|
||||
Error error() const;
|
||||
void setError(const Error &err);
|
||||
void clearError();
|
||||
|
||||
private:
|
||||
friend class Stream;
|
||||
Stanza(Stream *s, Kind k, const Jid &to, const QString &type, const QString &id);
|
||||
Stanza(Stream *s, const QDomElement &e);
|
||||
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
151
iris-legacy/iris/include/xmpp_status.h
Normal file
151
iris-legacy/iris/include/xmpp_status.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* xmpp_status.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_STATUS_H
|
||||
#define XMPP_STATUS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "xmpp_muc.h"
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Status
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
Offline, Online, Away, XA, DND, Invisible, FFC
|
||||
#ifdef YAPSI
|
||||
, Blocked, Reconnecting, NotAuthorizedToSeeStatus
|
||||
, GC_Active, GC_Inactive, GC_Favorited
|
||||
#endif
|
||||
};
|
||||
|
||||
Status(const QString &show="", const QString &status="", int priority=0, bool available=true);
|
||||
Status(Type type, const QString& status="", int priority=0);
|
||||
~Status();
|
||||
|
||||
int priority() const;
|
||||
Type type() const;
|
||||
QString typeString() const;
|
||||
const QString & show() const;
|
||||
const QString & status() const;
|
||||
QDateTime timeStamp() const;
|
||||
const QString & keyID() const;
|
||||
bool isAvailable() const;
|
||||
bool isAway() const;
|
||||
bool isInvisible() const;
|
||||
bool hasError() const;
|
||||
int errorCode() const;
|
||||
const QString & errorString() const;
|
||||
|
||||
const QString & xsigned() const;
|
||||
const QString & songTitle() const;
|
||||
const QString & capsNode() const;
|
||||
const QString & capsVersion() const;
|
||||
const QString & capsExt() const;
|
||||
#ifdef YAPSI
|
||||
const QString & notifyValue() const;
|
||||
#endif
|
||||
|
||||
bool isMUC() const;
|
||||
bool hasMUCItem() const;
|
||||
const MUCItem & mucItem() const;
|
||||
bool hasMUCDestroy() const;
|
||||
const MUCDestroy & mucDestroy() const;
|
||||
bool hasMUCStatus() const;
|
||||
QList<int> getMUCStatuses() const;
|
||||
int mucStatus() const;
|
||||
const QString& mucPassword() const;
|
||||
bool hasMUCHistory() const;
|
||||
int mucHistoryMaxChars() const;
|
||||
int mucHistoryMaxStanzas() const;
|
||||
int mucHistorySeconds() const;
|
||||
|
||||
void setPriority(int);
|
||||
void setType(Type);
|
||||
void setType(QString);
|
||||
void setShow(const QString &);
|
||||
void setStatus(const QString &);
|
||||
void setTimeStamp(const QDateTime &);
|
||||
void setKeyID(const QString &);
|
||||
void setIsAvailable(bool);
|
||||
void setIsInvisible(bool);
|
||||
void setError(int, const QString &);
|
||||
void setCapsNode(const QString&);
|
||||
void setCapsVersion(const QString&);
|
||||
void setCapsExt(const QString&);
|
||||
|
||||
void setMUC();
|
||||
void setMUCItem(const MUCItem&);
|
||||
void setMUCDestroy(const MUCDestroy&);
|
||||
void setMUCStatus(int);
|
||||
void setMUCPassword(const QString&);
|
||||
void setMUCHistory(int maxchars, int maxstanzas, int seconds);
|
||||
|
||||
void setXSigned(const QString &);
|
||||
void setSongTitle(const QString &);
|
||||
#ifdef YAPSI
|
||||
void setNotifyValue(const QString &);
|
||||
#endif
|
||||
|
||||
// JEP-153: VCard-based Avatars
|
||||
const QString& photoHash() const;
|
||||
void setPhotoHash(const QString&);
|
||||
bool hasPhotoHash() const;
|
||||
|
||||
private:
|
||||
int v_priority;
|
||||
QString v_show, v_status, v_key;
|
||||
QDateTime v_timeStamp;
|
||||
bool v_isAvailable;
|
||||
bool v_isInvisible;
|
||||
QString v_photoHash;
|
||||
bool v_hasPhotoHash;
|
||||
|
||||
QString v_xsigned;
|
||||
// gabber song extension
|
||||
QString v_songTitle;
|
||||
QString v_capsNode, v_capsVersion, v_capsExt;
|
||||
|
||||
// MUC
|
||||
bool v_isMUC, v_hasMUCItem, v_hasMUCDestroy;
|
||||
MUCItem v_mucItem;
|
||||
MUCDestroy v_mucDestroy;
|
||||
int v_mucStatus;
|
||||
QString v_mucPassword;
|
||||
int v_mucHistoryMaxChars, v_mucHistoryMaxStanzas, v_mucHistorySeconds;
|
||||
|
||||
#ifdef YAPSI
|
||||
QString v_notifyValue;
|
||||
#endif
|
||||
|
||||
int ecode;
|
||||
QString estr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
Q_DECLARE_METATYPE(XMPP::Status)
|
||||
|
||||
#endif
|
||||
81
iris-legacy/iris/include/xmpp_stream.h
Normal file
81
iris-legacy/iris/include/xmpp_stream.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* xmpp.h - XMPP "core" library API
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_STREAM_H
|
||||
#define XMPP_STREAM_H
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QObject>
|
||||
|
||||
#include "xmpp_stanza.h"
|
||||
#include "xmpp_jid.h"
|
||||
|
||||
class QDomDocument;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Stream : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Error { ErrParse, ErrProtocol, ErrStream, ErrCustom = 10 };
|
||||
enum StreamCond {
|
||||
GenericStreamError,
|
||||
Conflict,
|
||||
ConnectionTimeout,
|
||||
InternalServerError,
|
||||
InvalidFrom,
|
||||
InvalidXml,
|
||||
PolicyViolation,
|
||||
ResourceConstraint,
|
||||
SystemShutdown
|
||||
};
|
||||
|
||||
Stream(QObject *parent=0);
|
||||
virtual ~Stream();
|
||||
|
||||
virtual QDomDocument & doc() const=0;
|
||||
virtual QString baseNS() const=0;
|
||||
virtual bool old() const=0;
|
||||
|
||||
virtual void close()=0;
|
||||
virtual bool stanzaAvailable() const=0;
|
||||
virtual Stanza read()=0;
|
||||
virtual void write(const Stanza &s)=0;
|
||||
|
||||
virtual int errorCondition() const=0;
|
||||
virtual QString errorText() const=0;
|
||||
virtual QDomElement errorAppSpec() const=0;
|
||||
|
||||
Stanza createStanza(Stanza::Kind k, const Jid &to="", const QString &type="", const QString &id="");
|
||||
Stanza createStanza(const QDomElement &e);
|
||||
|
||||
static QString xmlToString(const QDomElement &e, bool clip=false);
|
||||
|
||||
signals:
|
||||
void connectionClosed();
|
||||
void delayedCloseFinished();
|
||||
void readyRead();
|
||||
void stanzaWritten();
|
||||
void error(int);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
82
iris-legacy/iris/include/xmpp_task.h
Normal file
82
iris-legacy/iris/include/xmpp_task.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* xmpp_task.h
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_TASK_H
|
||||
#define XMPP_TASK_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
|
||||
namespace XMPP {
|
||||
class Client;
|
||||
class Jid;
|
||||
|
||||
class Task : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum { ErrDisc };
|
||||
Task(Task *parent);
|
||||
Task(Client *, bool isRoot);
|
||||
virtual ~Task();
|
||||
|
||||
Task *parent() const;
|
||||
Client *client() const;
|
||||
QDomDocument *doc() const;
|
||||
QString id() const;
|
||||
|
||||
bool success() const;
|
||||
int statusCode() const;
|
||||
const QString & statusString() const;
|
||||
|
||||
void go(bool autoDelete=false);
|
||||
virtual bool take(const QDomElement &);
|
||||
void safeDelete();
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
protected:
|
||||
virtual void onGo();
|
||||
virtual void onDisconnect();
|
||||
void send(const QDomElement &);
|
||||
void setSuccess(int code=0, const QString &str="");
|
||||
void setError(const QDomElement &);
|
||||
void setError(int code=0, const QString &str="");
|
||||
void debug(const char *, ...);
|
||||
void debug(const QString &);
|
||||
bool iqVerify(const QDomElement &x, const Jid &to, const QString &id, const QString &xmlns="");
|
||||
|
||||
private slots:
|
||||
void clientDisconnected();
|
||||
void done();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
class TaskPrivate;
|
||||
TaskPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
49
iris-legacy/iris/include/xmpp_url.h
Normal file
49
iris-legacy/iris/include/xmpp_url.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_URL
|
||||
#define XMPP_URL
|
||||
|
||||
class QString;
|
||||
|
||||
namespace XMPP
|
||||
{
|
||||
class Url
|
||||
{
|
||||
public:
|
||||
Url(const QString &url="", const QString &desc="");
|
||||
Url(const Url &);
|
||||
Url & operator=(const Url &);
|
||||
~Url();
|
||||
|
||||
QString url() const;
|
||||
QString desc() const;
|
||||
|
||||
void setUrl(const QString &);
|
||||
void setDesc(const QString &);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
typedef QList<Url> UrlList;
|
||||
}
|
||||
|
||||
#endif
|
||||
158
iris-legacy/iris/include/xmpp_xdata.h
Normal file
158
iris-legacy/iris/include/xmpp_xdata.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* xmpp_xdata.h - a class for jabber:x:data forms
|
||||
* Copyright (C) 2003-2004 Michail Pishchagin
|
||||
*
|
||||
* 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPPXDATA_H
|
||||
#define XMPPXDATA_H
|
||||
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QList>
|
||||
#include <QSharedDataPointer>
|
||||
#include <QStringList>
|
||||
|
||||
class QDomElement;
|
||||
class QDomDocument;
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
class XData
|
||||
{
|
||||
public:
|
||||
XData();
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &);
|
||||
|
||||
QString instructions() const;
|
||||
void setInstructions(const QString &);
|
||||
|
||||
enum Type {
|
||||
Data_Form,
|
||||
Data_Result,
|
||||
Data_Submit,
|
||||
Data_Cancel
|
||||
};
|
||||
|
||||
Type type() const;
|
||||
void setType(Type);
|
||||
|
||||
struct ReportField {
|
||||
ReportField() { }
|
||||
ReportField( QString _label, QString _name ) { label = _label; name = _name; }
|
||||
QString label;
|
||||
QString name;
|
||||
};
|
||||
const QList<ReportField> &report() const;
|
||||
|
||||
typedef QMap<QString, QString> ReportItem;
|
||||
const QList<ReportItem> &reportItems() const;
|
||||
|
||||
void fromXml(const QDomElement &);
|
||||
QDomElement toXml(QDomDocument *, bool submitForm = true) const;
|
||||
bool isValid() const;
|
||||
|
||||
public:
|
||||
class Field {
|
||||
public:
|
||||
Field();
|
||||
~Field();
|
||||
|
||||
QString desc() const;
|
||||
void setDesc(const QString &);
|
||||
|
||||
struct Option {
|
||||
QString label;
|
||||
QString value;
|
||||
};
|
||||
|
||||
typedef QList<Option> OptionList;
|
||||
OptionList options() const;
|
||||
void setOptions(OptionList);
|
||||
|
||||
bool required() const;
|
||||
void setRequired(bool);
|
||||
|
||||
QString label() const;
|
||||
void setLabel(const QString &);
|
||||
|
||||
QString var() const;
|
||||
void setVar(const QString &);
|
||||
|
||||
// generic value variable, because every possible Type
|
||||
// can be converted to QStringList. Field_Single will
|
||||
// use just one string in QStringList. Field_Boolean will
|
||||
// use just one string, and that string will equal 0 or 1.
|
||||
// and so on...
|
||||
QStringList value() const;
|
||||
void setValue(const QStringList &);
|
||||
|
||||
enum Type {
|
||||
Field_Boolean,
|
||||
Field_Fixed,
|
||||
Field_Hidden,
|
||||
Field_JidMulti,
|
||||
Field_JidSingle,
|
||||
Field_ListMulti,
|
||||
Field_ListSingle,
|
||||
Field_TextMulti,
|
||||
Field_TextPrivate,
|
||||
Field_TextSingle
|
||||
};
|
||||
|
||||
Type type() const;
|
||||
void setType(Type);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void fromXml(const QDomElement &);
|
||||
QDomElement toXml(QDomDocument *, bool submitForm = true) const;
|
||||
|
||||
private:
|
||||
QString _desc, _label, _var;
|
||||
QList<Option> _options;
|
||||
bool _required;
|
||||
Type _type;
|
||||
QStringList _value;
|
||||
};
|
||||
|
||||
typedef QList<Field> FieldList;
|
||||
|
||||
FieldList fields() const;
|
||||
void setFields(const FieldList &);
|
||||
|
||||
void addField(XMPP::XData::Field::Type type, const QString& var, const QString& value);
|
||||
|
||||
private:
|
||||
class Private : public QSharedData {
|
||||
public:
|
||||
Private();
|
||||
|
||||
QString title, instructions;
|
||||
XData::Type type;
|
||||
FieldList fields;
|
||||
QList<ReportField> report;
|
||||
QList<ReportItem> reportItems;
|
||||
};
|
||||
QSharedDataPointer<Private> d;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
68
iris-legacy/iris/include/xmpp_yadatetime.h
Normal file
68
iris-legacy/iris/include/xmpp_yadatetime.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* xmpp_yadatetime.h
|
||||
* Copyright (C) 2009 Yandex LLC (Michail Pishchagin)
|
||||
*
|
||||
* 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_YADATETIME_H
|
||||
#define XMPP_YADATETIME_H
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
class YaDateTime : public QDateTime
|
||||
{
|
||||
public:
|
||||
YaDateTime();
|
||||
YaDateTime(const QDateTime& dateTime);
|
||||
YaDateTime(const YaDateTime& dateTime);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
int microsec() const;
|
||||
void setMiscosec(int microsec);
|
||||
|
||||
YaDateTime& operator=(const YaDateTime &other);
|
||||
bool operator==(const YaDateTime& other) const;
|
||||
bool operator!=(const YaDateTime& other) const;
|
||||
bool operator<(const YaDateTime& other) const;
|
||||
bool operator<=(const YaDateTime& other) const;
|
||||
bool operator>(const YaDateTime& other) const;
|
||||
bool operator>=(const YaDateTime& other) const;
|
||||
|
||||
QString toYaTime_t() const;
|
||||
static YaDateTime fromYaTime_t(const QString& str);
|
||||
|
||||
QString toYaIsoTime() const;
|
||||
static YaDateTime fromYaIsoTime(const QString& str);
|
||||
|
||||
private:
|
||||
int microsec_;
|
||||
|
||||
static int getMicrosec(const QString& str);
|
||||
};
|
||||
|
||||
}; // namespace XMPP
|
||||
|
||||
uint qHash(const XMPP::YaDateTime& yaDateTime);
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
Q_DECLARE_METATYPE(XMPP::YaDateTime)
|
||||
|
||||
#endif
|
||||
48
iris-legacy/iris/include/xmpp_yalastmail.h
Normal file
48
iris-legacy/iris/include/xmpp_yalastmail.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* xmpp_yalastmail.h - storage class for new mail notifications
|
||||
* Copyright (C) 2008 Yandex LLC (Michail Pishchagin)
|
||||
*
|
||||
* 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XMPP_YALASTMAIL_H
|
||||
#define XMPP_YALASTMAIL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
class YaLastMail
|
||||
{
|
||||
public:
|
||||
YaLastMail()
|
||||
: from(QString())
|
||||
, subject(QString())
|
||||
, timeStamp(QDateTime())
|
||||
, mid(QString())
|
||||
{}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
return from.isNull() && subject.isNull() && timeStamp.isNull() && mid.isNull();
|
||||
}
|
||||
|
||||
QString from;
|
||||
QString subject;
|
||||
QDateTime timeStamp;
|
||||
QString mid;
|
||||
};
|
||||
|
||||
#endif
|
||||
89
iris-legacy/iris/iris.pri
Normal file
89
iris-legacy/iris/iris.pri
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# libidn
|
||||
LIBIDN_BASE = $$PWD/libidn
|
||||
CONFIG += libidn
|
||||
include($$PWD/libidn.pri)
|
||||
|
||||
# IrisNet
|
||||
irisnet {
|
||||
include($$PWD/irisnet/irisnet.pri)
|
||||
}
|
||||
|
||||
DEFINES += XMPP_TEST
|
||||
|
||||
INCLUDEPATH += $$PWD/include $$PWD/xmpp-core $$PWD/xmpp-im $$PWD/jabber
|
||||
DEPENDPATH += $$PWD/include $$PWD/xmpp-core $$PWD/xmpp-im $$PWD/jabber
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/xmpp-core/securestream.h \
|
||||
$$PWD/xmpp-core/parser.h \
|
||||
$$PWD/xmpp-core/xmlprotocol.h \
|
||||
$$PWD/xmpp-core/protocol.h \
|
||||
$$PWD/xmpp-core/compressionhandler.h \
|
||||
$$PWD/xmpp-core/compress.h \
|
||||
$$PWD/xmpp-core/td.h \
|
||||
$$PWD/xmpp-im/xmpp_tasks.h \
|
||||
$$PWD/xmpp-im/xmpp_discoinfotask.h \
|
||||
$$PWD/xmpp-im/xmpp_xmlcommon.h \
|
||||
$$PWD/xmpp-im/xmpp_vcard.h \
|
||||
$$PWD/jabber/s5b.h \
|
||||
$$PWD/jabber/xmpp_ibb.h \
|
||||
$$PWD/jabber/filetransfer.h \
|
||||
$$PWD/include/xmpp.h \
|
||||
$$PWD/include/xmpp_jid.h \
|
||||
$$PWD/include/xmpp_url.h \
|
||||
$$PWD/include/xmpp_chatstate.h \
|
||||
$$PWD/include/xmpp_receipts.h \
|
||||
$$PWD/include/xmpp_client.h \
|
||||
$$PWD/include/xmpp_clientstream.h \
|
||||
$$PWD/include/xmpp_stanza.h \
|
||||
$$PWD/include/xmpp_stream.h \
|
||||
$$PWD/include/xmpp_address.h \
|
||||
$$PWD/include/xmpp_htmlelement.h \
|
||||
$$PWD/include/xmpp_muc.h \
|
||||
$$PWD/include/xmpp_message.h \
|
||||
$$PWD/include/xmpp_pubsubitem.h \
|
||||
$$PWD/include/xmpp_resource.h \
|
||||
$$PWD/include/xmpp_roster.h \
|
||||
$$PWD/include/xmpp_rosterx.h \
|
||||
$$PWD/include/xmpp_xdata.h \
|
||||
$$PWD/include/xmpp_rosteritem.h \
|
||||
$$PWD/include/xmpp_liveroster.h \
|
||||
$$PWD/include/xmpp_liverosteritem.h \
|
||||
$$PWD/include/xmpp_resourcelist.h \
|
||||
$$PWD/include/xmpp_task.h \
|
||||
$$PWD/include/xmpp_httpauthrequest.h \
|
||||
$$PWD/include/xmpp_status.h \
|
||||
$$PWD/include/xmpp_features.h \
|
||||
$$PWD/include/xmpp_agentitem.h \
|
||||
$$PWD/include/xmpp_discoitem.h \
|
||||
$$PWD/include/im.h \
|
||||
$$PWD/include/xmpp_yalastmail.h \
|
||||
$$PWD/include/xmpp_yadatetime.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/xmpp-core/connector.cpp \
|
||||
$$PWD/xmpp-core/tlshandler.cpp \
|
||||
$$PWD/xmpp-core/jid.cpp \
|
||||
$$PWD/xmpp-core/securestream.cpp \
|
||||
$$PWD/xmpp-core/parser.cpp \
|
||||
$$PWD/xmpp-core/xmlprotocol.cpp \
|
||||
$$PWD/xmpp-core/protocol.cpp \
|
||||
$$PWD/xmpp-core/compress.cpp \
|
||||
$$PWD/xmpp-core/compressionhandler.cpp \
|
||||
$$PWD/xmpp-core/stream.cpp \
|
||||
$$PWD/xmpp-core/simplesasl.cpp \
|
||||
$$PWD/xmpp-core/xmpp_stanza.cpp \
|
||||
$$PWD/xmpp-im/types.cpp \
|
||||
$$PWD/xmpp-im/client.cpp \
|
||||
$$PWD/xmpp-im/xmpp_features.cpp \
|
||||
$$PWD/xmpp-im/xmpp_discoitem.cpp \
|
||||
$$PWD/xmpp-im/xmpp_discoinfotask.cpp \
|
||||
$$PWD/xmpp-im/xmpp_xdata.cpp \
|
||||
$$PWD/xmpp-im/xmpp_task.cpp \
|
||||
$$PWD/xmpp-im/xmpp_tasks.cpp \
|
||||
$$PWD/xmpp-im/xmpp_xmlcommon.cpp \
|
||||
$$PWD/xmpp-im/xmpp_vcard.cpp \
|
||||
$$PWD/jabber/s5b.cpp \
|
||||
$$PWD/jabber/xmpp_ibb.cpp \
|
||||
$$PWD/jabber/filetransfer.cpp \
|
||||
$$PWD/xmpp-core/xmpp_yadatetime.cpp
|
||||
1213
iris-legacy/iris/irisnet/Doxyfile
Normal file
1213
iris-legacy/iris/irisnet/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
4
iris-legacy/iris/irisnet/TODO
Normal file
4
iris-legacy/iris/irisnet/TODO
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
finish dns glue stuff
|
||||
win/mac/bsd/solaris netinterface
|
||||
if jdns ever does multiple interfaces, don't forget that late conflict should
|
||||
unpublish on all interfaces
|
||||
32
iris-legacy/iris/irisnet/irisnet.pri
Normal file
32
iris-legacy/iris/irisnet/irisnet.pri
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
QT *= network
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
# libidn
|
||||
#LIBS += -lidn
|
||||
|
||||
include(jdns/jdns.pri)
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/jdnsshared.h \
|
||||
$$PWD/irisnetexport.h \
|
||||
$$PWD/irisnetplugin.h \
|
||||
$$PWD/irisnetglobal.h \
|
||||
$$PWD/irisnetglobal_p.h \
|
||||
$$PWD/processquit.h \
|
||||
$$PWD/netinterface.h \
|
||||
$$PWD/netnames.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/jdnsshared.cpp \
|
||||
$$PWD/irisnetplugin.cpp \
|
||||
$$PWD/irisnetglobal.cpp \
|
||||
$$PWD/processquit.cpp \
|
||||
$$PWD/netinterface.cpp \
|
||||
$$PWD/netnames.cpp
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/netinterface_unix.cpp \
|
||||
$$PWD/netnames_jdns.cpp
|
||||
|
||||
include(legacy/legacy.pri)
|
||||
|
||||
7
iris-legacy/iris/irisnet/irisnet.pro
Normal file
7
iris-legacy/iris/irisnet/irisnet.pro
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
QT -= gui
|
||||
|
||||
include(irisnet.pri)
|
||||
|
||||
SOURCES += main.cpp
|
||||
36
iris-legacy/iris/irisnet/irisnetexport.h
Normal file
36
iris-legacy/iris/irisnet/irisnetexport.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IRISNETEXPORT_H
|
||||
#define IRISNETEXPORT_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifdef IRISNET_STATIC
|
||||
# define IRISNET_EXPORT
|
||||
#else
|
||||
# ifdef IRISNET_MAKEDLL
|
||||
# define IRISNET_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define IRISNET_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
286
iris-legacy/iris/irisnet/irisnetglobal.cpp
Normal file
286
iris-legacy/iris/irisnet/irisnetglobal.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "irisnetglobal_p.h"
|
||||
|
||||
#include "irisnetplugin.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
// built-in providers
|
||||
extern IrisNetProvider *irisnet_createUnixNetProvider();
|
||||
extern IrisNetProvider *irisnet_createJDnsProvider();
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// internal
|
||||
//----------------------------------------------------------------------------
|
||||
class PluginInstance
|
||||
{
|
||||
private:
|
||||
QPluginLoader *_loader;
|
||||
QObject *_instance;
|
||||
bool _ownInstance;
|
||||
|
||||
PluginInstance()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static PluginInstance *fromFile(const QString &fname)
|
||||
{
|
||||
QPluginLoader *loader = new QPluginLoader(fname);
|
||||
if(!loader->load())
|
||||
{
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
QObject *obj = loader->instance();
|
||||
if(!obj)
|
||||
{
|
||||
loader->unload();
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = loader;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromStatic(QObject *obj)
|
||||
{
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = false;
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromInstance(QObject *obj)
|
||||
{
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
return i;
|
||||
}
|
||||
|
||||
~PluginInstance()
|
||||
{
|
||||
if(_ownInstance)
|
||||
delete _instance;
|
||||
|
||||
if(_loader)
|
||||
{
|
||||
_loader->unload();
|
||||
delete _loader;
|
||||
}
|
||||
}
|
||||
|
||||
void claim()
|
||||
{
|
||||
if(_loader)
|
||||
_loader->moveToThread(0);
|
||||
if(_ownInstance)
|
||||
_instance->moveToThread(0);
|
||||
}
|
||||
|
||||
QObject *instance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
bool sameType(const PluginInstance *other)
|
||||
{
|
||||
if(!_instance || !other->_instance)
|
||||
return false;
|
||||
|
||||
if(qstrcmp(_instance->metaObject()->className(), other->_instance->metaObject()->className()) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
public:
|
||||
bool builtin_done;
|
||||
QStringList paths;
|
||||
QList<PluginInstance*> plugins;
|
||||
QList<IrisNetProvider*> providers;
|
||||
|
||||
PluginManager()
|
||||
{
|
||||
builtin_done = false;
|
||||
}
|
||||
|
||||
~PluginManager()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
bool tryAdd(PluginInstance *i, bool lowPriority = false)
|
||||
{
|
||||
// is it the right kind of plugin?
|
||||
IrisNetProvider *p = qobject_cast<IrisNetProvider*>(i->instance());
|
||||
if(!p)
|
||||
return false;
|
||||
|
||||
// make sure we don't have it already
|
||||
for(int n = 0; n < plugins.count(); ++n)
|
||||
{
|
||||
if(i->sameType(plugins[n]))
|
||||
return false;
|
||||
}
|
||||
|
||||
i->claim();
|
||||
plugins += i;
|
||||
if(lowPriority)
|
||||
providers.append(p);
|
||||
else
|
||||
providers.prepend(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
void addBuiltIn(IrisNetProvider *p)
|
||||
{
|
||||
PluginInstance *i = PluginInstance::fromInstance(p);
|
||||
if(!tryAdd(i, true))
|
||||
delete i;
|
||||
}
|
||||
|
||||
void scan()
|
||||
{
|
||||
if(!builtin_done)
|
||||
{
|
||||
addBuiltIn(irisnet_createUnixNetProvider());
|
||||
addBuiltIn(irisnet_createJDnsProvider());
|
||||
builtin_done = true;
|
||||
}
|
||||
|
||||
QObjectList list = QPluginLoader::staticInstances();
|
||||
for(int n = 0; n < list.count(); ++n)
|
||||
{
|
||||
PluginInstance *i = PluginInstance::fromStatic(list[n]);
|
||||
if(!tryAdd(i))
|
||||
delete i;
|
||||
}
|
||||
for(int n = 0; n < paths.count(); ++n)
|
||||
{
|
||||
QDir dir(paths[n]);
|
||||
if(!dir.exists())
|
||||
continue;
|
||||
|
||||
QStringList entries = dir.entryList();
|
||||
for(int k = 0; k < entries.count(); ++k)
|
||||
{
|
||||
QFileInfo fi(dir.filePath(entries[k]));
|
||||
if(!fi.exists())
|
||||
continue;
|
||||
QString fname = fi.filePath();
|
||||
PluginInstance *i = PluginInstance::fromFile(fname);
|
||||
if(!i)
|
||||
continue;
|
||||
|
||||
if(!tryAdd(i))
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unload()
|
||||
{
|
||||
qDeleteAll(plugins);
|
||||
plugins.clear();
|
||||
providers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class IrisNetGlobal
|
||||
{
|
||||
public:
|
||||
QMutex m;
|
||||
PluginManager pluginManager;
|
||||
QList<IrisNetCleanUpFunction> cleanupList;
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(QMutex, global_mutex)
|
||||
static IrisNetGlobal *global = 0;
|
||||
|
||||
static void deinit();
|
||||
|
||||
static void init()
|
||||
{
|
||||
QMutexLocker locker(global_mutex());
|
||||
if(global)
|
||||
return;
|
||||
|
||||
global = new IrisNetGlobal;
|
||||
qAddPostRoutine(deinit);
|
||||
}
|
||||
|
||||
void deinit()
|
||||
{
|
||||
if(!global)
|
||||
return;
|
||||
|
||||
while(!global->cleanupList.isEmpty())
|
||||
(global->cleanupList.takeFirst())();
|
||||
|
||||
delete global;
|
||||
global = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Global
|
||||
//----------------------------------------------------------------------------
|
||||
void irisNetSetPluginPaths(const QStringList &paths)
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->pluginManager.paths = paths;
|
||||
}
|
||||
|
||||
void irisNetCleanup()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
|
||||
void irisNetAddPostRoutine(IrisNetCleanUpFunction func)
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->cleanupList.prepend(func);
|
||||
}
|
||||
|
||||
QList<IrisNetProvider*> irisNetProviders()
|
||||
{
|
||||
init();
|
||||
|
||||
QMutexLocker locker(&global->m);
|
||||
global->pluginManager.scan();
|
||||
return global->pluginManager.providers;
|
||||
}
|
||||
|
||||
}
|
||||
39
iris-legacy/iris/irisnet/irisnetglobal.h
Normal file
39
iris-legacy/iris/irisnet/irisnetglobal.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IRISNETGLOBAL_H
|
||||
#define IRISNETGLOBAL_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include "irisnetexport.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
// set the directories for plugins. call before doing anything else.
|
||||
IRISNET_EXPORT void irisNetSetPluginPaths(const QStringList &paths);
|
||||
|
||||
// free any shared data and plugins.
|
||||
// note: this is automatically called when qapp shuts down.
|
||||
IRISNET_EXPORT void irisNetCleanup();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
36
iris-legacy/iris/irisnet/irisnetglobal_p.h
Normal file
36
iris-legacy/iris/irisnet/irisnetglobal_p.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IRISNETGLOBAL_P_H
|
||||
#define IRISNETGLOBAL_P_H
|
||||
|
||||
#include "irisnetglobal.h"
|
||||
#include "irisnetplugin.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
typedef void (*IrisNetCleanUpFunction)();
|
||||
|
||||
IRISNET_EXPORT void irisNetAddPostRoutine(IrisNetCleanUpFunction func);
|
||||
IRISNET_EXPORT QList<IrisNetProvider*> irisNetProviders();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
52
iris-legacy/iris/irisnet/irisnetplugin.cpp
Normal file
52
iris-legacy/iris/irisnet/irisnetplugin.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "irisnetplugin.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// IrisNetProvider
|
||||
//----------------------------------------------------------------------------
|
||||
IrisNetProvider::~IrisNetProvider()
|
||||
{
|
||||
}
|
||||
|
||||
NetInterfaceProvider *IrisNetProvider::createNetInterfaceProvider()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NameProvider *IrisNetProvider::createNameProviderInternet()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NameProvider *IrisNetProvider::createNameProviderLocal()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ServiceProvider *IrisNetProvider::createServiceProvider()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
127
iris-legacy/iris/irisnet/irisnetplugin.h
Normal file
127
iris-legacy/iris/irisnet/irisnetplugin.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IRISNETPLUGIN_H
|
||||
#define IRISNETPLUGIN_H
|
||||
|
||||
#include "irisnetglobal.h"
|
||||
#include "netinterface.h"
|
||||
#include "netnames.h"
|
||||
|
||||
namespace XMPP {
|
||||
|
||||
class NetInterfaceProvider;
|
||||
class NameProvider;
|
||||
class ServiceProvider;
|
||||
|
||||
class IRISNET_EXPORT IrisNetProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~IrisNetProvider();
|
||||
|
||||
virtual NetInterfaceProvider *createNetInterfaceProvider();
|
||||
virtual NameProvider *createNameProviderInternet();
|
||||
virtual NameProvider *createNameProviderLocal();
|
||||
virtual ServiceProvider *createServiceProvider();
|
||||
};
|
||||
|
||||
class IRISNET_EXPORT NetInterfaceProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class Info
|
||||
{
|
||||
public:
|
||||
QString id, name;
|
||||
bool isLoopback;
|
||||
QList<QHostAddress> addresses;
|
||||
QHostAddress gateway;
|
||||
};
|
||||
|
||||
NetInterfaceProvider(QObject *parent = 0) : QObject(parent) {}
|
||||
|
||||
// calling start should populate an initial list that can be
|
||||
// immediately fetched. do not signal updated() for this.
|
||||
virtual void start() = 0;
|
||||
virtual QList<Info> interfaces() const = 0;
|
||||
|
||||
signals:
|
||||
void updated();
|
||||
};
|
||||
|
||||
class IRISNET_EXPORT NameProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NameProvider(QObject *parent = 0) : QObject(parent) {}
|
||||
|
||||
virtual int resolve_start(const QByteArray &name, int qType, bool longLived) = 0;
|
||||
virtual void resolve_stop(int id) = 0;
|
||||
|
||||
// transfer from local back to internet
|
||||
virtual void resolve_localResultsReady(int id, const QList<XMPP::NameRecord> &results) = 0;
|
||||
virtual void resolve_localError(int id, XMPP::NameResolver::Error e) = 0;
|
||||
|
||||
signals:
|
||||
void resolve_resultsReady(int id, const QList<XMPP::NameRecord> &results);
|
||||
void resolve_error(int id, XMPP::NameResolver::Error e);
|
||||
|
||||
// transfer from internet to local provider
|
||||
void resolve_useLocal(int id, const QByteArray &name);
|
||||
};
|
||||
|
||||
class IRISNET_EXPORT ServiceProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ServiceProvider(QObject *parent = 0) : QObject(parent) {}
|
||||
|
||||
virtual int browse_start(const QString &type, const QString &domain) = 0;
|
||||
virtual void browse_stop(int id) = 0;
|
||||
virtual int resolve_start(const QByteArray &name) = 0;
|
||||
virtual void resolve_stop(int id) = 0;
|
||||
virtual int publish_start(const QString &instance, const QString &type, int port, const QMap<QString,QByteArray> &attributes) = 0;
|
||||
virtual int publish_update(const QMap<QString,QByteArray> &attributes) = 0;
|
||||
virtual void publish_cancel(int id) = 0;
|
||||
virtual int publish_extra_start(int pub_id, const NameRecord &name) = 0;
|
||||
virtual int publish_extra_update(int id, const NameRecord &name) = 0;
|
||||
virtual void publish_extra_cancel(int id) = 0;
|
||||
|
||||
signals:
|
||||
void browse_instanceAvailable(int id, const XMPP::ServiceInstance &instance);
|
||||
void browse_instanceUnavailable(int id, const XMPP::ServiceInstance &instance);
|
||||
void browse_error(int id);
|
||||
void resolve_resultsReady(int id, const QHostAddress &address, int port);
|
||||
void resolve_error(int id);
|
||||
void publish_published(int id);
|
||||
void publish_error(int id, XMPP::ServiceLocalPublisher::Error e);
|
||||
void publish_extra_published(int id);
|
||||
void publish_extra_error(int id, XMPP::ServiceLocalPublisher::Error e);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_INTERFACE(XMPP::IrisNetProvider, "com.affinix.irisnet.IrisNetProvider/1.0")
|
||||
Q_DECLARE_INTERFACE(XMPP::NetInterfaceProvider, "com.affinix.irisnet.NetInterfaceProvider/1.0")
|
||||
Q_DECLARE_INTERFACE(XMPP::NameProvider, "com.affinix.irisnet.NameProvider/1.0")
|
||||
Q_DECLARE_INTERFACE(XMPP::ServiceProvider, "com.affinix.irisnet.ServiceProvider/1.0")
|
||||
|
||||
#endif
|
||||
85
iris-legacy/iris/irisnet/jdns/README
Normal file
85
iris-legacy/iris/irisnet/jdns/README
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
JDNS
|
||||
----
|
||||
Date: October 1st, 2005
|
||||
Author: Justin Karneges <justin@affinix.com>
|
||||
|
||||
JDNS is a simple DNS implementation that can perform normal DNS queries
|
||||
of any record type (notably SRV), as well as Multicast DNS queries and
|
||||
advertising. Multicast support is based on Jeremie Miller's "mdnsd"
|
||||
implementation.
|
||||
|
||||
For maximum flexibility, JDNS is written in C with no direct dependencies,
|
||||
and is licensed under the MIT license. Your application must supply
|
||||
functionality to JDNS, such as UDP sending/receiving, via callbacks.
|
||||
|
||||
For Qt users there is a wrapper available called QJDns. jdns.pri can
|
||||
be used to include everything into a qmake project. jdns.pro will build
|
||||
the sample Qt-based commandline tool 'jdns'.
|
||||
|
||||
Features:
|
||||
- DNS client "stub" resolver
|
||||
- Can fetch any record type, but provides handy decoding for many
|
||||
known types: A, AAAA, SRV, MX, TXT, etc.
|
||||
- Performs retries, caching/expiration, and CNAME following
|
||||
- Algorithm logic adapted from Q3Dns
|
||||
- Multicast queries
|
||||
- Multicast advertising
|
||||
|
||||
Why?
|
||||
- Trolltech is phasing out the Qt DNS implementation, which in Qt 4 has
|
||||
been relegated to the Qt3Support module. A replacement was desired.
|
||||
|
||||
- While there are many DNS libraries available, at the time of this
|
||||
writing it was (and still may be) hard to find one that satisfies
|
||||
three essential conditions: cross-platform friendliness (and this
|
||||
includes Windows 9x!), the ability to integrate into existing
|
||||
eventloops, sensible licensing (ie, not GPL).
|
||||
|
||||
How to use:
|
||||
- Prepare callbacks and call jdns_session_new()
|
||||
- Call jdns_init_unicast() or jdns_init_multicast(), depending on
|
||||
if you want regular or multicast DNS. If you want both kinds, you
|
||||
can always make two sessions.
|
||||
- Make queries and have fun
|
||||
- Call jdns_step() at the right times to advance JDNS processing
|
||||
|
||||
What is left to you:
|
||||
- The callback functions, obviously.
|
||||
- Querying for several "qualified" names. Here is what Q3Dns does:
|
||||
Query for name as provided
|
||||
Query for name + '.domain' (for every domain the computer is in)
|
||||
- Detecting for '.local' in a name to be queried, and using that
|
||||
to decide whether to query via Multicast or normal DNS.
|
||||
- Recognition of IP addresses. If you want an IP address to resolve
|
||||
to itself, then do that yourself. Passing an IP address as a DNS
|
||||
name to JDNS won't work (especially since it wouldn't make any
|
||||
sense in some contexts, like SRV).
|
||||
- Recognition of known hosts. If you want this, compare inputs against
|
||||
jdns_system_dnsparams().
|
||||
- For zeroconf/Bonjour, keep in mind that JDNS only provides Multicast
|
||||
DNS capability. DNS-SD and any higher layers would be your job.
|
||||
|
||||
Using a custom DNS implementation has the drawback that it is difficult
|
||||
to take advantage of platform-specific features (for example, an OS-wide
|
||||
DNS cache or LDAP integration).
|
||||
|
||||
An application strategy for normal DNS should probably be:
|
||||
- If an A or AAAA record is desired, use a native lookup.
|
||||
- Else, if the platform has advanced DNS features already (ie,
|
||||
res_query), use those.
|
||||
- Else, use JDNS.
|
||||
|
||||
However, it may not be a bad idea at first to use JDNS for all occasions,
|
||||
so that it can be debugged.
|
||||
|
||||
For Multicast DNS, awareness of the platform is doubly important. There
|
||||
should only be one Multicast DNS "Responder" per computer, and using JDNS
|
||||
at the same time could result in a conflict.
|
||||
|
||||
An application strategy for Multicast DNS should be:
|
||||
- If the platform has a Multicast DNS daemon installed already, use
|
||||
it somehow.
|
||||
- Else, use JDNS.
|
||||
|
||||
Have fun!
|
||||
|
||||
1
iris-legacy/iris/irisnet/jdns/TODO
Normal file
1
iris-legacy/iris/irisnet/jdns/TODO
Normal file
|
|
@ -0,0 +1 @@
|
|||
(nothing)
|
||||
3176
iris-legacy/iris/irisnet/jdns/jdns.c
Normal file
3176
iris-legacy/iris/irisnet/jdns/jdns.c
Normal file
File diff suppressed because it is too large
Load diff
490
iris-legacy/iris/irisnet/jdns/jdns.h
Normal file
490
iris-legacy/iris/irisnet/jdns/jdns.h
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef JDNS_H
|
||||
#define JDNS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*jdns_object_dtor_func)(void *);
|
||||
typedef void *(*jdns_object_cctor_func)(const void *);
|
||||
|
||||
#define JDNS_OBJECT \
|
||||
jdns_object_dtor_func dtor; \
|
||||
jdns_object_cctor_func cctor;
|
||||
|
||||
#define JDNS_OBJECT_NEW(name) \
|
||||
(name##_t *)jdns_object_new(sizeof(name##_t), \
|
||||
(jdns_object_dtor_func)name##_delete, \
|
||||
(jdns_object_cctor_func)name##_copy);
|
||||
|
||||
typedef struct jdns_object
|
||||
{
|
||||
JDNS_OBJECT
|
||||
} jdns_object_t;
|
||||
|
||||
void *jdns_object_new(int size, void (*dtor)(void *),
|
||||
void *(*cctor)(const void *));
|
||||
void *jdns_object_copy(const void *a);
|
||||
void jdns_object_delete(void *a);
|
||||
void jdns_object_free(void *a);
|
||||
|
||||
#define JDNS_LIST_DECLARE(name) \
|
||||
JDNS_OBJECT \
|
||||
int count; \
|
||||
name##_t **item;
|
||||
|
||||
typedef struct jdns_list
|
||||
{
|
||||
JDNS_OBJECT
|
||||
int count;
|
||||
void **item;
|
||||
int valueList;
|
||||
int autoDelete;
|
||||
} jdns_list_t;
|
||||
|
||||
jdns_list_t *jdns_list_new();
|
||||
jdns_list_t *jdns_list_copy(const jdns_list_t *a);
|
||||
void jdns_list_delete(jdns_list_t *a);
|
||||
void jdns_list_clear(jdns_list_t *a);
|
||||
void jdns_list_insert(jdns_list_t *a, void *item, int pos);
|
||||
void jdns_list_insert_value(jdns_list_t *a, const void *item, int pos);
|
||||
void jdns_list_remove(jdns_list_t *a, void *item);
|
||||
void jdns_list_remove_at(jdns_list_t *a, int pos);
|
||||
|
||||
typedef struct jdns_string
|
||||
{
|
||||
JDNS_OBJECT
|
||||
unsigned char *data;
|
||||
int size;
|
||||
} jdns_string_t;
|
||||
|
||||
jdns_string_t *jdns_string_new();
|
||||
jdns_string_t *jdns_string_copy(const jdns_string_t *s);
|
||||
void jdns_string_delete(jdns_string_t *s);
|
||||
void jdns_string_set(jdns_string_t *s, const unsigned char *str,
|
||||
int str_len);
|
||||
void jdns_string_set_cstr(jdns_string_t *s, const char *str);
|
||||
|
||||
// overlays jdns_list
|
||||
typedef struct jdns_stringlist
|
||||
{
|
||||
JDNS_OBJECT
|
||||
int count;
|
||||
jdns_string_t **item;
|
||||
} jdns_stringlist_t;
|
||||
|
||||
jdns_stringlist_t *jdns_stringlist_new();
|
||||
jdns_stringlist_t *jdns_stringlist_copy(const jdns_stringlist_t *a);
|
||||
void jdns_stringlist_delete(jdns_stringlist_t *a);
|
||||
void jdns_stringlist_append(jdns_stringlist_t *a, const jdns_string_t *str);
|
||||
|
||||
typedef struct jdns_address
|
||||
{
|
||||
int isIpv6;
|
||||
union
|
||||
{
|
||||
unsigned long int v4;
|
||||
unsigned char *v6; // 16 bytes
|
||||
} addr;
|
||||
char *c_str;
|
||||
} jdns_address_t;
|
||||
|
||||
jdns_address_t *jdns_address_new();
|
||||
jdns_address_t *jdns_address_copy(const jdns_address_t *a);
|
||||
void jdns_address_delete(jdns_address_t *a);
|
||||
void jdns_address_set_ipv4(jdns_address_t *a, unsigned long int ipv4);
|
||||
void jdns_address_set_ipv6(jdns_address_t *a, const unsigned char *ipv6);
|
||||
// return 1 if string was ok, else 0. Note: IPv4 addresses only!
|
||||
int jdns_address_set_cstr(jdns_address_t *a, const char *str);
|
||||
// return 1 if the same, else 0
|
||||
int jdns_address_cmp(const jdns_address_t *a, const jdns_address_t *b);
|
||||
|
||||
// convenient predefined addresses/ports
|
||||
#define JDNS_UNICAST_PORT 53
|
||||
#define JDNS_MULTICAST_PORT 5353
|
||||
jdns_address_t *jdns_address_multicast4_new(); // 224.0.0.251
|
||||
jdns_address_t *jdns_address_multicast6_new(); // FF02::FB
|
||||
|
||||
typedef struct jdns_server
|
||||
{
|
||||
unsigned char *name;
|
||||
int port; // SRV only
|
||||
int priority;
|
||||
int weight; // SRV only
|
||||
} jdns_server_t;
|
||||
|
||||
jdns_server_t *jdns_server_new();
|
||||
jdns_server_t *jdns_server_copy(const jdns_server_t *s);
|
||||
void jdns_server_delete(jdns_server_t *s);
|
||||
void jdns_server_set_name(jdns_server_t *s, const unsigned char *name);
|
||||
|
||||
typedef struct jdns_nameserver
|
||||
{
|
||||
jdns_address_t *address;
|
||||
int port;
|
||||
} jdns_nameserver_t;
|
||||
|
||||
jdns_nameserver_t *jdns_nameserver_new();
|
||||
jdns_nameserver_t *jdns_nameserver_copy(const jdns_nameserver_t *a);
|
||||
void jdns_nameserver_delete(jdns_nameserver_t *a);
|
||||
void jdns_nameserver_set(jdns_nameserver_t *a, const jdns_address_t *addr,
|
||||
int port);
|
||||
|
||||
typedef struct jdns_nameserverlist
|
||||
{
|
||||
int count;
|
||||
jdns_nameserver_t **item;
|
||||
} jdns_nameserverlist_t;
|
||||
|
||||
jdns_nameserverlist_t *jdns_nameserverlist_new();
|
||||
jdns_nameserverlist_t *jdns_nameserverlist_copy(
|
||||
const jdns_nameserverlist_t *a);
|
||||
void jdns_nameserverlist_delete(jdns_nameserverlist_t *a);
|
||||
void jdns_nameserverlist_append(jdns_nameserverlist_t *a,
|
||||
const jdns_address_t *addr, int port);
|
||||
|
||||
typedef struct jdns_dnshost
|
||||
{
|
||||
jdns_string_t *name;
|
||||
jdns_address_t *address;
|
||||
} jdns_dnshost_t;
|
||||
|
||||
typedef struct jdns_dnshostlist
|
||||
{
|
||||
int count;
|
||||
jdns_dnshost_t **item;
|
||||
} jdns_dnshostlist_t;
|
||||
|
||||
typedef struct jdns_dnsparams
|
||||
{
|
||||
jdns_nameserverlist_t *nameservers;
|
||||
jdns_stringlist_t *domains;
|
||||
jdns_dnshostlist_t *hosts;
|
||||
} jdns_dnsparams_t;
|
||||
|
||||
jdns_dnsparams_t *jdns_dnsparams_new();
|
||||
jdns_dnsparams_t *jdns_dnsparams_copy(jdns_dnsparams_t *a);
|
||||
void jdns_dnsparams_delete(jdns_dnsparams_t *a);
|
||||
void jdns_dnsparams_append_nameserver(jdns_dnsparams_t *a,
|
||||
const jdns_address_t *addr, int port);
|
||||
void jdns_dnsparams_append_domain(jdns_dnsparams_t *a,
|
||||
const jdns_string_t *domain);
|
||||
void jdns_dnsparams_append_host(jdns_dnsparams_t *a,
|
||||
const jdns_string_t *name, const jdns_address_t *address);
|
||||
|
||||
#define JDNS_RTYPE_A 1
|
||||
#define JDNS_RTYPE_AAAA 28
|
||||
#define JDNS_RTYPE_MX 15
|
||||
#define JDNS_RTYPE_SRV 33
|
||||
#define JDNS_RTYPE_CNAME 5
|
||||
#define JDNS_RTYPE_PTR 12
|
||||
#define JDNS_RTYPE_TXT 16
|
||||
#define JDNS_RTYPE_HINFO 13
|
||||
#define JDNS_RTYPE_NS 2
|
||||
#define JDNS_RTYPE_ANY 255
|
||||
|
||||
typedef struct jdns_rr
|
||||
{
|
||||
unsigned char *owner;
|
||||
int ttl;
|
||||
int type;
|
||||
int qclass;
|
||||
int rdlength;
|
||||
unsigned char *rdata;
|
||||
int haveKnown;
|
||||
|
||||
union
|
||||
{
|
||||
jdns_address_t *address; // for A, AAAA
|
||||
jdns_server_t *server; // for MX, SRV
|
||||
unsigned char *name; // for CNAME, PTR, NS
|
||||
jdns_stringlist_t *texts; // for TXT
|
||||
struct
|
||||
{
|
||||
jdns_string_t *cpu;
|
||||
jdns_string_t *os;
|
||||
} hinfo; // for HINFO
|
||||
} data;
|
||||
} jdns_rr_t;
|
||||
|
||||
jdns_rr_t *jdns_rr_new();
|
||||
jdns_rr_t *jdns_rr_copy(const jdns_rr_t *r);
|
||||
void jdns_rr_delete(jdns_rr_t *r);
|
||||
void jdns_rr_set_owner(jdns_rr_t *r, const unsigned char *name);
|
||||
void jdns_rr_set_record(jdns_rr_t *r, int type, const unsigned char *rdata,
|
||||
int rdlength);
|
||||
void jdns_rr_set_A(jdns_rr_t *r, const jdns_address_t *address);
|
||||
void jdns_rr_set_AAAA(jdns_rr_t *r, const jdns_address_t *address);
|
||||
void jdns_rr_set_MX(jdns_rr_t *r, const unsigned char *name, int priority);
|
||||
void jdns_rr_set_SRV(jdns_rr_t *r, const unsigned char *name, int port,
|
||||
int priority, int weight);
|
||||
void jdns_rr_set_CNAME(jdns_rr_t *r, const unsigned char *name);
|
||||
void jdns_rr_set_PTR(jdns_rr_t *r, const unsigned char *name);
|
||||
void jdns_rr_set_TXT(jdns_rr_t *r, const jdns_stringlist_t *texts);
|
||||
void jdns_rr_set_HINFO(jdns_rr_t *r, const jdns_string_t *cpu,
|
||||
const jdns_string_t *os);
|
||||
void jdns_rr_set_NS(jdns_rr_t *r, const unsigned char *name);
|
||||
// note: only works on known types
|
||||
int jdns_rr_verify(const jdns_rr_t *r);
|
||||
|
||||
typedef struct jdns_response
|
||||
{
|
||||
int answerCount;
|
||||
jdns_rr_t **answerRecords;
|
||||
int authorityCount;
|
||||
jdns_rr_t **authorityRecords;
|
||||
int additionalCount;
|
||||
jdns_rr_t **additionalRecords;
|
||||
} jdns_response_t;
|
||||
|
||||
jdns_response_t *jdns_response_new();
|
||||
jdns_response_t *jdns_response_copy(const jdns_response_t *r);
|
||||
void jdns_response_delete(jdns_response_t *r);
|
||||
void jdns_response_append_answer(jdns_response_t *r, const jdns_rr_t *rr);
|
||||
void jdns_response_append_authority(jdns_response_t *r, const jdns_rr_t *rr);
|
||||
void jdns_response_append_additional(jdns_response_t *r,
|
||||
const jdns_rr_t *rr);
|
||||
|
||||
#define JDNS_PUBLISH_SHARED 0x0001
|
||||
#define JDNS_PUBLISH_UNIQUE 0x0002
|
||||
|
||||
#define JDNS_STEP_TIMER 0x0001
|
||||
#define JDNS_STEP_HANDLE 0x0002
|
||||
|
||||
#define JDNS_EVENT_RESPONSE 0x0001
|
||||
#define JDNS_EVENT_PUBLISH 0x0002
|
||||
#define JDNS_EVENT_SHUTDOWN 0x0003
|
||||
|
||||
#define JDNS_STATUS_SUCCESS 0x0001
|
||||
#define JDNS_STATUS_NXDOMAIN 0x0002
|
||||
#define JDNS_STATUS_ERROR 0x0003
|
||||
#define JDNS_STATUS_TIMEOUT 0x0004
|
||||
#define JDNS_STATUS_CONFLICT 0x0005
|
||||
|
||||
typedef struct jdns_session jdns_session_t;
|
||||
|
||||
typedef struct jdns_callbacks
|
||||
{
|
||||
void *app; // user-supplied context
|
||||
|
||||
// time_now:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// return: milliseconds since session started
|
||||
int (*time_now)(jdns_session_t *s, void *app);
|
||||
|
||||
// rand_int:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// return: random integer between 0-65535
|
||||
int (*rand_int)(jdns_session_t *s, void *app);
|
||||
|
||||
// debug_line:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// str: a line of debug text
|
||||
// return: nothing
|
||||
void (*debug_line)(jdns_session_t *s, void *app, const char *str);
|
||||
|
||||
// udp_bind:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// addr: ip address of interface to bind to. 0 for all
|
||||
// port: port of interface to bind to. 0 for any
|
||||
// maddr: multicast address. 0 if not using multicast
|
||||
// return: handle (>0) of bound socket, or 0 on error
|
||||
// note: for multicast, the following must be done:
|
||||
// use SO_REUSEPORT to share with other mdns programs
|
||||
// use IP_ADD_MEMBERSHIP to associate addr and maddr
|
||||
// set IP_MULTICAST_TTL to 255
|
||||
int (*udp_bind)(jdns_session_t *s, void *app,
|
||||
const jdns_address_t *addr, int port,
|
||||
const jdns_address_t *maddr);
|
||||
|
||||
// udp_unbind:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// handle: handle of socket obtained with udp_bind
|
||||
// return: nothing
|
||||
void (*udp_unbind)(jdns_session_t *s, void *app, int handle);
|
||||
|
||||
// udp_read:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// handle: handle of socket obtained with udp_bind
|
||||
// addr: store ip address of sender
|
||||
// port: store port of sender
|
||||
// buf: store packet content
|
||||
// bufsize: value contains max size, to be changed to real size
|
||||
// return: 1 if packet read, 0 if none available
|
||||
int (*udp_read)(jdns_session_t *s, void *app, int handle,
|
||||
jdns_address_t *addr, int *port, unsigned char *buf,
|
||||
int *bufsize);
|
||||
|
||||
// udp_write:
|
||||
// s: session
|
||||
// app: user-supplied context
|
||||
// handle: handle of socket obtained with udp_bind
|
||||
// addr: ip address of recipient
|
||||
// port: port of recipient
|
||||
// buf: packet content
|
||||
// bufsize: size of packet
|
||||
// return: 1 if packet taken for writing, 0 if this is a bad time
|
||||
int (*udp_write)(jdns_session_t *s, void *app, int handle,
|
||||
const jdns_address_t *addr, int port, unsigned char *buf,
|
||||
int bufsize);
|
||||
} jdns_callbacks_t;
|
||||
|
||||
typedef struct jdns_event
|
||||
{
|
||||
int type; // JDNS_EVENT
|
||||
int id; // query id or publish id
|
||||
|
||||
// for query, this can be SUCCESS, NXDOMAIN, ERROR, or TIMEOUT
|
||||
// for publish, this can be SUCCESS, ERROR, or CONFLICT
|
||||
int status;
|
||||
|
||||
// for query
|
||||
jdns_response_t *response;
|
||||
} jdns_event_t;
|
||||
|
||||
void jdns_event_delete(jdns_event_t *e);
|
||||
|
||||
// jdns_session_new:
|
||||
// callbacks: the struct of callbacks
|
||||
// return: newly allocated session
|
||||
jdns_session_t *jdns_session_new(jdns_callbacks_t *callbacks);
|
||||
|
||||
// jdns_session_delete:
|
||||
// s: session to free
|
||||
// return: nothing
|
||||
void jdns_session_delete(jdns_session_t *s);
|
||||
|
||||
// jdns_init_unicast:
|
||||
// s: session
|
||||
// addr: ip address of interface to bind to. NULL for all
|
||||
// port: port of interface to bind to. 0 for any
|
||||
// return: 1 on success, 0 on failure
|
||||
int jdns_init_unicast(jdns_session_t *s, const jdns_address_t *addr,
|
||||
int port);
|
||||
|
||||
// jdns_init_multicast:
|
||||
// s: session
|
||||
// addr: ip address of interface to bind to. NULL for all
|
||||
// port: port of interface to bind to. 0 for any
|
||||
// addr: multicast address to associate with. cannot be NULL
|
||||
// return: 1 on success, 0 on failure
|
||||
int jdns_init_multicast(jdns_session_t *s, const jdns_address_t *addr,
|
||||
int port, const jdns_address_t *maddr);
|
||||
|
||||
// jdns_shutdown:
|
||||
// s: session
|
||||
// return: nothing
|
||||
void jdns_shutdown(jdns_session_t *s);
|
||||
|
||||
// jdns_set_nameservers:
|
||||
// s: session
|
||||
// nslist: list of nameservers
|
||||
// return nothing
|
||||
void jdns_set_nameservers(jdns_session_t *s,
|
||||
const jdns_nameserverlist_t *nslist);
|
||||
|
||||
// jdns_probe:
|
||||
// s: session
|
||||
// return: nothing
|
||||
void jdns_probe(jdns_session_t *s);
|
||||
|
||||
// jdns_query:
|
||||
// s: session
|
||||
// name: the name to look up
|
||||
// rtype: the record type
|
||||
// return: id of this operation
|
||||
int jdns_query(jdns_session_t *s, const unsigned char *name, int rtype);
|
||||
|
||||
// jdns_cancel_query:
|
||||
// s: session
|
||||
// id: the operation id to cancel
|
||||
// return: nothing
|
||||
void jdns_cancel_query(jdns_session_t *s, int id);
|
||||
|
||||
// jdns_publish:
|
||||
// s: session
|
||||
// mode: JDNS_PUBLISH shared or unique
|
||||
// rec: the record data
|
||||
// return: id of this operation
|
||||
// note: supported record types: A, AAAA, SRV, CNAME, PTR, TXT, and HINFO.
|
||||
// if the published type is not one of these, raw rdata must be set.
|
||||
int jdns_publish(jdns_session_t *s, int mode, const jdns_rr_t *rec);
|
||||
|
||||
// jdns_update_publish:
|
||||
// s: session
|
||||
// id: the operation id to update
|
||||
// rec: the record data
|
||||
// return: nothing
|
||||
void jdns_update_publish(jdns_session_t *s, int id, const jdns_rr_t *rec);
|
||||
|
||||
// jdns_cancel_publish:
|
||||
// s: session
|
||||
// id: the operation id to cancel
|
||||
// return: nothing
|
||||
void jdns_cancel_publish(jdns_session_t *s, int id);
|
||||
|
||||
// jdns_step:
|
||||
// s: session
|
||||
// return: JDNS_STEP flags OR'd together
|
||||
int jdns_step(jdns_session_t *s);
|
||||
|
||||
// jdns_next_timer:
|
||||
// s: session
|
||||
// return: milliseconds until timeout
|
||||
int jdns_next_timer(jdns_session_t *s);
|
||||
|
||||
// jdns_set_handle_readable:
|
||||
// s: session
|
||||
// handle: handle that is now readable
|
||||
// return: nothing
|
||||
void jdns_set_handle_readable(jdns_session_t *s, int handle);
|
||||
|
||||
// jdns_set_handle_writable:
|
||||
// s: session
|
||||
// handle: handle that is now writable
|
||||
// return: nothing
|
||||
void jdns_set_handle_writable(jdns_session_t *s, int handle);
|
||||
|
||||
// jdns_next_event:
|
||||
// s: session
|
||||
// return: newly allocated event, or zero if none are ready
|
||||
jdns_event_t *jdns_next_event(jdns_session_t *s);
|
||||
|
||||
// jdns_system_dnsparams:
|
||||
// return: newly allocated dnsparams from the system
|
||||
jdns_dnsparams_t *jdns_system_dnsparams();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
27
iris-legacy/iris/irisnet/jdns/jdns.pri
Normal file
27
iris-legacy/iris/irisnet/jdns/jdns.pri
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# qmake project include file
|
||||
|
||||
QT *= network
|
||||
|
||||
windows:{
|
||||
LIBS += -lWs2_32 -lAdvapi32
|
||||
}
|
||||
unix:{
|
||||
#QMAKE_CFLAGS += -pedantic
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/jdns_packet.h \
|
||||
$$PWD/jdns_mdnsd.h \
|
||||
$$PWD/jdns_p.h \
|
||||
$$PWD/jdns.h \
|
||||
$$PWD/qjdns_sock.h \
|
||||
$$PWD/qjdns.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/jdns_util.c \
|
||||
$$PWD/jdns_packet.c \
|
||||
$$PWD/jdns_mdnsd.c \
|
||||
$$PWD/jdns_sys.c \
|
||||
$$PWD/jdns.c \
|
||||
$$PWD/qjdns_sock.cpp \
|
||||
$$PWD/qjdns.cpp
|
||||
9
iris-legacy/iris/irisnet/jdns/jdns.pro
Normal file
9
iris-legacy/iris/irisnet/jdns/jdns.pro
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
QT -= gui
|
||||
QT += network
|
||||
|
||||
include(jdns.pri)
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
||||
1097
iris-legacy/iris/irisnet/jdns/jdns_mdnsd.c
Normal file
1097
iris-legacy/iris/irisnet/jdns/jdns_mdnsd.c
Normal file
File diff suppressed because it is too large
Load diff
120
iris-legacy/iris/irisnet/jdns/jdns_mdnsd.h
Normal file
120
iris-legacy/iris/irisnet/jdns/jdns_mdnsd.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Jeremie Miller
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef JDNS_MDNSD_H
|
||||
#define JDNS_MDNSD_H
|
||||
|
||||
#include "jdns_p.h"
|
||||
|
||||
struct mytimeval
|
||||
{
|
||||
unsigned long int tv_sec; /* seconds */
|
||||
unsigned long int tv_usec; /* microseconds */
|
||||
};
|
||||
|
||||
typedef struct mdnsd_struct *mdnsd; // main daemon data
|
||||
typedef struct mdnsdr_struct *mdnsdr; // record entry
|
||||
// answer data
|
||||
typedef struct mdnsda_struct
|
||||
{
|
||||
unsigned char *name;
|
||||
unsigned short int type;
|
||||
unsigned long int ttl;
|
||||
unsigned long int real_ttl;
|
||||
unsigned short int rdlen;
|
||||
unsigned char *rdata;
|
||||
unsigned long int ip; // A
|
||||
unsigned char *rdname; // NS/CNAME/PTR/SRV
|
||||
struct { unsigned short int priority, weight, port; } srv; // SRV
|
||||
} *mdnsda;
|
||||
|
||||
///////////
|
||||
// Global functions
|
||||
//
|
||||
// create a new mdns daemon for the given class of names (usually 1) and maximum frame size
|
||||
mdnsd mdnsd_new(int class, int frame, int port, int (*time_now)(mdnsd d, void *arg), int (*rand_int)(mdnsd d, void *arg), void *arg);
|
||||
//
|
||||
// gracefully shutdown the daemon, use mdnsd_out() to get the last packets
|
||||
void mdnsd_shutdown(mdnsd d);
|
||||
//
|
||||
// flush all cached records (network/interface changed)
|
||||
void mdnsd_flush(mdnsd d);
|
||||
//
|
||||
// free given mdnsd (should have used mdnsd_shutdown() first!)
|
||||
void mdnsd_free(mdnsd d);
|
||||
//
|
||||
///////////
|
||||
|
||||
///////////
|
||||
// I/O functions
|
||||
//
|
||||
// incoming message from host (to be cached/processed)
|
||||
void mdnsd_in(mdnsd d, const jdns_packet_t *m, const jdns_response_t *resp, const jdns_address_t *addr, unsigned short int port);
|
||||
//
|
||||
// outgoing messge to be delivered to host, returns >0 if one was returned and m/ip/port set
|
||||
int mdnsd_out(mdnsd d, jdns_packet_t **m, jdns_address_t **addr, unsigned short int *port);
|
||||
//
|
||||
// returns the max wait-time until mdnsd_out() needs to be called again
|
||||
struct mytimeval *mdnsd_sleep(mdnsd d);
|
||||
//
|
||||
////////////
|
||||
|
||||
///////////
|
||||
// Q/A functions
|
||||
//
|
||||
// register a new query
|
||||
// answer(record, arg) is called whenever one is found/changes/expires (immediate or anytime after, mdnsda valid until ->ttl==0)
|
||||
// either answer returns -1, or another mdnsd_query with a NULL answer will remove/unregister this query
|
||||
void mdnsd_query(mdnsd d, char *host, int type, int (*answer)(mdnsda a, void *arg), void *arg);
|
||||
//
|
||||
// returns the first (if last == NULL) or next answer after last from the cache
|
||||
// mdnsda only valid until an I/O function is called
|
||||
mdnsda mdnsd_list(mdnsd d, char *host, int type, mdnsda last);
|
||||
//
|
||||
///////////
|
||||
|
||||
///////////
|
||||
// Publishing functions
|
||||
//
|
||||
// create a new unique record (try mdnsda_list first to make sure it's not used)
|
||||
// conflict(arg) called at any point when one is detected and unable to recover
|
||||
// after the first data is set_*(), any future changes effectively expire the old one and attempt to create a new unique record
|
||||
mdnsdr mdnsd_unique(mdnsd d, char *host, int type, long int ttl, void (*pubresult)(int result, char *host, int type, void *arg), void *arg);
|
||||
//
|
||||
// create a new shared record
|
||||
mdnsdr mdnsd_shared(mdnsd d, char *host, int type, long int ttl);
|
||||
//
|
||||
// de-list the given record
|
||||
void mdnsd_done(mdnsd d, mdnsdr r);
|
||||
//
|
||||
// these all set/update the data for the given record, nothing is published until they are called
|
||||
void mdnsd_set_raw(mdnsd d, mdnsdr r, char *data, int len);
|
||||
void mdnsd_set_host(mdnsd d, mdnsdr r, char *name);
|
||||
void mdnsd_set_ip(mdnsd d, mdnsdr r, unsigned long int ip);
|
||||
void mdnsd_set_srv(mdnsd d, mdnsdr r, int priority, int weight, int port, char *name);
|
||||
//
|
||||
///////////
|
||||
|
||||
|
||||
#endif
|
||||
83
iris-legacy/iris/irisnet/jdns/jdns_p.h
Normal file
83
iris-legacy/iris/irisnet/jdns/jdns_p.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef JDNS_P_H
|
||||
#define JDNS_P_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
# define JDNS_OS_WIN
|
||||
#else
|
||||
# define JDNS_OS_UNIX
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
|
||||
# define JDNS_OS_MAC
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
# include <unistd.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "jdns.h"
|
||||
#include "jdns_packet.h"
|
||||
|
||||
// jdns_util.c
|
||||
void *jdns_alloc(int size);
|
||||
void *jdns_realloc(void *p, int size);
|
||||
void jdns_free(void *p);
|
||||
char *jdns_strdup(const char *s);
|
||||
unsigned char *jdns_copy_array(const unsigned char *src, int size);
|
||||
int jdns_domain_cmp(const unsigned char *a, const unsigned char *b);
|
||||
|
||||
int jdns_string_indexOf(const jdns_string_t *s, unsigned char c, int pos);
|
||||
jdns_stringlist_t *jdns_string_split(const jdns_string_t *s, unsigned char sep);
|
||||
|
||||
jdns_dnshost_t *jdns_dnshost_new();
|
||||
jdns_dnshost_t *jdns_dnshost_copy(const jdns_dnshost_t *a);
|
||||
void jdns_dnshost_delete(jdns_dnshost_t *a);
|
||||
jdns_dnshostlist_t *jdns_dnshostlist_new();
|
||||
jdns_dnshostlist_t *jdns_dnshostlist_copy(const jdns_dnshostlist_t *a);
|
||||
void jdns_dnshostlist_delete(jdns_dnshostlist_t *a);
|
||||
void jdns_dnshostlist_append(jdns_dnshostlist_t *a, const jdns_dnshost_t *host);
|
||||
|
||||
jdns_rr_t *jdns_rr_from_resource(const jdns_packet_resource_t *pr, const jdns_packet_t *ref);
|
||||
void jdns_response_remove_extra(jdns_response_t *r);
|
||||
void jdns_response_remove_answer(jdns_response_t *r, int pos);
|
||||
|
||||
#define alloc_type(type) (type *)jdns_alloc(sizeof(type))
|
||||
#define _ustrdup(str) (unsigned char *)jdns_strdup((const char *)str)
|
||||
#define _ustrlen(str) strlen((const char *)str)
|
||||
#define _ustrcmp(a, b) strcmp((const char *)a, (const char *)b)
|
||||
|
||||
#endif
|
||||
989
iris-legacy/iris/irisnet/jdns/jdns_packet.c
Normal file
989
iris-legacy/iris/irisnet/jdns/jdns_packet.c
Normal file
|
|
@ -0,0 +1,989 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "jdns_packet.h"
|
||||
|
||||
#include "jdns_p.h"
|
||||
|
||||
// jer's endian functions
|
||||
static unsigned short int net2short(const unsigned char **bufp)
|
||||
{
|
||||
unsigned short int i;
|
||||
i = **bufp;
|
||||
i <<= 8;
|
||||
i |= *(*bufp + 1);
|
||||
*bufp += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned long int net2long(const unsigned char **bufp)
|
||||
{
|
||||
unsigned long int l;
|
||||
l = **bufp;
|
||||
l <<= 8;
|
||||
l |= *(*bufp + 1);
|
||||
l <<= 8;
|
||||
l |= *(*bufp + 2);
|
||||
l <<= 8;
|
||||
l |= *(*bufp + 3);
|
||||
*bufp += 4;
|
||||
return l;
|
||||
}
|
||||
|
||||
static void short2net(unsigned short int i, unsigned char **bufp)
|
||||
{
|
||||
*(*bufp + 1) = (unsigned char)i;
|
||||
i >>= 8;
|
||||
**bufp = (unsigned char)i;
|
||||
*bufp += 2;
|
||||
}
|
||||
|
||||
static void long2net(unsigned long int l, unsigned char **bufp)
|
||||
{
|
||||
*(*bufp + 3) = (unsigned char)l;
|
||||
l >>= 8;
|
||||
*(*bufp + 2) = (unsigned char)l;
|
||||
l >>= 8;
|
||||
*(*bufp + 1) = (unsigned char)l;
|
||||
l >>= 8;
|
||||
**bufp = (unsigned char)l;
|
||||
*bufp += 4;
|
||||
}
|
||||
|
||||
// label stuff
|
||||
typedef struct jdns_packet_label
|
||||
{
|
||||
JDNS_OBJECT
|
||||
int offset;
|
||||
jdns_string_t *value;
|
||||
} jdns_packet_label_t;
|
||||
|
||||
static void jdns_packet_label_delete(jdns_packet_label_t *a);
|
||||
static jdns_packet_label_t *jdns_packet_label_copy(const jdns_packet_label_t *a);
|
||||
|
||||
static jdns_packet_label_t *jdns_packet_label_new()
|
||||
{
|
||||
jdns_packet_label_t *a = JDNS_OBJECT_NEW(jdns_packet_label);
|
||||
a->offset = 0;
|
||||
a->value = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
jdns_packet_label_t *jdns_packet_label_copy(const jdns_packet_label_t *a)
|
||||
{
|
||||
jdns_packet_label_t *c = jdns_packet_label_new();
|
||||
c->offset = a->offset;
|
||||
if(a->value)
|
||||
c->value = jdns_string_copy(a->value);
|
||||
return c;
|
||||
}
|
||||
|
||||
void jdns_packet_label_delete(jdns_packet_label_t *a)
|
||||
{
|
||||
if(!a)
|
||||
return;
|
||||
jdns_string_delete(a->value);
|
||||
jdns_object_free(a);
|
||||
}
|
||||
|
||||
// gets an offset for decompression. does range and hop count checking also
|
||||
static int getoffset(const unsigned char *str, int refsize, int *hopsleft)
|
||||
{
|
||||
unsigned short int x;
|
||||
if(*hopsleft <= 0)
|
||||
return -1;
|
||||
--(*hopsleft);
|
||||
x = str[0] & 0x3f;
|
||||
x <<= 8;
|
||||
x |= str[1];
|
||||
// stay in bounds
|
||||
if(x >= refsize)
|
||||
return -1;
|
||||
return x;
|
||||
}
|
||||
|
||||
static int readlabel(const unsigned char *in, int insize, const unsigned char *ref, int refsize, int *_at, jdns_string_t **name)
|
||||
{
|
||||
int at;
|
||||
unsigned char out[255];
|
||||
int out_size;
|
||||
const unsigned char *label, *last;
|
||||
int hopped_yet;
|
||||
int hopsleft;
|
||||
int label_size;
|
||||
|
||||
at = *_at;
|
||||
|
||||
// stay in range
|
||||
if(at < 0 || at >= insize)
|
||||
return 0;
|
||||
|
||||
out_size = 0;
|
||||
label = in + at;
|
||||
hopped_yet = 0;
|
||||
last = in + insize;
|
||||
while(1)
|
||||
{
|
||||
// need a byte
|
||||
if(label + 1 > last)
|
||||
goto error;
|
||||
|
||||
// we make this a while loop instead of an 'if', in case
|
||||
// there's a pointer to a pointer. as a precaution,
|
||||
// we will hop no more than 8 times
|
||||
hopsleft = 8;
|
||||
while(*label & 0xc0)
|
||||
{
|
||||
int offset;
|
||||
|
||||
// need the next byte, too
|
||||
if(label + 2 > last)
|
||||
goto error;
|
||||
|
||||
offset = getoffset(label, refsize, &hopsleft);
|
||||
if(offset == -1)
|
||||
goto error;
|
||||
|
||||
label = ref + offset;
|
||||
if(!hopped_yet)
|
||||
{
|
||||
at += 2;
|
||||
hopped_yet = 1;
|
||||
last = ref + refsize;
|
||||
}
|
||||
|
||||
// need a byte
|
||||
if(label + 1 > last)
|
||||
goto error;
|
||||
}
|
||||
|
||||
label_size = *label & 0x3f;
|
||||
|
||||
// null label? then we're done
|
||||
if(label_size == 0)
|
||||
{
|
||||
if(!hopped_yet)
|
||||
++at;
|
||||
break;
|
||||
}
|
||||
|
||||
// enough source bytes? (length byte + length)
|
||||
if(label + label_size + 1 > last)
|
||||
goto error;
|
||||
|
||||
// enough dest bytes? (length + dot)
|
||||
if(out_size + label_size + 1 > 255)
|
||||
goto error;
|
||||
|
||||
memcpy(out + out_size, label + 1, label_size);
|
||||
out_size += label_size;
|
||||
out[out_size] = '.';
|
||||
++out_size;
|
||||
|
||||
if(!hopped_yet)
|
||||
at += label_size + 1;
|
||||
|
||||
label += label_size + 1;
|
||||
}
|
||||
|
||||
*_at = at;
|
||||
*name = jdns_string_new();
|
||||
jdns_string_set(*name, out, out_size);
|
||||
return 1;
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this function compares labels in label format:
|
||||
// [length] [value ...] [length] [value ...] [0]
|
||||
static int matchlabel(const unsigned char *a, int asize, const unsigned char *b, int bsize, const unsigned char *ref, int refsize, int ahopsleft, int bhopsleft)
|
||||
{
|
||||
int n, alen, blen, offset;
|
||||
|
||||
// same pointer?
|
||||
if(a == b)
|
||||
return 1;
|
||||
|
||||
if(asize < 1 || bsize < 1)
|
||||
return 0;
|
||||
|
||||
// always ensure we get called without a pointer
|
||||
if(*a & 0xc0)
|
||||
{
|
||||
if(asize < 2)
|
||||
return 0;
|
||||
offset = getoffset(a, refsize, &ahopsleft);
|
||||
if(offset == -1)
|
||||
return 0;
|
||||
return matchlabel(ref + offset, refsize - offset, b, bsize, ref, refsize, ahopsleft, bhopsleft);
|
||||
}
|
||||
if(*b & 0xc0)
|
||||
{
|
||||
if(bsize < 2)
|
||||
return 0;
|
||||
offset = getoffset(b, refsize, &bhopsleft);
|
||||
if(offset == -1)
|
||||
return 0;
|
||||
return matchlabel(a, asize, ref + offset, refsize - offset, ref, refsize, ahopsleft, bhopsleft);
|
||||
}
|
||||
|
||||
alen = *a & 0x3f;
|
||||
blen = *b & 0x3f;
|
||||
|
||||
// must be same length
|
||||
if(alen != blen)
|
||||
return 0;
|
||||
|
||||
// done?
|
||||
if(alen == 0)
|
||||
return 1;
|
||||
|
||||
// length byte + length + first byte of next label
|
||||
if(asize < alen + 2)
|
||||
return 0;
|
||||
if(bsize < blen + 2)
|
||||
return 0;
|
||||
|
||||
// compare the value
|
||||
for(n = 1; n < alen + 1; ++n)
|
||||
{
|
||||
if(a[n] != b[n])
|
||||
return 0;
|
||||
}
|
||||
|
||||
// try next labels
|
||||
n = alen + 1;
|
||||
return matchlabel(a + n, asize - n, b + n, bsize - n, ref, refsize, ahopsleft, bhopsleft);
|
||||
}
|
||||
|
||||
int jdns_packet_name_isvalid(const unsigned char *name, int size)
|
||||
{
|
||||
int n, at, len;
|
||||
|
||||
// at least one byte, no larger than 254 (one byte is gained when
|
||||
// converting to a label, which has a 255 byte max)
|
||||
if(size < 1 || size > 254)
|
||||
return 0;
|
||||
|
||||
// last byte must be a dot
|
||||
if(name[size - 1] != '.')
|
||||
return 0;
|
||||
|
||||
// first byte can't be a dot if there are characters after
|
||||
if(size > 1 && name[0] == '.')
|
||||
return 0;
|
||||
|
||||
// each sublabel must be between 1 and 63 in length
|
||||
at = 0;
|
||||
while(1)
|
||||
{
|
||||
// search for dot or end
|
||||
for(n = at; n < size; ++n)
|
||||
{
|
||||
if(name[n] == '.')
|
||||
break;
|
||||
}
|
||||
// length of last one is always zero
|
||||
if(n >= size)
|
||||
break;
|
||||
|
||||
len = n - at;
|
||||
if(len < 1 || len > 63)
|
||||
return 0;
|
||||
at = n + 1; // skip over the dot
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// this function assumes label is pointing to a 255 byte buffer
|
||||
static int name_to_label(const jdns_string_t *name, unsigned char *label)
|
||||
{
|
||||
int n, i, at, len;
|
||||
|
||||
if(!jdns_packet_name_isvalid(name->data, name->size))
|
||||
return -1;
|
||||
|
||||
if(name->size == 1)
|
||||
{
|
||||
label[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
at = 0;
|
||||
i = 0;
|
||||
while(1)
|
||||
{
|
||||
// search for dot or end
|
||||
for(n = at; n < name->size; ++n)
|
||||
{
|
||||
if(name->data[n] == '.')
|
||||
break;
|
||||
}
|
||||
len = n - at;
|
||||
if(i + (len + 1) > 255) // length byte + length
|
||||
return 0;
|
||||
|
||||
label[i++] = len;
|
||||
memcpy(label + i, name->data + at, len);
|
||||
i += len;
|
||||
|
||||
if(n >= name->size) // end?
|
||||
break;
|
||||
at = n + 1; // skip over the dot
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// lookup list is made of jdns_packet_labels
|
||||
static int writelabel(const jdns_string_t *name, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
|
||||
{
|
||||
unsigned char label[255];
|
||||
int n, i, len;
|
||||
unsigned char *l;
|
||||
unsigned char *ref;
|
||||
int refsize;
|
||||
|
||||
len = name_to_label(name, label);
|
||||
if(len == -1)
|
||||
return 0;
|
||||
|
||||
ref = *bufp - at;
|
||||
refsize = at + left;
|
||||
for(n = 0; label[n]; n += label[n] + 1)
|
||||
{
|
||||
for(i = 0; i < lookup->count; ++i)
|
||||
{
|
||||
jdns_packet_label_t *pl = (jdns_packet_label_t *)lookup->item[i];
|
||||
|
||||
if(matchlabel(label + n, len - n, pl->value->data, pl->value->size, ref, refsize, 8, 8))
|
||||
{
|
||||
// set up a pointer right here, overwriting
|
||||
// the length byte and the first content
|
||||
// byte of this section within 'label'.
|
||||
// this is safe, because the length value
|
||||
// will always be greater than zero,
|
||||
// ensuring we have two bytes available to
|
||||
// use.
|
||||
l = label + n;
|
||||
short2net((unsigned short int)pl->offset, &l);
|
||||
label[n] |= 0xc0;
|
||||
len = n + 2; // cut things short
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(label[n] & 0xc0) // double loop, so break again
|
||||
break;
|
||||
}
|
||||
|
||||
if(left < len)
|
||||
return 0;
|
||||
|
||||
// copy into buffer, point there now
|
||||
memcpy(*bufp, label, len);
|
||||
l = *bufp;
|
||||
*bufp += len;
|
||||
|
||||
// for each new label, store its location for future compression
|
||||
for(n = 0; l[n]; n += l[n] + 1)
|
||||
{
|
||||
jdns_string_t *str;
|
||||
jdns_packet_label_t *pl;
|
||||
if(l[n] & 0xc0)
|
||||
break;
|
||||
|
||||
pl = jdns_packet_label_new();
|
||||
str = jdns_string_new();
|
||||
jdns_string_set(str, l + n, len - n);
|
||||
pl->offset = l + n - ref;
|
||||
pl->value = str;
|
||||
jdns_list_insert(lookup, pl, -1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// jdns_packet_write
|
||||
//----------------------------------------------------------------------------
|
||||
#define JDNS_PACKET_WRITE_RAW 0
|
||||
#define JDNS_PACKET_WRITE_NAME 1
|
||||
|
||||
struct jdns_packet_write
|
||||
{
|
||||
JDNS_OBJECT
|
||||
int type;
|
||||
jdns_string_t *value;
|
||||
};
|
||||
|
||||
void jdns_packet_write_delete(jdns_packet_write_t *a);
|
||||
jdns_packet_write_t *jdns_packet_write_copy(const jdns_packet_write_t *a);
|
||||
|
||||
jdns_packet_write_t *jdns_packet_write_new()
|
||||
{
|
||||
jdns_packet_write_t *a = JDNS_OBJECT_NEW(jdns_packet_write);
|
||||
a->type = 0;
|
||||
a->value = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
jdns_packet_write_t *jdns_packet_write_copy(const jdns_packet_write_t *a)
|
||||
{
|
||||
jdns_packet_write_t *c = jdns_packet_write_new();
|
||||
c->type = a->type;
|
||||
if(a->value)
|
||||
c->value = jdns_string_copy(a->value);
|
||||
return c;
|
||||
}
|
||||
|
||||
void jdns_packet_write_delete(jdns_packet_write_t *a)
|
||||
{
|
||||
if(!a)
|
||||
return;
|
||||
jdns_string_delete(a->value);
|
||||
jdns_object_free(a);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// jdns_packet_question
|
||||
//----------------------------------------------------------------------------
|
||||
jdns_packet_question_t *jdns_packet_question_new()
|
||||
{
|
||||
jdns_packet_question_t *a = JDNS_OBJECT_NEW(jdns_packet_question);
|
||||
a->qname = 0;
|
||||
a->qtype = 0;
|
||||
a->qclass = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
jdns_packet_question_t *jdns_packet_question_copy(const jdns_packet_question_t *a)
|
||||
{
|
||||
jdns_packet_question_t *c = jdns_packet_question_new();
|
||||
if(a->qname)
|
||||
c->qname = jdns_string_copy(a->qname);
|
||||
c->qtype = a->qtype;
|
||||
c->qclass = a->qclass;
|
||||
return c;
|
||||
}
|
||||
|
||||
void jdns_packet_question_delete(jdns_packet_question_t *a)
|
||||
{
|
||||
if(!a)
|
||||
return;
|
||||
jdns_string_delete(a->qname);
|
||||
jdns_object_free(a);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// jdns_packet_resource
|
||||
//----------------------------------------------------------------------------
|
||||
jdns_packet_resource_t *jdns_packet_resource_new()
|
||||
{
|
||||
jdns_packet_resource_t *a = JDNS_OBJECT_NEW(jdns_packet_resource);
|
||||
a->qname = 0;
|
||||
a->qtype = 0;
|
||||
a->qclass = 0;
|
||||
a->ttl = 0;
|
||||
a->rdlength = 0;
|
||||
a->rdata = 0;
|
||||
|
||||
a->writelog = jdns_list_new();
|
||||
a->writelog->valueList = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
jdns_packet_resource_t *jdns_packet_resource_copy(const jdns_packet_resource_t *a)
|
||||
{
|
||||
jdns_packet_resource_t *c = jdns_packet_resource_new();
|
||||
if(a->qname)
|
||||
c->qname = jdns_string_copy(a->qname);
|
||||
c->qtype = a->qtype;
|
||||
c->qclass = a->qclass;
|
||||
c->ttl = a->ttl;
|
||||
c->rdlength = a->rdlength;
|
||||
c->rdata = jdns_copy_array(a->rdata, a->rdlength);
|
||||
|
||||
jdns_list_delete(c->writelog);
|
||||
c->writelog = jdns_list_copy(a->writelog);
|
||||
return c;
|
||||
}
|
||||
|
||||
void jdns_packet_resource_delete(jdns_packet_resource_t *a)
|
||||
{
|
||||
if(!a)
|
||||
return;
|
||||
jdns_string_delete(a->qname);
|
||||
if(a->rdata)
|
||||
jdns_free(a->rdata);
|
||||
jdns_list_delete(a->writelog);
|
||||
jdns_object_free(a);
|
||||
}
|
||||
|
||||
void jdns_packet_resource_add_bytes(jdns_packet_resource_t *a, const unsigned char *data, int size)
|
||||
{
|
||||
jdns_packet_write_t *write = jdns_packet_write_new();
|
||||
write->type = JDNS_PACKET_WRITE_RAW;
|
||||
write->value = jdns_string_new();
|
||||
jdns_string_set(write->value, data, size);
|
||||
jdns_list_insert_value(a->writelog, write, -1);
|
||||
jdns_packet_write_delete(write);
|
||||
}
|
||||
|
||||
void jdns_packet_resource_add_name(jdns_packet_resource_t *a, const jdns_string_t *name)
|
||||
{
|
||||
jdns_packet_write_t *write = jdns_packet_write_new();
|
||||
write->type = JDNS_PACKET_WRITE_NAME;
|
||||
write->value = jdns_string_copy(name);
|
||||
jdns_list_insert_value(a->writelog, write, -1);
|
||||
jdns_packet_write_delete(write);
|
||||
}
|
||||
|
||||
int jdns_packet_resource_read_name(const jdns_packet_resource_t *a, const jdns_packet_t *p, int *at, jdns_string_t **name)
|
||||
{
|
||||
return readlabel(a->rdata, a->rdlength, p->raw_data, p->raw_size, at, name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// jdns_packet
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// note: both process_qsection and process_rrsection modify the 'dest' list,
|
||||
// even if later items cause an error. this turns out to be convenient
|
||||
// for handling truncated dns packets
|
||||
|
||||
static int process_qsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp)
|
||||
{
|
||||
int n;
|
||||
int offset, at;
|
||||
jdns_string_t *name = 0;
|
||||
const unsigned char *buf;
|
||||
|
||||
buf = *bufp;
|
||||
for(n = 0; n < count; ++n)
|
||||
{
|
||||
jdns_packet_question_t *q;
|
||||
|
||||
offset = buf - data;
|
||||
at = 0;
|
||||
|
||||
if(!readlabel(data + offset, size - offset, data, size, &at, &name))
|
||||
goto error;
|
||||
|
||||
offset += at;
|
||||
|
||||
// need 4 more bytes
|
||||
if(size - offset < 4)
|
||||
goto error;
|
||||
|
||||
buf = data + offset;
|
||||
|
||||
q = jdns_packet_question_new();
|
||||
q->qname = name;
|
||||
name = 0;
|
||||
q->qtype = net2short(&buf);
|
||||
q->qclass = net2short(&buf);
|
||||
|
||||
jdns_list_insert_value(dest, q, -1);
|
||||
jdns_packet_question_delete(q);
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
jdns_string_delete(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_rrsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp)
|
||||
{
|
||||
int n;
|
||||
int offset, at;
|
||||
jdns_string_t *name = 0;
|
||||
const unsigned char *buf;
|
||||
|
||||
buf = *bufp;
|
||||
for(n = 0; n < count; ++n)
|
||||
{
|
||||
jdns_packet_resource_t *r;
|
||||
|
||||
offset = buf - data;
|
||||
at = 0;
|
||||
|
||||
if(!readlabel(data + offset, size - offset, data, size, &at, &name))
|
||||
goto error;
|
||||
|
||||
offset += at;
|
||||
|
||||
// need 10 more bytes
|
||||
if(offset + 10 > size)
|
||||
goto error;
|
||||
|
||||
buf = data + offset;
|
||||
|
||||
r = jdns_packet_resource_new();
|
||||
r->qname = name;
|
||||
name = 0;
|
||||
r->qtype = net2short(&buf);
|
||||
r->qclass = net2short(&buf);
|
||||
r->ttl = net2long(&buf);
|
||||
r->rdlength = net2short(&buf);
|
||||
|
||||
offset = buf - data;
|
||||
|
||||
// make sure we have enough for the rdata
|
||||
if(size - offset < r->rdlength)
|
||||
{
|
||||
jdns_packet_resource_delete(r);
|
||||
goto error;
|
||||
}
|
||||
|
||||
r->rdata = jdns_copy_array(buf, r->rdlength);
|
||||
buf += r->rdlength;
|
||||
|
||||
jdns_list_insert_value(dest, r, -1);
|
||||
jdns_packet_resource_delete(r);
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
jdns_string_delete(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int append_qsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
|
||||
{
|
||||
unsigned char *buf, *start, *last;
|
||||
int n;
|
||||
|
||||
buf = *bufp;
|
||||
start = buf - at;
|
||||
last = buf + left;
|
||||
for(n = 0; n < src->count; ++n)
|
||||
{
|
||||
jdns_packet_question_t *q = (jdns_packet_question_t *)src->item[n];
|
||||
|
||||
if(!writelabel(q->qname, buf - start, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
|
||||
if(buf + 4 > last)
|
||||
goto error;
|
||||
|
||||
short2net(q->qtype, &buf);
|
||||
short2net(q->qclass, &buf);
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int append_rrsection(const jdns_list_t *src, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
|
||||
{
|
||||
unsigned char *buf, *start, *last, *rdlengthp;
|
||||
int n, i, rdlength;
|
||||
|
||||
buf = *bufp;
|
||||
start = buf - at;
|
||||
last = buf + left;
|
||||
for(n = 0; n < src->count; ++n)
|
||||
{
|
||||
jdns_packet_resource_t *r = (jdns_packet_resource_t *)src->item[n];
|
||||
|
||||
if(!writelabel(r->qname, buf - start, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
|
||||
if(buf + 10 > last)
|
||||
goto error;
|
||||
|
||||
short2net(r->qtype, &buf);
|
||||
short2net(r->qclass, &buf);
|
||||
long2net(r->ttl, &buf);
|
||||
|
||||
// skip over rdlength
|
||||
rdlengthp = buf;
|
||||
buf += 2;
|
||||
|
||||
// play write log
|
||||
rdlength = 0;
|
||||
for(i = 0; i < r->writelog->count; ++i)
|
||||
{
|
||||
jdns_packet_write_t *write = (jdns_packet_write_t *)r->writelog->item[i];
|
||||
if(write->type == JDNS_PACKET_WRITE_RAW)
|
||||
{
|
||||
if(buf + write->value->size > last)
|
||||
goto error;
|
||||
|
||||
memcpy(buf, write->value->data, write->value->size);
|
||||
buf += write->value->size;
|
||||
}
|
||||
else // JDNS_PACKET_WRITE_NAME
|
||||
{
|
||||
if(!writelabel(write->value, buf - start, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
i = buf - rdlengthp; // should be rdata size + 2
|
||||
short2net((unsigned short int)(i - 2), &rdlengthp);
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
jdns_packet_t *jdns_packet_new()
|
||||
{
|
||||
jdns_packet_t *a = JDNS_OBJECT_NEW(jdns_packet);
|
||||
a->id = 0;
|
||||
a->opts.qr = 0;
|
||||
a->opts.opcode = 0;
|
||||
a->opts.aa = 0;
|
||||
a->opts.tc = 0;
|
||||
a->opts.rd = 0;
|
||||
a->opts.ra = 0;
|
||||
a->opts.z = 0;
|
||||
a->opts.rcode = 0;
|
||||
|
||||
a->questions = jdns_list_new();
|
||||
a->answerRecords = jdns_list_new();
|
||||
a->authorityRecords = jdns_list_new();
|
||||
a->additionalRecords = jdns_list_new();
|
||||
|
||||
a->questions->valueList = 1;
|
||||
a->answerRecords->valueList = 1;
|
||||
a->authorityRecords->valueList = 1;
|
||||
a->additionalRecords->valueList = 1;
|
||||
|
||||
a->fully_parsed = 0;
|
||||
|
||||
a->raw_size = 0;
|
||||
a->raw_data = 0;
|
||||
return a;
|
||||
}
|
||||
|
||||
jdns_packet_t *jdns_packet_copy(const jdns_packet_t *a)
|
||||
{
|
||||
jdns_packet_t *c = jdns_packet_new();
|
||||
c->id = a->id;
|
||||
c->opts.qr = a->opts.qr;
|
||||
c->opts.opcode = a->opts.opcode;
|
||||
c->opts.aa = a->opts.aa;
|
||||
c->opts.tc = a->opts.tc;
|
||||
c->opts.rd = a->opts.rd;
|
||||
c->opts.ra = a->opts.ra;
|
||||
c->opts.z = a->opts.z;
|
||||
c->opts.rcode = a->opts.rcode;
|
||||
|
||||
jdns_list_delete(c->questions);
|
||||
jdns_list_delete(c->answerRecords);
|
||||
jdns_list_delete(c->authorityRecords);
|
||||
jdns_list_delete(c->additionalRecords);
|
||||
c->questions = jdns_list_copy(a->questions);
|
||||
c->answerRecords = jdns_list_copy(a->answerRecords);
|
||||
c->authorityRecords = jdns_list_copy(a->authorityRecords);
|
||||
c->additionalRecords = jdns_list_copy(a->additionalRecords);
|
||||
|
||||
c->fully_parsed = a->fully_parsed;
|
||||
|
||||
c->raw_size = a->raw_size;
|
||||
c->raw_data = jdns_copy_array(a->raw_data, a->raw_size);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void jdns_packet_delete(jdns_packet_t *a)
|
||||
{
|
||||
if(!a)
|
||||
return;
|
||||
jdns_list_delete(a->questions);
|
||||
jdns_list_delete(a->answerRecords);
|
||||
jdns_list_delete(a->authorityRecords);
|
||||
jdns_list_delete(a->additionalRecords);
|
||||
if(a->raw_data)
|
||||
jdns_free(a->raw_data);
|
||||
jdns_object_free(a);
|
||||
}
|
||||
|
||||
int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size)
|
||||
{
|
||||
jdns_packet_t *tmp = 0;
|
||||
const unsigned char *buf;
|
||||
|
||||
// need at least some data
|
||||
if(!data || size == 0)
|
||||
return 0;
|
||||
|
||||
// header (id + options + item counts) is 12 bytes
|
||||
if(size < 12)
|
||||
goto error;
|
||||
|
||||
tmp = jdns_packet_new();
|
||||
buf = data;
|
||||
|
||||
// id
|
||||
tmp->id = net2short(&buf);
|
||||
|
||||
// options
|
||||
if(buf[0] & 0x80) // qr is bit 7
|
||||
tmp->opts.qr = 1;
|
||||
tmp->opts.opcode = (buf[0] & 0x78) >> 3; // opcode is bits 6,5,4,3
|
||||
if(buf[0] & 0x04) // aa is bit 2
|
||||
tmp->opts.aa = 1;
|
||||
if(buf[0] & 0x02) // tc is bit 1
|
||||
tmp->opts.tc = 1;
|
||||
if(buf[0] & 0x01) // rd is bit 0
|
||||
tmp->opts.rd = 1;
|
||||
if(buf[1] & 0x80) // ra is bit 7 (second byte)
|
||||
tmp->opts.ra = 1;
|
||||
tmp->opts.z = (buf[1] & 0x70) >> 4; // z is bits 6,5,4
|
||||
tmp->opts.rcode = buf[1] & 0x0f; // rcode is bits 3,2,1,0
|
||||
buf += 2;
|
||||
|
||||
// item counts
|
||||
tmp->qdcount = net2short(&buf);
|
||||
tmp->ancount = net2short(&buf);
|
||||
tmp->nscount = net2short(&buf);
|
||||
tmp->arcount = net2short(&buf);
|
||||
|
||||
// if these fail, we don't count them as errors, since the packet
|
||||
// might have been truncated
|
||||
if(!process_qsection(tmp->questions, tmp->qdcount, data, size, &buf))
|
||||
goto skip;
|
||||
if(!process_rrsection(tmp->answerRecords, tmp->ancount, data, size, &buf))
|
||||
goto skip;
|
||||
if(!process_rrsection(tmp->authorityRecords, tmp->nscount, data, size, &buf))
|
||||
goto skip;
|
||||
if(!process_rrsection(tmp->additionalRecords, tmp->arcount, data, size, &buf))
|
||||
goto skip;
|
||||
|
||||
tmp->fully_parsed = 1;
|
||||
|
||||
skip:
|
||||
// keep the raw data for reference during rdata parsing
|
||||
tmp->raw_size = size;
|
||||
tmp->raw_data = jdns_copy_array(data, size);
|
||||
|
||||
*a = tmp;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
jdns_packet_delete(tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jdns_packet_export(jdns_packet_t *a, int maxsize)
|
||||
{
|
||||
unsigned char *block = 0;
|
||||
unsigned char *buf, *last;
|
||||
unsigned char c;
|
||||
int size;
|
||||
jdns_list_t *lookup = 0; // to hold jdns_packet_label_t
|
||||
|
||||
// clear out any existing raw data before we begin
|
||||
if(a->raw_data)
|
||||
{
|
||||
jdns_free(a->raw_data);
|
||||
a->raw_data = 0;
|
||||
a->raw_size = 0;
|
||||
}
|
||||
|
||||
// preallocate
|
||||
size = maxsize;
|
||||
block = (unsigned char *)jdns_alloc(size);
|
||||
memset(block, 0, size);
|
||||
|
||||
buf = block;
|
||||
last = block + size;
|
||||
|
||||
if(size < 12)
|
||||
goto error;
|
||||
|
||||
short2net(a->id, &buf);
|
||||
if(a->opts.qr)
|
||||
buf[0] |= 0x80;
|
||||
c = (unsigned char)a->opts.opcode;
|
||||
buf[0] |= c << 3;
|
||||
if(a->opts.aa)
|
||||
buf[0] |= 0x04;
|
||||
if(a->opts.tc)
|
||||
buf[0] |= 0x02;
|
||||
if(a->opts.rd)
|
||||
buf[0] |= 0x01;
|
||||
if(a->opts.ra)
|
||||
buf[1] |= 0x80;
|
||||
c = (unsigned char)a->opts.z;
|
||||
buf[1] |= c << 4;
|
||||
c = (unsigned char)a->opts.rcode;
|
||||
buf[1] |= c;
|
||||
buf += 2;
|
||||
short2net((unsigned short int)a->questions->count, &buf);
|
||||
short2net((unsigned short int)a->answerRecords->count, &buf);
|
||||
short2net((unsigned short int)a->authorityRecords->count, &buf);
|
||||
short2net((unsigned short int)a->additionalRecords->count, &buf);
|
||||
|
||||
// append sections
|
||||
lookup = jdns_list_new();
|
||||
lookup->autoDelete = 1;
|
||||
|
||||
if(!append_qsection(a->questions, buf - block, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
if(!append_rrsection(a->answerRecords, buf - block, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
if(!append_rrsection(a->authorityRecords, buf - block, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
if(!append_rrsection(a->additionalRecords, buf - block, last - buf, &buf, lookup))
|
||||
goto error;
|
||||
|
||||
// done with all sections
|
||||
jdns_list_delete(lookup);
|
||||
|
||||
// condense
|
||||
size = buf - block;
|
||||
block = (unsigned char *)jdns_realloc(block, size);
|
||||
|
||||
// finalize
|
||||
a->qdcount = a->questions->count;
|
||||
a->ancount = a->answerRecords->count;
|
||||
a->nscount = a->authorityRecords->count;
|
||||
a->arcount = a->additionalRecords->count;
|
||||
a->raw_data = block;
|
||||
a->raw_size = size;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
jdns_list_delete(lookup);
|
||||
if(block)
|
||||
jdns_free(block);
|
||||
return 0;
|
||||
}
|
||||
116
iris-legacy/iris/irisnet/jdns/jdns_packet.h
Normal file
116
iris-legacy/iris/irisnet/jdns/jdns_packet.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef JDNS_PACKET_H
|
||||
#define JDNS_PACKET_H
|
||||
|
||||
#include "jdns.h"
|
||||
|
||||
// -- howto --
|
||||
//
|
||||
// writing packets:
|
||||
// 1) call jdns_packet_new()
|
||||
// 2) populate the jdns_packet_t structure, using the functions
|
||||
// as necessary
|
||||
// 3) call jdns_packet_export() to populate the raw data of the packet
|
||||
//
|
||||
// reading packets:
|
||||
// 1) call jdns_packet_new()
|
||||
// 2) call jdns_packet_import() with the raw data
|
||||
// 3) the jdns_packet_t structure is now populated
|
||||
//
|
||||
// IMPORTANT: all names must be valid. that is, ending in a dot character
|
||||
|
||||
int jdns_packet_name_isvalid(const unsigned char *name, int size); // 0 if not valid
|
||||
|
||||
typedef struct jdns_packet_question
|
||||
{
|
||||
JDNS_OBJECT
|
||||
jdns_string_t *qname;
|
||||
unsigned short int qtype, qclass;
|
||||
} jdns_packet_question_t;
|
||||
|
||||
jdns_packet_question_t *jdns_packet_question_new();
|
||||
jdns_packet_question_t *jdns_packet_question_copy(const jdns_packet_question_t *a);
|
||||
void jdns_packet_question_delete(jdns_packet_question_t *a);
|
||||
|
||||
typedef struct jdns_packet_write jdns_packet_write_t;
|
||||
typedef struct jdns_packet jdns_packet_t;
|
||||
|
||||
typedef struct jdns_packet_resource
|
||||
{
|
||||
JDNS_OBJECT
|
||||
jdns_string_t *qname;
|
||||
unsigned short int qtype, qclass;
|
||||
unsigned long int ttl;
|
||||
unsigned short int rdlength;
|
||||
unsigned char *rdata;
|
||||
|
||||
// private
|
||||
jdns_list_t *writelog; // jdns_packet_write_t
|
||||
} jdns_packet_resource_t;
|
||||
|
||||
jdns_packet_resource_t *jdns_packet_resource_new();
|
||||
jdns_packet_resource_t *jdns_packet_resource_copy(const jdns_packet_resource_t *a);
|
||||
void jdns_packet_resource_delete(jdns_packet_resource_t *a);
|
||||
void jdns_packet_resource_add_bytes(jdns_packet_resource_t *a, const unsigned char *data, int size);
|
||||
void jdns_packet_resource_add_name(jdns_packet_resource_t *a, const jdns_string_t *name);
|
||||
int jdns_packet_resource_read_name(const jdns_packet_resource_t *a, const jdns_packet_t *p, int *at, jdns_string_t **name);
|
||||
|
||||
struct jdns_packet
|
||||
{
|
||||
JDNS_OBJECT
|
||||
unsigned short int id;
|
||||
struct
|
||||
{
|
||||
unsigned short qr, opcode, aa, tc, rd, ra, z, rcode;
|
||||
} opts;
|
||||
|
||||
// item counts as specified by the packet. do not use these
|
||||
// for iteration over the item lists, since they can be wrong
|
||||
// if the packet is truncated.
|
||||
int qdcount, ancount, nscount, arcount;
|
||||
|
||||
// value lists
|
||||
jdns_list_t *questions; // jdns_packet_question_t
|
||||
jdns_list_t *answerRecords; // jdns_packet_resource_t
|
||||
jdns_list_t *authorityRecords; // jdns_packet_resource_t
|
||||
jdns_list_t *additionalRecords; // jdns_packet_resource_t
|
||||
|
||||
// since dns packets are allowed to be truncated, it is possible
|
||||
// for a packet to not get fully parsed yet still be considered
|
||||
// successfully parsed. this flag means the packet was fully
|
||||
// parsed also.
|
||||
int fully_parsed;
|
||||
|
||||
int raw_size;
|
||||
unsigned char *raw_data;
|
||||
};
|
||||
|
||||
jdns_packet_t *jdns_packet_new();
|
||||
jdns_packet_t *jdns_packet_copy(const jdns_packet_t *a);
|
||||
void jdns_packet_delete(jdns_packet_t *a);
|
||||
int jdns_packet_import(jdns_packet_t **a, const unsigned char *data, int size); // 0 on fail
|
||||
int jdns_packet_export(jdns_packet_t *a, int maxsize); // 0 on fail
|
||||
|
||||
#endif
|
||||
822
iris-legacy/iris/irisnet/jdns/jdns_sys.c
Normal file
822
iris-legacy/iris/irisnet/jdns/jdns_sys.c
Normal file
|
|
@ -0,0 +1,822 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
this code probes the system for dns settings. blah.
|
||||
|
||||
q3dns strategies
|
||||
----------------
|
||||
|
||||
windows:
|
||||
|
||||
domain name, name server, "search list" found in windows registry here:
|
||||
|
||||
HKEY_LOCAL_MACHINE
|
||||
System\CurrentControlSet\Services\Tcpip\Parameters <-- win nt+
|
||||
System\CurrentControlSet\Services\VxD\MSTCP <-- win 98
|
||||
|
||||
for domain, try DhcpDomain else Domain
|
||||
for name servers, try DhcpNameServer, else NameServer
|
||||
for search list, try SearchList
|
||||
|
||||
iphlpapi.dll : GetNetworkParams(PFIXED_INFO, PULONG);
|
||||
|
||||
info->DomainName
|
||||
info->DnsServerList (if not null, use it, and loop through ->Next until
|
||||
null)
|
||||
no search list
|
||||
|
||||
first try getnetworkparams. if that fails, try the nt regkey then the 98
|
||||
regkey. it seems that search list can only come from the registry, so
|
||||
maybe we need to grab that entry even if getnetworkparams works.
|
||||
|
||||
in the case of the registry, the nameserver and searchlist entries are
|
||||
delimited by spaces on win nt and commas on win 98. probably a good
|
||||
idea to simplify white space first (chop away space at start and end,
|
||||
reduce all sections of spaces to one char). also, lowercase the search
|
||||
list.
|
||||
|
||||
qt doesn't read the hosts file on windows. this might be a good idea, but
|
||||
probably not worth it.
|
||||
|
||||
unix:
|
||||
|
||||
read /etc/resolv.conf manually:
|
||||
for each line, split at spaces
|
||||
if the first item is "nameserver", then there should be an IP address
|
||||
following it. note: may contain mixed ipv4 and ipv6 addresses
|
||||
if the first item is "search", all other items are added to the domain
|
||||
list
|
||||
if the first item is "domain", then the next item should be added to the
|
||||
domain list.
|
||||
do case-insensitive matching for the item types
|
||||
for search/domain, the items are in the 8-bit system locale
|
||||
|
||||
info can also be fetched using system calls. we use the res_* stuff here.
|
||||
first we should detect for a "modern res api". this is available from
|
||||
glibc 2.3 and onward. use the following scheme to check for it:
|
||||
|
||||
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2)
|
||||
&& (__GLIBC_MINOR__ >= 3)))
|
||||
// modern res api
|
||||
#endif
|
||||
|
||||
on mac we should look up res_init in the system library. see:
|
||||
qt_mac_resolve_sys(RTLD_NEXT, "res_init"); for a hint.
|
||||
otherwise we can just use res_init() straight.
|
||||
|
||||
under a modern res api, we do:
|
||||
struct __res_state res;
|
||||
res_ninit(&res);
|
||||
otherwise, we simply call res_init(). for the modern api, we use the "res"
|
||||
struct that we made. otherwise, we use the global "_res" struct.
|
||||
|
||||
read the res struct to obtain the name servers, search list, and domain.
|
||||
lowercase the search list and domain.
|
||||
|
||||
qt tries the file, and if that fails it tries the syscalls. we may want to
|
||||
do the syscalls first, or even just do both all the time.
|
||||
|
||||
read /etc/hosts manually:
|
||||
for each line
|
||||
if there is a '#' character in the line, remove it and everything to
|
||||
the right
|
||||
simplify white space
|
||||
convert to lowercase
|
||||
split the line at spaces
|
||||
first item is the ip address
|
||||
all remaining items are hostnames
|
||||
|
||||
note: these hosts could also be used for reverse-dns too
|
||||
note2: Windows has a hosts file as well (like C:\WINDOWS\hosts)
|
||||
*/
|
||||
|
||||
#include "jdns_p.h"
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/nameser.h>
|
||||
# include <resolv.h>
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#define string_indexOf jdns_string_indexOf
|
||||
#define string_split jdns_string_split
|
||||
|
||||
static int char_isspace(unsigned char c)
|
||||
{
|
||||
if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char *string_getnextword(unsigned char *in, int size, int pos, int *newpos)
|
||||
{
|
||||
int n;
|
||||
int at;
|
||||
int len;
|
||||
unsigned char *out;
|
||||
|
||||
at = pos;
|
||||
|
||||
// skip any space at the start
|
||||
while(at < size && char_isspace(in[at]))
|
||||
++at;
|
||||
|
||||
// all space? no word then
|
||||
if(at >= size)
|
||||
return 0;
|
||||
|
||||
// skip until a space or end
|
||||
n = at;
|
||||
while(n < size && !char_isspace(in[n]))
|
||||
++n;
|
||||
len = n - at;
|
||||
|
||||
// allocate length + zero byte
|
||||
out = (unsigned char *)jdns_alloc(len + 1);
|
||||
if(!out)
|
||||
return 0;
|
||||
memcpy(out, in + at, len);
|
||||
out[len] = 0;
|
||||
*newpos = at + len;
|
||||
return out;
|
||||
}
|
||||
|
||||
static jdns_string_t *string_simplify(const jdns_string_t *in)
|
||||
{
|
||||
int n;
|
||||
int pos;
|
||||
int total;
|
||||
unsigned char *out;
|
||||
int outlen;
|
||||
jdns_string_t *outstr;
|
||||
jdns_stringlist_t *wordlist;
|
||||
|
||||
// gather words and total of lengths
|
||||
pos = 0;
|
||||
total = 0;
|
||||
wordlist = jdns_stringlist_new();
|
||||
while(1)
|
||||
{
|
||||
jdns_string_t *word;
|
||||
unsigned char *str = string_getnextword(in->data, in->size, pos, &pos);
|
||||
if(!str)
|
||||
break;
|
||||
word = jdns_string_new();
|
||||
jdns_string_set_cstr(word, (char *)str);
|
||||
jdns_free(str);
|
||||
jdns_stringlist_append(wordlist, word);
|
||||
total += word->size;
|
||||
jdns_string_delete(word);
|
||||
}
|
||||
|
||||
if(total == 0)
|
||||
{
|
||||
jdns_stringlist_delete(wordlist);
|
||||
|
||||
outstr = jdns_string_new();
|
||||
jdns_string_set_cstr(outstr, "");
|
||||
return outstr;
|
||||
}
|
||||
|
||||
// we need to allocate space for total lengths and wordcount-1 spaces
|
||||
outlen = total + (wordlist->count - 1);
|
||||
out = (unsigned char *)jdns_alloc(outlen);
|
||||
|
||||
// lay out the words
|
||||
pos = 0;
|
||||
for(n = 0; n < wordlist->count; ++n)
|
||||
{
|
||||
unsigned char *data = wordlist->item[n]->data;
|
||||
int size = wordlist->item[n]->size;
|
||||
memcpy(out + pos, data, size);
|
||||
pos += size;
|
||||
|
||||
// if this is not the last word, append a space
|
||||
if(n + 1 < wordlist->count)
|
||||
out[pos++] = ' ';
|
||||
}
|
||||
jdns_stringlist_delete(wordlist);
|
||||
|
||||
outstr = jdns_string_new();
|
||||
jdns_string_set(outstr, out, outlen);
|
||||
jdns_free(out);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
static jdns_string_t *string_tolower(const jdns_string_t *in)
|
||||
{
|
||||
int n;
|
||||
jdns_string_t *out = jdns_string_copy(in);
|
||||
for(n = 0; n < out->size; ++n)
|
||||
out->data[n] = tolower(out->data[n]);
|
||||
return out;
|
||||
}
|
||||
|
||||
static jdns_string_t *file_nextline(FILE *f)
|
||||
{
|
||||
int at, size;
|
||||
unsigned char *buf;
|
||||
jdns_string_t *str;
|
||||
|
||||
size = 1023;
|
||||
buf = (unsigned char *)jdns_alloc(size);
|
||||
at = 0;
|
||||
while(1)
|
||||
{
|
||||
unsigned char c = fgetc(f);
|
||||
if(feof(f))
|
||||
{
|
||||
jdns_free(buf);
|
||||
return 0;
|
||||
}
|
||||
if(c == '\n')
|
||||
break;
|
||||
if(c == '\r')
|
||||
continue;
|
||||
if(at < 1023)
|
||||
buf[at++] = c;
|
||||
}
|
||||
|
||||
str = jdns_string_new();
|
||||
jdns_string_set(str, buf, at);
|
||||
jdns_free(buf);
|
||||
return str;
|
||||
}
|
||||
|
||||
static jdns_dnshostlist_t *read_hosts_file(const char *path)
|
||||
{
|
||||
jdns_dnshostlist_t *out;
|
||||
FILE *f;
|
||||
jdns_string_t *line, *simp;
|
||||
jdns_stringlist_t *parts;
|
||||
jdns_address_t *addr;
|
||||
int n;
|
||||
|
||||
out = jdns_dnshostlist_new();
|
||||
|
||||
f = fopen(path, "r");
|
||||
if(!f)
|
||||
return out;
|
||||
while(1)
|
||||
{
|
||||
line = file_nextline(f);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
// truncate at comment
|
||||
n = string_indexOf(line, '#', 0);
|
||||
if(n != -1)
|
||||
{
|
||||
line->size = n;
|
||||
line->data[n] = 0;
|
||||
}
|
||||
|
||||
simp = string_simplify(line);
|
||||
jdns_string_delete(line);
|
||||
|
||||
parts = string_split(simp, ' ');
|
||||
jdns_string_delete(simp);
|
||||
|
||||
if(parts->count < 2)
|
||||
{
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = jdns_address_new();
|
||||
if(!jdns_address_set_cstr(addr, (const char *)parts->item[0]->data))
|
||||
{
|
||||
jdns_address_delete(addr);
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(n = 1; n < parts->count; ++n)
|
||||
{
|
||||
jdns_dnshost_t *h = jdns_dnshost_new();
|
||||
h->name = jdns_string_copy(parts->item[n]);
|
||||
h->address = jdns_address_copy(addr);
|
||||
jdns_dnshostlist_append(out, h);
|
||||
jdns_dnshost_delete(h);
|
||||
}
|
||||
|
||||
jdns_address_delete(addr);
|
||||
jdns_stringlist_delete(parts);
|
||||
}
|
||||
fclose(f);
|
||||
return out;
|
||||
}
|
||||
|
||||
static void apply_hosts_file(jdns_dnsparams_t *a, const char *path)
|
||||
{
|
||||
int n;
|
||||
jdns_dnshostlist_t *list;
|
||||
|
||||
list = read_hosts_file(path);
|
||||
for(n = 0; n < list->count; ++n)
|
||||
jdns_dnshostlist_append(a->hosts, list->item[n]);
|
||||
jdns_dnshostlist_delete(list);
|
||||
}
|
||||
|
||||
static int dnsparams_have_domain(const jdns_dnsparams_t *a, const jdns_string_t *domain)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < a->domains->count; ++n)
|
||||
{
|
||||
jdns_string_t *str = a->domains->item[n];
|
||||
if(strcmp((const char *)str->data, (const char *)domain->data) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef JDNS_OS_WIN
|
||||
|
||||
// from Microsoft IPTypes.h
|
||||
#ifndef IP_TYPES_INCLUDED
|
||||
#define MAX_HOSTNAME_LEN 128
|
||||
#define MAX_DOMAIN_NAME_LEN 128
|
||||
#define MAX_SCOPE_ID_LEN 256
|
||||
typedef struct {
|
||||
char String[4 * 4];
|
||||
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
|
||||
typedef struct _IP_ADDR_STRING {
|
||||
struct _IP_ADDR_STRING* Next;
|
||||
IP_ADDRESS_STRING IpAddress;
|
||||
IP_MASK_STRING IpMask;
|
||||
DWORD Context;
|
||||
} IP_ADDR_STRING, *PIP_ADDR_STRING;
|
||||
typedef struct {
|
||||
char HostName[MAX_HOSTNAME_LEN + 4] ;
|
||||
char DomainName[MAX_DOMAIN_NAME_LEN + 4];
|
||||
PIP_ADDR_STRING CurrentDnsServer;
|
||||
IP_ADDR_STRING DnsServerList;
|
||||
UINT NodeType;
|
||||
char ScopeId[MAX_SCOPE_ID_LEN + 4];
|
||||
UINT EnableRouting;
|
||||
UINT EnableProxy;
|
||||
UINT EnableDns;
|
||||
} FIXED_INFO, *PFIXED_INFO;
|
||||
#endif
|
||||
|
||||
typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO, PULONG);
|
||||
|
||||
static jdns_string_t *reg_readString(HKEY hk, const char *subkey)
|
||||
{
|
||||
char *buf;
|
||||
DWORD bufsize;
|
||||
int ret;
|
||||
jdns_string_t *str = 0;
|
||||
|
||||
bufsize = 1024;
|
||||
buf = (char *)jdns_alloc((int)bufsize);
|
||||
if(!buf)
|
||||
return 0;
|
||||
ret = RegQueryValueExA(hk, subkey, 0, 0, (LPBYTE)buf, &bufsize);
|
||||
if(ret == ERROR_MORE_DATA)
|
||||
{
|
||||
buf = (char *)jdns_realloc(buf, bufsize);
|
||||
if(!buf)
|
||||
{
|
||||
jdns_free(buf);
|
||||
return 0;
|
||||
}
|
||||
ret = RegQueryValueExA(hk, subkey, 0, 0, (LPBYTE)buf, &bufsize);
|
||||
}
|
||||
if(ret == ERROR_SUCCESS)
|
||||
{
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, (char *)buf);
|
||||
}
|
||||
jdns_free(buf);
|
||||
return str;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_winreg()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
HKEY key;
|
||||
int ret;
|
||||
char sep;
|
||||
jdns_string_t *str_domain, *str_nameserver, *str_searchlist;
|
||||
jdns_stringlist_t *list_nameserver, *list_searchlist;
|
||||
|
||||
sep = ' ';
|
||||
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
|
||||
0, KEY_READ, &key);
|
||||
if(ret != ERROR_SUCCESS)
|
||||
{
|
||||
sep = ',';
|
||||
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\VxD\\MSTCP",
|
||||
0, KEY_READ, &key);
|
||||
if(ret != ERROR_SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
str_domain = reg_readString(key, "DhcpDomain");
|
||||
if(!str_domain)
|
||||
str_domain = reg_readString(key, "Domain");
|
||||
str_nameserver = reg_readString(key, "DhcpNameServer");
|
||||
if(!str_nameserver)
|
||||
str_nameserver = reg_readString(key, "NameServer");
|
||||
str_searchlist = reg_readString(key, "SearchList");
|
||||
|
||||
RegCloseKey(key);
|
||||
|
||||
list_nameserver = 0;
|
||||
if(str_nameserver)
|
||||
{
|
||||
list_nameserver = string_split(str_nameserver, sep);
|
||||
jdns_string_delete(str_nameserver);
|
||||
}
|
||||
list_searchlist = 0;
|
||||
if(str_searchlist)
|
||||
{
|
||||
// lowercase the string
|
||||
jdns_string_t *p = string_tolower(str_searchlist);
|
||||
jdns_string_delete(str_searchlist);
|
||||
str_searchlist = p;
|
||||
|
||||
list_searchlist = string_split(str_searchlist, sep);
|
||||
jdns_string_delete(str_searchlist);
|
||||
}
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
if(list_nameserver)
|
||||
{
|
||||
// qt seems to do a strange thing here by running each name
|
||||
// server address through the q3dns setLabel function, and
|
||||
// then pulls the result as a list of addresses. i have
|
||||
// no idea why they do this, or how one IP address would
|
||||
// turn into anything else, let alone several addresses.
|
||||
// so, uh, we're not going to do that.
|
||||
for(n = 0; n < list_nameserver->count; ++n)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
if(jdns_address_set_cstr(addr, (char *)list_nameserver->item[n]->data))
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
jdns_stringlist_delete(list_nameserver);
|
||||
}
|
||||
if(str_domain)
|
||||
{
|
||||
if(str_domain->size > 0)
|
||||
jdns_dnsparams_append_domain(params, str_domain);
|
||||
jdns_string_delete(str_domain);
|
||||
}
|
||||
if(list_searchlist)
|
||||
{
|
||||
for(n = 0; n < list_searchlist->count; ++n)
|
||||
{
|
||||
if(list_searchlist->item[n]->size > 0)
|
||||
jdns_dnsparams_append_domain(params, list_searchlist->item[n]);
|
||||
}
|
||||
jdns_stringlist_delete(list_searchlist);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_winsys()
|
||||
{
|
||||
jdns_dnsparams_t *params;
|
||||
GetNetworkParamsFunc myGetNetworkParams;
|
||||
DWORD ret;
|
||||
HINSTANCE lib;
|
||||
jdns_address_t *addr;
|
||||
jdns_string_t *str;
|
||||
IP_ADDR_STRING *ipstr;
|
||||
|
||||
lib = LoadLibraryA("iphlpapi");
|
||||
if(!lib)
|
||||
return 0;
|
||||
|
||||
params = 0;
|
||||
myGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(lib, "GetNetworkParams");
|
||||
if(myGetNetworkParams)
|
||||
{
|
||||
ULONG bufsize = 0;
|
||||
ret = myGetNetworkParams(0, &bufsize);
|
||||
if(ret == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
FIXED_INFO *info = (FIXED_INFO *)jdns_alloc((int)bufsize);
|
||||
ret = myGetNetworkParams(info, &bufsize);
|
||||
if(ret == ERROR_SUCCESS)
|
||||
{
|
||||
params = jdns_dnsparams_new();
|
||||
ipstr = &info->DnsServerList;
|
||||
while(ipstr)
|
||||
{
|
||||
addr = jdns_address_new();
|
||||
if(jdns_address_set_cstr(addr, (char *)ipstr->IpAddress.String))
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
ipstr = ipstr->Next;
|
||||
}
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, info->DomainName);
|
||||
if(str->size > 0)
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
jdns_free(info);
|
||||
}
|
||||
}
|
||||
FreeLibrary(lib);
|
||||
return params;
|
||||
}
|
||||
|
||||
static void apply_win_hosts_file(jdns_dnsparams_t *a)
|
||||
{
|
||||
char *p, *str;
|
||||
int len;
|
||||
|
||||
p = getenv("WINDIR");
|
||||
if(!p)
|
||||
return;
|
||||
len = strlen(p);
|
||||
str = (char *)jdns_alloc(len + 100); // should be enough
|
||||
memcpy(str, p, len);
|
||||
strcpy(str + len, "\\system32\\drivers\\etc\\hosts"); // winnt+
|
||||
apply_hosts_file(a, str);
|
||||
strcpy(str + len, "\\hosts"); // win9x
|
||||
apply_hosts_file(a, str);
|
||||
jdns_free(str);
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_win()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *sys_params, *reg_params;
|
||||
|
||||
reg_params = dnsparams_get_winreg();
|
||||
sys_params = dnsparams_get_winsys();
|
||||
|
||||
// no sys params? take the reg params then
|
||||
if(!sys_params)
|
||||
{
|
||||
apply_win_hosts_file(reg_params);
|
||||
return reg_params;
|
||||
}
|
||||
|
||||
// sys params don't have a search list, so merge the domains from
|
||||
// the registry if possible
|
||||
if(reg_params)
|
||||
{
|
||||
for(n = 0; n < reg_params->domains->count; ++n)
|
||||
{
|
||||
jdns_string_t *reg_str = reg_params->domains->item[n];
|
||||
|
||||
// don't add dups
|
||||
if(!dnsparams_have_domain(sys_params, reg_str))
|
||||
jdns_dnsparams_append_domain(sys_params, reg_str);
|
||||
}
|
||||
jdns_dnsparams_delete(reg_params);
|
||||
}
|
||||
apply_win_hosts_file(sys_params);
|
||||
return sys_params;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef JDNS_OS_UNIX
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unixfiles()
|
||||
{
|
||||
FILE *f;
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
jdns_string_t *line, *simp;
|
||||
jdns_stringlist_t *parts;
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
|
||||
f = fopen("/etc/resolv.conf", "r");
|
||||
if(!f)
|
||||
return params;
|
||||
while(1)
|
||||
{
|
||||
line = file_nextline(f);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
// truncate at comment
|
||||
n = string_indexOf(line, '#', 0);
|
||||
if(n != -1)
|
||||
{
|
||||
line->size = n;
|
||||
line->data[n] = 0;
|
||||
}
|
||||
|
||||
simp = string_simplify(line);
|
||||
jdns_string_delete(line);
|
||||
|
||||
parts = string_split(simp, ' ');
|
||||
jdns_string_delete(simp);
|
||||
|
||||
if(parts->count < 2)
|
||||
{
|
||||
jdns_stringlist_delete(parts);
|
||||
continue;
|
||||
}
|
||||
|
||||
simp = string_tolower(parts->item[0]);
|
||||
if(strcmp((char *)simp->data, "nameserver") == 0)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
jdns_address_set_cstr(addr, (const char *)parts->item[1]->data);
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
else if(strcmp((char *)simp->data, "search") == 0)
|
||||
{
|
||||
for(n = 1; n < parts->count; ++n)
|
||||
{
|
||||
jdns_dnsparams_append_domain(params, parts->item[n]);
|
||||
}
|
||||
}
|
||||
else if(strcmp((char *)simp->data, "domain") == 0)
|
||||
{
|
||||
jdns_dnsparams_append_domain(params, parts->item[1]);
|
||||
}
|
||||
jdns_string_delete(simp);
|
||||
|
||||
jdns_stringlist_delete(parts);
|
||||
}
|
||||
fclose(f);
|
||||
return params;
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
|
||||
# define JDNS_MODERN_RES_API
|
||||
#endif
|
||||
|
||||
#ifndef JDNS_MODERN_RES_API
|
||||
typedef int (*res_init_func)();
|
||||
static int my_res_init()
|
||||
{
|
||||
#ifdef JDNS_OS_MAC
|
||||
res_init_func mac_res_init;
|
||||
|
||||
// look up res_init in the system library (qt does this, not sure why)
|
||||
mac_res_init = (res_init_func)dlsym(RTLD_NEXT, "res_init");
|
||||
if(!mac_res_init)
|
||||
return -1;
|
||||
return mac_res_init();
|
||||
#else
|
||||
return res_init();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __res_state_ext
|
||||
# define USE_EXTEXT
|
||||
#endif
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unixsys()
|
||||
{
|
||||
int n;
|
||||
jdns_dnsparams_t *params;
|
||||
|
||||
#ifdef JDNS_MODERN_RES_API
|
||||
struct __res_state res;
|
||||
memset(&res, 0, sizeof(struct __res_state));
|
||||
n = res_ninit(&res);
|
||||
#define RESVAR res
|
||||
#else
|
||||
n = my_res_init();
|
||||
#define RESVAR _res
|
||||
#endif
|
||||
|
||||
params = jdns_dnsparams_new();
|
||||
|
||||
// error initializing?
|
||||
if(n == -1)
|
||||
return params;
|
||||
|
||||
// nameservers - ipv6
|
||||
for(n = 0; n < MAXNS && n < RESVAR._u._ext.nscount; ++n)
|
||||
{
|
||||
jdns_address_t *addr;
|
||||
struct sockaddr_in6 *sa6;
|
||||
|
||||
#ifdef USE_EXTEXT
|
||||
sa6 = ((struct sockaddr_in6 *)RESVAR._u._ext.ext) + n;
|
||||
#else
|
||||
sa6 = RESVAR._u._ext.nsaddrs[n];
|
||||
#endif
|
||||
|
||||
if(sa6 == NULL)
|
||||
continue;
|
||||
addr = jdns_address_new();
|
||||
jdns_address_set_ipv6(addr, sa6->sin6_addr.s6_addr);
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
|
||||
// nameservers - ipv4
|
||||
for(n = 0; n < MAXNS && n < RESVAR.nscount; ++n)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
jdns_address_set_ipv4(addr, ntohl(RESVAR.nsaddr_list[n].sin_addr.s_addr));
|
||||
jdns_dnsparams_append_nameserver(params, addr, JDNS_UNICAST_PORT);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
|
||||
// domain name
|
||||
if(strlen(RESVAR.defdname) > 0)
|
||||
{
|
||||
jdns_string_t *str;
|
||||
jdns_string_t *p;
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, RESVAR.defdname);
|
||||
p = string_tolower(str);
|
||||
jdns_string_delete(str);
|
||||
str = p;
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
|
||||
// search list
|
||||
#ifdef MAXDFLSRCH
|
||||
for(n = 0; n < MAXDFLSRCH && RESVAR.dnsrch[n]; ++n)
|
||||
{
|
||||
if(strlen(RESVAR.dnsrch[n]) > 0)
|
||||
{
|
||||
jdns_string_t *str;
|
||||
jdns_string_t *p;
|
||||
str = jdns_string_new();
|
||||
jdns_string_set_cstr(str, RESVAR.dnsrch[n]);
|
||||
p = string_tolower(str);
|
||||
jdns_string_delete(str);
|
||||
str = p;
|
||||
|
||||
// don't add dups
|
||||
if(!dnsparams_have_domain(params, str))
|
||||
jdns_dnsparams_append_domain(params, str);
|
||||
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
static jdns_dnsparams_t *dnsparams_get_unix()
|
||||
{
|
||||
jdns_dnsparams_t *params;
|
||||
|
||||
// prefer system calls over files
|
||||
params = dnsparams_get_unixsys();
|
||||
if(params->nameservers->count == 0)
|
||||
{
|
||||
jdns_dnsparams_delete(params);
|
||||
params = dnsparams_get_unixfiles();
|
||||
}
|
||||
|
||||
apply_hosts_file(params, "/etc/hosts");
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
jdns_dnsparams_t *jdns_system_dnsparams()
|
||||
{
|
||||
#ifdef JDNS_OS_WIN
|
||||
return dnsparams_get_win();
|
||||
#else
|
||||
return dnsparams_get_unix();
|
||||
#endif
|
||||
}
|
||||
1471
iris-legacy/iris/irisnet/jdns/jdns_util.c
Normal file
1471
iris-legacy/iris/irisnet/jdns/jdns_util.c
Normal file
File diff suppressed because it is too large
Load diff
596
iris-legacy/iris/irisnet/jdns/main.cpp
Normal file
596
iris-legacy/iris/irisnet/jdns/main.cpp
Normal file
|
|
@ -0,0 +1,596 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include "qjdns.h"
|
||||
|
||||
QString dataToString(const QByteArray &buf)
|
||||
{
|
||||
QString out;
|
||||
for(int n = 0; n < buf.size(); ++n)
|
||||
{
|
||||
unsigned char c = (unsigned char)buf[n];
|
||||
if(c == '\\')
|
||||
out += "\\\\";
|
||||
else if(c >= 0x20 && c < 0x7f)
|
||||
out += c;
|
||||
else
|
||||
out += QString().sprintf("\\x%02x", (unsigned int)c);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void print_record(const QJDns::Record &r)
|
||||
{
|
||||
switch(r.type)
|
||||
{
|
||||
case QJDns::A:
|
||||
printf(" A: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl);
|
||||
break;
|
||||
case QJDns::Aaaa:
|
||||
printf(" AAAA: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl);
|
||||
break;
|
||||
case QJDns::Mx:
|
||||
printf(" MX: [%s] priority=%d (ttl=%d)\n", r.name.data(), r.priority, r.ttl);
|
||||
break;
|
||||
case QJDns::Srv:
|
||||
printf(" SRV: [%s] port=%d priority=%d weight=%d (ttl=%d)\n", r.name.data(), r.port, r.priority, r.weight, r.ttl);
|
||||
break;
|
||||
case QJDns::Cname:
|
||||
printf(" CNAME: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Ptr:
|
||||
printf(" PTR: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Txt:
|
||||
{
|
||||
printf(" TXT: count=%d (ttl=%d)\n", r.texts.count(), r.ttl);
|
||||
for(int n = 0; n < r.texts.count(); ++n)
|
||||
printf(" len=%d [%s]\n", r.texts[n].size(), qPrintable(dataToString(r.texts[n])));
|
||||
break;
|
||||
}
|
||||
case QJDns::Hinfo:
|
||||
printf(" HINFO: [%s] [%s] (ttl=%d)\n", r.cpu.data(), r.os.data(), r.ttl);
|
||||
break;
|
||||
case QJDns::Ns:
|
||||
printf(" NS: [%s] (ttl=%d)\n", r.name.data(), r.ttl);
|
||||
break;
|
||||
default:
|
||||
printf(" (Unknown): type=%d, size=%d (ttl=%d)\n", r.type, r.rdata.size(), r.ttl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class App : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
bool opt_debug, opt_ipv6, opt_quit;
|
||||
int quit_time;
|
||||
QString mode, type, name, ipaddr;
|
||||
QStringList nslist;
|
||||
QList<QJDns::Record> pubitems;
|
||||
QJDns jdns;
|
||||
int req_id;
|
||||
|
||||
App()
|
||||
{
|
||||
connect(&jdns, SIGNAL(resultsReady(int, const QJDns::Response &)), SLOT(jdns_resultsReady(int, const QJDns::Response &)));
|
||||
connect(&jdns, SIGNAL(published(int)), SLOT(jdns_published(int)));
|
||||
connect(&jdns, SIGNAL(error(int, QJDns::Error)), SLOT(jdns_error(int, QJDns::Error)));
|
||||
connect(&jdns, SIGNAL(shutdownFinished()), SLOT(jdns_shutdownFinished()));
|
||||
connect(&jdns, SIGNAL(debugLinesReady()), SLOT(jdns_debugLinesReady()));
|
||||
}
|
||||
|
||||
~App()
|
||||
{
|
||||
}
|
||||
|
||||
public slots:
|
||||
void start()
|
||||
{
|
||||
if(mode == "uni")
|
||||
{
|
||||
if(!jdns.init(QJDns::Unicast, opt_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any))
|
||||
{
|
||||
jdns_debugLinesReady();
|
||||
printf("unable to bind\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QJDns::NameServer> addrs;
|
||||
for(int n = 0; n < nslist.count(); ++n)
|
||||
{
|
||||
QJDns::NameServer host;
|
||||
QString str = nslist[n];
|
||||
if(str == "mul")
|
||||
{
|
||||
if(opt_ipv6)
|
||||
host.address = QHostAddress("FF02::FB");
|
||||
else
|
||||
host.address = QHostAddress("224.0.0.251");
|
||||
host.port = 5353;
|
||||
}
|
||||
else
|
||||
{
|
||||
int at = str.indexOf(';');
|
||||
if(at != -1)
|
||||
{
|
||||
host.address = QHostAddress(str.mid(0, at));
|
||||
host.port = str.mid(at + 1).toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
host.address = QHostAddress(str);
|
||||
}
|
||||
}
|
||||
|
||||
if(host.address.isNull() || host.port <= 0)
|
||||
{
|
||||
printf("bad nameserver: [%s]\n", qPrintable(nslist[n]));
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
addrs += host;
|
||||
}
|
||||
|
||||
if(addrs.isEmpty())
|
||||
addrs = QJDns::systemInfo().nameServers;
|
||||
|
||||
if(addrs.isEmpty())
|
||||
{
|
||||
printf("no nameservers were detected or specified\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
|
||||
jdns.setNameServers(addrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!jdns.init(QJDns::Multicast, opt_ipv6 ? QHostAddress::AnyIPv6 : QHostAddress::Any))
|
||||
{
|
||||
jdns_debugLinesReady();
|
||||
printf("unable to bind\n");
|
||||
emit quit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(mode == "uni" || mode == "mul")
|
||||
{
|
||||
int x = QJDns::A;
|
||||
if(type == "ptr")
|
||||
x = QJDns::Ptr;
|
||||
else if(type == "srv")
|
||||
x = QJDns::Srv;
|
||||
else if(type == "a")
|
||||
x = QJDns::A;
|
||||
else if(type == "aaaa")
|
||||
x = QJDns::Aaaa;
|
||||
else if(type == "mx")
|
||||
x = QJDns::Mx;
|
||||
else if(type == "txt")
|
||||
x = QJDns::Txt;
|
||||
else if(type == "hinfo")
|
||||
x = QJDns::Hinfo;
|
||||
else if(type == "cname")
|
||||
x = QJDns::Cname;
|
||||
else if(type == "any")
|
||||
x = QJDns::Any;
|
||||
else
|
||||
{
|
||||
bool ok;
|
||||
int y = type.toInt(&ok);
|
||||
if(ok)
|
||||
x = y;
|
||||
}
|
||||
|
||||
req_id = jdns.queryStart(name.toLatin1(), x);
|
||||
printf("[%d] Querying for [%s] type=%d ...\n", req_id, qPrintable(name), x);
|
||||
}
|
||||
else // publish
|
||||
{
|
||||
for(int n = 0; n < pubitems.count(); ++n)
|
||||
{
|
||||
const QJDns::Record &rr = pubitems[n];
|
||||
QJDns::PublishMode m = QJDns::Unique;
|
||||
if(rr.type == QJDns::Ptr)
|
||||
m = QJDns::Shared;
|
||||
int id = jdns.publishStart(m, rr);
|
||||
printf("[%d] Publishing [%s] type=%d ...\n", id, rr.owner.data(), rr.type);
|
||||
}
|
||||
}
|
||||
|
||||
if(opt_quit)
|
||||
QTimer::singleShot(quit_time * 1000, this, SLOT(doShutdown()));
|
||||
}
|
||||
|
||||
signals:
|
||||
void quit();
|
||||
|
||||
private slots:
|
||||
void jdns_resultsReady(int id, const QJDns::Response &results)
|
||||
{
|
||||
printf("[%d] Results\n", id);
|
||||
for(int n = 0; n < results.answerRecords.count(); ++n)
|
||||
print_record(results.answerRecords[n]);
|
||||
|
||||
if(mode == "uni")
|
||||
jdns.shutdown();
|
||||
}
|
||||
|
||||
void jdns_published(int id)
|
||||
{
|
||||
printf("[%d] Published\n", id);
|
||||
}
|
||||
|
||||
void jdns_error(int id, QJDns::Error e)
|
||||
{
|
||||
QString str;
|
||||
if(e == QJDns::ErrorGeneric)
|
||||
str = "Generic";
|
||||
else if(e == QJDns::ErrorNXDomain)
|
||||
str = "NXDomain";
|
||||
else if(e == QJDns::ErrorTimeout)
|
||||
str = "Timeout";
|
||||
else if(e == QJDns::ErrorConflict)
|
||||
str = "Conflict";
|
||||
printf("[%d] Error: %s\n", id, qPrintable(str));
|
||||
jdns.shutdown();
|
||||
}
|
||||
|
||||
void jdns_shutdownFinished()
|
||||
{
|
||||
emit quit();
|
||||
}
|
||||
|
||||
void jdns_debugLinesReady()
|
||||
{
|
||||
QStringList lines = jdns.debugLines();
|
||||
if(opt_debug)
|
||||
{
|
||||
for(int n = 0; n < lines.count(); ++n)
|
||||
printf("jdns: %s\n", qPrintable(lines[n]));
|
||||
}
|
||||
}
|
||||
|
||||
void doShutdown()
|
||||
{
|
||||
jdns.shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("usage: jdns (options) uni [type] [name] (nameserver(;port)|mul ...)\n");
|
||||
printf(" jdns (options) mul [type] [name]\n");
|
||||
printf(" jdns (options) pub [items ...]\n");
|
||||
printf(" jdns sys\n");
|
||||
printf("\n");
|
||||
printf("options:\n");
|
||||
printf(" -d show debug output\n");
|
||||
printf(" -6 use ipv6\n");
|
||||
printf(" -q x quit x seconds after starting\n");
|
||||
printf("\n");
|
||||
printf("uni/mul types: a aaaa ptr srv mx txt hinfo cname any\n");
|
||||
printf("pub items: ptr:name,answer srv:name,answer,port a:name,ipaddr\n");
|
||||
printf(" txt:name,str0,...,strn aaaa:name,ipaddr\n");
|
||||
printf("\n");
|
||||
printf("examples:\n");
|
||||
printf(" jdns uni a jabber.org 192.168.0.1\n");
|
||||
printf(" jdns uni srv _xmpp-client._tcp.jabber.org 192.168.0.1;53\n");
|
||||
printf(" jdns uni 10 user@host._presence._tcp.local mul\n");
|
||||
printf(" jdns mul a foobar.local\n");
|
||||
printf(" jdns mul ptr _services._dns-sd._udp.local\n");
|
||||
printf(" jdns pub a:mybox.local.,192.168.0.55\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get args
|
||||
QStringList args;
|
||||
for(int n = 1; n < argc; ++n)
|
||||
args += QString(argv[n]);
|
||||
|
||||
bool opt_debug = false;
|
||||
bool opt_ipv6 = false;
|
||||
bool opt_quit = false;
|
||||
int quit_time = 0;
|
||||
QString mode, type, name, ipaddr;
|
||||
QStringList nslist;
|
||||
QList<QJDns::Record> pubitems;
|
||||
|
||||
// options
|
||||
for(int n = 0; n < args.count(); ++n)
|
||||
{
|
||||
if(args[n].left(1) == "-")
|
||||
{
|
||||
if(args[n] == "-d")
|
||||
opt_debug = true;
|
||||
else if(args[n] == "-6")
|
||||
opt_ipv6 = true;
|
||||
else if(args[n] == "-q")
|
||||
{
|
||||
if(n + 1 >= args.count())
|
||||
{
|
||||
printf("need to specify number of seconds\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x = args[n + 1].toInt();
|
||||
if(x < 1)
|
||||
x = 30;
|
||||
|
||||
opt_quit = true;
|
||||
quit_time = x;
|
||||
|
||||
args.removeAt(n + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad option\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
args.removeAt(n);
|
||||
--n; // adjust position
|
||||
}
|
||||
}
|
||||
|
||||
mode = args[0];
|
||||
if(mode == "uni" || mode == "mul")
|
||||
{
|
||||
if(args.count() < 3)
|
||||
{
|
||||
printf("not enough args\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
type = args[1];
|
||||
name = args[2];
|
||||
if(mode == "uni")
|
||||
{
|
||||
for(int n = 3; n < args.count(); ++n)
|
||||
nslist += QString(args[n]);
|
||||
}
|
||||
}
|
||||
else if(mode == "pub")
|
||||
{
|
||||
if(args.count() < 2)
|
||||
{
|
||||
printf("not enough args\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
for(int n = 1; n < args.count(); ++n)
|
||||
{
|
||||
QString arg = args[n];
|
||||
int at = arg.indexOf(':');
|
||||
if(at == -1)
|
||||
{
|
||||
printf("missing colon\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QString type = arg.mid(0, at).toLower();
|
||||
QString val = arg.mid(at + 1);
|
||||
if(type == "a")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for A type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QHostAddress host(list[1]);
|
||||
if(host.isNull() || host.protocol() != QAbstractSocket::IPv4Protocol)
|
||||
{
|
||||
printf("bad format for A type IP address\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::A;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = host;
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "aaaa")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for AAAA type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
QHostAddress host(list[1]);
|
||||
if(host.isNull() || host.protocol() != QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
printf("bad format for AAAA type IP address\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Aaaa;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = host;
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "srv")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 3)
|
||||
{
|
||||
printf("bad format for SRV type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Srv;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.name = list[1].toLatin1();
|
||||
rec.priority = 0;
|
||||
rec.weight = 0;
|
||||
rec.port = list[2].toInt();
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "ptr")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
if(list.count() != 2)
|
||||
{
|
||||
printf("bad format for PTR type\n");
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Ptr;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.name = list[1].toLatin1();
|
||||
pubitems += rec;
|
||||
}
|
||||
else if(type == "txt")
|
||||
{
|
||||
QStringList list = val.split(',');
|
||||
QList<QByteArray> texts;
|
||||
for(int n = 1; n < list.count(); ++n)
|
||||
texts += list[n].toLatin1();
|
||||
|
||||
QJDns::Record rec;
|
||||
rec.owner = list[0].toLatin1();
|
||||
rec.type = QJDns::Txt;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.texts = texts;
|
||||
pubitems += rec;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad record type [%s]\n", qPrintable(type));
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mode == "sys")
|
||||
{
|
||||
QJDns::SystemInfo info = QJDns::systemInfo();
|
||||
|
||||
printf("DNS System Information\n");
|
||||
printf(" Name Servers:\n");
|
||||
if(!info.nameServers.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.nameServers.count(); ++n)
|
||||
printf(" %s\n", qPrintable(info.nameServers[n].address.toString()));
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
printf(" Domains:\n");
|
||||
if(!info.domains.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.domains.count(); ++n)
|
||||
printf(" [%s]\n", info.domains[n].data());
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
printf(" Hosts:\n");
|
||||
if(!info.hosts.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < info.hosts.count(); ++n)
|
||||
{
|
||||
const QJDns::DnsHost &h = info.hosts[n];
|
||||
printf(" [%s] -> %s\n", h.name.data(), qPrintable(h.address.toString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" (None)\n");
|
||||
|
||||
QHostAddress addr;
|
||||
printf("Primary IPv4 Multicast Address: ");
|
||||
addr = QJDns::detectPrimaryMulticast(QHostAddress::Any);
|
||||
if(!addr.isNull())
|
||||
printf("%s\n", qPrintable(addr.toString()));
|
||||
else
|
||||
printf("(None)\n");
|
||||
printf("Primary IPv6 Multicast Address: ");
|
||||
addr = QJDns::detectPrimaryMulticast(QHostAddress::AnyIPv6);
|
||||
if(!addr.isNull())
|
||||
printf("%s\n", qPrintable(addr.toString()));
|
||||
else
|
||||
printf("(None)\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
App a;
|
||||
a.opt_debug = opt_debug;
|
||||
a.opt_ipv6 = opt_ipv6;
|
||||
a.opt_quit = opt_quit;
|
||||
a.quit_time = quit_time;
|
||||
a.mode = mode;
|
||||
a.type = type.toLower();
|
||||
a.name = name;
|
||||
a.ipaddr = ipaddr;
|
||||
a.nslist = nslist;
|
||||
a.pubitems = pubitems;
|
||||
QObject::connect(&a, SIGNAL(quit()), &app, SLOT(quit()));
|
||||
QTimer::singleShot(0, &a, SLOT(start()));
|
||||
app.exec();
|
||||
return 0;
|
||||
}
|
||||
908
iris-legacy/iris/irisnet/jdns/qjdns.cpp
Normal file
908
iris-legacy/iris/irisnet/jdns/qjdns.cpp
Normal file
|
|
@ -0,0 +1,908 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qjdns.h"
|
||||
|
||||
#include <time.h>
|
||||
#include "qjdns_sock.h"
|
||||
#include "jdns.h"
|
||||
|
||||
static jdns_string_t *qt2str(const QByteArray &in)
|
||||
{
|
||||
jdns_string_t *out = jdns_string_new();
|
||||
jdns_string_set(out, (const unsigned char *)in.data(), in.size());
|
||||
return out;
|
||||
}
|
||||
|
||||
static QByteArray str2qt(const jdns_string_t *in)
|
||||
{
|
||||
return QByteArray((const char *)in->data, in->size);
|
||||
}
|
||||
|
||||
static void qt2addr_set(jdns_address_t *addr, const QHostAddress &host)
|
||||
{
|
||||
if(host.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
jdns_address_set_ipv6(addr, host.toIPv6Address().c);
|
||||
else
|
||||
jdns_address_set_ipv4(addr, host.toIPv4Address());
|
||||
}
|
||||
|
||||
static jdns_address_t *qt2addr(const QHostAddress &host)
|
||||
{
|
||||
jdns_address_t *addr = jdns_address_new();
|
||||
qt2addr_set(addr, host);
|
||||
return addr;
|
||||
}
|
||||
|
||||
static QHostAddress addr2qt(const jdns_address_t *addr)
|
||||
{
|
||||
if(addr->isIpv6)
|
||||
return QHostAddress(addr->addr.v6);
|
||||
else
|
||||
return QHostAddress(addr->addr.v4);
|
||||
}
|
||||
|
||||
static QJDns::Record import_record(const jdns_rr_t *in)
|
||||
{
|
||||
QJDns::Record out;
|
||||
|
||||
out.owner = QByteArray((const char *)in->owner);
|
||||
out.ttl = in->ttl;
|
||||
out.type = in->type;
|
||||
out.rdata = QByteArray((const char *)in->rdata, in->rdlength);
|
||||
|
||||
// known
|
||||
if(in->haveKnown)
|
||||
{
|
||||
int type = in->type;
|
||||
|
||||
if(type == QJDns::A || type == QJDns::Aaaa)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.address = addr2qt(in->data.address);
|
||||
}
|
||||
else if(type == QJDns::Mx)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.name = QByteArray((const char *)in->data.server->name);
|
||||
out.priority = in->data.server->priority;
|
||||
}
|
||||
else if(type == QJDns::Srv)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.name = QByteArray((const char *)in->data.server->name);
|
||||
out.priority = in->data.server->priority;
|
||||
out.weight = in->data.server->weight;
|
||||
out.port = in->data.server->port;
|
||||
}
|
||||
else if(type == QJDns::Cname || type == QJDns::Ptr || type == QJDns::Ns)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.name = QByteArray((const char *)in->data.name);
|
||||
}
|
||||
else if(type == QJDns::Txt)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.texts.clear();
|
||||
for(int n = 0; n < in->data.texts->count; ++n)
|
||||
out.texts += str2qt(in->data.texts->item[n]);
|
||||
}
|
||||
else if(type == QJDns::Hinfo)
|
||||
{
|
||||
out.haveKnown = true;
|
||||
out.cpu = str2qt(in->data.hinfo.cpu);
|
||||
out.os = str2qt(in->data.hinfo.os);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static jdns_rr_t *export_record(const QJDns::Record &in)
|
||||
{
|
||||
jdns_rr_t *out = jdns_rr_new();
|
||||
|
||||
jdns_rr_set_owner(out, (const unsigned char *)in.owner.data());
|
||||
out->ttl = in.ttl;
|
||||
|
||||
// if we have known, use that
|
||||
if(in.haveKnown)
|
||||
{
|
||||
int type = in.type;
|
||||
|
||||
if(type == QJDns::A)
|
||||
{
|
||||
jdns_address_t *addr = qt2addr(in.address);
|
||||
jdns_rr_set_A(out, addr);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
else if(type == QJDns::Aaaa)
|
||||
{
|
||||
jdns_address_t *addr = qt2addr(in.address);
|
||||
jdns_rr_set_AAAA(out, addr);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
else if(type == QJDns::Mx)
|
||||
{
|
||||
jdns_rr_set_MX(out, (const unsigned char *)in.name.data(), in.priority);
|
||||
}
|
||||
else if(type == QJDns::Srv)
|
||||
{
|
||||
jdns_rr_set_SRV(out, (const unsigned char *)in.name.data(), in.port, in.priority, in.weight);
|
||||
}
|
||||
else if(type == QJDns::Cname)
|
||||
{
|
||||
jdns_rr_set_CNAME(out, (const unsigned char *)in.name.data());
|
||||
}
|
||||
else if(type == QJDns::Ptr)
|
||||
{
|
||||
jdns_rr_set_PTR(out, (const unsigned char *)in.name.data());
|
||||
}
|
||||
else if(type == QJDns::Txt)
|
||||
{
|
||||
jdns_stringlist_t *list = jdns_stringlist_new();
|
||||
for(int n = 0; n < in.texts.count(); ++n)
|
||||
{
|
||||
jdns_string_t *str = qt2str(in.texts[n]);
|
||||
jdns_stringlist_append(list, str);
|
||||
jdns_string_delete(str);
|
||||
}
|
||||
jdns_rr_set_TXT(out, list);
|
||||
jdns_stringlist_delete(list);
|
||||
}
|
||||
else if(type == QJDns::Hinfo)
|
||||
{
|
||||
jdns_string_t *cpu = qt2str(in.cpu);
|
||||
jdns_string_t *os = qt2str(in.os);
|
||||
jdns_rr_set_HINFO(out, cpu, os);
|
||||
jdns_string_delete(cpu);
|
||||
jdns_string_delete(os);
|
||||
}
|
||||
else if(type == QJDns::Ns)
|
||||
{
|
||||
jdns_rr_set_NS(out, (const unsigned char *)in.name.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
jdns_rr_set_record(out, in.type, (const unsigned char *)in.rdata.data(), in.rdata.size());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns::NameServer
|
||||
//----------------------------------------------------------------------------
|
||||
QJDns::NameServer::NameServer()
|
||||
{
|
||||
port = JDNS_UNICAST_PORT;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns::Record
|
||||
//----------------------------------------------------------------------------
|
||||
QJDns::Record::Record()
|
||||
{
|
||||
ttl = 0;
|
||||
type = -1;
|
||||
haveKnown = false;
|
||||
}
|
||||
|
||||
bool QJDns::Record::verify() const
|
||||
{
|
||||
jdns_rr_t *rr = export_record(*this);
|
||||
int ok = jdns_rr_verify(rr);
|
||||
jdns_rr_delete(rr);
|
||||
return (ok ? true : false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// QJDns
|
||||
//----------------------------------------------------------------------------
|
||||
static int my_srand_done = 0;
|
||||
|
||||
static void my_srand()
|
||||
{
|
||||
if(my_srand_done)
|
||||
return;
|
||||
|
||||
// lame attempt at randomizing without srand
|
||||
int count = ::time(NULL) % 128;
|
||||
for(int n = 0; n < count; ++n)
|
||||
rand();
|
||||
|
||||
my_srand_done = 1;
|
||||
}
|
||||
|
||||
class QJDns::Private : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class LateError
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
Error error;
|
||||
};
|
||||
|
||||
class LateResponse
|
||||
{
|
||||
public:
|
||||
int id;
|
||||
QJDns::Response response;
|
||||
};
|
||||
|
||||
QJDns *q;
|
||||
QJDns::Mode mode;
|
||||
jdns_session_t *sess;
|
||||
bool shutting_down;
|
||||
QTimer stepTrigger, debugTrigger;
|
||||
QTimer stepTimeout;
|
||||
QTime clock;
|
||||
QStringList debug_strings;
|
||||
bool new_debug_strings;
|
||||
int next_handle;
|
||||
bool need_handle;
|
||||
QHash<int,QUdpSocket*> socketForHandle;
|
||||
QHash<QUdpSocket*,int> handleForSocket;
|
||||
int pending;
|
||||
bool pending_wait;
|
||||
bool complete_shutdown;
|
||||
QList<LateError> lateErrors;
|
||||
|
||||
Private(QJDns *_q) : QObject(_q), q(_q), stepTrigger(this), debugTrigger(this), stepTimeout(this)
|
||||
{
|
||||
sess = 0;
|
||||
shutting_down = false;
|
||||
new_debug_strings = false;
|
||||
pending = 0;
|
||||
|
||||
connect(&stepTrigger, SIGNAL(timeout()), SLOT(doNextStepSlot()));
|
||||
stepTrigger.setSingleShot(true);
|
||||
|
||||
connect(&debugTrigger, SIGNAL(timeout()), SLOT(doDebug()));
|
||||
debugTrigger.setSingleShot(true);
|
||||
|
||||
connect(&stepTimeout, SIGNAL(timeout()), SLOT(st_timeout()));
|
||||
stepTimeout.setSingleShot(true);
|
||||
|
||||
my_srand();
|
||||
|
||||
clock.start();
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
if(sess)
|
||||
{
|
||||
jdns_session_delete(sess);
|
||||
sess = 0;
|
||||
}
|
||||
shutting_down = false;
|
||||
pending = 0;
|
||||
qDeleteAll(socketForHandle);
|
||||
socketForHandle.clear();
|
||||
handleForSocket.clear();
|
||||
stepTrigger.stop();
|
||||
stepTimeout.stop();
|
||||
need_handle = 0;
|
||||
}
|
||||
|
||||
bool init(QJDns::Mode _mode, const QHostAddress &address)
|
||||
{
|
||||
mode = _mode;
|
||||
|
||||
jdns_callbacks_t callbacks;
|
||||
callbacks.app = this;
|
||||
callbacks.time_now = cb_time_now;
|
||||
callbacks.rand_int = cb_rand_int;
|
||||
callbacks.debug_line = cb_debug_line;
|
||||
callbacks.udp_bind = cb_udp_bind;
|
||||
callbacks.udp_unbind = cb_udp_unbind;
|
||||
callbacks.udp_read = cb_udp_read;
|
||||
callbacks.udp_write = cb_udp_write;
|
||||
sess = jdns_session_new(&callbacks);
|
||||
next_handle = 1;
|
||||
need_handle = false;
|
||||
|
||||
int ret;
|
||||
|
||||
jdns_address_t *baddr = qt2addr(address);
|
||||
if(mode == Unicast)
|
||||
{
|
||||
ret = jdns_init_unicast(sess, baddr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
jdns_address_t *maddr;
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
maddr = jdns_address_multicast6_new();
|
||||
else
|
||||
maddr = jdns_address_multicast4_new();
|
||||
ret = jdns_init_multicast(sess, baddr, JDNS_MULTICAST_PORT, maddr);
|
||||
jdns_address_delete(maddr);
|
||||
}
|
||||
jdns_address_delete(baddr);
|
||||
|
||||
if(!ret)
|
||||
{
|
||||
jdns_session_delete(sess);
|
||||
sess = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void setNameServers(const QList<NameServer> &nslist)
|
||||
{
|
||||
jdns_nameserverlist_t *addrs = jdns_nameserverlist_new();
|
||||
for(int n = 0; n < nslist.count(); ++n)
|
||||
{
|
||||
jdns_address_t *addr = qt2addr(nslist[n].address);
|
||||
jdns_nameserverlist_append(addrs, addr, nslist[n].port);
|
||||
jdns_address_delete(addr);
|
||||
}
|
||||
jdns_set_nameservers(sess, addrs);
|
||||
jdns_nameserverlist_delete(addrs);
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
if(!stepTrigger.isActive())
|
||||
{
|
||||
stepTimeout.stop();
|
||||
stepTrigger.start();
|
||||
}
|
||||
}
|
||||
|
||||
void processDebug()
|
||||
{
|
||||
new_debug_strings = true;
|
||||
if(!debugTrigger.isActive())
|
||||
debugTrigger.start();
|
||||
}
|
||||
|
||||
void doNextStep()
|
||||
{
|
||||
if(shutting_down && complete_shutdown)
|
||||
{
|
||||
cleanup();
|
||||
emit q->shutdownFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
QPointer<QObject> self = this;
|
||||
|
||||
int ret = jdns_step(sess);
|
||||
|
||||
QList<LateError> errors;
|
||||
QList<int> published;
|
||||
QList<LateResponse> responses;
|
||||
bool finish_shutdown = false;
|
||||
|
||||
while(1)
|
||||
{
|
||||
jdns_event_t *e = jdns_next_event(sess);
|
||||
if(!e)
|
||||
break;
|
||||
|
||||
if(e->type == JDNS_EVENT_SHUTDOWN)
|
||||
{
|
||||
finish_shutdown = true;
|
||||
}
|
||||
else if(e->type == JDNS_EVENT_PUBLISH)
|
||||
{
|
||||
if(e->status != JDNS_STATUS_SUCCESS)
|
||||
{
|
||||
QJDns::Error error;
|
||||
if(e->status == JDNS_STATUS_CONFLICT)
|
||||
error = QJDns::ErrorConflict;
|
||||
else
|
||||
error = QJDns::ErrorGeneric;
|
||||
LateError le;
|
||||
le.id = e->id;
|
||||
le.error = error;
|
||||
errors += le;
|
||||
}
|
||||
else
|
||||
{
|
||||
published += e->id;
|
||||
}
|
||||
}
|
||||
else if(e->type == JDNS_EVENT_RESPONSE)
|
||||
{
|
||||
if(e->status != JDNS_STATUS_SUCCESS)
|
||||
{
|
||||
QJDns::Error error;
|
||||
if(e->status == JDNS_STATUS_NXDOMAIN)
|
||||
error = QJDns::ErrorNXDomain;
|
||||
else if(e->status == JDNS_STATUS_TIMEOUT)
|
||||
error = QJDns::ErrorTimeout;
|
||||
else
|
||||
error = QJDns::ErrorGeneric;
|
||||
LateError le;
|
||||
le.id = e->id;
|
||||
le.error = error;
|
||||
errors += le;
|
||||
}
|
||||
else
|
||||
{
|
||||
QJDns::Response out_response;
|
||||
for(int n = 0; n < e->response->answerCount; ++n)
|
||||
out_response.answerRecords += import_record(e->response->answerRecords[n]);
|
||||
LateResponse lr;
|
||||
lr.id = e->id;
|
||||
lr.response = out_response;
|
||||
responses += lr;
|
||||
}
|
||||
}
|
||||
|
||||
jdns_event_delete(e);
|
||||
}
|
||||
|
||||
if(ret & JDNS_STEP_TIMER)
|
||||
stepTimeout.start(jdns_next_timer(sess));
|
||||
else
|
||||
stepTimeout.stop();
|
||||
|
||||
need_handle = (ret & JDNS_STEP_HANDLE);
|
||||
|
||||
for(int n = 0; n < errors.count(); ++n)
|
||||
{
|
||||
emit q->error(errors[n].id, errors[n].error);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
for(int n = 0; n < published.count(); ++n)
|
||||
{
|
||||
emit q->published(published[n]);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
for(int n = 0; n < responses.count(); ++n)
|
||||
{
|
||||
emit q->resultsReady(responses[n].id, responses[n].response);
|
||||
if(!self)
|
||||
return;
|
||||
}
|
||||
|
||||
if(finish_shutdown)
|
||||
{
|
||||
// if we have pending udp packets to write, stick around
|
||||
if(pending > 0)
|
||||
{
|
||||
pending_wait = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
complete_shutdown = true;
|
||||
process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private slots:
|
||||
void udp_readyRead()
|
||||
{
|
||||
QUdpSocket *sock = (QUdpSocket *)sender();
|
||||
int handle = handleForSocket.value(sock);
|
||||
|
||||
if(need_handle)
|
||||
{
|
||||
jdns_set_handle_readable(sess, handle);
|
||||
process();
|
||||
}
|
||||
else
|
||||
{
|
||||
// eat packet
|
||||
QByteArray buf(4096, 0);
|
||||
QHostAddress from_addr;
|
||||
quint16 from_port;
|
||||
sock->readDatagram(buf.data(), buf.size(), &from_addr, &from_port);
|
||||
}
|
||||
}
|
||||
|
||||
void udp_bytesWritten(qint64)
|
||||
{
|
||||
if(pending > 0)
|
||||
{
|
||||
--pending;
|
||||
if(shutting_down && pending_wait && pending == 0)
|
||||
{
|
||||
pending_wait = false;
|
||||
complete_shutdown = true;
|
||||
process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void st_timeout()
|
||||
{
|
||||
doNextStep();
|
||||
}
|
||||
|
||||
void doNextStepSlot()
|
||||
{
|
||||
doNextStep();
|
||||
}
|
||||
|
||||
void doDebug()
|
||||
{
|
||||
if(new_debug_strings)
|
||||
{
|
||||
new_debug_strings = false;
|
||||
if(!debug_strings.isEmpty())
|
||||
emit q->debugLinesReady();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// jdns callbacks
|
||||
static int cb_time_now(jdns_session_t *, void *app)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
return self->clock.elapsed();
|
||||
}
|
||||
|
||||
static int cb_rand_int(jdns_session_t *, void *)
|
||||
{
|
||||
return rand() % 65536;
|
||||
}
|
||||
|
||||
static void cb_debug_line(jdns_session_t *, void *app, const char *str)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
self->debug_strings += QString::fromLatin1(str);
|
||||
self->processDebug();
|
||||
}
|
||||
|
||||
static int cb_udp_bind(jdns_session_t *, void *app, const jdns_address_t *addr, int port, const jdns_address_t *maddr)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
// we always pass non-null to jdns_init, so this should be a valid address
|
||||
QHostAddress host = addr2qt(addr);
|
||||
|
||||
QUdpSocket *sock = new QUdpSocket(self);
|
||||
self->connect(sock, SIGNAL(readyRead()), SLOT(udp_readyRead()));
|
||||
|
||||
// use queued for bytesWritten, since qt is evil and emits before writeDatagram returns
|
||||
qRegisterMetaType<qint64>("qint64");
|
||||
self->connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(udp_bytesWritten(qint64)), Qt::QueuedConnection);
|
||||
|
||||
QUdpSocket::BindMode mode;
|
||||
mode |= QUdpSocket::ShareAddress;
|
||||
mode |= QUdpSocket::ReuseAddressHint;
|
||||
if(!sock->bind(host, port, mode))
|
||||
{
|
||||
delete sock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(maddr)
|
||||
{
|
||||
int sd = sock->socketDescriptor();
|
||||
bool ok;
|
||||
int errorCode;
|
||||
if(maddr->isIpv6)
|
||||
ok = qjdns_sock_setMulticast6(sd, maddr->addr.v6, &errorCode);
|
||||
else
|
||||
ok = qjdns_sock_setMulticast4(sd, maddr->addr.v4, &errorCode);
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
delete sock;
|
||||
|
||||
self->debug_strings += QString("failed to setup multicast on the socket (errorCode=%1)").arg(errorCode);
|
||||
self->processDebug();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(maddr->isIpv6)
|
||||
{
|
||||
qjdns_sock_setTTL6(sd, 255);
|
||||
qjdns_sock_setIPv6Only(sd);
|
||||
}
|
||||
else
|
||||
qjdns_sock_setTTL4(sd, 255);
|
||||
}
|
||||
|
||||
int handle = self->next_handle++;
|
||||
self->socketForHandle.insert(handle, sock);
|
||||
self->handleForSocket.insert(sock, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void cb_udp_unbind(jdns_session_t *, void *app, int handle)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
QUdpSocket *sock = self->socketForHandle.value(handle);
|
||||
if(!sock)
|
||||
return;
|
||||
|
||||
self->socketForHandle.remove(handle);
|
||||
self->handleForSocket.remove(sock);
|
||||
delete sock;
|
||||
}
|
||||
|
||||
static int cb_udp_read(jdns_session_t *, void *app, int handle, jdns_address_t *addr, int *port, unsigned char *buf, int *bufsize)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
QUdpSocket *sock = self->socketForHandle.value(handle);
|
||||
if(!sock)
|
||||
return 0;
|
||||
|
||||
// nothing to read?
|
||||
if(!sock->hasPendingDatagrams())
|
||||
return 0;
|
||||
|
||||
QHostAddress from_addr;
|
||||
quint16 from_port;
|
||||
int ret = sock->readDatagram((char *)buf, *bufsize, &from_addr, &from_port);
|
||||
if(ret == -1)
|
||||
return 0;
|
||||
|
||||
qt2addr_set(addr, from_addr);
|
||||
*port = (int)from_port;
|
||||
*bufsize = ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cb_udp_write(jdns_session_t *, void *app, int handle, const jdns_address_t *addr, int port, unsigned char *buf, int bufsize)
|
||||
{
|
||||
QJDns::Private *self = (QJDns::Private *)app;
|
||||
|
||||
QUdpSocket *sock = self->socketForHandle.value(handle);
|
||||
if(!sock)
|
||||
return 0;
|
||||
|
||||
QHostAddress host = addr2qt(addr);
|
||||
int ret = sock->writeDatagram((const char *)buf, bufsize, host, port);
|
||||
if(ret == -1)
|
||||
{
|
||||
// this can happen if the datagram to send is too big. i'm not sure what else
|
||||
// may cause this. if we return 0, then jdns may try to resend the packet,
|
||||
// which might not work if it is too large (causing the same error over and
|
||||
// over). we'll return success to jdns, so the result is as if the packet
|
||||
// was dropped.
|
||||
return 1;
|
||||
}
|
||||
|
||||
++self->pending;
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
QJDns::QJDns(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private(this);
|
||||
}
|
||||
|
||||
QJDns::~QJDns()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool QJDns::init(Mode mode, const QHostAddress &address)
|
||||
{
|
||||
return d->init(mode, address);
|
||||
}
|
||||
|
||||
void QJDns::shutdown()
|
||||
{
|
||||
d->shutting_down = true;
|
||||
d->pending_wait = false;
|
||||
d->complete_shutdown = false;
|
||||
jdns_shutdown(d->sess);
|
||||
d->process();
|
||||
}
|
||||
|
||||
QStringList QJDns::debugLines()
|
||||
{
|
||||
QStringList tmp = d->debug_strings;
|
||||
d->debug_strings.clear();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
QJDns::SystemInfo QJDns::systemInfo()
|
||||
{
|
||||
SystemInfo out;
|
||||
jdns_dnsparams_t *params = jdns_system_dnsparams();
|
||||
for(int n = 0; n < params->nameservers->count; ++n)
|
||||
{
|
||||
NameServer ns;
|
||||
ns.address = addr2qt(params->nameservers->item[n]->address);
|
||||
out.nameServers += ns;
|
||||
}
|
||||
for(int n = 0; n < params->domains->count; ++n)
|
||||
out.domains += str2qt(params->domains->item[n]);
|
||||
for(int n = 0; n < params->hosts->count; ++n)
|
||||
{
|
||||
DnsHost h;
|
||||
h.name = str2qt(params->hosts->item[n]->name);
|
||||
h.address = addr2qt(params->hosts->item[n]->address);
|
||||
out.hosts += h;
|
||||
}
|
||||
jdns_dnsparams_delete(params);
|
||||
return out;
|
||||
}
|
||||
|
||||
#define PROBE_BASE 20000
|
||||
#define PROBE_RANGE 100
|
||||
|
||||
QHostAddress QJDns::detectPrimaryMulticast(const QHostAddress &address)
|
||||
{
|
||||
my_srand();
|
||||
|
||||
QUdpSocket *sock = new QUdpSocket;
|
||||
QUdpSocket::BindMode mode;
|
||||
mode |= QUdpSocket::ShareAddress;
|
||||
mode |= QUdpSocket::ReuseAddressHint;
|
||||
int port = -1;
|
||||
for(int n = 0; n < PROBE_RANGE; ++n)
|
||||
{
|
||||
if(sock->bind(address, PROBE_BASE + n, mode))
|
||||
{
|
||||
port = PROBE_BASE + n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(port == -1)
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
jdns_address_t *a;
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
a = jdns_address_multicast6_new();
|
||||
else
|
||||
a = jdns_address_multicast4_new();
|
||||
QHostAddress maddr = addr2qt(a);
|
||||
jdns_address_delete(a);
|
||||
|
||||
if(address.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
int x;
|
||||
if(!qjdns_sock_setMulticast6(sock->socketDescriptor(), maddr.toIPv6Address().c, &x))
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
qjdns_sock_setTTL6(sock->socketDescriptor(), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x;
|
||||
if(!qjdns_sock_setMulticast4(sock->socketDescriptor(), maddr.toIPv4Address(), &x))
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
qjdns_sock_setTTL4(sock->socketDescriptor(), 0);
|
||||
}
|
||||
|
||||
QHostAddress result;
|
||||
QByteArray out(128, 0);
|
||||
for(int n = 0; n < out.size(); ++n)
|
||||
out[n] = rand();
|
||||
if(sock->writeDatagram(out.data(), out.size(), maddr, port) == -1)
|
||||
{
|
||||
delete sock;
|
||||
return QHostAddress();
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
sock->waitForReadyRead(-1);
|
||||
QByteArray in(128, 0);
|
||||
QHostAddress from_addr;
|
||||
quint16 from_port;
|
||||
int ret = sock->readDatagram(in.data(), in.size(), &from_addr, &from_port);
|
||||
if(ret == -1)
|
||||
continue;
|
||||
if(from_port != port)
|
||||
continue;
|
||||
in.resize(ret);
|
||||
if(in.size() != out.size())
|
||||
continue;
|
||||
bool ok = true;
|
||||
for(int n = 0; n < in.size(); ++n)
|
||||
{
|
||||
if(in[n] != out[n])
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!ok)
|
||||
continue;
|
||||
|
||||
result = from_addr;
|
||||
break;
|
||||
}
|
||||
delete sock;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QJDns::setNameServers(const QList<NameServer> &list)
|
||||
{
|
||||
d->setNameServers(list);
|
||||
}
|
||||
|
||||
int QJDns::queryStart(const QByteArray &name, int type)
|
||||
{
|
||||
int id = jdns_query(d->sess, (const unsigned char *)name.data(), type);
|
||||
d->process();
|
||||
return id;
|
||||
}
|
||||
|
||||
void QJDns::queryCancel(int id)
|
||||
{
|
||||
jdns_cancel_query(d->sess, id);
|
||||
d->process();
|
||||
}
|
||||
|
||||
int QJDns::publishStart(PublishMode m, const Record &record)
|
||||
{
|
||||
jdns_rr_t *rr = export_record(record);
|
||||
|
||||
int pubmode;
|
||||
if(m == QJDns::Unique)
|
||||
pubmode = JDNS_PUBLISH_UNIQUE;
|
||||
else
|
||||
pubmode = JDNS_PUBLISH_SHARED;
|
||||
|
||||
int id = jdns_publish(d->sess, pubmode, rr);
|
||||
jdns_rr_delete(rr);
|
||||
d->process();
|
||||
return id;
|
||||
}
|
||||
|
||||
void QJDns::publishUpdate(int id, const Record &record)
|
||||
{
|
||||
jdns_rr_t *rr = export_record(record);
|
||||
|
||||
jdns_update_publish(d->sess, id, rr);
|
||||
jdns_rr_delete(rr);
|
||||
d->process();
|
||||
}
|
||||
|
||||
void QJDns::publishCancel(int id)
|
||||
{
|
||||
jdns_cancel_publish(d->sess, id);
|
||||
d->process();
|
||||
}
|
||||
|
||||
#include "qjdns.moc"
|
||||
158
iris-legacy/iris/irisnet/jdns/qjdns.h
Normal file
158
iris-legacy/iris/irisnet/jdns/qjdns.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// this is the Qt wrapper to jdns. it requires Qt 4.1+
|
||||
|
||||
#ifndef QJDNS_H
|
||||
#define QJDNS_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
|
||||
class QJDns : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode
|
||||
{
|
||||
Unicast,
|
||||
Multicast
|
||||
};
|
||||
|
||||
enum PublishMode
|
||||
{
|
||||
Unique,
|
||||
Shared
|
||||
};
|
||||
|
||||
enum Type
|
||||
{
|
||||
A = 1,
|
||||
Aaaa = 28,
|
||||
Mx = 15,
|
||||
Srv = 33,
|
||||
Cname = 5,
|
||||
Ptr = 12,
|
||||
Txt = 16,
|
||||
Hinfo = 13,
|
||||
Ns = 2,
|
||||
Any = 255
|
||||
};
|
||||
|
||||
enum Error
|
||||
{
|
||||
ErrorGeneric,
|
||||
ErrorNXDomain, // query only
|
||||
ErrorTimeout, // query only
|
||||
ErrorConflict // publish only
|
||||
};
|
||||
|
||||
class NameServer
|
||||
{
|
||||
public:
|
||||
QHostAddress address;
|
||||
int port;
|
||||
|
||||
NameServer();
|
||||
};
|
||||
|
||||
class DnsHost
|
||||
{
|
||||
public:
|
||||
QByteArray name;
|
||||
QHostAddress address;
|
||||
};
|
||||
|
||||
class SystemInfo
|
||||
{
|
||||
public:
|
||||
QList<NameServer> nameServers;
|
||||
QList<QByteArray> domains;
|
||||
QList<DnsHost> hosts;
|
||||
};
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
QByteArray owner;
|
||||
int ttl;
|
||||
int type;
|
||||
QByteArray rdata;
|
||||
bool haveKnown;
|
||||
|
||||
// known
|
||||
QHostAddress address; // for A, Aaaa
|
||||
QByteArray name; // for Mx, Srv, Cname, Ptr, Ns
|
||||
int priority; // for Mx, Srv
|
||||
int weight; // for Srv
|
||||
int port; // for Srv
|
||||
QList<QByteArray> texts; // for Txt
|
||||
QByteArray cpu; // for Hinfo
|
||||
QByteArray os; // for Hinfo
|
||||
|
||||
Record();
|
||||
bool verify() const;
|
||||
};
|
||||
|
||||
class Response
|
||||
{
|
||||
public:
|
||||
QList<Record> answerRecords;
|
||||
QList<Record> authorityRecords;
|
||||
QList<Record> additionalRecords;
|
||||
};
|
||||
|
||||
QJDns(QObject *parent = 0);
|
||||
~QJDns();
|
||||
|
||||
bool init(Mode mode, const QHostAddress &address);
|
||||
void shutdown();
|
||||
QStringList debugLines();
|
||||
|
||||
static SystemInfo systemInfo();
|
||||
static QHostAddress detectPrimaryMulticast(const QHostAddress &address);
|
||||
|
||||
void setNameServers(const QList<NameServer> &list);
|
||||
|
||||
int queryStart(const QByteArray &name, int type);
|
||||
void queryCancel(int id);
|
||||
|
||||
// for multicast mode only
|
||||
int publishStart(PublishMode m, const Record &record);
|
||||
void publishUpdate(int id, const Record &record);
|
||||
void publishCancel(int id);
|
||||
|
||||
signals:
|
||||
void resultsReady(int id, const QJDns::Response &results);
|
||||
void published(int id);
|
||||
void error(int id, QJDns::Error e);
|
||||
void shutdownFinished();
|
||||
void debugLinesReady();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
friend class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
#endif
|
||||
184
iris-legacy/iris/irisnet/jdns/qjdns_sock.cpp
Normal file
184
iris-legacy/iris/irisnet/jdns/qjdns_sock.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qjdns_sock.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
# include <signal.h>
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_IPV6
|
||||
# define HAVE_IPV6
|
||||
# ifndef IPPROTO_IPV6
|
||||
# define IPPROTO_IPV6 41
|
||||
struct in6_addr
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char _S6_u8[16];
|
||||
unsigned short _S6_u16[8];
|
||||
unsigned long _S6_u32[4];
|
||||
} _S6_un;
|
||||
};
|
||||
# define s6_addr _S6_un._S6_u8
|
||||
# endif
|
||||
# ifndef IPV6_JOIN_GROUP
|
||||
# define IPV6_JOIN_GROUP 12
|
||||
# define IPV6_MULTICAST_HOPS 10
|
||||
struct ipv6_mreq
|
||||
{
|
||||
struct in6_addr ipv6mr_multiaddr;
|
||||
unsigned int ipv6mr_interface;
|
||||
};
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int get_last_error()
|
||||
{
|
||||
int x;
|
||||
#ifdef Q_OS_WIN
|
||||
x = WSAGetLastError();
|
||||
#else
|
||||
x = errno;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setMulticast4(int s, unsigned long int addr, int *errorCode)
|
||||
{
|
||||
int ret;
|
||||
struct ip_mreq mc;
|
||||
|
||||
memset(&mc, 0, sizeof(mc));
|
||||
mc.imr_multiaddr.s_addr = htonl(addr);
|
||||
mc.imr_interface.s_addr = INADDR_ANY;
|
||||
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mc, sizeof(mc));
|
||||
if(ret != 0)
|
||||
{
|
||||
if(errorCode)
|
||||
*errorCode = get_last_error();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setMulticast6(int s, unsigned char *addr, int *errorCode)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
int ret;
|
||||
struct ipv6_mreq mc;
|
||||
|
||||
memset(&mc, 0, sizeof(mc));
|
||||
memcpy(mc.ipv6mr_multiaddr.s6_addr, addr, 16);
|
||||
mc.ipv6mr_interface = 0;
|
||||
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&mc, sizeof(mc));
|
||||
if(ret != 0)
|
||||
{
|
||||
if(errorCode)
|
||||
*errorCode = get_last_error();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
Q_UNUSED(addr);
|
||||
Q_UNUSED(errorCode);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool qjdns_sock_setTTL4(int s, int ttl)
|
||||
{
|
||||
unsigned char cttl;
|
||||
int ret, ittl;
|
||||
|
||||
cttl = ttl;
|
||||
ittl = ttl;
|
||||
|
||||
// IP_MULTICAST_TTL might take 1 byte or 4, try both
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&cttl, sizeof(cttl));
|
||||
if(ret != 0)
|
||||
{
|
||||
ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ittl, sizeof(ittl));
|
||||
if(ret != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qjdns_sock_setTTL6(int s, int ttl)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
unsigned char cttl;
|
||||
int ret, ittl;
|
||||
|
||||
cttl = ttl;
|
||||
ittl = ttl;
|
||||
|
||||
// IPV6_MULTICAST_HOPS might take 1 byte or 4, try both
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&cttl, sizeof(cttl));
|
||||
if(ret != 0)
|
||||
{
|
||||
ret = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&ittl, sizeof(ittl));
|
||||
if(ret != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
Q_UNUSED(ttl);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool qjdns_sock_setIPv6Only(int s)
|
||||
{
|
||||
#if defined(HAVE_IPV6) && defined(IPV6_V6ONLY)
|
||||
int x = 1;
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&x, sizeof(x)) != 0)
|
||||
return false;
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(s);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
33
iris-legacy/iris/irisnet/jdns/qjdns_sock.h
Normal file
33
iris-legacy/iris/irisnet/jdns/qjdns_sock.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2005,2006 Justin Karneges
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QJDNS_SOCK_H
|
||||
#define QJDNS_SOCK_H
|
||||
|
||||
bool qjdns_sock_setMulticast4(int s, unsigned long int addr, int *errorCode);
|
||||
bool qjdns_sock_setMulticast6(int s, unsigned char *addr, int *errorCode);
|
||||
bool qjdns_sock_setTTL4(int s, int ttl);
|
||||
bool qjdns_sock_setTTL6(int s, int ttl);
|
||||
bool qjdns_sock_setIPv6Only(int s);
|
||||
|
||||
#endif
|
||||
1201
iris-legacy/iris/irisnet/jdnsshared.cpp
Normal file
1201
iris-legacy/iris/irisnet/jdnsshared.cpp
Normal file
File diff suppressed because it is too large
Load diff
511
iris-legacy/iris/irisnet/jdnsshared.h
Normal file
511
iris-legacy/iris/irisnet/jdnsshared.h
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
* Copyright (C) 2006,2007 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef JDNSSHARED_H
|
||||
#define JDNSSHARED_H
|
||||
|
||||
#include "jdns/qjdns.h"
|
||||
|
||||
class JDnsShared;
|
||||
class JDnsSharedPrivate;
|
||||
class JDnsSharedRequestPrivate;
|
||||
class JDnsSharedDebugPrivate;
|
||||
|
||||
/**
|
||||
\brief Collects debugging information from JDnsShared
|
||||
|
||||
\note Iris users should utilize NetNames for DNS capabilities, <i>not</i> JDnsSharedDebug. See the JDnsShared documentation for more information.
|
||||
|
||||
JDnsSharedDebug is used to collect debugging information from one or many JDnsShared objects. To use it, simply create it and pass it to JDnsShared::setDebug().
|
||||
|
||||
Example use:
|
||||
|
||||
\code
|
||||
JDnsSharedDebug *db = new JDnsSharedDebug;
|
||||
connect(db, SIGNAL(debugLinesReady(const QStringList &)),
|
||||
SLOT(db_debugLinesReady(const QStringList &)));
|
||||
|
||||
JDnsShared *jdnsShared1 = new JDnsShared(JDnsShared::UnicastInternet);
|
||||
jdnsShared1->setDebug(db, "U");
|
||||
|
||||
JDnsShared *jdnsShared2 = new JDnsShared(JDnsShared::UnicastLocal);
|
||||
jdnsShared2->setDebug(db, "L");
|
||||
...
|
||||
void db_debugLinesReady(const QStringList &lines)
|
||||
{
|
||||
foreach(QString line, lines)
|
||||
printf("%s\n", qPrintable(line));
|
||||
}
|
||||
\endcode
|
||||
|
||||
JDnsShared reports debug lines with the name and interface number prepended to each line. For example, if there is debug information to report about the second interface added to \a jdnsShared2 in the above example, the lines would be prepended with "L1: ".
|
||||
|
||||
Do not destroy JDnsSharedDebug until all of the JDnsShared objects associated with it have been destroyed.
|
||||
|
||||
\sa JDnsShared JDnsSharedRequest
|
||||
*/
|
||||
class JDnsSharedDebug : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
\brief Constructs a new object with the given \a parent
|
||||
*/
|
||||
JDnsSharedDebug(QObject *parent = 0);
|
||||
|
||||
/**
|
||||
\brief Destroys the object
|
||||
*/
|
||||
~JDnsSharedDebug();
|
||||
|
||||
/**
|
||||
\brief Read the available debug information
|
||||
|
||||
Debug information is reported as a series of lines. The lines are of reasonable length, and so if you're storing a backlog of the most recent debug information, it should be safe to make the cut-off point based on lines.
|
||||
|
||||
\sa readyRead
|
||||
*/
|
||||
QStringList readDebugLines();
|
||||
|
||||
signals:
|
||||
/**
|
||||
\brief Emitted when there is debug information to report
|
||||
|
||||
\sa readDebugLines
|
||||
*/
|
||||
void readyRead();
|
||||
|
||||
private:
|
||||
friend class JDnsShared;
|
||||
friend class JDnsSharedPrivate;
|
||||
friend class JDnsSharedDebugPrivate;
|
||||
JDnsSharedDebugPrivate *d;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Performs a DNS operation using JDnsShared
|
||||
|
||||
\note Iris users should utilize NetNames for DNS capabilities, <i>not</i> JDnsSharedRequest. See the JDnsShared documentation for more information.
|
||||
|
||||
JDnsSharedRequest is used to perform DNS operations on a JDnsShared object. Many requests may be performed simultaneously, such that a single JDnsShared object can be "shared" across the application. Please see the JDnsShared documentation for more complete information about how the overall system works.
|
||||
|
||||
Call query() to perform a query. Call publish() (or publishUpdate()) to make DNS records available on the local network (JDnsShared::Multicast mode only). When the operation has something to report, the resultsReady() signal is emitted. Call success() to determine the status of the operation. If success() returns false, then the operation has failed and the reason for the failure can be determined with error(). If success() returns true, then the meaning differs depending on the type of operation being performed:
|
||||
<ul>
|
||||
<li>For JDnsShared::UnicastInternet and JDnsShared::UnicastLocal modes, call results() to obtain the records obtained by the query. In these modes, resultsReady() is only emitted once, at which point the operation is no longer active.</li>
|
||||
<li>For JDnsShared::Multicast, operations are long-lived. Query operations never timeout, and resultsReady() may be emitted multiple times. In order to stop the query, either call cancel() or destroy the JDnsSharedRequest object. Similarly, publishing is long-lived. The record stays published as long as the JDnsSharedRequest has not been cancelled or destroyed.</li>
|
||||
</ul>
|
||||
|
||||
Here is how you might look up an A record:
|
||||
|
||||
\code
|
||||
JDnsSharedRequest *req = new JDnsSharedRequest(jdnsShared);
|
||||
connect(req, SIGNAL(resultsReady()), SLOT(req_resultsReady()));
|
||||
req->query("psi-im.org", QJDns::A);
|
||||
...
|
||||
void req_resultsReady()
|
||||
{
|
||||
if(req->success())
|
||||
{
|
||||
// print all of the IP addresses obtained
|
||||
QList<QJDns::Record> results = req->results();
|
||||
foreach(QJDns::Record r, results)
|
||||
{
|
||||
if(r.type == QJDns::A)
|
||||
printf("%s\n", qPrintable(r.address.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("Error resolving!\n");
|
||||
}
|
||||
\endcode
|
||||
|
||||
Here is an example of publishing a record:
|
||||
|
||||
\code
|
||||
JDnsSharedRequest *pub = new JDnsSharedRequest(jdnsShared);
|
||||
connect(pub, SIGNAL(resultsReady()), SLOT(pub_resultsReady()));
|
||||
|
||||
// let's publish an A record
|
||||
QJDns::Record rec;
|
||||
rec.owner = "SomeComputer.local.";
|
||||
rec.type = QJDns::A;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = QHostAddress("192.168.0.32");
|
||||
|
||||
pub->publish(QJDns::Unique, rec);
|
||||
...
|
||||
void pub_resultsReady()
|
||||
{
|
||||
if(pub->success())
|
||||
printf("Record published\n");
|
||||
else
|
||||
printf("Error publishing!\n");
|
||||
}
|
||||
\endcode
|
||||
|
||||
To update an existing record, use publishUpdate():
|
||||
|
||||
\code
|
||||
// the IP address of the host changed, so make a new record
|
||||
QJDns::Record rec;
|
||||
rec.owner = "SomeComputer.local.";
|
||||
rec.type = QJDns::A;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = QHostAddress("192.168.0.64");
|
||||
|
||||
// update it
|
||||
pub->publishUpdate(rec);
|
||||
\endcode
|
||||
|
||||
As a special exception, the address value can be left unspecified for A and Aaaa record types, which tells JDnsShared to substitute the address value with the address of whatever interfaces the record gets published on. This is the preferred way to publish the IP address of your own machine, and in fact it is the only way to do so if you have multiple interfaces, because there will likely be a different IP address value for each interface (the record resolves to a different answer depending on which interface a query comes from).
|
||||
|
||||
\code
|
||||
// let's publish our own A record
|
||||
QJDns::Record rec;
|
||||
rec.owner = "MyComputer.local.";
|
||||
rec.type = QJDns::A;
|
||||
rec.ttl = 120;
|
||||
rec.haveKnown = true;
|
||||
rec.address = QHostAddress();
|
||||
|
||||
pub->publish(QJDns::Unique, rec);
|
||||
\endcode
|
||||
|
||||
When you want to unpublish, call cancel() or destroy the JDnsSharedRequest.
|
||||
|
||||
\sa JDnsShared
|
||||
*/
|
||||
class JDnsSharedRequest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
\brief Operation type
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
Query, ///< Query operation, initiated by query()
|
||||
Publish ///< Publish operation, initiated by publish() or publishUpdate()
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Request error
|
||||
*/
|
||||
enum Error
|
||||
{
|
||||
ErrorNoNet, ///< There are no available network interfaces to operate on. This happens if JDnsShared::addInterface() was not called.
|
||||
ErrorGeneric, ///< Generic error during the operation.
|
||||
ErrorNXDomain, ///< The name looked up does not exist.
|
||||
ErrorTimeout, ///< The operation timed out.
|
||||
ErrorConflict ///< Attempt to publish an already published unique record.
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Constructs a new object with the given \a jdnsShared and \a parent
|
||||
*/
|
||||
JDnsSharedRequest(JDnsShared *jdnsShared, QObject *parent = 0);
|
||||
|
||||
/**
|
||||
\brief Destroys the object
|
||||
|
||||
If there is an active operation, it is cancelled.
|
||||
*/
|
||||
~JDnsSharedRequest();
|
||||
|
||||
/**
|
||||
\brief The type of operation being performed
|
||||
*/
|
||||
Type type();
|
||||
|
||||
/**
|
||||
\brief Perform a query operation
|
||||
*/
|
||||
void query(const QByteArray &name, int type);
|
||||
|
||||
/**
|
||||
\brief Perform a publish operation
|
||||
*/
|
||||
void publish(QJDns::PublishMode m, const QJDns::Record &record);
|
||||
|
||||
/**
|
||||
\brief Update a record that is currently published
|
||||
*/
|
||||
void publishUpdate(const QJDns::Record &record);
|
||||
|
||||
/**
|
||||
\brief Cancels the current operation
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
\brief Indicates whether or not the operation was successful
|
||||
*/
|
||||
bool success() const;
|
||||
|
||||
/**
|
||||
\brief Returns the reason for error
|
||||
*/
|
||||
Error error() const;
|
||||
|
||||
/**
|
||||
\brief Returns the results of the operation
|
||||
*/
|
||||
QList<QJDns::Record> results() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
\brief Indicates that the operation has something to report
|
||||
|
||||
After receiving this signal, call success() to check on the status of the operation, followed by results() or error() as appropriate.
|
||||
*/
|
||||
void resultsReady();
|
||||
|
||||
private:
|
||||
friend class JDnsShared;
|
||||
friend class JDnsSharedPrivate;
|
||||
friend class JDnsSharedRequestPrivate;
|
||||
JDnsSharedRequestPrivate *d;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Abstraction layer on top of QJDns
|
||||
|
||||
\note Iris users should utilize NetNames for DNS capabilities, <i>not</i> JDnsShared. JDnsShared is provided for non-Iris users (and it is also used internally by NetNames). To use JDnsShared by itself, simply drop the jdnsshared.h and jdnsshared.cpp files, along with JDNS, into your project. It is not a full replacement for Qt's Q3Dns, as some tasks are left to you, but it covers most of it.
|
||||
|
||||
QJDns supports everything a typical application should ever need in DNS. However, it is expected that modern applications will need to maintain multiple QJDns instances at the same time, and this is where things can get complicated. For example, most applications will want at least two QJDns instances: one for IPv4 unicast and one for IPv6 unicast.
|
||||
|
||||
A single JDnsShared object encapsulates multiple instances of QJDns that are related. For example, an IPv4 unicast instance and an IPv6 unicast instance could be coupled within JDnsShared. Then, when a unicast operation is performed on the JDnsShared object, both underlying instances will be queried as appropriate. The application itself would not need to perform two resolutions itself, nor deal with any related complexity.
|
||||
|
||||
Further, individual operations are performed using a separate class called JDnsSharedRequest, eliminating the need for the application to directly interface with a central QJDns object or track integer handles. This makes it easier for individual parts of the application to "share" the same instance (or set of instances) of QJDns, hence the name.
|
||||
|
||||
JDnsShared is a thin abstraction. QJDns subtypes (e.g. QJDns::Record, QJDns::NameServer, etc) are still used with JDnsShared. Because of the duplication of documentation effort between NetNames and QJDns, there is no formal documentation for QJDns. Users of JDnsShared will need to read qjdns.h, although a basic explanation of the elements can be found below.
|
||||
|
||||
Types:
|
||||
<table>
|
||||
<tr><td>QJDns::Type</td><td>This is a convenience enumeration for common DNS record types. For example: A, Aaaa, Srv, etc. The values directly map to the integer values of the DNS protocol (e.g. Srv = 33). See qjdns.h for all of the types and values.</td></tr>
|
||||
<tr><td>QJDns::Record</td><td>This class holds a DNS record. The main fields are <i>type</i> (integer type, probably something listed in QJDns::Type), <i>rdata</i> (QByteArray of the record value), and <i>haveKnown</i> (boolean to indicate if a decoded form of the record value is also available). See qjdns.h for the possible known fields. You will most-likely always work with known types. Received records that have a type listed in QJDns::Type are guaranteed to be known and will provide a decoded value. If you are creating a record for publishing, you will need to set <i>owner</i>, <i>ttl</i>, and <i>type</i>. If the type to be published is listed in QJDns::Type, then you will need to set <i>haveKnown</i> to true and set the known fields as appropriate, otherwise you need to set <i>rdata</i>. You do not need to supply an encoded form in <i>rdata</i> for known types, it can be left empty in that case.</td></tr>
|
||||
<tr><td>QJDns::PublishMode</td><td>This is for Multicast DNS, and can either be Unique or Shared. A shared record can be published by multiple owners (for example, a "_ssh._tcp.local." PTR record might resolve to many different SSH services owned by different machines). A unique record can only have one owner (for example, a "mycomputer.local." A record would resolve to the IP address of the machine that published it). Attempting to publish a record on a network where a unique record is already present will result in a conflict error.</td></tr>
|
||||
</table>
|
||||
|
||||
Functions:
|
||||
<table>
|
||||
<tr><td>QJDns::detectPrimaryMulticast()</td><td>Detects a multicast interface. Pass QHostAddress::Any or QHostAddress::AnyIPv6, depending on which type of interface is desired.</td></tr>
|
||||
</table>
|
||||
|
||||
To use JDnsShared, first create an instance of it, set it up by calling addInterface() as necessary, and then use JDnsSharedRequest to perform operations on it.
|
||||
|
||||
Here is an example of how to create and set up a JDnsShared object for typical DNS resolution:
|
||||
|
||||
\code
|
||||
// construct
|
||||
JDnsShared *dns = new JDnsShared(JDnsShared::UnicastInternet);
|
||||
|
||||
// add IPv4 and IPv6 interfaces
|
||||
dns->addInterface(QHostAddress::Any);
|
||||
dns->addInterface(QHostAddress::AnyIPv6);
|
||||
|
||||
// at this point, the object is ready for operation
|
||||
\endcode
|
||||
|
||||
Perform a resolution like this:
|
||||
|
||||
\code
|
||||
JDnsSharedRequest *req = new JDnsSharedRequest(dns);
|
||||
connect(req, SIGNAL(resultsReady()), SLOT(req_resultsReady()));
|
||||
req->query("psi-im.org", QJDns::A);
|
||||
...
|
||||
void req_resultsReady()
|
||||
{
|
||||
if(req->success())
|
||||
{
|
||||
// print all of the IP addresses obtained
|
||||
QList<QJDns::Record> results = req->results();
|
||||
foreach(QJDns::Record r, results)
|
||||
{
|
||||
if(r.type == QJDns::A)
|
||||
printf("%s\n", qPrintable(r.address.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("Error resolving!\n");
|
||||
}
|
||||
\endcode
|
||||
|
||||
It is important to filter the results as shown in the above example. QJDns guarantees at least one record in the results will be of the type queried for, but there may also be CNAME records present (of course, if the query was for a CNAME type, then the results will only be CNAME records). The recommended approach is to simply filter for the record types desired, as shown, rather than single out CNAME specifically.
|
||||
|
||||
When you are finished with a JDnsShared object, it should be shut down before deleting:
|
||||
|
||||
\code
|
||||
connect(dns, SIGNAL(shutdownFinished()), SLOT(dns_shutdownFinished()));
|
||||
dns->shutdown();
|
||||
...
|
||||
void dns_shutdownFinished()
|
||||
{
|
||||
delete dns;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Setting up JDnsShared for UnicastLocal and Multicast mode is done the same way as with UnicastInternet.
|
||||
|
||||
For example, here is how Multicast mode could be set up:
|
||||
|
||||
\code
|
||||
// construct
|
||||
JDnsShared *dns = new JDnsShared(JDnsShared::Multicast);
|
||||
|
||||
// add IPv4 interface
|
||||
QHostAddress addr = QJDns::detectPrimaryMulticast(QHostAddress::Any);
|
||||
dns->addInterface(addr);
|
||||
|
||||
// at this point, the object is ready for operation
|
||||
\endcode
|
||||
|
||||
JDnsShared provides a lot of functionality, but certain aspects of DNS are deemed out of its scope. Below are the responsibilities of the user of JDnsShared, if a more complete DNS behavior is desired:
|
||||
<ul>
|
||||
<li>Querying for several "qualified" names. You should first query for the name as provided, and if that fails then query for name + ".domain" (for every domain the computer is in). See domains().</li>
|
||||
<li>Detecting for ".local" in the name to be queried, and using that to decide whether to query via Multicast/UnicastLocal or UnicastInternet.</li>
|
||||
<li>For zeroconf/Bonjour, keep in mind that JDnsShared only provides low-level record queries. DNS-SD and any higher layers would be your job.</li>
|
||||
</ul>
|
||||
|
||||
Using a custom DNS implementation, such as JDnsShared, has the drawback that it is difficult to take advantage of platform-specific features (for example, an OS-wide DNS cache or LDAP integration). An application strategy for normal DNS should probably be:
|
||||
<ul>
|
||||
<li>If an A or AAAA record is desired, use a native lookup.</li>
|
||||
<li>Else, if the platform has advanced DNS features already (ie, res_query), use those.</li>
|
||||
<li>Else, use JDnsShared.</li>
|
||||
</ul>
|
||||
|
||||
For Multicast DNS, awareness of the platform is doubly important. There should only be one Multicast DNS "Responder" per computer, and using JDnsShared in Multicast mode at the same time could result in a conflict. An application strategy for Multicast DNS should be:
|
||||
<ul>
|
||||
<li>If the platform has a Multicast DNS daemon installed already, use it somehow.</li>
|
||||
<li>Else, use JDnsShared.</li>
|
||||
</ul>
|
||||
|
||||
\sa JDnsSharedRequest
|
||||
*/
|
||||
class JDnsShared : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
\brief The mode to operate in
|
||||
*/
|
||||
enum Mode
|
||||
{
|
||||
/**
|
||||
For regular DNS resolution. In this mode, lookups are performed on all interfaces, and the first returned result is used.
|
||||
*/
|
||||
UnicastInternet,
|
||||
|
||||
/**
|
||||
Perform regular DNS resolution using the Multicast DNS address. This is used to resolve large and/or known Multicast DNS names without actually multicasting anything.
|
||||
*/
|
||||
UnicastLocal,
|
||||
|
||||
/**
|
||||
Multicast DNS querying and publishing.
|
||||
|
||||
\note JDnsShared supports up to one interface for each IP version (e.g. one IPv4 interface and one IPv6 interface), and expects the default/primary multicast interface for that IP version to be used.
|
||||
*/
|
||||
Multicast
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Constructs a new object with the given \a mode and \a parent
|
||||
*/
|
||||
JDnsShared(Mode mode, QObject *parent = 0);
|
||||
|
||||
/**
|
||||
\brief Destroys the object
|
||||
*/
|
||||
~JDnsShared();
|
||||
|
||||
/**
|
||||
\brief Sets the debug object to report to
|
||||
|
||||
If a debug object is set using this function, then JDnsShared will send output text to it, prefixing each line with \a name.
|
||||
*/
|
||||
void setDebug(JDnsSharedDebug *db, const QString &name);
|
||||
|
||||
/**
|
||||
\brief Adds an interface to operate on
|
||||
|
||||
For UnicastInternet and UnicastLocal, these will almost always be QHostAddress::Any or QHostAddress::AnyIPv6 (operate on the default interface for IPv4 or IPv6, respectively).
|
||||
|
||||
For Multicast, it is expected that the default/primary multicast interface will be used here. Do not pass QHostAddress::Any (or AnyIPv6) with Multicast mode.
|
||||
|
||||
Returns true if the interface was successfully added, otherwise returns false.
|
||||
*/
|
||||
bool addInterface(const QHostAddress &addr);
|
||||
|
||||
/**
|
||||
\brief Removes a previously-added interface
|
||||
*/
|
||||
void removeInterface(const QHostAddress &addr);
|
||||
|
||||
/**
|
||||
\brief Shuts down the object
|
||||
|
||||
This operation primarily exists for Multicast mode, so that any published records have a chance to be unpublished. If the JDnsShared object is simply deleted without performing a shutdown, then published records will linger on the network until their TTLs expire.
|
||||
|
||||
When shutdown is complete, the shutdownFinished() signal will be emitted.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
\brief The domains to search in
|
||||
|
||||
You should perform a separate resolution for every domain configured on this machine.
|
||||
*/
|
||||
static QList<QByteArray> domains();
|
||||
|
||||
/**
|
||||
\brief Performs a blocking shutdown of many JDnsShared instances
|
||||
|
||||
This function is a convenient way to shutdown multiple JDnsShared instances synchronously. This function blocks, although the internal shutdown procedure uses no more than a few cycles of the eventloop, so it should be safe to call without worry of the application being overly stalled. This function takes over the instances passed to it, and will delete them upon completion.
|
||||
|
||||
Additionally, this function works without a nested eventloop. All of the JDnsShared instances are moved into a temporary thread to perform the shutdown procedure.
|
||||
|
||||
\code
|
||||
QList<JDnsShared*> list;
|
||||
list += jdnsShared_unicast;
|
||||
list += jdnsShared_multicast;
|
||||
JDnsShared::waitForShutdown(list);
|
||||
|
||||
// collect remaining debug information
|
||||
QStringList finalDebugLines = jdnsSharedDebug.readDebugLines();
|
||||
\endcode
|
||||
*/
|
||||
static void waitForShutdown(const QList<JDnsShared*> instances);
|
||||
|
||||
signals:
|
||||
/**
|
||||
\brief Indicates the object has been shut down
|
||||
*/
|
||||
void shutdownFinished();
|
||||
|
||||
private:
|
||||
friend class JDnsSharedRequest;
|
||||
friend class JDnsSharedPrivate;
|
||||
JDnsSharedPrivate *d;
|
||||
};
|
||||
|
||||
#endif
|
||||
13
iris-legacy/iris/irisnet/legacy/legacy.pri
Normal file
13
iris-legacy/iris/irisnet/legacy/legacy.pri
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/safedelete.h \
|
||||
$$PWD/ndns.h \
|
||||
$$PWD/srvresolver.h \
|
||||
$$PWD/servsock.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/safedelete.cpp \
|
||||
$$PWD/ndns.cpp \
|
||||
$$PWD/srvresolver.cpp \
|
||||
$$PWD/servsock.cpp
|
||||
147
iris-legacy/iris/irisnet/legacy/ndns.cpp
Normal file
147
iris-legacy/iris/irisnet/legacy/ndns.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* ndns.cpp - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
//! \class NDns ndns.h
|
||||
//! \brief Simple DNS resolution using native system calls
|
||||
//!
|
||||
//! This class is to be used when Qt's QDns is not good enough. Because QDns
|
||||
//! does not use threads, it cannot make a system call asyncronously. Thus,
|
||||
//! QDns tries to imitate the behavior of each platform's native behavior, and
|
||||
//! generally falls short.
|
||||
//!
|
||||
//! NDns uses a thread to make the system call happen in the background. This
|
||||
//! gives your program native DNS behavior, at the cost of requiring threads
|
||||
//! to build.
|
||||
//!
|
||||
//! \code
|
||||
//! #include "ndns.h"
|
||||
//!
|
||||
//! ...
|
||||
//!
|
||||
//! NDns dns;
|
||||
//! dns.resolve("psi.affinix.com");
|
||||
//!
|
||||
//! // The class will emit the resultsReady() signal when the resolution
|
||||
//! // is finished. You may then retrieve the results:
|
||||
//!
|
||||
//! QHostAddress ip_address = dns.result();
|
||||
//!
|
||||
//! // or if you want to get the IP address as a string:
|
||||
//!
|
||||
//! QString ip_address = dns.resultString();
|
||||
//! \endcode
|
||||
|
||||
#include "ndns.h"
|
||||
|
||||
#include "netnames.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// NDns
|
||||
//----------------------------------------------------------------------------
|
||||
//! \fn void NDns::resultsReady()
|
||||
//! This signal is emitted when the DNS resolution succeeds or fails.
|
||||
|
||||
//!
|
||||
//! Constructs an NDns object with parent \a parent.
|
||||
NDns::NDns(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
busy = false;
|
||||
|
||||
connect(&dns, SIGNAL(resultsReady(const QList<XMPP::NameRecord> &)), SLOT(dns_resultsReady(const QList<XMPP::NameRecord> &)));
|
||||
connect(&dns, SIGNAL(error(XMPP::NameResolver::Error)), SLOT(dns_error(XMPP::NameResolver::Error)));
|
||||
}
|
||||
|
||||
//!
|
||||
//! Destroys the object and frees allocated resources.
|
||||
NDns::~NDns()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Resolves hostname \a host (eg. psi.affinix.com)
|
||||
void NDns::resolve(const QString &host)
|
||||
{
|
||||
QHostAddress a;
|
||||
if (a.setAddress(host)) {
|
||||
addr = a;
|
||||
QMetaObject::invokeMethod(this, "resultsReady", Qt::QueuedConnection);
|
||||
}
|
||||
else {
|
||||
stop();
|
||||
busy = true;
|
||||
dns.start(host.toLatin1());
|
||||
}
|
||||
}
|
||||
|
||||
//!
|
||||
//! Cancels the lookup action.
|
||||
//! \note This will not stop the underlying system call, which must finish before the next lookup will proceed.
|
||||
void NDns::stop()
|
||||
{
|
||||
dns.stop();
|
||||
busy = false;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as QHostAddress. This will be a Null QHostAddress if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QHostAddress NDns::result() const
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns the IP address as a string. This will be an empty string if the lookup failed.
|
||||
//! \sa resultsReady()
|
||||
QString NDns::resultString() const
|
||||
{
|
||||
if (addr.isNull())
|
||||
return QString();
|
||||
else
|
||||
return addr.toString();
|
||||
}
|
||||
|
||||
//!
|
||||
//! Returns TRUE if busy resolving a hostname.
|
||||
bool NDns::isBusy() const
|
||||
{
|
||||
return busy;
|
||||
}
|
||||
|
||||
void NDns::dns_resultsReady(const QList<XMPP::NameRecord> &results)
|
||||
{
|
||||
addr = results[0].address();
|
||||
busy = false;
|
||||
emit resultsReady();
|
||||
}
|
||||
|
||||
void NDns::dns_error(XMPP::NameResolver::Error)
|
||||
{
|
||||
addr = QHostAddress();
|
||||
busy = false;
|
||||
emit resultsReady();
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
59
iris-legacy/iris/irisnet/legacy/ndns.h
Normal file
59
iris-legacy/iris/irisnet/legacy/ndns.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* ndns.h - native DNS resolution
|
||||
* Copyright (C) 2001, 2002 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CS_NDNS_H
|
||||
#define CS_NDNS_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtNetwork>
|
||||
#include "netnames.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
class NDns : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NDns(QObject *parent=0);
|
||||
~NDns();
|
||||
|
||||
void resolve(const QString &);
|
||||
void stop();
|
||||
bool isBusy() const;
|
||||
|
||||
QHostAddress result() const;
|
||||
QString resultString() const;
|
||||
|
||||
signals:
|
||||
void resultsReady();
|
||||
|
||||
private slots:
|
||||
void dns_resultsReady(const QList<XMPP::NameRecord> &);
|
||||
void dns_error(XMPP::NameResolver::Error);
|
||||
|
||||
private:
|
||||
XMPP::NameResolver dns;
|
||||
bool busy;
|
||||
QHostAddress addr;
|
||||
};
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
114
iris-legacy/iris/irisnet/legacy/safedelete.cpp
Normal file
114
iris-legacy/iris/irisnet/legacy/safedelete.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#include"safedelete.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDelete
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDelete::SafeDelete()
|
||||
{
|
||||
lock = 0;
|
||||
}
|
||||
|
||||
SafeDelete::~SafeDelete()
|
||||
{
|
||||
if(lock)
|
||||
lock->dying();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteLater(QObject *o)
|
||||
{
|
||||
if(!lock)
|
||||
deleteSingle(o);
|
||||
else
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDelete::unlock()
|
||||
{
|
||||
lock = 0;
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteAll()
|
||||
{
|
||||
if(list.isEmpty())
|
||||
return;
|
||||
|
||||
for(int n = 0; n < list.size(); ++n)
|
||||
deleteSingle(list[n]);
|
||||
list.clear();
|
||||
}
|
||||
|
||||
void SafeDelete::deleteSingle(QObject *o)
|
||||
{
|
||||
#if QT_VERSION < 0x030000
|
||||
// roll our own QObject::deleteLater()
|
||||
SafeDeleteLater *sdl = SafeDeleteLater::ensureExists();
|
||||
sdl->deleteItLater(o);
|
||||
#else
|
||||
o->deleteLater();
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLock
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLock::SafeDeleteLock(SafeDelete *sd)
|
||||
{
|
||||
own = false;
|
||||
if(!sd->lock) {
|
||||
_sd = sd;
|
||||
_sd->lock = this;
|
||||
}
|
||||
else
|
||||
_sd = 0;
|
||||
}
|
||||
|
||||
SafeDeleteLock::~SafeDeleteLock()
|
||||
{
|
||||
if(_sd) {
|
||||
_sd->unlock();
|
||||
if(own)
|
||||
delete _sd;
|
||||
}
|
||||
}
|
||||
|
||||
void SafeDeleteLock::dying()
|
||||
{
|
||||
_sd = new SafeDelete(*_sd);
|
||||
own = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// SafeDeleteLater
|
||||
//----------------------------------------------------------------------------
|
||||
SafeDeleteLater *SafeDeleteLater::self = 0;
|
||||
|
||||
SafeDeleteLater *SafeDeleteLater::ensureExists()
|
||||
{
|
||||
if(!self)
|
||||
new SafeDeleteLater();
|
||||
return self;
|
||||
}
|
||||
|
||||
SafeDeleteLater::SafeDeleteLater()
|
||||
{
|
||||
self = this;
|
||||
QTimer::singleShot(0, this, SLOT(explode()));
|
||||
}
|
||||
|
||||
SafeDeleteLater::~SafeDeleteLater()
|
||||
{
|
||||
qDeleteAll(list);
|
||||
list.clear();
|
||||
self = 0;
|
||||
}
|
||||
|
||||
void SafeDeleteLater::deleteItLater(QObject *o)
|
||||
{
|
||||
list.append(o);
|
||||
}
|
||||
|
||||
void SafeDeleteLater::explode()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
59
iris-legacy/iris/irisnet/legacy/safedelete.h
Normal file
59
iris-legacy/iris/irisnet/legacy/safedelete.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef SAFEDELETE_H
|
||||
#define SAFEDELETE_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class SafeDelete;
|
||||
class SafeDeleteLock
|
||||
{
|
||||
public:
|
||||
SafeDeleteLock(SafeDelete *sd);
|
||||
~SafeDeleteLock();
|
||||
|
||||
private:
|
||||
SafeDelete *_sd;
|
||||
bool own;
|
||||
friend class SafeDelete;
|
||||
void dying();
|
||||
};
|
||||
|
||||
class SafeDelete
|
||||
{
|
||||
public:
|
||||
SafeDelete();
|
||||
~SafeDelete();
|
||||
|
||||
void deleteLater(QObject *o);
|
||||
|
||||
// same as QObject::deleteLater()
|
||||
static void deleteSingle(QObject *o);
|
||||
|
||||
private:
|
||||
QObjectList list;
|
||||
void deleteAll();
|
||||
|
||||
friend class SafeDeleteLock;
|
||||
SafeDeleteLock *lock;
|
||||
void unlock();
|
||||
};
|
||||
|
||||
class SafeDeleteLater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SafeDeleteLater *ensureExists();
|
||||
void deleteItLater(QObject *o);
|
||||
|
||||
private slots:
|
||||
void explode();
|
||||
|
||||
private:
|
||||
SafeDeleteLater();
|
||||
~SafeDeleteLater();
|
||||
|
||||
QObjectList list;
|
||||
friend class SafeDelete;
|
||||
static SafeDeleteLater *self;
|
||||
};
|
||||
|
||||
#endif
|
||||
111
iris-legacy/iris/irisnet/legacy/servsock.cpp
Normal file
111
iris-legacy/iris/irisnet/legacy/servsock.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* servsock.cpp - simple wrapper to QServerSocket
|
||||
* Copyright (C) 2003 Justin Karneges
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "servsock.h"
|
||||
|
||||
// CS_NAMESPACE_BEGIN
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSock
|
||||
//----------------------------------------------------------------------------
|
||||
class ServSock::Private
|
||||
{
|
||||
public:
|
||||
Private() {}
|
||||
|
||||
ServSockSignal *serv;
|
||||
};
|
||||
|
||||
ServSock::ServSock(QObject *parent)
|
||||
:QObject(parent)
|
||||
{
|
||||
d = new Private;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
ServSock::~ServSock()
|
||||
{
|
||||
stop();
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool ServSock::isActive() const
|
||||
{
|
||||
return (d->serv ? true: false);
|
||||
}
|
||||
|
||||
bool ServSock::listen(quint16 port)
|
||||
{
|
||||
stop();
|
||||
|
||||
d->serv = new ServSockSignal(this);
|
||||
if(!d->serv->listen(QHostAddress::Any, port)) {
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
return false;
|
||||
}
|
||||
connect(d->serv, SIGNAL(connectionReady(int)), SLOT(sss_connectionReady(int)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServSock::stop()
|
||||
{
|
||||
delete d->serv;
|
||||
d->serv = 0;
|
||||
}
|
||||
|
||||
int ServSock::port() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverPort();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
QHostAddress ServSock::address() const
|
||||
{
|
||||
if(d->serv)
|
||||
return d->serv->serverAddress();
|
||||
else
|
||||
return QHostAddress();
|
||||
}
|
||||
|
||||
void ServSock::sss_connectionReady(int s)
|
||||
{
|
||||
connectionReady(s);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ServSockSignal
|
||||
//----------------------------------------------------------------------------
|
||||
ServSockSignal::ServSockSignal(QObject *parent)
|
||||
:QTcpServer(parent)
|
||||
{
|
||||
setMaxPendingConnections(16);
|
||||
}
|
||||
|
||||
void ServSockSignal::incomingConnection(int socketDescriptor)
|
||||
{
|
||||
connectionReady(socketDescriptor);
|
||||
}
|
||||
|
||||
// CS_NAMESPACE_END
|
||||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue