summaryrefslogtreecommitdiffstats
path: root/src/tdeioslave/obex/tdeio_obex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tdeioslave/obex/tdeio_obex.cpp')
-rw-r--r--src/tdeioslave/obex/tdeio_obex.cpp548
1 files changed, 548 insertions, 0 deletions
diff --git a/src/tdeioslave/obex/tdeio_obex.cpp b/src/tdeioslave/obex/tdeio_obex.cpp
new file mode 100644
index 0000000..fbd2fb5
--- /dev/null
+++ b/src/tdeioslave/obex/tdeio_obex.cpp
@@ -0,0 +1,548 @@
+/*
+ This file is part of tdeio_obex.
+
+ Copyright (c) 2003 Mathias Froehlich <Mathias.Froehlich@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+//#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <kdebug.h>
+
+#include <tdeapplication.h>
+#include <dcopclient.h>
+#include <tdecmdlineargs.h>
+
+#include <tqdbusvariant.h>
+#include <tqdbusdatalist.h>
+#include <tqdbusdatamap.h>
+
+#include "tdeio_obex.h"
+
+static const TDECmdLineOptions options[] = { { "+protocol", I18N_NOOP(
+ "Protocol name"), 0 }, { "+pool", I18N_NOOP("Socket name"), 0 }, {
+ "+app", I18N_NOOP("Socket name"), 0 }, TDECmdLineLastOption };
+
+extern "C" {
+ int KDE_EXPORT kdemain( int argc, char **argv )
+ {
+ // TDEApplication is necessary to use other ioslaves
+ putenv(strdup("SESSION_MANAGER="));
+ TDECmdLineArgs::init(argc, argv, "tdeio_obex", 0, 0, 0, 0);
+ TDECmdLineArgs::addCmdLineOptions( options );
+ TDEApplication app( false, false, false );
+ // We want to be anonymous even if we use DCOP
+ app.dcopClient()->attach();
+
+ TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+ ObexProtocol slave( args->arg(0), args->arg(1), args->arg(2) );
+ slave.dispatchLoop();
+ return 0;
+ }
+}
+
+ObexProtocol::ObexProtocol(const TQCString &protocol, const TQCString &pool_socket, const TQCString &app_socket) :
+ SlaveBase(protocol, pool_socket, app_socket)
+{
+ kdDebug() << k_funcinfo << endl;
+ mChannel = 0;
+ mAddress = TQString::null;
+ mSessionPath = TQString();
+ mFileTransfer = 0;
+ mSessionProperties = 0;
+ mSession = 0;
+ mClient = 0;
+ mProtocol = protocol;
+ mHost = TQString::null;
+ mConnected = false;
+
+ mManager = new TDEObex::ObexObjectManagerImpl("org.bluez.obex", "/");
+ if (!mManager->isConnectedToDBUS())
+ {
+ TQString err = "ObexObjectManager is not connected to DBus";
+ tqDebug(err);
+ // infoMessage(i18n("Error"));
+ TDEIO::SlaveBase::error(TDEIO::ERR_COULD_NOT_CONNECT, err);
+ exit();
+ }
+
+ kdDebug() << "ObexProtocol::ObexProtocol DBus connection: " << (*(mManager->getConnection())).uniqueName() << endl;
+
+ if (mProtocol == "obexftp" || mProtocol == "obexopp")
+ {
+ obex = new Obex(mProtocol);
+ // mConnected = connectObex();
+ }
+ else
+ exit();
+
+ if (!mClient)
+ mClient = mManager->getClient();
+ if (!mClient)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_COULD_NOT_CONNECT, "ObexClient was not created");
+ exit();
+ }
+
+}
+
+ObexProtocol::~ObexProtocol()
+{
+ kdDebug() << k_funcinfo << endl;
+ if (mConnected)
+ closeObex();
+ if (obex)
+ delete obex;
+ if (mManager)
+ delete mManager;
+}
+
+void ObexProtocol::closeConnection()
+{
+ kdDebug() << k_funcinfo << endl;
+ closeObex();
+}
+
+void ObexProtocol::closeObex()
+{
+ kdDebug() << k_funcinfo << endl;
+
+ TQT_DBusError dbuserror;
+ if (mConnected && !mSessionPath.isEmpty())
+ {
+ // infoMessage(i18n("Disconnecting"));
+ if (!mClient->RemoveSession(mSessionPath, dbuserror))
+ {
+ if (dbuserror.isValid())
+ TDEIO::SlaveBase::error(TDEIO::ERR_COULD_NOT_CONNECT, dbuserror.message());
+ }
+ // infoMessage(i18n("Disconnected"));
+ }
+
+ if (mFileTransfer)
+ delete mFileTransfer;
+ if (mSessionProperties)
+ delete mSessionProperties;
+ if (mSession)
+ delete mSession;
+ if (mClient)
+ delete mClient;
+ mConnected = false;
+
+ exit();
+}
+
+//void ObexProtocol::openConnection()
+//{
+// kdDebug() << k_funcinfo << endl;
+//
+//}
+
+bool ObexProtocol::connectObex()
+{
+ kdDebug() << k_funcinfo << endl;
+
+ TQT_DBusError dbuserror;
+
+ TQT_DBusVariant obexprot;
+ if (mProtocol == "obexftp")
+ obexprot.value = TQT_DBusData::fromString("00001106-0000-1000-8000-00805f9b34fb");
+ else if (mProtocol == "obexopp")
+ obexprot.value = TQT_DBusData::fromString("00001105-0000-1000-8000-00805f9b34fb");
+ else if (mProtocol == "obexmap")
+ obexprot.value = TQT_DBusData::fromString("00001134-0000-1000-8000-00805f9b34fb");
+ else if (mProtocol == "obexpbap")
+ obexprot.value = TQT_DBusData::fromString("00001130-0000-1000-8000-00805f9b34fb");
+ else if (mProtocol == "obexsync")
+ obexprot.value = TQT_DBusData::fromString("00001104-0000-1000-8000-00805f9b34fb");
+ obexprot.signature = obexprot.value.buildDBusSignature();
+ TQMap<TQString, TQT_DBusVariant> args;
+ args.insert(TQString("Target"), obexprot);
+
+ if (mSessionPath.isEmpty())
+ {
+ kdDebug() << "ObexProtocol::connectObex : trying to create session" << endl;
+ if (!mClient->CreateSession(mAddress, args, mSessionPath, dbuserror))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_COULD_NOT_CONNECT, i18n("Could not create session for %1.").arg(mAddress));
+ return false;
+ }
+ }
+
+ kdDebug() << "ObexProtocol::connectObex mSessionPath: " << mSessionPath << endl;
+ if (!mSession)
+ {
+ mSession = new org::bluez::obex::Session1Proxy("org.bluez.obex", mSessionPath);
+ mSession->setConnection((*(mManager->getConnection())));
+
+ mSessionProperties = new org::freedesktop::DBus::PropertiesProxy("org.bluez", mSessionPath);
+ mSessionProperties->setConnection((*(mManager->getConnection())));
+
+ connect(mSessionProperties, SIGNAL(PropertiesChanged ( const TQString&, const TQMap< TQString, TQT_DBusVariant >&, const TQStringList& )),
+ this, SLOT(slotPropertiesChanged ( const TQString& , const TQMap< TQString, TQT_DBusVariant >&, const TQStringList& )));
+
+ mFileTransfer = new org::bluez::obex::FileTransfer1Proxy("org.bluez.obex", mSessionPath);
+ mFileTransfer->setConnection((*(mManager->getConnection())));
+
+ }
+ if (mClient != 0 && mSession != 0 && mFileTransfer != 0)
+ mConnected = true;
+ return mConnected;
+}
+
+void ObexProtocol::listDir(const KURL &url)
+{
+ kdDebug() << k_funcinfo << endl;
+ kdDebug() << "utl: " << url.url() << endl;
+ kdDebug() << "path: " << url.path() << endl;
+
+ if (url.path().length() <= 1)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_MALFORMED_URL, url.prettyURL());
+ finished();
+ return;
+ }
+
+ TQString address, name, path;
+ bool ok = obex->parseURL(url, address, name, path);
+
+ if (!ok || address.isEmpty())
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_MALFORMED_URL, url.prettyURL());
+ finished();
+ return;
+ }
+ mAddress = address;
+
+ kdDebug() << k_funcinfo << " address " << mAddress << endl;
+ kdDebug() << k_funcinfo << " name " << name << endl;
+ kdDebug() << k_funcinfo << " path " << path << endl;
+ kdDebug() << k_funcinfo << " at line " << __LINE__ << endl;
+
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+
+ if (!path.isEmpty())
+ {
+ if (!changeWorkingDirectory(path))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, path);
+
+ finished();
+ closeObex();
+ return;
+ }
+ }
+
+ kdDebug() << k_funcinfo << " at line " << __LINE__ << endl;
+ TQT_DBusDataList folderinfo;
+ TQT_DBusError dbuserror;
+ if (!mFileTransfer->ListFolder(folderinfo, dbuserror))
+ {
+ if (dbuserror.isValid())
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, i18n("%1.\n%2").arg(url.prettyURL()).arg(dbuserror.message()));
+ }
+ else
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL());
+ }
+
+ finished();
+ closeObex();
+ return;
+ }
+
+ TDEIO::UDSEntryList entries;
+ entries.clear();
+
+ TQValueList<TQT_DBusData> vl = folderinfo.toTQValueList();
+ TQValueList<TQT_DBusData>::Iterator dit = vl.begin();
+ for (dit; dit != vl.end(); ++dit)
+ {
+ bool ok = false;
+ TQMap<TQString, TQT_DBusData> map = (*dit).toStringKeyMap(&ok).toTQMap();
+ if (!ok)
+ {
+ kdDebug() << k_funcinfo << " failed " << endl;
+ continue;
+ }
+ TDEIO::UDSEntry entry = obex->createUDSEntry(map);
+ entries.append(entry);
+ kdDebug() << k_funcinfo << " at line " << __LINE__ << endl;
+ }
+
+ listEntries(entries);
+ listEntry(UDSEntry(), true); // ready
+
+ finished();
+ closeObex();
+}
+
+void ObexProtocol::stat(const KURL &url)
+{
+ kdDebug() << k_funcinfo << " url: " << url << endl;
+
+ TQString address, name, path;
+ bool ok = obex->parseURL(url, address, name, path);
+ kdDebug() << k_funcinfo << " addr: " << address << endl;
+ kdDebug() << k_funcinfo << " name: " << name << endl;
+ kdDebug() << k_funcinfo << " path: " << path << endl;
+
+ if (!ok || address.isEmpty())
+ {
+ error(TDEIO::ERR_MALFORMED_URL, url.prettyURL());
+ return;
+ }
+
+ TDEIO::UDSEntry entry;
+ if (path.isEmpty() || path == "/")
+ {
+ // The root is "virtual" - it's not a single physical directory
+ obex->createTopLevelEntry(entry);
+ }
+ else
+ {
+ obex->createDirEntry(entry, url.url());
+ }
+ statEntry(entry);
+ finished();
+}
+
+void ObexProtocol::get(const KURL& url)
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if (!mFileTransfer)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not get file: %1. No file transport").arg(url.prettyURL()));
+ return;
+ }
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+// TQT_DBusError dbuserror;
+// if (!mFileTransfer->GetFile(url.url(), dbuserror)) {
+// TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not get file: %1.").arg(dbuserror.message()));
+// }
+}
+
+void ObexProtocol::copy(const KURL &src, const KURL &dest, int permissions, bool overwrite)
+{
+ kdDebug() << k_funcinfo << endl;
+ // obex->copy(src, dest, permissions, overwrite);
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+}
+
+void ObexProtocol::put(const KURL& url, int permissions, bool overwrite, bool resume)
+{
+ kdDebug() << k_funcinfo << endl;
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+ if (!mFileTransfer)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not put file: %1. No file transport").arg(url.prettyURL()));
+ return;
+ }
+
+//
+// TQT_DBusError dbuserror;
+// if (!mFileTransfer->PutFile(url.url(), dbuserror)) {
+// TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not put file: %1.").arg(dbuserror.message()));
+// }
+
+}
+
+void ObexProtocol::del(const KURL &url, bool isfile)
+{
+ kdDebug() << k_funcinfo << endl;
+
+ if (!isfile)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Only files can be deleted. Request to delete: %1").arg(url.prettyURL()));
+ return;
+ }
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+ if (!mFileTransfer)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not delete file: %1. No file transport").arg(url.prettyURL()));
+ return;
+ }
+
+ TQT_DBusError dbuserror;
+ if (!mFileTransfer->Delete(url.url(), dbuserror))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not delete file: %1.").arg(dbuserror.message()));
+ }
+
+}
+
+//void ObexProtocol::rename(const KURL& src, const KURL& dest, bool overwrite)
+//{
+// kdDebug() << k_funcinfo << endl;
+// // obex->rename(src, dest, overwrite);
+//
+//}
+
+void ObexProtocol::mkdir(const KURL&url, int permissions)
+{
+ kdDebug() << k_funcinfo << endl;
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return;
+ }
+ }
+ if (!mFileTransfer)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not create directory: %1. No file transport").arg(url.prettyURL()));
+ return;
+ }
+
+ TQT_DBusError dbuserror;
+ if (!mFileTransfer->CreateFolder(url.url(), dbuserror))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not create directory: %1.").arg(dbuserror.message()));
+ }
+
+}
+
+bool ObexProtocol::changeWorkingDirectory(const TQString& dir)
+{
+ kdDebug() << "ObexProtocol::changeWorkingDirectory( " << dir << " )" << endl;
+ if (!dir.startsWith("/"))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_MALFORMED_URL, i18n("Could not change directory: %1. Directory should start with \"/\"").arg(dir));
+ return false;
+ }
+ if (!mConnected)
+ {
+ if (!connectObex())
+ {
+ finished();
+ return false;
+ }
+ }
+ if (!mFileTransfer)
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not change directory: %1. No file transport").arg(dir));
+ return false;
+ }
+
+ TQT_DBusError dbuserror;
+ if (!mFileTransfer->ChangeFolder(dir, dbuserror))
+ {
+ TDEIO::SlaveBase::error(TDEIO::ERR_INTERNAL, i18n("Could not change directory: %1.").arg(dbuserror.message()));
+ return false;
+ }
+
+ return true;
+}
+
+void ObexProtocol::slotPropertiesChanged(const TQString& interface, const TQMap<
+ TQString, TQT_DBusVariant>& changed_properties, const TQStringList& invalidated_properties)
+{
+ kdDebug() << k_funcinfo << endl;
+ kdDebug() << interface << endl;
+
+ if (interface == "org.bluez.obex.Session1")
+ {
+ TQMap<TQString, TQT_DBusVariant>::const_iterator it;
+ for (it = changed_properties.begin(); it != changed_properties.end();
+ ++it)
+ {
+ bool ok = false;
+ if (it.key() == "Source")
+ emit sessionSourceChanged(mSessionPath, it.data().value.toBool(&ok));
+ else if (it.key() == "Destination")
+ emit sessionDestinationChanged(mSessionPath, it.data().value.toString(&ok));
+ else if (it.key() == "Channel")
+ emit sessionChannelChanged(mSessionPath, it.data().value.toByte(&ok));
+ else if (it.key() == "Target")
+ emit sessionTargetChanged(mSessionPath, it.data().value.toString(&ok));
+ else if (it.key() == "Root")
+ emit sessionRootChanged(mSessionPath, it.data().value.toString(&ok));
+ else
+ continue;
+ if (!ok)
+ tqDebug("ObjectManagerImpl::slotPropertiesChanged conversion failed");
+ }
+ }
+
+ if (interface == "org.bluez.obex.FileTransfer1" || interface == "org.bluez.obex.Transfer1")
+ {
+ TQMap<TQString, TQT_DBusVariant>::const_iterator it;
+ for (it = changed_properties.begin(); it != changed_properties.end();
+ ++it)
+ {
+ bool ok = false;
+ if (it.key() == "Size")
+ emit transferSizeChanged(mSessionPath, it.data().value.toUInt64(&ok));
+ else if (it.key() == "Status")
+ emit transferStatusChanged(mSessionPath, it.data().value.toString(&ok));
+ else if (it.key() == "Transferred")
+ emit transferTransferredChanged(mSessionPath, it.data().value.toUInt64(&ok));
+ else if (it.key() == "Time")
+ emit transferTimeChanged(mSessionPath, it.data().value.toUInt64(&ok));
+ else if (it.key() == "Filename")
+ emit transferFilenameChanged(mSessionPath, it.data().value.toString(&ok));
+ else
+ continue;
+ if (!ok)
+ tqDebug("ObjectManagerImpl::slotPropertiesChanged conversion failed");
+ }
+ }
+}
+
+#include "tdeio_obex.moc"