/* This file is part of the KDE KMobile library Copyright (C) 2003 Helge Deller This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "kio_mobile.h" #include using namespace KIO; #define KIO_MOBILE_DEBUG_AREA 7126 #define PRINT_DEBUG kdDebug(KIO_MOBILE_DEBUG_AREA) << "kio_mobile: " extern "C" { KDE_EXPORT int kdemain(int argc, char **argv); } /** * The main program. */ int kdemain(int argc, char **argv) { TDEInstance instance( "kio_mobile" ); PRINT_DEBUG << "Starting " << getpid() << endl; if (argc != 4) { fprintf(stderr, "Usage kio_mobile protocol pool app\n"); return -1; } // let the protocol class do its work KMobileProtocol slave(argv[2], argv[3]); slave.dispatchLoop(); PRINT_DEBUG << "Done" << endl; return 0; } /** * Initialize the mobile slave */ KMobileProtocol::KMobileProtocol(const TQCString &pool, const TQCString &app) : SlaveBase( "mobile", pool, app) { } KMobileProtocol::~KMobileProtocol() { } /* * getDeviceAndRessource("mobile:///...") - split */ int KMobileProtocol::getDeviceAndRessource(const TQString &_path, TQString &devName, TQString &resource, TQString &devPath, KMobileDevice::Capabilities &devCaps) { // PRINT_DEBUG << TQString("###getDeviceAndRessource### %1\n").arg(_path); TQStringList path = TQStringList::split('/', _path, false); devName = resource = devPath = TQString(); devCaps = KMobileDevice::hasNothing; if (path.count() >= 1) { devName = path[0]; path.pop_front(); }; if (path.count() >= 1) { resource = path[0]; path.pop_front(); }; if (path.count() >= 1) devPath = path.join("/"); if (devName.isEmpty()) return 0; int _caps = m_dev.capabilities(devName); if (resource.isEmpty()) { devCaps = (KMobileDevice::Capabilities) _caps; return 0; } for (int i=0; i<31; i++) { int cap = 1UL << i; if ((_caps & cap) == 0) continue; TQString capname = m_dev.nameForCap(devName,cap); if (capname != resource) continue; devCaps = (KMobileDevice::Capabilities) cap; return 0; } return KIO::ERR_DOES_NOT_EXIST; } static void addAtom(KIO::UDSEntry& entry, unsigned int ID, long l, const TQString& s = TQString()) { KIO::UDSAtom atom; atom.m_uds = ID; atom.m_long = l; atom.m_str = s; entry.append(atom); } static void createDirEntry(KIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime) { entry.clear(); addAtom(entry, KIO::UDS_NAME, 0, name); addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR); addAtom(entry, KIO::UDS_ACCESS, 0500); addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime); addAtom(entry, KIO::UDS_URL, 0, url); addAtom(entry, KIO::UDS_USER, 0, getenv("USER")); addAtom(entry, KIO::UDS_GROUP, 0, getenv("USER")); PRINT_DEBUG << TQString("createDirEntry: File: %1 MIME: %2 URL: %3\n").arg(name).arg(mime).arg(url); // addAtom(entry, KIO::UDS_SIZE, 0); addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, mime); } static void createFileEntry(KIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime, const unsigned long size = 0) { entry.clear(); addAtom(entry, KIO::UDS_NAME, 0, name); addAtom(entry, KIO::UDS_FILE_TYPE, S_IFREG); addAtom(entry, KIO::UDS_URL, 0, url); addAtom(entry, KIO::UDS_ACCESS, 0400); addAtom(entry, KIO::UDS_USER, 0, getenv("USER")); addAtom(entry, KIO::UDS_GROUP, 0, getenv("USER")); addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime); if (size) addAtom(entry, KIO::UDS_SIZE, size); addAtom(entry, KIO::UDS_GUESSED_MIME_TYPE, 0, mime); PRINT_DEBUG << TQString("createFileEntry: File: %1, Size: %2, MIME: %3\n").arg(name).arg(size).arg(mime); } /** * Get the information contained in the URL. */ void KMobileProtocol::get(const KURL &url) { PRINT_DEBUG << "###############################\n"; PRINT_DEBUG << TQString("get(%1)\n").arg(url.path()); KMobileDevice::Capabilities devCaps; TQString devName, resource, devPath; int err = getDeviceAndRessource(url.path(), devName, resource, devPath, devCaps); if (err) { error(err, url.path()); return; } if (devName.isEmpty() || resource.isEmpty()) { error(KIO::ERR_DOES_NOT_EXIST, url.path()); return; } // collect the result TQCString result; TQString mime; switch (devCaps) { case KMobileDevice::hasAddressBook: err = getVCard(devName, result, mime, devPath); break; case KMobileDevice::hasCalendar: err = getCalendar(devName, result, mime, devPath); break; case KMobileDevice::hasNotes: err = getNote(devName, result, mime, devPath); break; case KMobileDevice::hasFileStorage: err = getFileStorage(devName, result, mime, devPath); break; default: err = KIO::ERR_CANNOT_ENTER_DIRECTORY; /* TODO */ } if (err) { error(err, url.path()); return; } // tell the mimetype mimeType(mime); // tell the length KIO::filesize_t processed_size = result.length(); totalSize(processed_size); // tell the contents of the URL TQByteArray array; array.setRawData( result.data(), result.length() ); data(array); array.resetRawData( result.data(), result.length() ); processedSize( processed_size ); // tell we are finished data(TQByteArray()); // tell we are finished finished(); } /* * listRoot() - gives listing of all devices */ void KMobileProtocol::listRoot(const KURL& url) { PRINT_DEBUG << TQString("########## listRoot(%1) for %2:/\n").arg(url.path()).arg(url.protocol()); KIO::UDSEntry entry; TQStringList deviceNames = m_dev.deviceNames(); unsigned int dirs = deviceNames.count(); totalSize(dirs); int classMask = KMobileDevice::Unclassified; /* handle all possible protocols here and just add a .protocol file */ if (url.protocol() == "cellphone") // cellphone:/ classMask = KMobileDevice::Phone; if (url.protocol() == "organizer" || // organizer:/ url.protocol() == "pda") // pda:/ classMask = KMobileDevice::Organizer; if (url.protocol() == "phonecamera") // camera:/ classMask = KMobileDevice::Camera; for (unsigned int i=0; i") - sub-directory of a devices */ void KMobileProtocol::listTopDeviceDir(const TQString &devName) { PRINT_DEBUG << TQString("listTopDeviceDir(%1)\n").arg(devName); KIO::UDSEntry entry; unsigned int caps = m_dev.capabilities(devName); for (int i=0; i<31; i++) { unsigned int cap = 1UL</") - resources of a device */ void KMobileProtocol::listEntries(const TQString &devName, const TQString &resource, const TQString &devPath, const KMobileDevice::Capabilities devCaps) { PRINT_DEBUG << TQString("listEntries(%1,%2,%3)\n").arg(devName).arg(resource).arg(devPath); switch (devCaps) { case KMobileDevice::hasAddressBook: listAddressBook(devName, resource); break; case KMobileDevice::hasCalendar: listCalendar(devName, resource); break; case KMobileDevice::hasNotes: listNotes(devName, resource); break; case KMobileDevice::hasFileStorage: listFileStorage(devName, resource, devPath); break; default: error( ERR_CANNOT_ENTER_DIRECTORY, TQString("/%1/%2").arg(devName).arg(resource) ); } } /* * listAddressBook("mobile://Addressbook) - list the addressbook */ void KMobileProtocol::listAddressBook(const TQString &devName, const TQString &resource) { PRINT_DEBUG << TQString("listAddressBook(%1)\n").arg(devName); KIO::UDSEntry entry; int fieldwidth; int entries = m_dev.numAddresses(devName); if (entries>=1000) fieldwidth=4; else if (entries>=100) fieldwidth=3; else if (entries>=10) fieldwidth=2; else fieldwidth=1; totalSize(entries); // TQRegExp rx; rx.setPattern( ".*FN:([\\w\\s]*)[\\n\\r]{2}.*" ); TQString name; for (int i=0; i0) index = path.left(index).toInt(); if (index<0 || index>=m_dev.numAddresses(devName)) return KIO::ERR_DOES_NOT_EXIST; TQString str = m_dev.readAddress(devName, index); if (str.isEmpty()) return KIO::ERR_INTERNAL; result = str.utf8(); mime = entryMimeType(KMobileDevice::hasAddressBook); // setMetaData("plugin", "const TQString &key, const TQString &value); return 0; } /* * listCalendar("mobile://Calendar) - list the calendar entries */ void KMobileProtocol::listCalendar( const TQString &devName, const TQString &resource) { PRINT_DEBUG << TQString("listCalendar(%1)\n").arg(devName); KIO::UDSEntry entry; int entries = m_dev.numCalendarEntries(devName); totalSize(entries); for (int i=0; i/Notes) - list the notes */ void KMobileProtocol::listNotes( const TQString &devName, const TQString &resource) { PRINT_DEBUG << TQString("listNotes(%1)\n").arg(devName); KIO::UDSEntry entry; int entries = m_dev.numNotes(devName); totalSize(entries); for (int i=0; i0) index = path.left(index).toInt(); if (index<0 || index>=m_dev.numNotes(devName)) return KIO::ERR_DOES_NOT_EXIST; TQString note = m_dev.readNote(devName, index); if (note.isEmpty()) return KIO::ERR_DOES_NOT_EXIST; result = note.utf8(); mime = entryMimeType(KMobileDevice::hasNotes); return 0; } /* * listFileStorage("mobile://Files) - list the files on the device */ void KMobileProtocol::listFileStorage(const TQString &devName, const TQString &resource, const TQString &devPath) { PRINT_DEBUG << TQString("listFileStorage(%1,%2)\n").arg(devName).arg(devPath); /* TODO */ error( KIO::ERR_DOES_NOT_EXIST, TQString("/%1/%2/%3").arg(devName).arg(resource).arg(devPath) ); } /* * getFileStorage() - gives the file contents of the given file */ int KMobileProtocol::getFileStorage(const TQString &devName, TQCString &result, TQString &mime, const TQString &path) { PRINT_DEBUG << TQString("getFileStorage(%1)\n").arg(path); /* TODO */ Q_UNUSED(devName); Q_UNUSED(result); Q_UNUSED(mime); return KIO::ERR_CANNOT_ENTER_DIRECTORY; } /** * Test if the url contains a directory or a file. */ void KMobileProtocol::stat( const KURL &url ) { PRINT_DEBUG << "###############################\n"; PRINT_DEBUG << TQString("stat(%1)\n").arg(url.path()); KMobileDevice::Capabilities devCaps; TQString devName, resource, devPath; int err = getDeviceAndRessource(url.path(), devName, resource, devPath, devCaps); if (err) { error(err, url.path()); return; } TQStringList path = TQStringList::split('/', url.path(), false); TQString filename = (path.count()>0) ? path[path.count()-1] : "/"; TQString fullPath = path.join("/"); TQString fullUrl = TQString("mobile:/%1").arg(fullPath); UDSEntry entry; bool isDir = devPath.isEmpty(); if (isDir) { createDirEntry(entry, filename, fullUrl, folderMimeType(devCaps)); } else { createFileEntry(entry, filename, fullUrl, entryMimeType(devCaps)); } statEntry(entry); finished(); } /** * Get the mimetype. */ void KMobileProtocol::mimetype(const KURL &url) { PRINT_DEBUG << "###############################\n"; PRINT_DEBUG << TQString("mimetype(%1)\n").arg(url.path()); KMobileDevice::Capabilities devCaps; TQString devName, resource, devPath; int err = getDeviceAndRessource(url.path(), devName, resource, devPath, devCaps); if (err) { error(err, url.path()); return; } // tell the mimetype mimeType(entryMimeType(devCaps)); finished(); } /** * List the contents of a directory. */ void KMobileProtocol::listDir(const KURL &url) { PRINT_DEBUG << "###############################\n"; PRINT_DEBUG << TQString("listDir(%1)\n").arg(url.path()); if (!m_dev.isKMobileAvailable()) { error( KIO::ERR_CONNECTION_BROKEN, i18n("TDE Mobile Device Manager") ); return; } KMobileDevice::Capabilities devCaps; TQString devName, resource, devPath; int err = getDeviceAndRessource(url.path(), devName, resource, devPath, devCaps); if (err) { error(err, url.path()); return; } if (devName.isEmpty()) { listRoot(url); return; } #if 0 if (!dev) { error( KIO::ERR_DOES_NOT_EXIST, TQString("/%1").arg(devName) ); return; } #endif if (resource.isEmpty()) { listTopDeviceDir(devName); return; } listEntries(devName, resource, devPath, devCaps); }