diff options
author | Darrell Anderson <humanreadable@yahoo.com> | 2014-02-06 17:54:49 -0600 |
---|---|---|
committer | Darrell Anderson <humanreadable@yahoo.com> | 2014-02-06 17:54:49 -0600 |
commit | ca705978d11b2e0bdcaf8186b0addff48d851483 (patch) | |
tree | da2d37c0fc29b1746cc24594e948bc7c9f1241eb /tdeioslaves | |
parent | eaa1b143397fadcb31d69944ed69d6cf215be77d (diff) | |
download | tdepim-ca705978d11b2e0bdcaf8186b0addff48d851483.tar.gz tdepim-ca705978d11b2e0bdcaf8186b0addff48d851483.zip |
Reorganize tdeioslave help handbooks, fix related protocol files and issues, update and add handbooks.
Diffstat (limited to 'tdeioslaves')
79 files changed, 0 insertions, 14329 deletions
diff --git a/tdeioslaves/CMakeLists.txt b/tdeioslaves/CMakeLists.txt deleted file mode 100644 index 567a1434b..000000000 --- a/tdeioslaves/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include( ConfigureChecks.cmake ) - -add_subdirectory( imap4 ) -add_subdirectory( mbox ) - -if( WITH_SASL ) - add_subdirectory( sieve ) -else( ) - message( "*** sieve tdeioslave will not be built (because lack of sasl support)" ) -endif( ) diff --git a/tdeioslaves/ConfigureChecks.cmake b/tdeioslaves/ConfigureChecks.cmake deleted file mode 100644 index 9cbd46c01..000000000 --- a/tdeioslaves/ConfigureChecks.cmake +++ /dev/null @@ -1,22 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -if( WITH_SASL ) - check_include_file( sasl/sasl.h HAVE_SASL_SASL_H ) - if( HAVE_SASL_SASL_H ) - check_library_exists( sasl2 sasl_client_init "" HAVE_LIBSASL2 ) - endif( ) - if( HAVE_LIBSASL2 ) - set( SASL_LIBRARY sasl2 CACHE INTERNAL "" ) - else( ) - tde_message_fatal( "cyrus-sasl are requested, but not found on your system" ) - endif( ) -endif( ) diff --git a/tdeioslaves/Mainpage.dox b/tdeioslaves/Mainpage.dox deleted file mode 100644 index 24e1ca685..000000000 --- a/tdeioslaves/Mainpage.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** @mainpage -* -* IO Slaves. -* -* KDE PIM contains a few KIOSlaves. The most important -* of these is the IMAP4Protocol slave which is used for IMAP operations. -* Similarly, the MBoxProtocol slave is used to access mbox files. -* -*/ diff --git a/tdeioslaves/Makefile.am b/tdeioslaves/Makefile.am deleted file mode 100644 index 217a0c599..000000000 --- a/tdeioslaves/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -## $Id$ - -if compile_tdeio_sieve - SIEVE_SUBDIR = sieve -endif - -SUBDIRS = imap4 mbox $(SIEVE_SUBDIR) - -DOXYGEN_REFERENCES = tdeioslaves/imap4 tdeioslaves/mbox -include $(top_srcdir)/admin/Doxyfile.am - diff --git a/tdeioslaves/configure.in.bot b/tdeioslaves/configure.in.bot deleted file mode 100644 index fdad4b633..000000000 --- a/tdeioslaves/configure.in.bot +++ /dev/null @@ -1,6 +0,0 @@ -if test "x$with_sasl" = xcheck && test -z "$SASL2_LIBS"; then - echo "" - echo "cyrus-sasl 2 library is missing. The sieve ioslave will not be built, and imap4 will lack of a lot of authentication methods." - echo "" - all_tests=bad -fi diff --git a/tdeioslaves/configure.in.in b/tdeioslaves/configure.in.in deleted file mode 100644 index 43b243b2b..000000000 --- a/tdeioslaves/configure.in.in +++ /dev/null @@ -1,27 +0,0 @@ -KDE_CHECK_SSL - -AC_ARG_WITH(sasl, - [AC_HELP_STRING(--with-sasl, - [enable support for authentication through cyrus-sasl @<:@default=check@:>@])], - [], with_sasl=check) - -sasl2_header="no" -SASL2_LIBS="" -if test "x$with_sasl" != xno; then - KDE_CHECK_HEADERS(sasl/sasl.h, sasl2_header="yes") - if test "$sasl2_header" = "yes" ; then - KDE_CHECK_LIB(sasl2, sasl_client_init, SASL2_LIBS="-lsasl2") - fi - - if test "x$SASL2_LIBS" != "x" ; then - AC_DEFINE_UNQUOTED(HAVE_LIBSASL2, 1, [Define if you have cyrus-sasl2 libraries]) - fi - - if test "x$with_sasl" != xcheck && test -z "$SASL2_LIBS"; then - AC_MSG_ERROR([--with-sasl was given, but test for cyrus-sasl failed]) - fi -fi - -AC_SUBST(SASL2_LIBS) - -AM_CONDITIONAL(compile_tdeio_sieve, test -n "$SASL2_LIBS") diff --git a/tdeioslaves/imap4/CMakeLists.txt b/tdeioslaves/imap4/CMakeLists.txt deleted file mode 100644 index f427c2581..000000000 --- a/tdeioslaves/imap4/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -tde_import( libkmime ) - -include_directories( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/libemailfunctions - ${CMAKE_SOURCE_DIR}/libkmime - ${CMAKE_SOURCE_DIR}/libtdepim - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### other data ################################ - -install( FILES - imap4.protocol imaps.protocol - DESTINATION ${SERVICES_INSTALL_DIR} ) - - -##### tdeio_imap4 (module) ######################## - -tde_add_kpart( tdeio_imap4 - SOURCES - imapcommand.cc imaplist.cc mailaddress.cc mimeheader.cc - rfcdecoder.cc imap4.cc imapinfo.cc imapparser.cc - mailheader.cc mimehdrline.cc mimeio.cc - LINK emailfunctions-static kmime-shared tdeio-shared ${SASL_LIBRARY} - DESTINATION ${PLUGIN_INSTALL_DIR} -) diff --git a/tdeioslaves/imap4/Makefile.am b/tdeioslaves/imap4/Makefile.am deleted file mode 100644 index f52af2c62..000000000 --- a/tdeioslaves/imap4/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -INCLUDES= -I$(top_srcdir)/libkmime \ - -I$(srcdir)/.. $(SSL_INCLUDES) \ - -I$(top_srcdir)/libemailfunctions \ - $(all_includes) - -####### Files - -kde_module_LTLIBRARIES = tdeio_imap4.la - -tdeio_imap4_la_SOURCES = imapcommand.cc imaplist.cc mailaddress.cc \ - mimeheader.cc rfcdecoder.cc imap4.cc imapinfo.cc imapparser.cc mailheader.cc \ - mimehdrline.cc mimeio.cc -tdeio_imap4_la_LIBADD = $(LIB_TDEIO) $(SASL2_LIBS) ../../libkmime/libkmime.la \ - ../../libemailfunctions/libemailfunctions.la -tdeio_imap4_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -module $(KDE_PLUGIN) - -noinst_HEADERS = imap4.h -EXTRA_DIST = README - -kdelnk_DATA = imap4.protocol imaps.protocol -kdelnkdir = $(kde_servicesdir) - -messages: - $(XGETTEXT) *.cc -o $(podir)/tdeio_imap4.pot - -include $(top_srcdir)/admin/Doxyfile.am diff --git a/tdeioslaves/imap4/PATCHING b/tdeioslaves/imap4/PATCHING deleted file mode 100644 index 39bcdce95..000000000 --- a/tdeioslaves/imap4/PATCHING +++ /dev/null @@ -1,7 +0,0 @@ -If you are patching this code, please be very sensitive to performance issues. -The parser is already very slow and resource intensive. Be careful not to add -any extra string iterations (copies, QCString.length(), etc), mallocs, or -implicit object creation/copies. Use calltree before and after your patch to -verify that it is not too expensive, along with cpu usage timing and even -wall clock time. - diff --git a/tdeioslaves/imap4/README b/tdeioslaves/imap4/README deleted file mode 100644 index af8af8f04..000000000 --- a/tdeioslaves/imap4/README +++ /dev/null @@ -1,48 +0,0 @@ -This is s.carstens@gmx.de release of KDE 2.0 tdeioslave -for the IMAP protocol. - -It supports LOGIN, AUTHENTICATE LOGIN, AUTHENTICATE ANONYMOUS and -AUTHENTICATE CRAM-MD5. -It supports the rfc2192 URL naming convention. - -- UIDVALIDITY check is conditional -- put will check if the mailbox exists and create it - or will append the data to that mailbox - (no append after create) - use edit->new->textfile from konqueror -- move will try to guess the correct destination - as konqueror appends the source mailbox name to - the destination -- del will currently delete empty directories, - mark messages for deletion. - If deleting a directory konqueror does the following: - - list the box - - take the box url + file name and try to delete it - - delete the box - As the konqueror created urls are invalid we ignore them - at the moment. -- relative URL's are not supported because - konqueror will not handle them -- there are 2 additional section keywords - ENVELOPE will do a FETCH ENVELOPE - STRUCTURE will do a FETCH BODYSTRUCTURE - normal behaviour is FETCH BODY.PEEK[section] - -- the mime types delivered are not really consistent - with the returned data - - it will return inode/directory on list entries - which contain inferiors - - it will return message/digest on selectable mailboxes - with file type S_IFDIR - - type message/rfc822-imap on selected messages - and type S_IFREG - -In Konqueror set the mimetype message/rfc822 to use -the inline viewer. - -Try it: imap://user@host/ - imap://user;AUTH=*@host/ - imap://user;AUTH=LOGIN@host/ - imap://user;AUTH=CRAM-MD5@host/ - -comments to s.carstens@gmx.de diff --git a/tdeioslaves/imap4/configure.in.in b/tdeioslaves/imap4/configure.in.in deleted file mode 100644 index 680e26e0a..000000000 --- a/tdeioslaves/imap4/configure.in.in +++ /dev/null @@ -1 +0,0 @@ -KDE_CHECK_SSL diff --git a/tdeioslaves/imap4/imap4.cc b/tdeioslaves/imap4/imap4.cc deleted file mode 100644 index 666bce9e5..000000000 --- a/tdeioslaves/imap4/imap4.cc +++ /dev/null @@ -1,2734 +0,0 @@ -/********************************************************************** - * - * imap4.cc - IMAP4rev1 KIOSlave - * Copyright (C) 2001-2002 Michael Haeckel <haeckel@kde.org> - * Copyright (C) 1999 John Corey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to jcorey@fruity.ath.cx - * - *********************************************************************/ - -/** - * @class IMAP4Protocol - * @note References: - * - RFC 2060 - Internet Message Access Protocol - Version 4rev1 - December 1996 - * - RFC 2192 - IMAP URL Scheme - September 1997 - * - RFC 1731 - IMAP Authentication Mechanisms - December 1994 - * (Discusses KERBEROSv4, GSSAPI, and S/Key) - * - RFC 2195 - IMAP/POP AUTHorize Extension for Simple Challenge/Response - * - September 1997 (CRAM-MD5 authentication method) - * - RFC 2104 - HMAC: Keyed-Hashing for Message Authentication - February 1997 - * - RFC 2086 - IMAP4 ACL extension - January 1997 - * - http://www.ietf.org/internet-drafts/draft-daboo-imap-annotatemore-05.txt - * IMAP ANNOTATEMORE draft - April 2004. - * - * - * Supported URLs: - * \verbatim -imap://server/ -imap://user:pass@server/ -imap://user;AUTH=method:pass@server/ -imap://server/folder/ - * \endverbatim - * These URLs cause the following actions (in order): - * - Prompt for user/pass, list all folders in home directory - * - Uses LOGIN to log in - * - Uses AUTHENTICATE to log in - * - List messages in folder - * - * @note API notes: - * Not receiving the required write access for a folder means - * ERR_CANNOT_OPEN_FOR_WRITING. - * ERR_DOES_NOT_EXIST is reserved for folders. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "imap4.h" - -#include "rfcdecoder.h" - -#include <sys/stat.h> - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/types.h> -#include <sys/wait.h> - -#ifdef HAVE_LIBSASL2 -extern "C" { -#include <sasl/sasl.h> -} -#endif - -#include <tqbuffer.h> -#include <tqdatetime.h> -#include <tqregexp.h> -#include <tdeprotocolmanager.h> -#include <tdemessagebox.h> -#include <kdebug.h> -#include <tdeio/connection.h> -#include <tdeio/slaveinterface.h> -#include <tdeio/passdlg.h> -#include <tdelocale.h> -#include <kmimetype.h> -#include <kmdcodec.h> - -#include "tdepimmacros.h" - -#define IMAP_PROTOCOL "imap" -#define IMAP_SSL_PROTOCOL "imaps" - -using namespace TDEIO; - -extern "C" -{ - void sigalrm_handler (int); - KDE_EXPORT int kdemain (int argc, char **argv); -} - -int -kdemain (int argc, char **argv) -{ - kdDebug(7116) << "IMAP4::kdemain" << endl; - - TDEInstance instance ("tdeio_imap4"); - if (argc != 4) - { - fprintf(stderr, "Usage: tdeio_imap4 protocol domain-socket1 domain-socket2\n"); - ::exit (-1); - } - -#ifdef HAVE_LIBSASL2 - if ( sasl_client_init( NULL ) != SASL_OK ) { - fprintf(stderr, "SASL library initialization failed!\n"); - ::exit (-1); - } -#endif - - //set debug handler - - IMAP4Protocol *slave; - if (strcasecmp (argv[1], IMAP_SSL_PROTOCOL) == 0) - slave = new IMAP4Protocol (argv[2], argv[3], true); - else if (strcasecmp (argv[1], IMAP_PROTOCOL) == 0) - slave = new IMAP4Protocol (argv[2], argv[3], false); - else - abort (); - slave->dispatchLoop (); - delete slave; - -#ifdef HAVE_LIBSASL2 - sasl_done(); -#endif - - return 0; -} - -void -sigchld_handler (int signo) -{ - int pid, status; - - while (true && signo == SIGCHLD) - { - pid = waitpid (-1, &status, WNOHANG); - if (pid <= 0) - { - // Reinstall signal handler, since Linux resets to default after - // the signal occurred ( BSD handles it different, but it should do - // no harm ). - signal (SIGCHLD, sigchld_handler); - return; - } - } -} - -IMAP4Protocol::IMAP4Protocol (const TQCString & pool, const TQCString & app, bool isSSL):TCPSlaveBase ((isSSL ? 993 : 143), - (isSSL ? IMAP_SSL_PROTOCOL : IMAP_PROTOCOL), pool, - app, isSSL), imapParser (), mimeIO (), outputBuffer(outputCache) -{ - outputBufferIndex = 0; - mySSL = isSSL; - readBuffer[0] = 0x00; - relayEnabled = false; - readBufferLen = 0; - cacheOutput = false; - decodeContent = false; - mTimeOfLastNoop = TQDateTime(); -} - -IMAP4Protocol::~IMAP4Protocol () -{ - closeDescriptor(); - kdDebug(7116) << "IMAP4: Finishing" << endl; -} - -void -IMAP4Protocol::get (const KURL & _url) -{ - if (!makeLogin()) return; - kdDebug(7116) << "IMAP4::get - " << _url.prettyURL() << endl; - TQString aBox, aSequence, aType, aSection, aValidity, aDelimiter, aInfo; - enum IMAP_TYPE aEnum = - parseURL (_url, aBox, aSection, aType, aSequence, aValidity, aDelimiter, aInfo); - if (aEnum != ITYPE_ATTACH) - mimeType (getMimeType(aEnum)); - if (aInfo == "DECODE") - decodeContent = true; - - if (aSequence == "0:0" && getState() == ISTATE_SELECT) - { - imapCommand *cmd = doCommand (imapCommand::clientNoop()); - completeQueue.removeRef(cmd); - } - - if (aSequence.isEmpty ()) - { - aSequence = "1:*"; - } - - mProcessedSize = 0; - imapCommand *cmd = NULL; - if (!assureBox (aBox, true)) return; - -#ifdef USE_VALIDITY - if (selectInfo.uidValidityAvailable () && !aValidity.isEmpty () - && selectInfo.uidValidity () != aValidity.toULong ()) - { - // this url is stale - error (ERR_COULD_NOT_READ, _url.prettyURL()); - return; - } - else -#endif - { - // The "section" specified by the application can be: - // * empty (which means body, size and flags) - // * a known keyword, like STRUCTURE, ENVELOPE, HEADER, BODY.PEEK[...] - // (in which case the slave has some logic to add the necessary items) - // * Otherwise, it specifies the exact data items to request. In this case, all - // the logic is in the app. - - TQString aUpper = aSection.upper(); - if (aUpper.find ("STRUCTURE") != -1) - { - aSection = "BODYSTRUCTURE"; - } - else if (aUpper.find ("ENVELOPE") != -1) - { - aSection = "UID RFC822.SIZE FLAGS ENVELOPE"; - if (hasCapability("IMAP4rev1")) { - aSection += " BODY.PEEK[HEADER.FIELDS (REFERENCES)]"; - } else { - // imap4 does not know HEADER.FIELDS - aSection += " RFC822.HEADER.LINES (REFERENCES)"; - } - } - else if (aUpper == "HEADER") - { - aSection = "UID RFC822.HEADER RFC822.SIZE FLAGS"; - } - else if (aUpper.find ("BODY.PEEK[") != -1) - { - if (aUpper.find ("BODY.PEEK[]") != -1) - { - if (!hasCapability("IMAP4rev1")) // imap4 does not know BODY.PEEK[] - aSection.replace("BODY.PEEK[]", "RFC822.PEEK"); - } - aSection.prepend("UID RFC822.SIZE FLAGS "); - } - else if (aSection.isEmpty()) - { - aSection = "UID BODY[] RFC822.SIZE FLAGS"; - } - if (aEnum == ITYPE_BOX || aEnum == ITYPE_DIR_AND_BOX) - { - // write the digest header - cacheOutput = true; - outputLine - ("Content-Type: multipart/digest; boundary=\"IMAPDIGEST\"\r\n", 55); - if (selectInfo.recentAvailable ()) - outputLineStr ("X-Recent: " + - TQString::number(selectInfo.recent ()) + "\r\n"); - if (selectInfo.countAvailable ()) - outputLineStr ("X-Count: " + TQString::number(selectInfo.count ()) + - "\r\n"); - if (selectInfo.unseenAvailable ()) - outputLineStr ("X-Unseen: " + - TQString::number(selectInfo.unseen ()) + "\r\n"); - if (selectInfo.uidValidityAvailable ()) - outputLineStr ("X-uidValidity: " + - TQString::number(selectInfo.uidValidity ()) + - "\r\n"); - if (selectInfo.uidNextAvailable ()) - outputLineStr ("X-UidNext: " + - TQString::number(selectInfo.uidNext ()) + "\r\n"); - if (selectInfo.flagsAvailable ()) - outputLineStr ("X-Flags: " + TQString::number(selectInfo.flags ()) + - "\r\n"); - if (selectInfo.permanentFlagsAvailable ()) - outputLineStr ("X-PermanentFlags: " + - TQString::number(selectInfo.permanentFlags ()) + "\r\n"); - if (selectInfo.readWriteAvailable ()) { - if (selectInfo.readWrite()) { - outputLine ("X-Access: Read/Write\r\n", 22); - } else { - outputLine ("X-Access: Read only\r\n", 21); - } - } - outputLine ("\r\n", 2); - flushOutput(TQString()); - cacheOutput = false; - } - - if (aEnum == ITYPE_MSG || (aEnum == ITYPE_ATTACH && !decodeContent)) - relayEnabled = true; // normal mode, relay data - - if (aSequence != "0:0") - { - TQString contentEncoding; - if (aEnum == ITYPE_ATTACH && decodeContent) - { - // get the MIME header and fill getLastHandled() - TQString mySection = aSection; - mySection.replace("]", ".MIME]"); - cmd = sendCommand (imapCommand::clientFetch (aSequence, mySection)); - do - { - while (!parseLoop ()) ; - } - while (!cmd->isComplete ()); - completeQueue.removeRef (cmd); - // get the content encoding now because getLastHandled will be cleared - if (getLastHandled() && getLastHandled()->getHeader()) - contentEncoding = getLastHandled()->getHeader()->getEncoding(); - - // from here on collect the data - // it is send to the client in flushOutput in one go - // needed to decode the content - cacheOutput = true; - } - - cmd = sendCommand (imapCommand::clientFetch (aSequence, aSection)); - int res; - aUpper = aSection.upper(); - do - { - while (!(res = parseLoop())) ; - if (res == -1) break; - - mailHeader *lastone = 0; - imapCache *cache = getLastHandled (); - if (cache) - lastone = cache->getHeader (); - - if (cmd && !cmd->isComplete ()) - { - if ((aUpper.find ("BODYSTRUCTURE") != -1) - || (aUpper.find ("FLAGS") != -1) - || (aUpper.find ("UID") != -1) - || (aUpper.find ("ENVELOPE") != -1) - || (aUpper.find ("BODY.PEEK[0]") != -1 - && (aEnum == ITYPE_BOX || aEnum == ITYPE_DIR_AND_BOX))) - { - if (aEnum == ITYPE_BOX || aEnum == ITYPE_DIR_AND_BOX) - { - // write the mime header (default is here message/rfc822) - outputLine ("--IMAPDIGEST\r\n", 14); - cacheOutput = true; - if (cache && cache->getUid () != 0) - outputLineStr ("X-UID: " + - TQString::number(cache->getUid ()) + "\r\n"); - if (cache && cache->getSize () != 0) - outputLineStr ("X-Length: " + - TQString::number(cache->getSize ()) + "\r\n"); - if (cache && !cache->getDate ().isEmpty()) - outputLineStr ("X-Date: " + cache->getDate () + "\r\n"); - if (cache && cache->getFlags () != 0) - outputLineStr ("X-Flags: " + - TQString::number(cache->getFlags ()) + "\r\n"); - } else cacheOutput = true; - if ( lastone && !decodeContent ) - lastone->outputPart (*this); - cacheOutput = false; - flushOutput(contentEncoding); - } - } // if not complete - } - while (cmd && !cmd->isComplete ()); - if (aEnum == ITYPE_BOX || aEnum == ITYPE_DIR_AND_BOX) - { - // write the end boundary - outputLine ("--IMAPDIGEST--\r\n", 16); - } - - completeQueue.removeRef (cmd); - } - } - - // just to keep everybody happy when no data arrived - data (TQByteArray ()); - - finished (); - relayEnabled = false; - cacheOutput = false; - kdDebug(7116) << "IMAP4::get - finished" << endl; -} - -void -IMAP4Protocol::listDir (const KURL & _url) -{ - kdDebug(7116) << " IMAP4::listDir - " << _url.prettyURL() << endl; - - if (_url.path().isEmpty()) - { - KURL url = _url; - url.setPath("/"); - redirection( url ); - finished(); - return; - } - - TQString myBox, mySequence, myLType, mySection, myValidity, myDelimiter, myInfo; - // parseURL with caching - enum IMAP_TYPE myType = - parseURL (_url, myBox, mySection, myLType, mySequence, myValidity, - myDelimiter, myInfo, true); - - if (!makeLogin()) return; - - if (myType == ITYPE_DIR || myType == ITYPE_DIR_AND_BOX) - { - TQString listStr = myBox; - imapCommand *cmd; - - if (!listStr.isEmpty () && !listStr.endsWith(myDelimiter) && - mySection != "FOLDERONLY") - listStr += myDelimiter; - - if (mySection.isEmpty()) - { - listStr += "%"; - } else if (mySection == "COMPLETE") { - listStr += "*"; - } - kdDebug(7116) << "IMAP4Protocol::listDir - listStr=" << listStr << endl; - cmd = - doCommand (imapCommand::clientList ("", listStr, - (myLType == "LSUB" || myLType == "LSUBNOCHECK"))); - if (cmd->result () == "OK") - { - TQString mailboxName; - UDSEntry entry; - UDSAtom atom; - KURL aURL = _url; - if (aURL.path().find(';') != -1) - aURL.setPath(aURL.path().left(aURL.path().find(';'))); - - kdDebug(7116) << "IMAP4Protocol::listDir - got " << listResponses.count () << endl; - - if (myLType == "LSUB") - { - // fire the same command as LIST to check if the box really exists - TQValueList<imapList> listResponsesSave = listResponses; - doCommand (imapCommand::clientList ("", listStr, false)); - for (TQValueListIterator < imapList > it = listResponsesSave.begin (); - it != listResponsesSave.end (); ++it) - { - bool boxOk = false; - for (TQValueListIterator < imapList > it2 = listResponses.begin (); - it2 != listResponses.end (); ++it2) - { - if ((*it2).name() == (*it).name()) - { - boxOk = true; - // copy the flags from the LIST-command - (*it) = (*it2); - break; - } - } - if (boxOk) - doListEntry (aURL, myBox, (*it), (mySection != "FOLDERONLY")); - else // this folder is dead - kdDebug(7116) << "IMAP4Protocol::listDir - suppress " << (*it).name() << endl; - } - listResponses = listResponsesSave; - } - else // LIST or LSUBNOCHECK - { - for (TQValueListIterator < imapList > it = listResponses.begin (); - it != listResponses.end (); ++it) - { - doListEntry (aURL, myBox, (*it), (mySection != "FOLDERONLY")); - } - } - entry.clear (); - listEntry (entry, true); - } - else - { - error (ERR_CANNOT_ENTER_DIRECTORY, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - if ((myType == ITYPE_BOX || myType == ITYPE_DIR_AND_BOX) - && myLType != "LIST" && myLType != "LSUB" && myLType != "LSUBNOCHECK") - { - KURL aURL = _url; - aURL.setQuery (TQString()); - const TQString encodedUrl = aURL.url(0, 106); // utf-8 - - if (!_url.query ().isEmpty ()) - { - TQString query = KURL::decode_string (_url.query ()); - query = query.right (query.length () - 1); - if (!query.isEmpty()) - { - imapCommand *cmd = NULL; - - if (!assureBox (myBox, true)) return; - - if (!selectInfo.countAvailable() || selectInfo.count()) - { - cmd = doCommand (imapCommand::clientSearch (query)); - if (cmd->result() != "OK") - { - error(ERR_UNSUPPORTED_ACTION, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - - TQStringList list = getResults (); - int stretch = 0; - - if (selectInfo.uidNextAvailable ()) - stretch = TQString::number(selectInfo.uidNext ()).length (); - UDSEntry entry; - imapCache fake; - - for (TQStringList::ConstIterator it = list.begin(); it != list.end(); - ++it) - { - fake.setUid((*it).toULong()); - doListEntry (encodedUrl, stretch, &fake); - } - entry.clear (); - listEntry (entry, true); - } - } - } - else - { - if (!assureBox (myBox, true)) return; - - kdDebug(7116) << "IMAP4: select returned:" << endl; - if (selectInfo.recentAvailable ()) - kdDebug(7116) << "Recent: " << selectInfo.recent () << "d" << endl; - if (selectInfo.countAvailable ()) - kdDebug(7116) << "Count: " << selectInfo.count () << "d" << endl; - if (selectInfo.unseenAvailable ()) - kdDebug(7116) << "Unseen: " << selectInfo.unseen () << "d" << endl; - if (selectInfo.uidValidityAvailable ()) - kdDebug(7116) << "uidValidity: " << selectInfo.uidValidity () << "d" << endl; - if (selectInfo.flagsAvailable ()) - kdDebug(7116) << "Flags: " << selectInfo.flags () << "d" << endl; - if (selectInfo.permanentFlagsAvailable ()) - kdDebug(7116) << "PermanentFlags: " << selectInfo.permanentFlags () << "d" << endl; - if (selectInfo.readWriteAvailable ()) - kdDebug(7116) << "Access: " << (selectInfo.readWrite ()? "Read/Write" : "Read only") << endl; - -#ifdef USE_VALIDITY - if (selectInfo.uidValidityAvailable () - && selectInfo.uidValidity () != myValidity.toULong ()) - { - //redirect - KURL newUrl = _url; - - newUrl.setPath ("/" + myBox + ";UIDVALIDITY=" + - TQString::number(selectInfo.uidValidity ())); - kdDebug(7116) << "IMAP4::listDir - redirecting to " << newUrl.prettyURL() << endl; - redirection (newUrl); - - - } - else -#endif - if (selectInfo.count () > 0) - { - int stretch = 0; - - if (selectInfo.uidNextAvailable ()) - stretch = TQString::number(selectInfo.uidNext ()).length (); - // kdDebug(7116) << selectInfo.uidNext() << "d used to stretch " << stretch << endl; - UDSEntry entry; - - if (mySequence.isEmpty()) mySequence = "1:*"; - - bool withSubject = mySection.isEmpty(); - if (mySection.isEmpty()) mySection = "UID RFC822.SIZE ENVELOPE"; - - bool withFlags = mySection.upper().find("FLAGS") != -1; - imapCommand *fetch = - sendCommand (imapCommand:: - clientFetch (mySequence, mySection)); - imapCache *cache; - do - { - while (!parseLoop ()) ; - - cache = getLastHandled (); - - if (cache && !fetch->isComplete()) - doListEntry (encodedUrl, stretch, cache, withFlags, withSubject); - } - while (!fetch->isComplete ()); - entry.clear (); - listEntry (entry, true); - } - } - } - if ( !selectInfo.alert().isNull() ) { - if ( !myBox.isEmpty() ) { - warning( i18n( "Message from %1 while processing '%2': %3" ).arg( myHost, myBox, selectInfo.alert() ) ); - } else { - warning( i18n( "Message from %1: %2" ).arg( myHost, TQString(selectInfo.alert()) ) ); - } - selectInfo.setAlert( 0 ); - } - - kdDebug(7116) << "IMAP4Protocol::listDir - Finishing listDir" << endl; - finished (); -} - -void -IMAP4Protocol::setHost (const TQString & _host, int _port, - const TQString & _user, const TQString & _pass) -{ - if (myHost != _host || myPort != _port || myUser != _user || myPass != _pass) - { // what's the point of doing 4 string compares to avoid 4 string copies? - // DF: I guess to avoid calling closeConnection() unnecessarily. - if (!myHost.isEmpty ()) - closeConnection (); - myHost = _host; - myPort = _port; - myUser = _user; - myPass = _pass; - } -} - -void -IMAP4Protocol::parseRelay (const TQByteArray & buffer) -{ - if (relayEnabled) { - // relay data immediately - data( buffer ); - mProcessedSize += buffer.size(); - processedSize( mProcessedSize ); - } else if (cacheOutput) - { - // collect data - if ( !outputBuffer.isOpen() ) { - outputBuffer.open(IO_WriteOnly); - } - outputBuffer.at(outputBufferIndex); - outputBuffer.writeBlock(buffer, buffer.size()); - outputBufferIndex += buffer.size(); - } -} - -void -IMAP4Protocol::parseRelay (ulong len) -{ - if (relayEnabled) - totalSize (len); -} - - -bool IMAP4Protocol::parseRead(TQByteArray & buffer, ulong len, ulong relay) -{ - char buf[8192]; - while (buffer.size() < len) - { - ssize_t readLen = myRead(buf, TQMIN(len - buffer.size(), sizeof(buf) - 1)); - if (readLen == 0) - { - kdDebug(7116) << "parseRead: readLen == 0 - connection broken" << endl; - error (ERR_CONNECTION_BROKEN, myHost); - setState(ISTATE_CONNECT); - closeConnection(); - return FALSE; - } - if (relay > buffer.size()) - { - TQByteArray relayData; - ssize_t relbuf = relay - buffer.size(); - int currentRelay = TQMIN(relbuf, readLen); - relayData.setRawData(buf, currentRelay); - parseRelay(relayData); - relayData.resetRawData(buf, currentRelay); - } - { - TQBuffer stream (buffer); - stream.open (IO_WriteOnly); - stream.at (buffer.size ()); - stream.writeBlock (buf, readLen); - stream.close (); - } - } - return (buffer.size() == len); -} - - -bool IMAP4Protocol::parseReadLine (TQByteArray & buffer, ulong relay) -{ - if (myHost.isEmpty()) return FALSE; - - while (true) { - ssize_t copyLen = 0; - if (readBufferLen > 0) - { - while (copyLen < readBufferLen && readBuffer[copyLen] != '\n') copyLen++; - if (copyLen < readBufferLen) copyLen++; - if (relay > 0) - { - TQByteArray relayData; - - if (copyLen < (ssize_t) relay) - relay = copyLen; - relayData.setRawData (readBuffer, relay); - parseRelay (relayData); - relayData.resetRawData (readBuffer, relay); -// kdDebug(7116) << "relayed : " << relay << "d" << endl; - } - // append to buffer - { - TQBuffer stream (buffer); - - stream.open (IO_WriteOnly); - stream.at (buffer.size ()); - stream.writeBlock (readBuffer, copyLen); - stream.close (); -// kdDebug(7116) << "appended " << copyLen << "d got now " << buffer.size() << endl; - } - - readBufferLen -= copyLen; - if (readBufferLen) - memmove(readBuffer, &readBuffer[copyLen], readBufferLen); - if (buffer[buffer.size() - 1] == '\n') return TRUE; - } - if (!isConnectionValid()) - { - kdDebug(7116) << "parseReadLine - connection broken" << endl; - error (ERR_CONNECTION_BROKEN, myHost); - setState(ISTATE_CONNECT); - closeConnection(); - return FALSE; - } - if (!waitForResponse( responseTimeout() )) - { - error(ERR_SERVER_TIMEOUT, myHost); - setState(ISTATE_CONNECT); - closeConnection(); - return FALSE; - } - readBufferLen = read(readBuffer, IMAP_BUFFER - 1); - if (readBufferLen == 0) - { - kdDebug(7116) << "parseReadLine: readBufferLen == 0 - connection broken" << endl; - error (ERR_CONNECTION_BROKEN, myHost); - setState(ISTATE_CONNECT); - closeConnection(); - return FALSE; - } - } -} - -void -IMAP4Protocol::setSubURL (const KURL & _url) -{ - kdDebug(7116) << "IMAP4::setSubURL - " << _url.prettyURL() << endl; - TDEIO::TCPSlaveBase::setSubURL (_url); -} - -void -IMAP4Protocol::put (const KURL & _url, int, bool, bool) -{ - kdDebug(7116) << "IMAP4::put - " << _url.prettyURL() << endl; -// TDEIO::TCPSlaveBase::put(_url,permissions,overwrite,resume); - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - enum IMAP_TYPE aType = - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - - // see if it is a box - if (aType != ITYPE_BOX && aType != ITYPE_DIR_AND_BOX) - { - if (aBox[aBox.length () - 1] == '/') - aBox = aBox.right (aBox.length () - 1); - imapCommand *cmd = doCommand (imapCommand::clientCreate (aBox)); - - if (cmd->result () != "OK") { - error (ERR_COULD_NOT_WRITE, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - else - { - TQPtrList < TQByteArray > bufferList; - int length = 0; - - int result; - // Loop until we got 'dataEnd' - do - { - TQByteArray *buffer = new TQByteArray (); - dataReq (); // Request for data - result = readData (*buffer); - if (result > 0) - { - bufferList.append (buffer); - length += result; - } else { - delete buffer; - } - } - while (result > 0); - - if (result != 0) - { - error (ERR_ABORTED, _url.prettyURL()); - return; - } - - imapCommand *cmd = - sendCommand (imapCommand::clientAppend (aBox, aSection, length)); - while (!parseLoop ()) ; - - // see if server is waiting - if (!cmd->isComplete () && !getContinuation ().isEmpty ()) - { - bool sendOk = true; - ulong wrote = 0; - - TQByteArray *buffer; - // send data to server - while (!bufferList.isEmpty () && sendOk) - { - buffer = bufferList.take (0); - - sendOk = - (write (buffer->data (), buffer->size ()) == - (ssize_t) buffer->size ()); - wrote += buffer->size (); - processedSize(wrote); - delete buffer; - if (!sendOk) - { - error (ERR_CONNECTION_BROKEN, myHost); - completeQueue.removeRef (cmd); - setState(ISTATE_CONNECT); - closeConnection(); - return; - } - } - parseWriteLine (""); - // Wait until cmd is complete, or connection breaks. - while (!cmd->isComplete () && getState() != ISTATE_NO) - parseLoop (); - if ( getState() == ISTATE_NO ) { - // TODO KDE4: pass cmd->resultInfo() as third argument. - // ERR_CONNECTION_BROKEN expects a host, no way to pass details about the problem. - error( ERR_CONNECTION_BROKEN, myHost ); - completeQueue.removeRef (cmd); - closeConnection(); - return; - } - else if (cmd->result () != "OK") { - error( ERR_SLAVE_DEFINED, cmd->resultInfo() ); - completeQueue.removeRef (cmd); - return; - } - else - { - if (hasCapability("UIDPLUS")) - { - TQString uid = cmd->resultInfo(); - if (uid.find("APPENDUID") != -1) - { - uid = uid.section(" ", 2, 2); - uid.truncate(uid.length()-1); - infoMessage("UID "+uid); - } - } - // MUST reselect to get the new message - else if (aBox == getCurrentBox ()) - { - cmd = - doCommand (imapCommand:: - clientSelect (aBox, !selectInfo.readWrite ())); - completeQueue.removeRef (cmd); - } - } - } - else - { - //error (ERR_COULD_NOT_WRITE, myHost); - // Better ship the error message, e.g. "Over Quota" - error (ERR_SLAVE_DEFINED, cmd->resultInfo()); - completeQueue.removeRef (cmd); - return; - } - - completeQueue.removeRef (cmd); - } - - finished (); -} - -void -IMAP4Protocol::mkdir (const KURL & _url, int) -{ - kdDebug(7116) << "IMAP4::mkdir - " << _url.prettyURL() << endl; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL(_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - kdDebug(7116) << "IMAP4::mkdir - create " << aBox << endl; - imapCommand *cmd = doCommand (imapCommand::clientCreate(aBox)); - - if (cmd->result () != "OK") - { - kdDebug(7116) << "IMAP4::mkdir - " << cmd->resultInfo() << endl; - error (ERR_COULD_NOT_MKDIR, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - - // start a new listing to find the type of the folder - enum IMAP_TYPE type = - parseURL(_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - if (type == ITYPE_BOX) - { - bool ask = ( aInfo.find( "ASKUSER" ) != -1 ); - if ( ask && - messageBox(QuestionYesNo, - i18n("The following folder will be created on the server: %1 " - "What do you want to store in this folder?").arg( aBox ), - i18n("Create Folder"), - i18n("&Messages"), i18n("&Subfolders")) == KMessageBox::No ) - { - cmd = doCommand(imapCommand::clientDelete(aBox)); - completeQueue.removeRef (cmd); - cmd = doCommand(imapCommand::clientCreate(aBox + aDelimiter)); - if (cmd->result () != "OK") - { - error (ERR_COULD_NOT_MKDIR, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - } - - cmd = doCommand(imapCommand::clientSubscribe(aBox)); - completeQueue.removeRef(cmd); - - finished (); -} - -void -IMAP4Protocol::copy (const KURL & src, const KURL & dest, int, bool overwrite) -{ - kdDebug(7116) << "IMAP4::copy - [" << (overwrite ? "Overwrite" : "NoOverwrite") << "] " << src.prettyURL() << " -> " << dest.prettyURL() << endl; - TQString sBox, sSequence, sLType, sSection, sValidity, sDelimiter, sInfo; - TQString dBox, dSequence, dLType, dSection, dValidity, dDelimiter, dInfo; - enum IMAP_TYPE sType = - parseURL (src, sBox, sSection, sLType, sSequence, sValidity, sDelimiter, sInfo); - enum IMAP_TYPE dType = - parseURL (dest, dBox, dSection, dLType, dSequence, dValidity, dDelimiter, dInfo); - - // see if we have to create anything - if (dType != ITYPE_BOX && dType != ITYPE_DIR_AND_BOX) - { - // this might be konqueror - int sub = dBox.find (sBox); - - // might be moving to upper folder - if (sub > 0) - { - KURL testDir = dest; - - TQString subDir = dBox.right (dBox.length () - dBox.findRev ('/')); - TQString topDir = dBox.left (sub); - testDir.setPath ("/" + topDir); - dType = - parseURL (testDir, topDir, dSection, dLType, dSequence, dValidity, - dDelimiter, dInfo); - - kdDebug(7116) << "IMAP4::copy - checking this destination " << topDir << endl; - // see if this is what the user wants - if (dType == ITYPE_BOX || dType == ITYPE_DIR_AND_BOX) - { - kdDebug(7116) << "IMAP4::copy - assuming this destination " << topDir << endl; - dBox = topDir; - } - else - { - - // maybe if we create a new mailbox - topDir = "/" + topDir + subDir; - testDir.setPath (topDir); - kdDebug(7116) << "IMAP4::copy - checking this destination " << topDir << endl; - dType = - parseURL (testDir, topDir, dSection, dLType, dSequence, dValidity, - dDelimiter, dInfo); - if (dType != ITYPE_BOX && dType != ITYPE_DIR_AND_BOX) - { - // ok then we'll create a mailbox - imapCommand *cmd = doCommand (imapCommand::clientCreate (topDir)); - - // on success we'll use it, else we'll just try to create the given dir - if (cmd->result () == "OK") - { - kdDebug(7116) << "IMAP4::copy - assuming this destination " << topDir << endl; - dType = ITYPE_BOX; - dBox = topDir; - } - else - { - completeQueue.removeRef (cmd); - cmd = doCommand (imapCommand::clientCreate (dBox)); - if (cmd->result () == "OK") - dType = ITYPE_BOX; - else - error (ERR_COULD_NOT_WRITE, dest.prettyURL()); - } - completeQueue.removeRef (cmd); - } - } - - } - } - if (sType == ITYPE_MSG || sType == ITYPE_BOX || sType == ITYPE_DIR_AND_BOX) - { - //select the source box - if (!assureBox(sBox, true)) return; - kdDebug(7116) << "IMAP4::copy - " << sBox << " -> " << dBox << endl; - - //issue copy command - imapCommand *cmd = - doCommand (imapCommand::clientCopy (dBox, sSequence)); - if (cmd->result () != "OK") - { - kdError(5006) << "IMAP4::copy - " << cmd->resultInfo() << endl; - error (ERR_COULD_NOT_WRITE, dest.prettyURL()); - completeQueue.removeRef (cmd); - return; - } else { - if (hasCapability("UIDPLUS")) - { - TQString uid = cmd->resultInfo(); - if (uid.find("COPYUID") != -1) - { - uid = uid.section(" ", 2, 3); - uid.truncate(uid.length()-1); - infoMessage("UID "+uid); - } - } - } - completeQueue.removeRef (cmd); - } - else - { - error (ERR_ACCESS_DENIED, src.prettyURL()); - return; - } - finished (); -} - -void -IMAP4Protocol::del (const KURL & _url, bool isFile) -{ - kdDebug(7116) << "IMAP4::del - [" << (isFile ? "File" : "NoFile") << "] " << _url.prettyURL() << endl; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - enum IMAP_TYPE aType = - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - - switch (aType) - { - case ITYPE_BOX: - case ITYPE_DIR_AND_BOX: - if (!aSequence.isEmpty ()) - { - if (aSequence == "*") - { - if (!assureBox (aBox, false)) return; - imapCommand *cmd = doCommand (imapCommand::clientExpunge ()); - if (cmd->result () != "OK") { - error (ERR_CANNOT_DELETE, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - else - { - // if open for read/write - if (!assureBox (aBox, false)) return; - imapCommand *cmd = - doCommand (imapCommand:: - clientStore (aSequence, "+FLAGS.SILENT", "\\DELETED")); - if (cmd->result () != "OK") { - error (ERR_CANNOT_DELETE, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - } - else - { - if (getCurrentBox() == aBox) - { - imapCommand *cmd = doCommand(imapCommand::clientClose()); - completeQueue.removeRef(cmd); - setState(ISTATE_LOGIN); - } - // We unsubscribe, otherwise we get ghost folders on UW-IMAP - imapCommand *cmd = doCommand(imapCommand::clientUnsubscribe(aBox)); - completeQueue.removeRef(cmd); - cmd = doCommand(imapCommand::clientDelete (aBox)); - // If this doesn't work, we try to empty the mailbox first - if (cmd->result () != "OK") - { - completeQueue.removeRef(cmd); - if (!assureBox(aBox, false)) return; - bool stillOk = true; - if (stillOk) - { - imapCommand *cmd = doCommand( - imapCommand::clientStore("1:*", "+FLAGS.SILENT", "\\DELETED")); - if (cmd->result () != "OK") stillOk = false; - completeQueue.removeRef(cmd); - } - if (stillOk) - { - imapCommand *cmd = doCommand(imapCommand::clientClose()); - if (cmd->result () != "OK") stillOk = false; - completeQueue.removeRef(cmd); - setState(ISTATE_LOGIN); - } - if (stillOk) - { - imapCommand *cmd = doCommand (imapCommand::clientDelete(aBox)); - if (cmd->result () != "OK") stillOk = false; - completeQueue.removeRef(cmd); - } - if (!stillOk) - { - error (ERR_COULD_NOT_RMDIR, _url.prettyURL()); - return; - } - } else { - completeQueue.removeRef (cmd); - } - } - break; - - case ITYPE_DIR: - { - imapCommand *cmd = doCommand (imapCommand::clientDelete (aBox)); - if (cmd->result () != "OK") { - error (ERR_COULD_NOT_RMDIR, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - break; - - case ITYPE_MSG: - { - // if open for read/write - if (!assureBox (aBox, false)) return; - imapCommand *cmd = - doCommand (imapCommand:: - clientStore (aSequence, "+FLAGS.SILENT", "\\DELETED")); - if (cmd->result () != "OK") { - error (ERR_CANNOT_DELETE, _url.prettyURL()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - break; - - case ITYPE_UNKNOWN: - case ITYPE_ATTACH: - error (ERR_CANNOT_DELETE, _url.prettyURL()); - break; - } - finished (); -} - -/* - * Copy a mail: data = 'C' + srcURL (KURL) + destURL (KURL) - * Capabilities: data = 'c'. Result shipped in infoMessage() signal - * No-op: data = 'N' - * Namespace: data = 'n'. Result shipped in infoMessage() signal - * The format is: section=namespace=delimiter - * Note that the namespace can be empty - * Unsubscribe: data = 'U' + URL (KURL) - * Subscribe: data = 'u' + URL (KURL) - * Change the status: data = 'S' + URL (KURL) + Flags (TQCString) - * ACL commands: data = 'A' + command + URL (KURL) + command-dependent args - * AnnotateMore commands: data = 'M' + 'G'et/'S'et + URL + entry + command-dependent args - * Search: data = 'E' + URL (KURL) - * Quota commands: data = 'Q' + 'R'oot/'G'et/'S'et + URL + entry + command-dependent args - * Custom command: data = 'X' + 'N'ormal/'E'xtended + command + command-dependent args - */ -void -IMAP4Protocol::special (const TQByteArray & aData) -{ - kdDebug(7116) << "IMAP4Protocol::special" << endl; - if (!makeLogin()) return; - - TQDataStream stream(aData, IO_ReadOnly); - - int tmp; - stream >> tmp; - - switch (tmp) { - case 'C': - { - // copy - KURL src; - KURL dest; - stream >> src >> dest; - copy(src, dest, 0, FALSE); - break; - } - case 'c': - { - // capabilities - infoMessage(imapCapabilities.join(" ")); - finished(); - break; - } - case 'N': - { - // NOOP - imapCommand *cmd = doCommand(imapCommand::clientNoop()); - if (cmd->result () != "OK") - { - kdDebug(7116) << "NOOP did not succeed - connection broken" << endl; - completeQueue.removeRef (cmd); - error (ERR_CONNECTION_BROKEN, myHost); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'n': - { - // namespace in the form "section=namespace=delimiter" - // entries are separated by , - infoMessage( imapNamespaces.join(",") ); - finished(); - break; - } - case 'U': - { - // unsubscribe - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - imapCommand *cmd = doCommand(imapCommand::clientUnsubscribe(aBox)); - if (cmd->result () != "OK") - { - completeQueue.removeRef (cmd); - error(ERR_SLAVE_DEFINED, i18n("Unsubscribe of folder %1 " - "failed. The server returned: %2") - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'u': - { - // subscribe - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - imapCommand *cmd = doCommand(imapCommand::clientSubscribe(aBox)); - if (cmd->result () != "OK") - { - completeQueue.removeRef (cmd); - error(ERR_SLAVE_DEFINED, i18n("Subscribe of folder %1 " - "failed. The server returned: %2") - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'A': - { - // acl - int cmd; - stream >> cmd; - if ( hasCapability( "ACL" ) ) { - specialACLCommand( cmd, stream ); - } else { - error( ERR_UNSUPPORTED_ACTION, "ACL" ); - } - break; - } - case 'M': - { - // annotatemore - int cmd; - stream >> cmd; - if ( hasCapability( "ANNOTATEMORE" ) ) { - specialAnnotateMoreCommand( cmd, stream ); - } else { - error( ERR_UNSUPPORTED_ACTION, "ANNOTATEMORE" ); - } - break; - } - case 'Q': - { - // quota - int cmd; - stream >> cmd; - if ( hasCapability( "QUOTA" ) ) { - specialQuotaCommand( cmd, stream ); - } else { - error( ERR_UNSUPPORTED_ACTION, "QUOTA" ); - } - break; - } - case 'S': - { - // status - KURL _url; - TQCString newFlags; - stream >> _url >> newFlags; - - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - if (!assureBox(aBox, false)) return; - - // make sure we only touch flags we know - TQCString knownFlags = "\\SEEN \\ANSWERED \\FLAGGED \\DRAFT"; - const imapInfo info = getSelected(); - if ( info.permanentFlagsAvailable() && (info.permanentFlags() & imapInfo::User) ) { - knownFlags += " KMAILFORWARDED KMAILTODO KMAILWATCHED KMAILIGNORED $FORWARDED $TODO $WATCHED $IGNORED"; - } - - imapCommand *cmd = doCommand (imapCommand:: - clientStore (aSequence, "-FLAGS.SILENT", knownFlags)); - if (cmd->result () != "OK") - { - completeQueue.removeRef (cmd); - error(ERR_COULD_NOT_WRITE, i18n("Changing the flags of message %1 " - "failed.").arg(_url.prettyURL())); - return; - } - completeQueue.removeRef (cmd); - if (!newFlags.isEmpty()) - { - cmd = doCommand (imapCommand:: - clientStore (aSequence, "+FLAGS.SILENT", newFlags)); - if (cmd->result () != "OK") - { - completeQueue.removeRef (cmd); - error(ERR_COULD_NOT_WRITE, i18n("Changing the flags of message %1 " - "failed.").arg(_url.prettyURL())); - return; - } - completeQueue.removeRef (cmd); - } - finished(); - break; - } - case 's': - { - // seen - KURL _url; - bool seen; - TQCString newFlags; - stream >> _url >> seen; - - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - if ( !assureBox(aBox, true) ) // read-only because changing SEEN should be possible even then - return; - - imapCommand *cmd; - if ( seen ) - cmd = doCommand( imapCommand::clientStore( aSequence, "+FLAGS.SILENT", "\\SEEN" ) ); - else - cmd = doCommand( imapCommand::clientStore( aSequence, "-FLAGS.SILENT", "\\SEEN" ) ); - - if (cmd->result () != "OK") - { - completeQueue.removeRef (cmd); - error(ERR_COULD_NOT_WRITE, i18n("Changing the flags of message %1 " - "failed.").arg(_url.prettyURL())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - - case 'E': - { - // search - specialSearchCommand( stream ); - break; - } - case 'X': - { - // custom command - specialCustomCommand( stream ); - break; - } - default: - kdWarning(7116) << "Unknown command in special(): " << tmp << endl; - error( ERR_UNSUPPORTED_ACTION, TQString(TQChar(tmp)) ); - break; - } -} - -void -IMAP4Protocol::specialACLCommand( int command, TQDataStream& stream ) -{ - // All commands start with the URL to the box - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - - switch( command ) { - case 'S': // SETACL - { - TQString user, acl; - stream >> user >> acl; - kdDebug(7116) << "SETACL " << aBox << " " << user << " " << acl << endl; - imapCommand *cmd = doCommand(imapCommand::clientSetACL(aBox, user, acl)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Setting the Access Control List on folder %1 " - "for user %2 failed. The server returned: %3") - .arg(_url.prettyURL()) - .arg(user) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'D': // DELETEACL - { - TQString user; - stream >> user; - kdDebug(7116) << "DELETEACL " << aBox << " " << user << endl; - imapCommand *cmd = doCommand(imapCommand::clientDeleteACL(aBox, user)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Deleting the Access Control List on folder %1 " - "for user %2 failed. The server returned: %3") - .arg(_url.prettyURL()) - .arg(user) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'G': // GETACL - { - kdDebug(7116) << "GETACL " << aBox << endl; - imapCommand *cmd = doCommand(imapCommand::clientGetACL(aBox)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Retrieving the Access Control List on folder %1 " - "failed. The server returned: %2") - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - // Returning information to the application from a special() command isn't easy. - // I'm reusing the infoMessage trick seen above (for capabilities), but this - // limits me to a string instead of a stringlist. Using DQUOTE as separator, - // because it's forbidden in userids by rfc3501 - kdDebug(7116) << getResults() << endl; - infoMessage(getResults().join( "\"" )); - finished(); - break; - } - case 'L': // LISTRIGHTS - { - // Do we need this one? It basically shows which rights are tied together, but that's all? - error( ERR_UNSUPPORTED_ACTION, TQString(TQChar(command)) ); - break; - } - case 'M': // MYRIGHTS - { - kdDebug(7116) << "MYRIGHTS " << aBox << endl; - imapCommand *cmd = doCommand(imapCommand::clientMyRights(aBox)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Retrieving the Access Control List on folder %1 " - "failed. The server returned: %2") - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - TQStringList lst = getResults(); - kdDebug(7116) << "myrights results: " << lst << endl; - if ( !lst.isEmpty() ) { - Q_ASSERT( lst.count() == 1 ); - infoMessage( lst.first() ); - } - finished(); - break; - } - default: - kdWarning(7116) << "Unknown special ACL command:" << command << endl; - error( ERR_UNSUPPORTED_ACTION, TQString(TQChar(command)) ); - } -} - -void -IMAP4Protocol::specialSearchCommand( TQDataStream& stream ) -{ - kdDebug(7116) << "IMAP4Protocol::specialSearchCommand" << endl; - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - if (!assureBox(aBox, false)) return; - - imapCommand *cmd = doCommand (imapCommand::clientSearch( aSection )); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Searching of folder %1 " - "failed. The server returned: %2") - .arg(aBox) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef(cmd); - TQStringList lst = getResults(); - kdDebug(7116) << "IMAP4Protocol::specialSearchCommand '" << aSection << - "' returns " << lst << endl; - infoMessage( lst.join( " " ) ); - - finished(); -} - -void -IMAP4Protocol::specialCustomCommand( TQDataStream& stream ) -{ - kdDebug(7116) << "IMAP4Protocol::specialCustomCommand" << endl; - - TQString command, arguments; - int type; - stream >> type; - stream >> command >> arguments; - - /** - * In 'normal' mode we send the command with all information in one go - * and retrieve the result. - */ - if ( type == 'N' ) { - kdDebug(7116) << "IMAP4Protocol::specialCustomCommand: normal mode" << endl; - imapCommand *cmd = doCommand (imapCommand::clientCustom( command, arguments )); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Custom command %1:%2 " - "failed. The server returned: %3") - .arg(command) - .arg(arguments) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef(cmd); - TQStringList lst = getResults(); - kdDebug(7116) << "IMAP4Protocol::specialCustomCommand '" << command << - ":" << arguments << - "' returns " << lst << endl; - infoMessage( lst.join( " " ) ); - - finished(); - } else - /** - * In 'extended' mode we send a first header and push the data of the request in - * streaming mode. - */ - if ( type == 'E' ) { - kdDebug(7116) << "IMAP4Protocol::specialCustomCommand: extended mode" << endl; - imapCommand *cmd = sendCommand (imapCommand::clientCustom( command, TQString() )); - while ( !parseLoop () ) ; - - // see if server is waiting - if (!cmd->isComplete () && !getContinuation ().isEmpty ()) - { - const TQByteArray buffer = arguments.utf8(); - - // send data to server - bool sendOk = (write (buffer.data (), buffer.size ()) == (ssize_t)buffer.size ()); - processedSize( buffer.size() ); - - if ( !sendOk ) { - error ( ERR_CONNECTION_BROKEN, myHost ); - completeQueue.removeRef ( cmd ); - setState(ISTATE_CONNECT); - closeConnection(); - return; - } - } - parseWriteLine (""); - - do - { - while (!parseLoop ()) ; - } - while (!cmd->isComplete ()); - - completeQueue.removeRef (cmd); - - TQStringList lst = getResults(); - kdDebug(7116) << "IMAP4Protocol::specialCustomCommand: returns " << lst << endl; - infoMessage( lst.join( " " ) ); - - finished (); - } -} - -void -IMAP4Protocol::specialAnnotateMoreCommand( int command, TQDataStream& stream ) -{ - // All commands start with the URL to the box - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - - switch( command ) { - case 'S': // SETANNOTATION - { - // Params: - // KURL URL of the mailbox - // TQString entry (should be an actual entry name, no % or *; empty for server entries) - // TQMap<TQString,TQString> attributes (name and value) - TQString entry; - TQMap<TQString, TQString> attributes; - stream >> entry >> attributes; - kdDebug(7116) << "SETANNOTATION " << aBox << " " << entry << " " << attributes.count() << " attributes" << endl; - imapCommand *cmd = doCommand(imapCommand::clientSetAnnotation(aBox, entry, attributes)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Setting the annotation %1 on folder %2 " - " failed. The server returned: %3") - .arg(entry) - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - completeQueue.removeRef (cmd); - finished(); - break; - } - case 'G': // GETANNOTATION. - { - // Params: - // KURL URL of the mailbox - // TQString entry (should be an actual entry name, no % or *; empty for server entries) - // TQStringList attributes (list of attributes to be retrieved, possibly with % or *) - TQString entry; - TQStringList attributeNames; - stream >> entry >> attributeNames; - kdDebug(7116) << "GETANNOTATION " << aBox << " " << entry << " " << attributeNames << endl; - imapCommand *cmd = doCommand(imapCommand::clientGetAnnotation(aBox, entry, attributeNames)); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Retrieving the annotation %1 on folder %2 " - "failed. The server returned: %3") - .arg(entry) - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - // Returning information to the application from a special() command isn't easy. - // I'm reusing the infoMessage trick seen above (for capabilities and acls), but this - // limits me to a string instead of a stringlist. Let's use \r as separator. - kdDebug(7116) << getResults() << endl; - infoMessage(getResults().join( "\r" )); - finished(); - break; - } - default: - kdWarning(7116) << "Unknown special annotate command:" << command << endl; - error( ERR_UNSUPPORTED_ACTION, TQString(TQChar(command)) ); - } -} - -void -IMAP4Protocol::specialQuotaCommand( int command, TQDataStream& stream ) -{ - // All commands start with the URL to the box - KURL _url; - stream >> _url; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, aInfo); - - switch( command ) { - case 'R': // GETQUOTAROOT - { - kdDebug(7116) << "QUOTAROOT " << aBox << endl; - imapCommand *cmd = doCommand(imapCommand::clientGetQuotaroot( aBox ) ); - if (cmd->result () != "OK") - { - error(ERR_SLAVE_DEFINED, i18n("Retrieving the quota root information on folder %1 " - "failed. The server returned: %2") - .arg(_url.prettyURL()) - .arg(cmd->resultInfo())); - return; - } - infoMessage(getResults().join( "\r" )); - finished(); - break; - } - case 'G': // GETQUOTA - { - kdDebug(7116) << "GETQUOTA command" << endl; - kdWarning(7116) << "UNIMPLEMENTED" << endl; - break; - } - case 'S': // SETQUOTA - { - kdDebug(7116) << "SETQUOTA command" << endl; - kdWarning(7116) << "UNIMPLEMENTED" << endl; - break; - } - default: - kdWarning(7116) << "Unknown special quota command:" << command << endl; - error( ERR_UNSUPPORTED_ACTION, TQString(TQChar(command)) ); - } -} - -void -IMAP4Protocol::rename (const KURL & src, const KURL & dest, bool overwrite) -{ - kdDebug(7116) << "IMAP4::rename - [" << (overwrite ? "Overwrite" : "NoOverwrite") << "] " << src.prettyURL() << " -> " << dest.prettyURL() << endl; - TQString sBox, sSequence, sLType, sSection, sValidity, sDelimiter, sInfo; - TQString dBox, dSequence, dLType, dSection, dValidity, dDelimiter, dInfo; - enum IMAP_TYPE sType = - parseURL (src, sBox, sSection, sLType, sSequence, sValidity, sDelimiter, sInfo, false); - enum IMAP_TYPE dType = - parseURL (dest, dBox, dSection, dLType, dSequence, dValidity, dDelimiter, dInfo, false); - - if (dType == ITYPE_UNKNOWN) - { - switch (sType) - { - case ITYPE_BOX: - case ITYPE_DIR: - case ITYPE_DIR_AND_BOX: - { - if (getState() == ISTATE_SELECT && sBox == getCurrentBox()) - { - kdDebug(7116) << "IMAP4::rename - close " << getCurrentBox() << endl; - // mailbox can only be renamed if it is closed - imapCommand *cmd = doCommand (imapCommand::clientClose()); - bool ok = cmd->result() == "OK"; - completeQueue.removeRef(cmd); - if (!ok) - { - kdWarning(7116) << "Unable to close mailbox!" << endl; - error(ERR_CANNOT_RENAME, src.path()); - return; - } - setState(ISTATE_LOGIN); - } - imapCommand *cmd = doCommand (imapCommand::clientRename (sBox, dBox)); - if (cmd->result () != "OK") { - error (ERR_CANNOT_RENAME, src.path()); - completeQueue.removeRef (cmd); - return; - } - completeQueue.removeRef (cmd); - } - break; - - case ITYPE_MSG: - case ITYPE_ATTACH: - case ITYPE_UNKNOWN: - error (ERR_CANNOT_RENAME, src.path()); - break; - } - } - else - { - error (ERR_CANNOT_RENAME, src.path()); - return; - } - finished (); -} - -void -IMAP4Protocol::slave_status () -{ - bool connected = (getState() != ISTATE_NO) && isConnectionValid(); - kdDebug(7116) << "IMAP4::slave_status " << connected << endl; - slaveStatus ( connected ? myHost : TQString(), connected ); -} - -void -IMAP4Protocol::dispatch (int command, const TQByteArray & data) -{ - kdDebug(7116) << "IMAP4::dispatch - command=" << command << endl; - TDEIO::TCPSlaveBase::dispatch (command, data); -} - -void -IMAP4Protocol::stat (const KURL & _url) -{ - kdDebug(7116) << "IMAP4::stat - " << _url.prettyURL() << endl; - TQString aBox, aSequence, aLType, aSection, aValidity, aDelimiter, aInfo; - // parseURL with caching - enum IMAP_TYPE aType = - parseURL (_url, aBox, aSection, aLType, aSequence, aValidity, aDelimiter, - aInfo, true); - - UDSEntry entry; - UDSAtom atom; - - atom.m_uds = UDS_NAME; - atom.m_str = aBox; - entry.append (atom); - - if (!aSection.isEmpty()) - { - if (getState() == ISTATE_SELECT && aBox == getCurrentBox()) - { - imapCommand *cmd = doCommand (imapCommand::clientClose()); - bool ok = cmd->result() == "OK"; - completeQueue.removeRef(cmd); - if (!ok) - { - error(ERR_COULD_NOT_STAT, aBox); - return; - } - setState(ISTATE_LOGIN); - } - bool ok = false; - TQString cmdInfo; - if (aType == ITYPE_MSG || aType == ITYPE_ATTACH) - ok = true; - else - { - imapCommand *cmd = doCommand(imapCommand::clienStatus(aBox, aSection)); - ok = cmd->result() == "OK"; - cmdInfo = cmd->resultInfo(); - completeQueue.removeRef(cmd); - } - if (!ok) - { - bool found = false; - imapCommand *cmd = doCommand (imapCommand::clientList ("", aBox)); - if (cmd->result () == "OK") - { - for (TQValueListIterator < imapList > it = listResponses.begin (); - it != listResponses.end (); ++it) - { - if (aBox == (*it).name ()) found = true; - } - } - completeQueue.removeRef (cmd); - if (found) - error(ERR_COULD_NOT_STAT, aBox); - else - error(TDEIO::ERR_DOES_NOT_EXIST, aBox); - return; - } - if ((aSection == "UIDNEXT" && geStatus().uidNextAvailable()) - || (aSection == "UNSEEN" && geStatus().unseenAvailable())) - { - atom.m_uds = UDS_SIZE; - atom.m_str = TQString(); - atom.m_long = (aSection == "UIDNEXT") ? geStatus().uidNext() - : geStatus().unseen(); - entry.append(atom); - } - } else - if (aType == ITYPE_BOX || aType == ITYPE_DIR_AND_BOX || aType == ITYPE_MSG || - aType == ITYPE_ATTACH) - { - ulong validity = 0; - // see if the box is already in select/examine state - if (aBox == getCurrentBox ()) - validity = selectInfo.uidValidity (); - else - { - // do a status lookup on the box - // only do this if the box is not selected - // the server might change the validity for new select/examine - imapCommand *cmd = - doCommand (imapCommand::clienStatus (aBox, "UIDVALIDITY")); - completeQueue.removeRef (cmd); - validity = geStatus ().uidValidity (); - } - validity = 0; // temporary - - if (aType == ITYPE_BOX || aType == ITYPE_DIR_AND_BOX) - { - // has no or an invalid uidvalidity - if (validity > 0 && validity != aValidity.toULong ()) - { - //redirect - KURL newUrl = _url; - - newUrl.setPath ("/" + aBox + ";UIDVALIDITY=" + - TQString::number(validity)); - kdDebug(7116) << "IMAP4::stat - redirecting to " << newUrl.prettyURL() << endl; - redirection (newUrl); - } - } - else if (aType == ITYPE_MSG || aType == ITYPE_ATTACH) - { - //must determine if this message exists - //cause konqueror will check this on paste operations - - // has an invalid uidvalidity - // or no messages in box - if (validity > 0 && validity != aValidity.toULong ()) - { - aType = ITYPE_UNKNOWN; - kdDebug(7116) << "IMAP4::stat - url has invalid validity [" << validity << "d] " << _url.prettyURL() << endl; - } - } - } - - atom.m_uds = UDS_MIME_TYPE; - atom.m_str = getMimeType (aType); - entry.append (atom); - - kdDebug(7116) << "IMAP4: stat: " << atom.m_str << endl; - switch (aType) - { - case ITYPE_DIR: - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFDIR; - entry.append (atom); - break; - - case ITYPE_BOX: - case ITYPE_DIR_AND_BOX: - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFDIR; - entry.append (atom); - break; - - case ITYPE_MSG: - case ITYPE_ATTACH: - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFREG; - entry.append (atom); - break; - - case ITYPE_UNKNOWN: - error (ERR_DOES_NOT_EXIST, _url.prettyURL()); - break; - } - - statEntry (entry); - kdDebug(7116) << "IMAP4::stat - Finishing stat" << endl; - finished (); -} - -void IMAP4Protocol::openConnection() -{ - if (makeLogin()) connected(); -} - -void IMAP4Protocol::closeConnection() -{ - if (getState() == ISTATE_NO) return; - if (getState() == ISTATE_SELECT && metaData("expunge") == "auto") - { - imapCommand *cmd = doCommand (imapCommand::clientExpunge()); - completeQueue.removeRef (cmd); - } - if (getState() != ISTATE_CONNECT) - { - imapCommand *cmd = doCommand (imapCommand::clientLogout()); - completeQueue.removeRef (cmd); - } - closeDescriptor(); - setState(ISTATE_NO); - completeQueue.clear(); - sentQueue.clear(); - lastHandled = 0; - currentBox = TQString(); - readBufferLen = 0; -} - -bool IMAP4Protocol::makeLogin () -{ - if (getState () == ISTATE_LOGIN || getState () == ISTATE_SELECT) - return true; - - kdDebug(7116) << "IMAP4::makeLogin - checking login" << endl; - bool alreadyConnected = getState() == ISTATE_CONNECT; - kdDebug(7116) << "IMAP4::makeLogin - alreadyConnected " << alreadyConnected << endl; - if (alreadyConnected || connectToHost (myHost.latin1(), myPort)) - { -// fcntl (m_iSock, F_SETFL, (fcntl (m_iSock, F_GETFL) | O_NDELAY)); - - setState(ISTATE_CONNECT); - - myAuth = metaData("auth"); - myTLS = metaData("tls"); - kdDebug(7116) << "myAuth: " << myAuth << endl; - - imapCommand *cmd; - - unhandled.clear (); - if (!alreadyConnected) while (!parseLoop ()) ; //get greeting - TQString greeting; - if (!unhandled.isEmpty()) greeting = unhandled.first().stripWhiteSpace(); - unhandled.clear (); //get rid of it - cmd = doCommand (new imapCommand ("CAPABILITY", "")); - - kdDebug(7116) << "IMAP4: setHost: capability" << endl; - for (TQStringList::Iterator it = imapCapabilities.begin (); - it != imapCapabilities.end (); ++it) - { - kdDebug(7116) << "'" << (*it) << "'" << endl; - } - completeQueue.removeRef (cmd); - - if (!hasCapability("IMAP4") && !hasCapability("IMAP4rev1")) - { - error(ERR_COULD_NOT_LOGIN, i18n("The server %1 supports neither " - "IMAP4 nor IMAP4rev1.\nIt identified itself with: %2") - .arg(myHost).arg(greeting)); - closeConnection(); - return false; - } - - if (metaData("nologin") == "on") return TRUE; - - if (myTLS == "on" && !hasCapability(TQString("STARTTLS"))) - { - error(ERR_COULD_NOT_LOGIN, i18n("The server does not support TLS.\n" - "Disable this security feature to connect unencrypted.")); - closeConnection(); - return false; - } - if ((myTLS == "on" || (canUseTLS() && myTLS != "off")) && - hasCapability(TQString("STARTTLS"))) - { - imapCommand *cmd = doCommand (imapCommand::clientStartTLS()); - if (cmd->result () == "OK") - { - completeQueue.removeRef(cmd); - int tlsrc = startTLS(); - if (tlsrc == 1) - { - kdDebug(7116) << "TLS mode has been enabled." << endl; - imapCommand *cmd2 = doCommand (new imapCommand ("CAPABILITY", "")); - for (TQStringList::Iterator it = imapCapabilities.begin (); - it != imapCapabilities.end (); ++it) - { - kdDebug(7116) << "'" << (*it) << "'" << endl; - } - completeQueue.removeRef (cmd2); - } else { - kdWarning(7116) << "TLS mode setup has failed. Aborting." << endl; - error (ERR_COULD_NOT_LOGIN, i18n("Starting TLS failed.")); - closeConnection(); - return false; - } - } else completeQueue.removeRef(cmd); - } - - if (myAuth.isEmpty () || myAuth == "*") { - if (hasCapability (TQString ("LOGINDISABLED"))) { - error (ERR_COULD_NOT_LOGIN, i18n("LOGIN is disabled by the server.")); - closeConnection(); - return false; - } - } - else { - if (!hasCapability (TQString ("AUTH=") + myAuth)) { - error (ERR_COULD_NOT_LOGIN, i18n("The authentication method %1 is not " - "supported by the server.").arg(myAuth)); - closeConnection(); - return false; - } - } - - if ( greeting.contains( TQRegExp( "Cyrus IMAP4 v2.1" ) ) ) { - removeCapability( "ANNOTATEMORE" ); - } - - // starting from Cyrus IMAP 2.3.9, shared seen flags are available - TQRegExp regExp( "Cyrus\\sIMAP[4]{0,1}\\sv(\\d+)\\.(\\d+)\\.(\\d+)", false ); - if ( regExp.search( greeting ) >= 0 ) { - const int major = regExp.cap( 1 ).toInt(); - const int minor = regExp.cap( 2 ).toInt(); - const int patch = regExp.cap( 3 ).toInt(); - if ( major > 2 || (major == 2 && (minor > 3 || (minor == 3 && patch > 9))) ) { - kdDebug(7116) << k_funcinfo << "Cyrus IMAP >= 2.3.9 detected, enabling shared seen flag support" << endl; - imapCapabilities.append( "x-kmail-sharedseen" ); - } - } - - kdDebug(7116) << "IMAP4::makeLogin - attempting login" << endl; - - TDEIO::AuthInfo authInfo; - authInfo.username = myUser; - authInfo.password = myPass; - authInfo.prompt = i18n ("Username and password for your IMAP account:"); - - kdDebug(7116) << "IMAP4::makeLogin - open_PassDlg said user=" << myUser << " pass=xx" << endl; - - TQString resultInfo; - if (myAuth.isEmpty () || myAuth == "*") - { - if (myUser.isEmpty () || myPass.isEmpty ()) { - if(openPassDlg (authInfo)) { - myUser = authInfo.username; - myPass = authInfo.password; - } - } - if (!clientLogin (myUser, myPass, resultInfo)) - error(TDEIO::ERR_COULD_NOT_AUTHENTICATE, i18n("Unable to login. Probably the " - "password is wrong.\nThe server %1 replied:\n%2").arg(myHost).arg(resultInfo)); - } - else - { -#ifdef HAVE_LIBSASL2 - if (!clientAuthenticate (this, authInfo, myHost, myAuth, mySSL, resultInfo)) - error(TDEIO::ERR_COULD_NOT_AUTHENTICATE, i18n("Unable to authenticate via %1.\n" - "The server %2 replied:\n%3").arg(myAuth).arg(myHost).arg(resultInfo)); - else { - myUser = authInfo.username; - myPass = authInfo.password; - } -#else - error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("SASL authentication is not compiled into tdeio_imap4.")); -#endif - } - if ( hasCapability("NAMESPACE") ) - { - // get all namespaces and save the namespace - delimiter association - cmd = doCommand( imapCommand::clientNamespace() ); - if (cmd->result () == "OK") - { - kdDebug(7116) << "makeLogin - registered namespaces" << endl; - } - completeQueue.removeRef (cmd); - } - // get the default delimiter (empty listing) - cmd = doCommand( imapCommand::clientList("", "") ); - if (cmd->result () == "OK") - { - TQValueListIterator < imapList > it = listResponses.begin(); - if ( it == listResponses.end() ) - { - // empty answer - this is a buggy imap server - // as a fallback we fire a normal listing and take the first answer - completeQueue.removeRef (cmd); - cmd = doCommand( imapCommand::clientList("", "%") ); - if (cmd->result () == "OK") - { - it = listResponses.begin(); - } - } - if ( it != listResponses.end() ) - { - namespaceToDelimiter[TQString()] = (*it).hierarchyDelimiter(); - kdDebug(7116) << "makeLogin - delimiter for empty ns='" << - (*it).hierarchyDelimiter() << "'" << endl; - if ( !hasCapability("NAMESPACE") ) - { - // server does not support namespaces - TQString nsentry = TQString::number( 0 ) + "==" - + (*it).hierarchyDelimiter(); - imapNamespaces.append( nsentry ); - } - } - } - completeQueue.removeRef (cmd); - } else { - kdDebug(7116) << "makeLogin - NO login" << endl; - } - - return getState() == ISTATE_LOGIN; -} - -void -IMAP4Protocol::parseWriteLine (const TQString & aStr) -{ - //kdDebug(7116) << "Writing: " << aStr << endl; - TQCString writer = aStr.utf8(); - int len = writer.length(); - - // append CRLF if necessary - if (len == 0 || (writer[len - 1] != '\n')) { - len += 2; - writer += "\r\n"; - } - - // write it - write(writer.data(), len); -} - -TQString -IMAP4Protocol::getMimeType (enum IMAP_TYPE aType) -{ - switch (aType) - { - case ITYPE_DIR: - return "inode/directory"; - break; - - case ITYPE_BOX: - return "message/digest"; - break; - - case ITYPE_DIR_AND_BOX: - return "message/directory"; - break; - - case ITYPE_MSG: - return "message/rfc822"; - break; - - // this should be handled by flushOutput - case ITYPE_ATTACH: - return "application/octet-stream"; - break; - - case ITYPE_UNKNOWN: - default: - return "unknown/unknown"; - } -} - - - -void -IMAP4Protocol::doListEntry (const KURL & _url, int stretch, imapCache * cache, - bool withFlags, bool withSubject) -{ - KURL aURL = _url; - aURL.setQuery (TQString()); - const TQString encodedUrl = aURL.url(0, 106); // utf-8 - doListEntry(encodedUrl, stretch, cache, withFlags, withSubject); -} - - - -void -IMAP4Protocol::doListEntry (const TQString & encodedUrl, int stretch, imapCache * cache, - bool withFlags, bool withSubject) -{ - if (cache) - { - UDSEntry entry; - UDSAtom atom; - - entry.clear (); - - const TQString uid = TQString::number(cache->getUid()); - - atom.m_uds = UDS_NAME; - atom.m_str = uid; - atom.m_long = 0; - if (stretch > 0) - { - atom.m_str = "0000000000000000" + atom.m_str; - atom.m_str = atom.m_str.right (stretch); - } - if (withSubject) - { - mailHeader *header = cache->getHeader(); - if (header) - atom.m_str += " " + header->getSubject(); - } - entry.append (atom); - - atom.m_uds = UDS_URL; - atom.m_str = encodedUrl; // utf-8 - if (atom.m_str[atom.m_str.length () - 1] != '/') - atom.m_str += '/'; - atom.m_str += ";UID=" + uid; - atom.m_long = 0; - entry.append (atom); - - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFREG; - entry.append (atom); - - atom.m_uds = UDS_SIZE; - atom.m_long = cache->getSize(); - entry.append (atom); - - atom.m_uds = UDS_MIME_TYPE; - atom.m_str = "message/rfc822"; - atom.m_long = 0; - entry.append (atom); - - atom.m_uds = UDS_USER; - atom.m_str = myUser; - entry.append (atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = (withFlags) ? cache->getFlags() : S_IRUSR | S_IXUSR | S_IWUSR; - entry.append (atom); - - listEntry (entry, false); - } -} - -void -IMAP4Protocol::doListEntry (const KURL & _url, const TQString & myBox, - const imapList & item, bool appendPath) -{ - KURL aURL = _url; - aURL.setQuery (TQString()); - UDSEntry entry; - UDSAtom atom; - int hdLen = item.hierarchyDelimiter().length(); - - { - // mailboxName will be appended to the path if appendPath is true - TQString mailboxName = item.name (); - - // some beautification - if (mailboxName.find (myBox) == 0 && mailboxName.length() > myBox.length()) - { - mailboxName = - mailboxName.right (mailboxName.length () - myBox.length ()); - } - if (mailboxName[0] == '/') - mailboxName = mailboxName.right (mailboxName.length () - 1); - if (mailboxName.left(hdLen) == item.hierarchyDelimiter()) - mailboxName = mailboxName.right(mailboxName.length () - hdLen); - if (mailboxName.right(hdLen) == item.hierarchyDelimiter()) - mailboxName.truncate(mailboxName.length () - hdLen); - - atom.m_uds = UDS_NAME; - if (!item.hierarchyDelimiter().isEmpty() && - mailboxName.find(item.hierarchyDelimiter()) != -1) - atom.m_str = mailboxName.section(item.hierarchyDelimiter(), -1); - else - atom.m_str = mailboxName; - - // konqueror will die with an assertion failure otherwise - if (atom.m_str.isEmpty ()) - atom.m_str = ".."; - - if (!atom.m_str.isEmpty ()) - { - atom.m_long = 0; - entry.append (atom); - - if (!item.noSelect ()) - { - atom.m_uds = UDS_MIME_TYPE; - if (!item.noInferiors ()) - { - atom.m_str = "message/directory"; - } else { - atom.m_str = "message/digest"; - } - atom.m_long = 0; - entry.append (atom); - mailboxName += '/'; - - // explicitly set this as a directory for KFileDialog - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFDIR; - entry.append (atom); - } - else if (!item.noInferiors ()) - { - atom.m_uds = UDS_MIME_TYPE; - atom.m_str = "inode/directory"; - atom.m_long = 0; - entry.append (atom); - mailboxName += '/'; - - // explicitly set this as a directory for KFileDialog - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = TQString(); - atom.m_long = S_IFDIR; - entry.append (atom); - } - else - { - atom.m_uds = UDS_MIME_TYPE; - atom.m_str = "unknown/unknown"; - atom.m_long = 0; - entry.append (atom); - } - - atom.m_uds = UDS_URL; - TQString path = aURL.path(); - atom.m_str = aURL.url (0, 106); // utf-8 - if (appendPath) - { - if (path[path.length() - 1] == '/' && !path.isEmpty() && path != "/") - path.truncate(path.length() - 1); - if (!path.isEmpty() && path != "/" - && path.right(hdLen) != item.hierarchyDelimiter()) { - path += item.hierarchyDelimiter(); - } - path += mailboxName; - if (path.upper() == "/INBOX/") { - // make sure the client can rely on INBOX - path = path.upper(); - } - } - aURL.setPath(path); - atom.m_str = aURL.url(0, 106); // utf-8 - atom.m_long = 0; - entry.append (atom); - - atom.m_uds = UDS_USER; - atom.m_str = myUser; - entry.append (atom); - - atom.m_uds = UDS_ACCESS; - atom.m_long = S_IRUSR | S_IXUSR | S_IWUSR; - entry.append (atom); - - atom.m_uds = UDS_EXTRA; - atom.m_str = item.attributesAsString(); - atom.m_long = 0; - entry.append (atom); - - listEntry (entry, false); - } - } -} - -enum IMAP_TYPE -IMAP4Protocol::parseURL (const KURL & _url, TQString & _box, - TQString & _section, TQString & _type, TQString & _uid, - TQString & _validity, TQString & _hierarchyDelimiter, - TQString & _info, bool cache) -{ - enum IMAP_TYPE retVal; - retVal = ITYPE_UNKNOWN; - - imapParser::parseURL (_url, _box, _section, _type, _uid, _validity, _info); -// kdDebug(7116) << "URL: query - '" << KURL::decode_string(_url.query()) << "'" << endl; - - // get the delimiter - TQString myNamespace = namespaceForBox( _box ); - kdDebug(7116) << "IMAP4::parseURL - namespace=" << myNamespace << endl; - if ( namespaceToDelimiter.contains(myNamespace) ) - { - _hierarchyDelimiter = namespaceToDelimiter[myNamespace]; - kdDebug(7116) << "IMAP4::parseURL - delimiter=" << _hierarchyDelimiter << endl; - } - - if (!_box.isEmpty ()) - { - kdDebug(7116) << "IMAP4::parseURL - box=" << _box << endl; - - if (makeLogin ()) - { - if (getCurrentBox () != _box || - _type == "LIST" || _type == "LSUB" || _type == "LSUBNOCHECK") - { - if ( cache ) - { - // assume a normal box - retVal = ITYPE_DIR_AND_BOX; - } else - { - // start a listing for the box to get the type - imapCommand *cmd; - - cmd = doCommand (imapCommand::clientList ("", _box)); - if (cmd->result () == "OK") - { - for (TQValueListIterator < imapList > it = listResponses.begin (); - it != listResponses.end (); ++it) - { - //kdDebug(7116) << "IMAP4::parseURL - checking " << _box << " to " << (*it).name() << endl; - if (_box == (*it).name ()) - { - if ( !(*it).hierarchyDelimiter().isEmpty() ) - _hierarchyDelimiter = (*it).hierarchyDelimiter(); - if ((*it).noSelect ()) - { - retVal = ITYPE_DIR; - } - else if ((*it).noInferiors ()) - { - retVal = ITYPE_BOX; - } - else - { - retVal = ITYPE_DIR_AND_BOX; - } - } - } - // if we got no list response for the box see if it's a prefix - if ( retVal == ITYPE_UNKNOWN && - namespaceToDelimiter.contains(_box) ) { - retVal = ITYPE_DIR; - } - } else { - kdDebug(7116) << "IMAP4::parseURL - got error for " << _box << endl; - } - completeQueue.removeRef (cmd); - } // cache - } - else // current == box - { - retVal = ITYPE_BOX; - } - } - else - kdDebug(7116) << "IMAP4::parseURL: no login!" << endl; - - } - else // empty box - { - // the root is just a dir - kdDebug(7116) << "IMAP4: parseURL: box [root]" << endl; - retVal = ITYPE_DIR; - } - - // see if it is a real sequence or a simple uid - if (retVal == ITYPE_BOX || retVal == ITYPE_DIR_AND_BOX) - { - if (!_uid.isEmpty ()) - { - if (_uid.find (':') == -1 && _uid.find (',') == -1 - && _uid.find ('*') == -1) - retVal = ITYPE_MSG; - } - } - if (retVal == ITYPE_MSG) - { - if ( (_section.find ("BODY.PEEK[", 0, false) != -1 || - _section.find ("BODY[", 0, false) != -1) && - _section.find(".MIME") == -1 && - _section.find(".HEADER") == -1 ) - retVal = ITYPE_ATTACH; - } - if ( _hierarchyDelimiter.isEmpty() && - (_type == "LIST" || _type == "LSUB" || _type == "LSUBNOCHECK") ) - { - // this shouldn't happen but when the delimiter is really empty - // we try to reconstruct it from the URL - if (!_box.isEmpty()) - { - int start = _url.path().findRev(_box); - if (start != -1) - _hierarchyDelimiter = _url.path().mid(start-1, start); - kdDebug(7116) << "IMAP4::parseURL - reconstructed delimiter:" << _hierarchyDelimiter - << " from URL " << _url.path() << endl; - } - if (_hierarchyDelimiter.isEmpty()) - _hierarchyDelimiter = "/"; - } - kdDebug(7116) << "IMAP4::parseURL - return " << retVal << endl; - - return retVal; -} - -int -IMAP4Protocol::outputLine (const TQCString & _str, int len) -{ - if (len == -1) { - len = _str.length(); - } - - if (cacheOutput) - { - if ( !outputBuffer.isOpen() ) { - outputBuffer.open(IO_WriteOnly); - } - outputBuffer.at(outputBufferIndex); - outputBuffer.writeBlock(_str.data(), len); - outputBufferIndex += len; - return 0; - } - - TQByteArray temp; - bool relay = relayEnabled; - - relayEnabled = true; - temp.setRawData (_str.data (), len); - parseRelay (temp); - temp.resetRawData (_str.data (), len); - - relayEnabled = relay; - return 0; -} - -void IMAP4Protocol::flushOutput(TQString contentEncoding) -{ - // send out cached data to the application - if (outputBufferIndex == 0) - return; - outputBuffer.close(); - outputCache.resize(outputBufferIndex); - if (decodeContent) - { - // get the coding from the MIME header - TQByteArray decoded; - if (contentEncoding.find("quoted-printable", 0, false) == 0) - decoded = KCodecs::quotedPrintableDecode(outputCache); - else if (contentEncoding.find("base64", 0, false) == 0) - KCodecs::base64Decode(outputCache, decoded); - else - decoded = outputCache; - - TQString mimetype = KMimeType::findByContent( decoded )->name(); - kdDebug(7116) << "IMAP4::flushOutput - mimeType " << mimetype << endl; - mimeType(mimetype); - decodeContent = false; - data( decoded ); - } else { - data( outputCache ); - } - mProcessedSize += outputBufferIndex; - processedSize( mProcessedSize ); - outputBufferIndex = 0; - outputCache[0] = '\0'; - outputBuffer.setBuffer(outputCache); -} - -ssize_t IMAP4Protocol::myRead(void *data, ssize_t len) -{ - if (readBufferLen) - { - ssize_t copyLen = (len < readBufferLen) ? len : readBufferLen; - memcpy(data, readBuffer, copyLen); - readBufferLen -= copyLen; - if (readBufferLen) memmove(readBuffer, &readBuffer[copyLen], readBufferLen); - return copyLen; - } - if (!isConnectionValid()) return 0; - waitForResponse( responseTimeout() ); - return read(data, len); -} - -bool -IMAP4Protocol::assureBox (const TQString & aBox, bool readonly) -{ - if (aBox.isEmpty()) return false; - - imapCommand *cmd = 0; - - if (aBox != getCurrentBox () || (!getSelected().readWrite() && !readonly)) - { - // open the box with the appropriate mode - kdDebug(7116) << "IMAP4Protocol::assureBox - opening box" << endl; - selectInfo = imapInfo(); - cmd = doCommand (imapCommand::clientSelect (aBox, readonly)); - bool ok = cmd->result() == "OK"; - TQString cmdInfo = cmd->resultInfo(); - completeQueue.removeRef (cmd); - - if (!ok) - { - bool found = false; - cmd = doCommand (imapCommand::clientList ("", aBox)); - if (cmd->result () == "OK") - { - for (TQValueListIterator < imapList > it = listResponses.begin (); - it != listResponses.end (); ++it) - { - if (aBox == (*it).name ()) found = true; - } - } - completeQueue.removeRef (cmd); - if (found) { - if (cmdInfo.find("permission", 0, false) != -1) { - // not allowed to enter this folder - error(ERR_ACCESS_DENIED, cmdInfo); - } else { - error(ERR_SLAVE_DEFINED, i18n("Unable to open folder %1. The server replied: %2").arg(aBox).arg(cmdInfo)); - } - } else { - error(TDEIO::ERR_DOES_NOT_EXIST, aBox); - } - return false; - } - } - else - { - // Give the server a chance to deliver updates every ten seconds. - // Doing this means a server roundtrip and since assureBox is called - // after every mail, we do it with a timeout. - kdDebug(7116) << "IMAP4Protocol::assureBox - reusing box" << endl; - if ( mTimeOfLastNoop.secsTo( TQDateTime::currentDateTime() ) > 10 ) { - cmd = doCommand (imapCommand::clientNoop ()); - completeQueue.removeRef (cmd); - mTimeOfLastNoop = TQDateTime::currentDateTime(); - kdDebug(7116) << "IMAP4Protocol::assureBox - noop timer fired" << endl; - } - } - - // if it is the mode we want - if (!getSelected().readWrite() && !readonly) - { - error(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, aBox); - return false; - } - - return true; -} diff --git a/tdeioslaves/imap4/imap4.h b/tdeioslaves/imap4/imap4.h deleted file mode 100644 index a6b160899..000000000 --- a/tdeioslaves/imap4/imap4.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef _IMAP4_H -#define _IMAP4_H -/********************************************************************** - * - * imap4.h - IMAP4rev1 KIOSlave - * Copyright (C) 2001-2002 Michael Haeckel <haeckel@kde.org> - * Copyright (C) 1999 John Corey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to jcorey@fruity.ath.cx - * - *********************************************************************/ - -#include "imapparser.h" -#include "mimeio.h" - -#include <tdeio/tcpslavebase.h> -#include <tqbuffer.h> - -#define IMAP_BUFFER 8192 - -/** @brief type of object the url refers too */ -enum IMAP_TYPE -{ - ITYPE_UNKNOWN, /*< unknown type */ - ITYPE_DIR, /*< Object is a directory. i.e. does not contain message, just mailboxes */ - ITYPE_BOX, /*< Object is a mailbox. i.e. contains mails */ - ITYPE_DIR_AND_BOX, /*< Object contains both mails and mailboxes */ - ITYPE_MSG, /*< Object is a mail */ - ITYPE_ATTACH /*< Object is an attachment */ -}; - -/** @brief IOSlave derived class */ -class IMAP4Protocol:public - TDEIO::TCPSlaveBase, - public - imapParser, - public - mimeIO -{ - -public: - - // reimplement the TCPSlave - IMAP4Protocol (const TQCString & pool, const TQCString & app, bool isSSL); - virtual ~IMAP4Protocol (); - - virtual void openConnection(); - virtual void closeConnection(); - - virtual void setHost (const TQString & _host, int _port, const TQString & _user, - const TQString & _pass); - /** - * @brief get a message or part of a message - * the data is normally send as we get it from the server - * if you want the slave to decode the content (e.g. for attachments) - * then append an additional INFO=DECODE to the URL - */ - virtual void get (const KURL & _url); - /** - * @brief stat a mailbox, message, attachment - */ - virtual void stat (const KURL & _url); - virtual void slave_status (); - /** - * @brief delete a mailbox - */ - virtual void del (const KURL & _url, bool isFile); - /** - * @brief Capabilites, NOOP, (Un)subscribe, Change status, - * Change ACL - */ - virtual void special (const TQByteArray & data); - /** - * @brief list a directory/mailbox - */ - virtual void listDir (const KURL & _url); - virtual void setSubURL (const KURL & _url); - virtual void dispatch (int command, const TQByteArray & data); - /** - * @brief create a mailbox - */ - virtual void mkdir (const KURL & url, int permissions); - virtual void put (const KURL & url, int permissions, bool overwrite, - bool resume); - virtual void rename (const KURL & src, const KURL & dest, bool overwrite); - virtual void copy (const KURL & src, const KURL & dest, int permissions, - bool overwrite); - - /** @brief reimplement the parser - * relay hook to send the fetched data directly to an upper level - */ - virtual void parseRelay (const TQByteArray & buffer); - - /** @brief reimplement the parser - * relay hook to announce the fetched data directly to an upper level - */ - virtual void parseRelay (ulong); - - /** @brief reimplement the parser - * read at least len bytes */ - virtual bool parseRead (TQByteArray &buffer,ulong len,ulong relay=0); - - /** @brief reimplement the parser - * @brief read at least a line (up to CRLF) */ - virtual bool parseReadLine (TQByteArray & buffer, ulong relay = 0); - - /** @brief reimplement the parser - * @brief write argument to the server */ - virtual void parseWriteLine (const TQString &); - - /** @brief reimplement the mimeIO */ - virtual int outputLine (const TQCString & _str, int len = -1); - - /** @brief send out cached data to the application */ - virtual void flushOutput(TQString contentEncoding = TQString()); - -protected: - - // select or examine the box if needed - bool assureBox (const TQString & aBox, bool readonly); - - ssize_t myRead(void *data, ssize_t len); - - /** - * @brief Parses the given URL - * The return values are set by parsing the URL and querying the server - * - * If you set caching to true the server is not queried but the type is always - * set to ITYPE_DIR_AND_BOX - */ - enum IMAP_TYPE - parseURL (const KURL & _url, TQString & _box, TQString & _section, - TQString & _type, TQString & _uid, TQString & _validity, - TQString & _hierarchyDelimiter, TQString & _info, - bool cache = false); - TQString getMimeType (enum IMAP_TYPE); - - bool makeLogin (); - - void outputLineStr (const TQString & _str) - { - outputLine (_str.latin1 (), _str.length()); - } - void doListEntry (const KURL & _url, int stretch, imapCache * cache = NULL, - bool withFlags = FALSE, bool withSubject = FALSE); - - /** - * Send a list entry (folder) to the application - * If @p appendPath is true the foldername will be appended - * to the path of @p url - */ - void doListEntry (const KURL & url, const TQString & myBox, - const imapList & item, bool appendPath = true); - - /** Send an ACL command which is identified by @p command */ - void specialACLCommand( int command, TQDataStream& stream ); - - /** Send an annotation command which is identified by @p command */ - void specialAnnotateMoreCommand( int command, TQDataStream& stream ); - void specialQuotaCommand( int command, TQDataStream& stream ); - - /** Search current folder, the search string is passed as SECTION */ - void specialSearchCommand( TQDataStream& ); - - /** Send a custom command to the server */ - void specialCustomCommand( TQDataStream& ); - -private: - - // This method behaves like the above method but takes an already encoded url, - // so you don't have to call KURL::url() for every mail. - void doListEntry (const TQString & encodedUrl, int stretch, imapCache * cache = NULL, - bool withFlags = FALSE, bool withSubject = FALSE); - - TQString myHost, myUser, myPass, myAuth, myTLS; - int myPort; - bool mySSL; - - bool relayEnabled, cacheOutput, decodeContent; - TQByteArray outputCache; - TQBuffer outputBuffer; - TQ_ULONG outputBufferIndex; - TDEIO::filesize_t mProcessedSize; - - char readBuffer[IMAP_BUFFER]; - ssize_t readBufferLen; - int readSize; - TQDateTime mTimeOfLastNoop; -}; - -#endif diff --git a/tdeioslaves/imap4/imap4.protocol b/tdeioslaves/imap4/imap4.protocol deleted file mode 100644 index f37556c17..000000000 --- a/tdeioslaves/imap4/imap4.protocol +++ /dev/null @@ -1,29 +0,0 @@ -[Protocol] -# The executable, of course -#### Temporary name -exec=tdeio_imap4 -# protocol that will appear in URLs -protocol=imap - -# input/output can be one of: filesystem, stream, none -input=stream -output=filesystem - -# Headings for file listings? -listing=Name,Type,Size,Owner -deleting=true -linking=false -# For now, reading yes, writing no -reading=true -writing=false -# For now, no moving -moving=false - -# Can be source protocol -source=true - -# List of capabilities (e.g. special() commands) -Capabilities=Subscription,ACL,Quota - -Icon=folder_inbox -DocPath=tdeioslave/imap/index.html diff --git a/tdeioslaves/imap4/imapcommand.cc b/tdeioslaves/imap4/imapcommand.cc deleted file mode 100644 index f88a65add..000000000 --- a/tdeioslaves/imap4/imapcommand.cc +++ /dev/null @@ -1,408 +0,0 @@ -/********************************************************************** - * - * imapcommand.cc - IMAP4rev1 command handler - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ - -#include "imapcommand.h" -#include "rfcdecoder.h" - -/*#include <stdlib.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <sys/stat.h> - -#include <fcntl.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <netdb.h> -#include <unistd.h> -#include <stdlib.h> - -#include <tqregexp.h> -#include <tqbuffer.h> - -#include <tdeprotocolmanager.h> -#include <ksock.h> -#include <kdebug.h> -#include <kinstance.h> -#include <tdeio/connection.h> -#include <tdeio/slaveinterface.h> -#include <tdeio/passdlg.h> -#include <tdelocale.h> */ - -imapCommand::imapCommand () -{ - mComplete = false; - mId = TQString(); -} - -imapCommand::imapCommand (const TQString & command, const TQString & parameter) -// aCommand(NULL), -// mResult(NULL), -// mParameter(NULL) -{ - mComplete = false; - aCommand = command; - aParameter = parameter; - mId = TQString(); -} - -bool -imapCommand::isComplete () -{ - return mComplete; -} - -const TQString & -imapCommand::result () -{ - return mResult; -} - -const TQString & -imapCommand::resultInfo () -{ - return mResultInfo; -} - -const TQString & -imapCommand::id () -{ - return mId; -} - -const TQString & -imapCommand::parameter () -{ - return aParameter; -} - -const TQString & -imapCommand::command () -{ - return aCommand; -} - -void -imapCommand::setId (const TQString & id) -{ - if (mId.isEmpty ()) - mId = id; -} - -void -imapCommand::setComplete () -{ - mComplete = true; -} - -void -imapCommand::setResult (const TQString & result) -{ - mResult = result; -} - -void -imapCommand::setResultInfo (const TQString & result) -{ - mResultInfo = result; -} - -void -imapCommand::setCommand (const TQString & command) -{ - aCommand = command; -} - -void -imapCommand::setParameter (const TQString & parameter) -{ - aParameter = parameter; -} - -const TQString -imapCommand::getStr () -{ - if (parameter().isEmpty()) - return id() + " " + command() + "\r\n"; - else - return id() + " " + command() + " " + parameter() + "\r\n"; -} - -imapCommand * -imapCommand::clientNoop () -{ - return new imapCommand ("NOOP", ""); -} - -imapCommand * -imapCommand::clientFetch (ulong uid, const TQString & fields, bool nouid) -{ - return clientFetch (uid, uid, fields, nouid); -} - -imapCommand * -imapCommand::clientFetch (ulong fromUid, ulong toUid, const TQString & fields, - bool nouid) -{ - TQString uid = TQString::number(fromUid); - - if (fromUid != toUid) - { - uid += ":"; - if (toUid < fromUid) - uid += "*"; - else - uid += TQString::number(toUid); - } - return clientFetch (uid, fields, nouid); -} - -imapCommand * -imapCommand::clientFetch (const TQString & sequence, const TQString & fields, - bool nouid) -{ - return new imapCommand (nouid ? "FETCH" : "UID FETCH", - sequence + " (" + fields + ")"); -} - -imapCommand * -imapCommand::clientList (const TQString & reference, const TQString & path, - bool lsub) -{ - return new imapCommand (lsub ? "LSUB" : "LIST", - TQString ("\"") + rfcDecoder::toIMAP (reference) + - "\" \"" + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientSelect (const TQString & path, bool examine) -{ - Q_UNUSED(examine); - /** @note We use always SELECT, because UW-IMAP doesn't check for new mail, when - used with the "mbox driver" and the folder is opened with EXAMINE - and Courier can't append to a mailbox that is in EXAMINE state */ - return new imapCommand ("SELECT", - TQString ("\"") + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientClose() -{ - return new imapCommand("CLOSE", ""); -} - -imapCommand * -imapCommand::clientCopy (const TQString & box, const TQString & sequence, - bool nouid) -{ - return new imapCommand (nouid ? "COPY" : "UID COPY", - sequence + " \"" + rfcDecoder::toIMAP (box) + "\""); -} - -imapCommand * -imapCommand::clientAppend (const TQString & box, const TQString & flags, - ulong size) -{ - return new imapCommand ("APPEND", - "\"" + rfcDecoder::toIMAP (box) + "\" " + - ((flags.isEmpty()) ? "" : ("(" + flags + ") ")) + - "{" + TQString::number(size) + "}"); -} - -imapCommand * -imapCommand::clienStatus (const TQString & path, const TQString & parameters) -{ - return new imapCommand ("STATUS", - TQString ("\"") + rfcDecoder::toIMAP (path) + - "\" (" + parameters + ")"); -} - -imapCommand * -imapCommand::clientCreate (const TQString & path) -{ - return new imapCommand ("CREATE", - TQString ("\"") + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientDelete (const TQString & path) -{ - return new imapCommand ("DELETE", - TQString ("\"") + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientSubscribe (const TQString & path) -{ - return new imapCommand ("SUBSCRIBE", - TQString ("\"") + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientUnsubscribe (const TQString & path) -{ - return new imapCommand ("UNSUBSCRIBE", - TQString ("\"") + rfcDecoder::toIMAP (path) + "\""); -} - -imapCommand * -imapCommand::clientExpunge () -{ - return new imapCommand ("EXPUNGE", TQString ("")); -} - -imapCommand * -imapCommand::clientRename (const TQString & src, const TQString & dest) -{ - return new imapCommand ("RENAME", - TQString ("\"") + rfcDecoder::toIMAP (src) + - "\" \"" + rfcDecoder::toIMAP (dest) + "\""); -} - -imapCommand * -imapCommand::clientSearch (const TQString & search, bool nouid) -{ - return new imapCommand (nouid ? "SEARCH" : "UID SEARCH", search); -} - -imapCommand * -imapCommand::clientStore (const TQString & set, const TQString & item, - const TQString & data, bool nouid) -{ - return new imapCommand (nouid ? "STORE" : "UID STORE", - set + " " + item + " (" + data + ")"); -} - -imapCommand * -imapCommand::clientLogout () -{ - return new imapCommand ("LOGOUT", ""); -} - -imapCommand * -imapCommand::clientStartTLS () -{ - return new imapCommand ("STARTTLS", ""); -} - -imapCommand * -imapCommand::clientSetACL( const TQString& box, const TQString& user, const TQString& acl ) -{ - return new imapCommand ("SETACL", TQString("\"") + rfcDecoder::toIMAP (box) - + "\" \"" + rfcDecoder::toIMAP (user) - + "\" \"" + rfcDecoder::toIMAP (acl) + "\""); -} - -imapCommand * -imapCommand::clientDeleteACL( const TQString& box, const TQString& user ) -{ - return new imapCommand ("DELETEACL", TQString("\"") + rfcDecoder::toIMAP (box) - + "\" \"" + rfcDecoder::toIMAP (user) - + "\""); -} - -imapCommand * -imapCommand::clientGetACL( const TQString& box ) -{ - return new imapCommand ("GETACL", TQString("\"") + rfcDecoder::toIMAP (box) - + "\""); -} - -imapCommand * -imapCommand::clientListRights( const TQString& box, const TQString& user ) -{ - return new imapCommand ("LISTRIGHTS", TQString("\"") + rfcDecoder::toIMAP (box) - + "\" \"" + rfcDecoder::toIMAP (user) - + "\""); -} - -imapCommand * -imapCommand::clientMyRights( const TQString& box ) -{ - return new imapCommand ("MYRIGHTS", TQString("\"") + rfcDecoder::toIMAP (box) - + "\""); -} - -imapCommand * -imapCommand::clientSetAnnotation( const TQString& box, const TQString& entry, const TQMap<TQString, TQString>& attributes ) -{ - TQString parameter = TQString("\"") + rfcDecoder::toIMAP (box) - + "\" \"" + rfcDecoder::toIMAP (entry) - + "\" ("; - for( TQMap<TQString,TQString>::ConstIterator it = attributes.begin(); it != attributes.end(); ++it ) { - parameter += "\""; - parameter += rfcDecoder::toIMAP (it.key()); - parameter += "\" \""; - parameter += rfcDecoder::toIMAP (it.data()); - parameter += "\" "; - } - // Turn last space into a ')' - parameter[parameter.length()-1] = ')'; - - return new imapCommand ("SETANNOTATION", parameter); -} - -imapCommand * -imapCommand::clientGetAnnotation( const TQString& box, const TQString& entry, const TQStringList& attributeNames ) -{ - TQString parameter = TQString("\"") + rfcDecoder::toIMAP (box) - + "\" \"" + rfcDecoder::toIMAP (entry) - + "\" "; - if ( attributeNames.count() == 1 ) - parameter += "\"" + rfcDecoder::toIMAP (attributeNames.first()) + '"'; - else { - parameter += '('; - for( TQStringList::ConstIterator it = attributeNames.begin(); it != attributeNames.end(); ++it ) { - parameter += "\"" + rfcDecoder::toIMAP (*it) + "\" "; - } - // Turn last space into a ')' - parameter[parameter.length()-1] = ')'; - } - return new imapCommand ("GETANNOTATION", parameter); -} - -imapCommand * -imapCommand::clientNamespace() -{ - return new imapCommand("NAMESPACE", ""); -} - -imapCommand * -imapCommand::clientGetQuotaroot( const TQString& box ) -{ - TQString parameter = TQString("\"") + rfcDecoder::toIMAP (box) + '"'; - return new imapCommand ("GETQUOTAROOT", parameter); -} - -imapCommand * -imapCommand::clientCustom( const TQString& command, const TQString& arguments ) -{ - return new imapCommand (command, arguments); -} - diff --git a/tdeioslaves/imap4/imapcommand.h b/tdeioslaves/imap4/imapcommand.h deleted file mode 100644 index 9e2834424..000000000 --- a/tdeioslaves/imap4/imapcommand.h +++ /dev/null @@ -1,394 +0,0 @@ -#ifndef _IMAPCOMMAND_H -#define _IMAPCOMMAND_H -/********************************************************************** - * - * imapcommand.h - IMAP4rev1 command handler - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -#include <tqstringlist.h> -#include <tqstring.h> -#include <tqmap.h> - -/** - * @brief encapulate a IMAP command - * @author Svenn Carstens - * @date 2000 - * @todo fix the documentation - */ - -class imapCommand -{ -public: - - /** - * @brief Constructor - */ - imapCommand (); - /** - * @fn imapCommand (const TQString & command, const TQString & parameter); - * @brief Constructor - * @param command Imap command - * @param parameter Parameters to the command - * @return none - */ - imapCommand (const TQString & command, const TQString & parameter); - /** - * @fn bool isComplete (); - * @brief is it complete? - * @return whether the command is completed - */ - bool isComplete (); - /** - * @fn const TQString & result (); - * @brief get the result of the command - * @return The result, i.e. first word of the result line, like OK - */ - const TQString & result (); - /** - * @fn const TQString & resultInfo (); - * @brief get information about the result - * @return Information about the result, i.e. the rest of the result line - */ - const TQString & resultInfo (); - /** - * @fn const TQString & parameter (); - * @brief get the parameter - * @return the parameter - */ - const TQString & parameter (); - /** - * @fn const TQString & command (); - * @brief get the command - * @return the command - */ - const TQString & command (); - /** - * @fn const TQString & id (); - * @brief get the id - * @return the id - */ - const TQString & id (); - - /** - * @fn void setId (const TQString &); - * @brief set the id - * @param id the id used by the command - * @return none - */ - void setId (const TQString &); - /** - * @fn void setComplete (); - * @brief set the completed state - * @return none - */ - void setComplete (); - /** - * @fn void setResult (const TQString &); - * @brief set the completed state - * @param result the command result - * @return none - */ - void setResult (const TQString &); - /** - * @fn void setResultInfo (const TQString &); - * @brief set the completed state - * @param result the command result information - * @return none - */ - void setResultInfo (const TQString &); - /** - * @fn void setCommand (const TQString &); - * @brief set the command - * @param command the imap command - * @return none - */ - void setCommand (const TQString &); - /** - * @fn void setParameter (const TQString &); - * @brief set the command parameter(s) - * @param parameter the comand parameter(s) - * @return none - */ - void setParameter (const TQString &); - /** - * @fn const TQString getStr (); - * @brief returns the data to send to the server - * The function returns the complete data to be sent to - * the server (\<id\> \<command\> [\<parameter\>]) - * @return the data to send to the server - * @todo possibly rename function to be clear of it's purpose - */ - const TQString getStr (); - - /** - * @fn static imapCommand *clientNoop (); - * @brief Create a NOOP command - * @return a NOOP imapCommand - */ - static imapCommand *clientNoop (); - /** - * @fn static imapCommand *clientFetch (ulong uid, const TQString & fields, bool nouid = false); - * @brief Create a FETCH command - * @param uid Uid of the message to fetch - * @param fields options to pass to the server - * @param nouid Perform a FETCH or UID FETCH command - * @return a FETCH imapCommand - * Fetch a single uid - */ - static imapCommand *clientFetch (ulong uid, const TQString & fields, - bool nouid = false); - /** - * @fn static imapCommand *clientFetch (ulong fromUid, ulong toUid, const TQString & fields, bool nouid = false); - * @brief Create a FETCH command - * @param fromUid start uid of the messages to fetch - * @param toUid last uid of the messages to fetch - * @param fields options to pass to the server - * @param nouid Perform a FETCH or UID FETCH command - * @return a FETCH imapCommand - * Fetch a range of uids - */ - static imapCommand *clientFetch (ulong fromUid, ulong toUid, - const TQString & fields, bool nouid = - false); - /** - * @fn static imapCommand *clientFetch (const TQString & sequence, const TQString & fields, bool nouid = false); - * @brief Create a FETCH command - * @param sequence a IMAP FETCH sequence string - * @param fields options to pass to the server - * @param nouid Perform a FETCH or UID FETCH command - * @return a FETCH imapCommand - * Fetch a range of uids. The other clientFetch functions are just - * wrappers around this function. - */ - static imapCommand *clientFetch (const TQString & sequence, - const TQString & fields, bool nouid = - false); - /** - * @fn static imapCommand *clientList (const TQString & reference, const TQString & path, bool lsub = false); - * @brief Create a LIST command - * @param reference - * @param path The path to list - * @param lsub Perform a LIST or a LSUB command - * @return a LIST imapCommand - */ - static imapCommand *clientList (const TQString & reference, - const TQString & path, bool lsub = false); - /** - * @fn static imapCommand *clientSelect (const TQString & path, bool examine = false); - * @brief Create a SELECT command - * @param path The path to select - * @param lsub Perform a SELECT or a EXAMINE command - * @return a SELECT imapCommand - */ - static imapCommand *clientSelect (const TQString & path, bool examine = - false); - /** - * @fn static imapCommand *clientClose(); - * @brief Create a CLOSE command - * @return a CLOSE imapCommand - */ - static imapCommand *clientClose(); - /** - * @brief Create a STATUS command - * @param path - * @param parameters - * @return a STATUS imapCommand - */ - static imapCommand *clienStatus (const TQString & path, - const TQString & parameters); - /** - * @brief Create a COPY command - * @param box - * @param sequence - * @param nouid Perform a COPY or UID COPY command - * @return a COPY imapCommand - */ - static imapCommand *clientCopy (const TQString & box, - const TQString & sequence, bool nouid = - false); - /** - * @brief Create a APPEND command - * @param box - * @param flags - * @param size - * @return a APPEND imapCommand - */ - static imapCommand *clientAppend (const TQString & box, - const TQString & flags, ulong size); - /** - * @brief Create a CREATE command - * @param path - * @return a CREATE imapCommand - */ - static imapCommand *clientCreate (const TQString & path); - /** - * @brief Create a DELETE command - * @param path - * @return a DELETE imapCommand - */ - static imapCommand *clientDelete (const TQString & path); - /** - * @brief Create a SUBSCRIBE command - * @param path - * @return a SUBSCRIBE imapCommand - */ - static imapCommand *clientSubscribe (const TQString & path); - /** - * @brief Create a UNSUBSCRIBE command - * @param path - * @return a UNSUBSCRIBE imapCommand - */ - static imapCommand *clientUnsubscribe (const TQString & path); - /** - * @brief Create a EXPUNGE command - * @return a EXPUNGE imapCommand - */ - static imapCommand *clientExpunge (); - /** - * @brief Create a RENAME command - * @param src Source - * @param dest Destination - * @return a RENAME imapCommand - */ - static imapCommand *clientRename (const TQString & src, - const TQString & dest); - /** - * @brief Create a SEARCH command - * @param search - * @param nouid Perform a UID SEARCH or a SEARCH command - * @return a SEARCH imapCommand - */ - static imapCommand *clientSearch (const TQString & search, bool nouid = - false); - /** - * @brief Create a STORE command - * @param set - * @param item - * @param data - * @param nouid Perform a UID STORE or a STORE command - * @return a STORE imapCommand - */ - static imapCommand *clientStore (const TQString & set, const TQString & item, - const TQString & data, bool nouid = false); - /** - * @brief Create a LOGOUT command - * @return a LOGOUT imapCommand - */ - static imapCommand *clientLogout (); - /** - * @brief Create a STARTTLS command - * @return a STARTTLS imapCommand - */ - static imapCommand *clientStartTLS (); - - //////////// ACL support (RFC 2086) ///////////// - /** - * @brief Create a SETACL command - * @param box mailbox name - * @param user authentication identifier - * @param acl access right modification (starting with optional +/-) - * @return a SETACL imapCommand - */ - static imapCommand *clientSetACL ( const TQString& box, const TQString& user, const TQString& acl ); - - /** - * @brief Create a DELETEACL command - * @param box mailbox name - * @param user authentication identifier - * @return a DELETEACL imapCommand - */ - static imapCommand *clientDeleteACL ( const TQString& box, const TQString& user ); - - /** - * @brief Create a GETACL command - * @param box mailbox name - * @return a GETACL imapCommand - */ - static imapCommand *clientGetACL ( const TQString& box ); - - /** - * @brief Create a LISTRIGHTS command - * @param box mailbox name - * @param user authentication identifier - * @return a LISTRIGHTS imapCommand - */ - static imapCommand *clientListRights ( const TQString& box, const TQString& user ); - - /** - * @brief Create a MYRIGHTS command - * @param box mailbox name - * @return a MYRIGHTS imapCommand - */ - static imapCommand *clientMyRights ( const TQString& box ); - - //////////// ANNOTATEMORE support ///////////// - /** - * @brief Create a SETANNOTATION command - * @param box mailbox name - * @param entry entry specifier - * @param attributes map of attribute names + values - * @return a SETANNOTATION imapCommand - */ - static imapCommand *clientSetAnnotation ( const TQString& box, const TQString& entry, const TQMap<TQString, TQString>& attributes ); - - /** - * @brief Create a GETANNOTATION command - * @param box mailbox name - * @param entry entry specifier - * @param attributeNames attribute specifier - * @return a GETANNOTATION imapCommand - */ - static imapCommand *clientGetAnnotation ( const TQString& box, const TQString& entry, const TQStringList& attributeNames ); - - /** - * @brief Create a NAMESPACE command - * @return a NAMESPACE imapCommand - */ - static imapCommand *clientNamespace (); - - /** - * @brief Create a GETQUOTAROOT command - * @param box mailbox name - * @return a GETQUOTAROOT imapCommand - */ - static imapCommand *clientGetQuotaroot ( const TQString& box ); - - /** - * @brief Create a custom command - * @param command The custom command - * @param arguments The custom arguments - * @return a custom imapCommand - */ - static imapCommand *clientCustom ( const TQString& command, const TQString& arguments ); - -protected: - TQString aCommand; - TQString mId; - bool mComplete; - TQString aParameter; - TQString mResult; - TQString mResultInfo; - -private: - imapCommand & operator = (const imapCommand &); -}; - -#endif diff --git a/tdeioslaves/imap4/imapinfo.cc b/tdeioslaves/imap4/imapinfo.cc deleted file mode 100644 index 4d1fc805c..000000000 --- a/tdeioslaves/imap4/imapinfo.cc +++ /dev/null @@ -1,236 +0,0 @@ -/********************************************************************** - * - * imapinfo.cc - IMAP4rev1 SELECT / EXAMINE handler - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -/* - References: - RFC 2060 - Internet Message Access Protocol - Version 4rev1 - December 1996 - RFC 2192 - IMAP URL Scheme - September 1997 - RFC 1731 - IMAP Authentication Mechanisms - December 1994 - (Discusses KERBEROSv4, GSSAPI, and S/Key) - RFC 2195 - IMAP/POP AUTHorize Extension for Simple Challenge/Response - - September 1997 (CRAM-MD5 authentication method) - RFC 2104 - HMAC: Keyed-Hashing for Message Authentication - February 1997 - - Supported URLs: - imap://server/ - Prompt for user/pass, list all folders in home directory - imap://user:pass@server/ - Uses LOGIN to log in - imap://user;AUTH=method:pass@server/ - Uses AUTHENTICATE to log in - - imap://server/folder/ - List messages in folder - */ - -#include "imapinfo.h" -#include "imapparser.h" - -#include <kdebug.h> - -imapInfo::imapInfo ():count_ (0), -recent_ (0), -unseen_ (0), -uidValidity_ (0), -uidNext_ (0), -flags_ (0), -permanentFlags_ (0), -readWrite_ (false), -countAvailable_ (false), -recentAvailable_ (false), -unseenAvailable_ (false), -uidValidityAvailable_ (false), -uidNextAvailable_ (false), -flagsAvailable_ (false), -permanentFlagsAvailable_ (false), readWriteAvailable_ (false) -{ -} - -imapInfo::imapInfo (const imapInfo & mi):count_ (mi.count_), -recent_ (mi.recent_), -unseen_ (mi.unseen_), -uidValidity_ (mi.uidValidity_), -uidNext_ (mi.uidNext_), -flags_ (mi.flags_), -permanentFlags_ (mi.permanentFlags_), -readWrite_ (mi.readWrite_), -countAvailable_ (mi.countAvailable_), -recentAvailable_ (mi.recentAvailable_), -unseenAvailable_ (mi.unseenAvailable_), -uidValidityAvailable_ (mi.uidValidityAvailable_), -uidNextAvailable_ (mi.uidNextAvailable_), -flagsAvailable_ (mi.flagsAvailable_), -permanentFlagsAvailable_ (mi.permanentFlagsAvailable_), -readWriteAvailable_ (mi.readWriteAvailable_) -{ -} - -imapInfo & imapInfo::operator = (const imapInfo & mi) -{ - // Avoid a = a. - if (this == &mi) - return *this; - - count_ = mi.count_; - recent_ = mi.recent_; - unseen_ = mi.unseen_; - uidValidity_ = mi.uidValidity_; - uidNext_ = mi.uidNext_; - flags_ = mi.flags_; - permanentFlags_ = mi.permanentFlags_; - readWrite_ = mi.readWrite_; - countAvailable_ = mi.countAvailable_; - recentAvailable_ = mi.recentAvailable_; - unseenAvailable_ = mi.unseenAvailable_; - uidValidityAvailable_ = mi.uidValidityAvailable_; - uidNextAvailable_ = mi.uidNextAvailable_; - flagsAvailable_ = mi.flagsAvailable_; - permanentFlagsAvailable_ = mi.permanentFlagsAvailable_; - readWriteAvailable_ = mi.readWriteAvailable_; - - return *this; -} - -imapInfo::imapInfo (const TQStringList & list):count_ (0), -recent_ (0), -unseen_ (0), -uidValidity_ (0), -uidNext_ (0), -flags_ (0), -permanentFlags_ (0), -readWrite_ (false), -countAvailable_ (false), -recentAvailable_ (false), -unseenAvailable_ (false), -uidValidityAvailable_ (false), -uidNextAvailable_ (false), -flagsAvailable_ (false), -permanentFlagsAvailable_ (false), readWriteAvailable_ (false) -{ - for (TQStringList::ConstIterator it (list.begin ()); it != list.end (); ++it) - { - TQString line (*it); - - line.truncate(line.length() - 2); - TQStringList tokens(TQStringList::split (' ', line)); - - kdDebug(7116) << "Processing: " << line << endl; - if (tokens[0] != "*") - continue; - - if (tokens[1] == "OK") - { - if (tokens[2] == "[UNSEEN") - setUnseen (tokens[3].left (tokens[3].length () - 1).toULong ()); - - else if (tokens[2] == "[UIDVALIDITY") - setUidValidity (tokens[3].left (tokens[3].length () - 1).toULong ()); - - else if (tokens[2] == "[UIDNEXT") - setUidNext (tokens[3].left (tokens[3].length () - 1).toULong ()); - - else if (tokens[2] == "[PERMANENTFLAGS") - { - int flagsStart = line.find('('); - int flagsEnd = line.find(')'); - - kdDebug(7116) << "Checking permFlags from " << flagsStart << " to " << flagsEnd << endl; - if ((-1 != flagsStart) && (-1 != flagsEnd) && flagsStart < flagsEnd) - setPermanentFlags (_flags (line.mid (flagsStart, flagsEnd).latin1())); - - } - else if (tokens[2] == "[READ-WRITE") - { - setReadWrite (true); - } - else if (tokens[2] == "[READ-ONLY") - { - setReadWrite (false); - } - else - { - kdDebug(7116) << "unknown token2: " << tokens[2] << endl; - } - } - else if (tokens[1] == "FLAGS") - { - int flagsStart = line.find ('('); - int flagsEnd = line.find (')'); - - if ((-1 != flagsStart) && (-1 != flagsEnd) && flagsStart < flagsEnd) - setFlags (_flags (line.mid (flagsStart, flagsEnd).latin1() )); - } - else - { - if (tokens[2] == "EXISTS") - setCount (tokens[1].toULong ()); - - else if (tokens[2] == "RECENT") - setRecent (tokens[1].toULong ()); - - else - kdDebug(7116) << "unknown token1/2: " << tokens[1] << " " << tokens[2] << endl; - } - } - -} - -ulong imapInfo::_flags (const TQCString & inFlags) -{ - ulong flags = 0; - parseString flagsString; - flagsString.data.duplicate(inFlags.data(), inFlags.length()); - - if (flagsString[0] == '(') - flagsString.pos++; - - while (!flagsString.isEmpty () && flagsString[0] != ')') - { - TQCString entry = imapParser::parseOneWordC(flagsString).upper(); - - if (entry.isEmpty ()) - flagsString.clear(); - else if (0 != entry.contains ("\\SEEN")) - flags ^= Seen; - else if (0 != entry.contains ("\\ANSWERED")) - flags ^= Answered; - else if (0 != entry.contains ("\\FLAGGED")) - flags ^= Flagged; - else if (0 != entry.contains ("\\DELETED")) - flags ^= Deleted; - else if (0 != entry.contains ("\\DRAFT")) - flags ^= Draft; - else if (0 != entry.contains ("\\RECENT")) - flags ^= Recent; - else if (0 != entry.contains ("\\*")) - flags ^= User; - - // non standard kmail falgs - else if ( entry.contains( "KMAILFORWARDED" ) || entry.contains( "$FORWARDED" ) ) - flags = flags | Forwarded; - else if ( entry.contains( "KMAILTODO" ) || entry.contains( "$TODO" ) ) - flags = flags | Todo; - else if ( entry.contains( "KMAILWATCHED" ) || entry.contains( "$WATCHED" ) ) - flags = flags | Watched; - else if ( entry.contains( "KMAILIGNORED" ) || entry.contains( "$IGNORED" ) ) - flags = flags | Ignored; - } - - return flags; -} diff --git a/tdeioslaves/imap4/imapinfo.h b/tdeioslaves/imap4/imapinfo.h deleted file mode 100644 index 735054496..000000000 --- a/tdeioslaves/imap4/imapinfo.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef _IMAPINFO_H -#define _IMAPINFO_H -/********************************************************************** - * - * imapinfo.h - IMAP4rev1 SELECT / EXAMINE handler - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -#include <tqstringlist.h> -#include <tqstring.h> - -//class handling the info we get on EXAMINE and SELECT -class imapInfo -{ -public: - - - enum MessageAttribute - { - Seen = 1 << 0, - Answered = 1 << 1, - Flagged = 1 << 2, - Deleted = 1 << 3, - Draft = 1 << 4, - Recent = 1 << 5, - User = 1 << 6, - // non standard flags - Forwarded = 1 << 7, - Todo = 1 << 8, - Watched = 1 << 9, - Ignored = 1 << 10 - }; - - - imapInfo (); - imapInfo (const TQStringList &); - imapInfo (const imapInfo &); - imapInfo & operator = (const imapInfo &); - - static ulong _flags (const TQCString &); - - void setCount (ulong l) - { - countAvailable_ = true; - count_ = l; - } - - void setRecent (ulong l) - { - recentAvailable_ = true; - recent_ = l; - } - - void setUnseen (ulong l) - { - unseenAvailable_ = true; - unseen_ = l; - } - - void setUidValidity (ulong l) - { - uidValidityAvailable_ = true; - uidValidity_ = l; - } - - void setUidNext (ulong l) - { - uidNextAvailable_ = true; - uidNext_ = l; - } - - void setFlags (ulong l) - { - flagsAvailable_ = true; - flags_ = l; - } - - void setFlags (const TQCString & inFlag) - { - flagsAvailable_ = true; - flags_ = _flags (inFlag); - } - - void setPermanentFlags (ulong l) - { - permanentFlagsAvailable_ = true; - permanentFlags_ = l; - } - - void setPermanentFlags (const TQCString & inFlag) - { - permanentFlagsAvailable_ = true; - permanentFlags_ = _flags (inFlag); - } - - void setReadWrite (bool b) - { - readWriteAvailable_ = true; - readWrite_ = b; - } - - void setAlert( const char* cstr ) - { - alert_ = cstr; - } - - ulong count () const - { - return count_; - } - - ulong recent () const - { - return recent_; - } - - ulong unseen () const - { - return unseen_; - } - - ulong uidValidity () const - { - return uidValidity_; - } - - ulong uidNext () const - { - return uidNext_; - } - - ulong flags () const - { - return flags_; - } - - ulong permanentFlags () const - { - return permanentFlags_; - } - - bool readWrite () const - { - return readWrite_; - } - - ulong countAvailable () const - { - return countAvailable_; - } - - ulong recentAvailable () const - { - return recentAvailable_; - } - - ulong unseenAvailable () const - { - return unseenAvailable_; - } - - ulong uidValidityAvailable () const - { - return uidValidityAvailable_; - } - - ulong uidNextAvailable () const - { - return uidNextAvailable_; - } - - ulong flagsAvailable () const - { - return flagsAvailable_; - } - - ulong permanentFlagsAvailable () const - { - return permanentFlagsAvailable_; - } - - bool readWriteAvailable () const - { - return readWriteAvailable_; - } - - TQCString alert() const - { - return alert_; - } - -private: - - TQCString alert_; - - ulong count_; - ulong recent_; - ulong unseen_; - ulong uidValidity_; - ulong uidNext_; - ulong flags_; - ulong permanentFlags_; - bool readWrite_; - - bool countAvailable_; - bool recentAvailable_; - bool unseenAvailable_; - bool uidValidityAvailable_; - bool uidNextAvailable_; - bool flagsAvailable_; - bool permanentFlagsAvailable_; - bool readWriteAvailable_; -}; - -#endif diff --git a/tdeioslaves/imap4/imaplist.cc b/tdeioslaves/imap4/imaplist.cc deleted file mode 100644 index 92918d8c1..000000000 --- a/tdeioslaves/imap4/imaplist.cc +++ /dev/null @@ -1,135 +0,0 @@ -/********************************************************************** - * - * imapinfo.cc - IMAP4rev1 EXAMINE / SELECT handler - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -/* - References: - RFC 2060 - Internet Message Access Protocol - Version 4rev1 - December 1996 - RFC 2192 - IMAP URL Scheme - September 1997 - RFC 1731 - IMAP Authentication Mechanisms - December 1994 - (Discusses KERBEROSv4, GSSAPI, and S/Key) - RFC 2195 - IMAP/POP AUTHorize Extension for Simple Challenge/Response - - September 1997 (CRAM-MD5 authentication method) - RFC 2104 - HMAC: Keyed-Hashing for Message Authentication - February 1997 - - Supported URLs: - imap://server/ - Prompt for user/pass, list all folders in home directory - imap://user:pass@server/ - Uses LOGIN to log in - imap://user;AUTH=method:pass@server/ - Uses AUTHENTICATE to log in - - imap://server/folder/ - List messages in folder - */ - -#include "rfcdecoder.h" -#include "imaplist.h" -#include "imapparser.h" - -#include <kdebug.h> - -imapList::imapList (): parser_(0), noInferiors_ (false), -noSelect_ (false), marked_ (false), unmarked_ (false), -hasChildren_ (false), hasNoChildren_ (false) -{ -} - -imapList::imapList (const imapList & lr):parser_(lr.parser_), -hierarchyDelimiter_ (lr.hierarchyDelimiter_), -name_ (lr.name_), -noInferiors_ (lr.noInferiors_), -noSelect_ (lr.noSelect_), marked_ (lr.marked_), unmarked_ (lr.unmarked_), -hasChildren_ (lr.hasChildren_), hasNoChildren_ (lr.hasNoChildren_), -attributes_ (lr.attributes_) -{ -} - -imapList & imapList::operator = (const imapList & lr) -{ - // Avoid a = a. - if (this == &lr) - return *this; - - parser_ = lr.parser_; - hierarchyDelimiter_ = lr.hierarchyDelimiter_; - name_ = lr.name_; - noInferiors_ = lr.noInferiors_; - noSelect_ = lr.noSelect_; - marked_ = lr.marked_; - unmarked_ = lr.unmarked_; - hasChildren_ = lr.hasChildren_; - hasNoChildren_ = lr.hasNoChildren_; - attributes_ = lr.attributes_; - - return *this; -} - -imapList::imapList (const TQString & inStr, imapParser &parser) -: parser_(&parser), -noInferiors_ (false), -noSelect_ (false), -marked_ (false), unmarked_ (false), hasChildren_ (false), -hasNoChildren_ (false) -{ - parseString s; - s.data.duplicate(inStr.latin1(), inStr.length()); - - if (s[0] != '(') - return; //not proper format for us - - s.pos++; // tie off ( - - parseAttributes( s ); - - s.pos++; // tie off ) - parser_->skipWS (s); - - hierarchyDelimiter_ = parser_->parseOneWordC(s); - if (hierarchyDelimiter_ == "NIL") - hierarchyDelimiter_ = TQString(); - name_ = rfcDecoder::fromIMAP (parser_->parseLiteral (s)); // decode modified UTF7 -} - -void imapList::parseAttributes( parseString & str ) -{ - TQCString attribute, orig; - - while ( !str.isEmpty () && str[0] != ')' ) - { - orig = parser_->parseOneWordC(str); - attributes_ << orig; - attribute = orig.lower(); - if (-1 != attribute.find ("\\noinferiors")) - noInferiors_ = true; - else if (-1 != attribute.find ("\\noselect")) - noSelect_ = true; - else if (-1 != attribute.find ("\\marked")) - marked_ = true; - else if (-1 != attribute.find ("\\unmarked")) - unmarked_ = true; - else if (-1 != attribute.find ("\\haschildren")) - hasChildren_ = true; - else if (-1 != attribute.find ("\\hasnochildren")) - hasNoChildren_ = true; - else - kdDebug(7116) << "imapList::imapList: bogus attribute " << attribute << endl; - } -} - diff --git a/tdeioslaves/imap4/imaplist.h b/tdeioslaves/imap4/imaplist.h deleted file mode 100644 index 9aa01f78d..000000000 --- a/tdeioslaves/imap4/imaplist.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef _IMAPLIST_H -#define _IMAPLIST_H -/********************************************************************** - * - * imaplist.h - IMAP4rev1 list response handler - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -#include <tqstringlist.h> -#include <tqstring.h> - -class parseString; -class imapParser; - -//the class handling the responses from list -class imapList -{ -public: - - imapList (); - imapList (const TQString &, imapParser &); - imapList (const imapList &); - imapList & operator = (const imapList &); - - // process the attributes - void parseAttributes( parseString & ); - - // return all atributes concatenated - TQString attributesAsString() const - { - return attributes_.join(","); - } - - TQString hierarchyDelimiter () const - { - return hierarchyDelimiter_; - } - void setHierarchyDelimiter (const TQString & _str) - { - hierarchyDelimiter_ = _str; - } - - TQString name () const - { - return name_; - } - void setName (const TQString & _str) - { - name_ = _str; - } - - bool noInferiors () const - { - return noInferiors_; - } - void setNoInferiors (bool _val) - { - noInferiors_ = _val; - } - - bool noSelect () const - { - return noSelect_; - } - void setNoSelect (bool _val) - { - noSelect_ = _val; - } - - bool hasChildren () const - { - return hasChildren_; - } - void setHasChildren (bool _val) - { - hasChildren_ = _val; - } - - bool hasNoChildren () const - { - return hasNoChildren_; - } - void setHasNoChildren (bool _val) - { - hasNoChildren_ = _val; - } - - bool marked () const - { - return marked_; - } - void setMarked (bool _val) - { - marked_ = _val; - } - - bool unmarked () const - { - return unmarked_; - } - void setUnmarked (bool _val) - { - unmarked_ = _val; - } - -private: - - imapParser* parser_; - TQString hierarchyDelimiter_; - TQString name_; - bool noInferiors_; - bool noSelect_; - bool marked_; - bool unmarked_; - bool hasChildren_; - bool hasNoChildren_; - TQStringList attributes_; -}; - -#endif diff --git a/tdeioslaves/imap4/imapparser.cc b/tdeioslaves/imap4/imapparser.cc deleted file mode 100644 index 8cb06e318..000000000 --- a/tdeioslaves/imap4/imapparser.cc +++ /dev/null @@ -1,2094 +0,0 @@ -/********************************************************************** - * - * imapparser.cc - IMAP4rev1 Parser - * Copyright (C) 2001-2002 Michael Haeckel <haeckel@kde.org> - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "rfcdecoder.h" - -#include "imapparser.h" - -#include "imapinfo.h" - -#include "mailheader.h" -#include "mimeheader.h" -#include "mailaddress.h" - -#include <sys/types.h> - -#include <stdlib.h> -#include <unistd.h> - -#ifdef HAVE_LIBSASL2 -extern "C" { -#include <sasl/sasl.h> -} -#endif - -#include <tqregexp.h> -#include <tqbuffer.h> -#include <tqstring.h> -#include <tqstringlist.h> - -#include <kdebug.h> -#include <kmdcodec.h> -#include <kurl.h> - -#include <kasciistricmp.h> -#include <kasciistringtools.h> - -#ifdef HAVE_LIBSASL2 -static sasl_callback_t callbacks[] = { - { SASL_CB_ECHOPROMPT, NULL, NULL }, - { SASL_CB_NOECHOPROMPT, NULL, NULL }, - { SASL_CB_GETREALM, NULL, NULL }, - { SASL_CB_USER, NULL, NULL }, - { SASL_CB_AUTHNAME, NULL, NULL }, - { SASL_CB_PASS, NULL, NULL }, - { SASL_CB_CANON_USER, NULL, NULL }, - { SASL_CB_LIST_END, NULL, NULL } -}; -#endif - -imapParser::imapParser () -{ - sentQueue.setAutoDelete (false); - completeQueue.setAutoDelete (true); - currentState = ISTATE_NO; - commandCounter = 0; - lastHandled = 0; -} - -imapParser::~imapParser () -{ - delete lastHandled; - lastHandled = 0; -} - -imapCommand * -imapParser::doCommand (imapCommand * aCmd) -{ - int pl = 0; - sendCommand (aCmd); - while (pl != -1 && !aCmd->isComplete ()) { - while ((pl = parseLoop ()) == 0) - ; - } - - return aCmd; -} - -imapCommand * -imapParser::sendCommand (imapCommand * aCmd) -{ - aCmd->setId (TQString::number(commandCounter++)); - sentQueue.append (aCmd); - - continuation.resize(0); - const TQString& command = aCmd->command(); - - if (command == "SELECT" || command == "EXAMINE") - { - // we need to know which box we are selecting - parseString p; - p.fromString(aCmd->parameter()); - currentBox = parseOneWordC(p); - kdDebug(7116) << "imapParser::sendCommand - setting current box to " << currentBox << endl; - } - else if (command == "CLOSE") - { - // we no longer have a box open - currentBox = TQString(); - } - else if (command.find ("SEARCH") != -1 - || command == "GETACL" - || command == "LISTRIGHTS" - || command == "MYRIGHTS" - || command == "GETANNOTATION" - || command == "NAMESPACE" - || command == "GETQUOTAROOT" - || command == "GETQUOTA" - || command == "X-GET-OTHER-USERS" - || command == "X-GET-DELEGATES" - || command == "X-GET-OUT-OF-OFFICE") - { - lastResults.clear (); - } - else if (command == "LIST" - || command == "LSUB") - { - listResponses.clear (); - } - parseWriteLine (aCmd->getStr ()); - return aCmd; -} - -bool -imapParser::clientLogin (const TQString & aUser, const TQString & aPass, - TQString & resultInfo) -{ - imapCommand *cmd; - bool retVal = false; - - cmd = - doCommand (new - imapCommand ("LOGIN", "\"" + rfcDecoder::quoteIMAP(aUser) - + "\" \"" + rfcDecoder::quoteIMAP(aPass) + "\"")); - - if (cmd->result () == "OK") - { - currentState = ISTATE_LOGIN; - retVal = true; - } - resultInfo = cmd->resultInfo(); - completeQueue.removeRef (cmd); - - return retVal; -} - -#ifdef HAVE_LIBSASL2 -static bool sasl_interact( TDEIO::SlaveBase *slave, TDEIO::AuthInfo &ai, void *in ) -{ - kdDebug(7116) << "sasl_interact" << endl; - sasl_interact_t *interact = ( sasl_interact_t * ) in; - - //some mechanisms do not require username && pass, so it doesn't need a popup - //window for getting this info - for ( ; interact->id != SASL_CB_LIST_END; interact++ ) { - if ( interact->id == SASL_CB_AUTHNAME || - interact->id == SASL_CB_PASS ) { - - if ( ai.username.isEmpty() || ai.password.isEmpty() ) { - if (!slave->openPassDlg(ai)) - return false; - } - break; - } - } - - interact = ( sasl_interact_t * ) in; - while( interact->id != SASL_CB_LIST_END ) { - kdDebug(7116) << "SASL_INTERACT id: " << interact->id << endl; - switch( interact->id ) { - case SASL_CB_USER: - case SASL_CB_AUTHNAME: - kdDebug(7116) << "SASL_CB_[USER|AUTHNAME]: '" << ai.username << "'" << endl; - interact->result = strdup( ai.username.utf8() ); - interact->len = strlen( (const char *) interact->result ); - break; - case SASL_CB_PASS: - kdDebug(7116) << "SASL_CB_PASS: [hidden] " << endl; - interact->result = strdup( ai.password.utf8() ); - interact->len = strlen( (const char *) interact->result ); - break; - default: - interact->result = 0; - interact->len = 0; - break; - } - interact++; - } - return true; -} -#endif - -bool -imapParser::clientAuthenticate ( TDEIO::SlaveBase *slave, TDEIO::AuthInfo &ai, - const TQString & aFTQDN, const TQString & aAuth, bool isSSL, TQString & resultInfo) -{ - bool retVal = false; -#ifdef HAVE_LIBSASL2 - int result; - sasl_conn_t *conn = 0; - sasl_interact_t *client_interact = 0; - const char *out = 0; - uint outlen = 0; - const char *mechusing = 0; - TQByteArray tmp, challenge; - - kdDebug(7116) << "aAuth: " << aAuth << " FTQDN: " << aFTQDN << " isSSL: " << isSSL << endl; - - // see if server supports this authenticator - if (!hasCapability ("AUTH=" + aAuth)) - return false; - -// result = sasl_client_new( isSSL ? "imaps" : "imap", - result = sasl_client_new( "imap", /* FIXME: with cyrus-imapd, even imaps' digest-uri - must be 'imap'. I don't know if it's good or bad. */ - aFTQDN.latin1(), - 0, 0, callbacks, 0, &conn ); - - if ( result != SASL_OK ) { - kdDebug(7116) << "sasl_client_new failed with: " << result << endl; - resultInfo = TQString::fromUtf8( sasl_errdetail( conn ) ); - return false; - } - - do { - result = sasl_client_start(conn, aAuth.latin1(), &client_interact, - hasCapability("SASL-IR") ? &out : 0, &outlen, &mechusing); - - if ( result == SASL_INTERACT ) { - if ( !sasl_interact( slave, ai, client_interact ) ) { - sasl_dispose( &conn ); - return false; - } - } - } while ( result == SASL_INTERACT ); - - if ( result != SASL_CONTINUE && result != SASL_OK ) { - kdDebug(7116) << "sasl_client_start failed with: " << result << endl; - resultInfo = TQString::fromUtf8( sasl_errdetail( conn ) ); - sasl_dispose( &conn ); - return false; - } - imapCommand *cmd; - - tmp.setRawData( out, outlen ); - KCodecs::base64Encode( tmp, challenge ); - tmp.resetRawData( out, outlen ); - // then lets try it - TQString firstCommand = aAuth; - if ( !challenge.isEmpty() ) { - firstCommand += " "; - firstCommand += TQString::fromLatin1( challenge.data(), challenge.size() ); - } - cmd = sendCommand (new imapCommand ("AUTHENTICATE", firstCommand.latin1())); - - int pl = 0; - while ( pl != -1 && !cmd->isComplete () ) - { - //read the next line - while ((pl = parseLoop()) == 0) ; - - if (!continuation.isEmpty()) - { -// kdDebug(7116) << "S: " << TQCString(continuation.data(),continuation.size()+1) << endl; - if ( continuation.size() > 4 ) { - tmp.setRawData( continuation.data() + 2, continuation.size() - 4 ); - KCodecs::base64Decode( tmp, challenge ); -// kdDebug(7116) << "S-1: " << TQCString(challenge.data(),challenge.size()+1) << endl; - tmp.resetRawData( continuation.data() + 2, continuation.size() - 4 ); - } - - do { - result = sasl_client_step(conn, challenge.isEmpty() ? 0 : challenge.data(), - challenge.size(), - &client_interact, - &out, &outlen); - - if (result == SASL_INTERACT) { - if ( !sasl_interact( slave, ai, client_interact ) ) { - sasl_dispose( &conn ); - return false; - } - } - } while ( result == SASL_INTERACT ); - - if ( result != SASL_CONTINUE && result != SASL_OK ) { - kdDebug(7116) << "sasl_client_step failed with: " << result << endl; - resultInfo = TQString::fromUtf8( sasl_errdetail( conn ) ); - sasl_dispose( &conn ); - return false; - } - - tmp.setRawData( out, outlen ); -// kdDebug(7116) << "C-1: " << TQCString(tmp.data(),tmp.size()+1) << endl; - KCodecs::base64Encode( tmp, challenge ); - tmp.resetRawData( out, outlen ); -// kdDebug(7116) << "C: " << TQCString(challenge.data(),challenge.size()+1) << endl; - parseWriteLine (challenge); - continuation.resize(0); - } - } - - if (cmd->result () == "OK") - { - currentState = ISTATE_LOGIN; - retVal = true; - } - resultInfo = cmd->resultInfo(); - completeQueue.removeRef (cmd); - - sasl_dispose( &conn ); //we don't use sasl_en/decode(), so it's safe to dispose the connection. -#endif //HAVE_LIBSASL2 - return retVal; -} - -void -imapParser::parseUntagged (parseString & result) -{ - //kdDebug(7116) << "imapParser::parseUntagged - '" << result.cstr() << "'" << endl; - - parseOneWordC(result); // * - TQByteArray what = parseLiteral (result); // see whats coming next - - if(!what.isEmpty ()) { - switch (what[0]) - { - //the status responses - case 'B': // BAD or BYE - if (tqstrncmp(what, "BAD", what.size()) == 0) - { - parseResult (what, result); - } - else if (tqstrncmp(what, "BYE", what.size()) == 0) - { - parseResult (what, result); - if ( sentQueue.count() ) { - // BYE that interrupts a command -> copy the reason for it - imapCommand *current = sentQueue.at (0); - current->setResultInfo(result.cstr()); - } - currentState = ISTATE_NO; - } - break; - - case 'N': // NO - if (what[1] == 'O' && what.size() == 2) - { - parseResult (what, result); - } - else if (tqstrncmp(what, "NAMESPACE", what.size()) == 0) - { - parseNamespace (result); - } - break; - - case 'O': // OK - if (what[1] == 'K' && what.size() == 2) - { - parseResult (what, result); - } else if (tqstrncmp(what, "OTHER-USER", 10) == 0) { // X-GET-OTHER-USER - parseOtherUser (result); - } else if (tqstrncmp(what, "OUT-OF-OFFICE", 13) == 0) { // X-GET-OUT-OF-OFFICE - parseOutOfOffice (result); - } - break; - case 'D': - if (tqstrncmp(what, "DELEGATE", 8) == 0) { // X-GET-DELEGATES - parseDelegate (result); - } - break; - - case 'P': // PREAUTH - if (tqstrncmp(what, "PREAUTH", what.size()) == 0) - { - parseResult (what, result); - currentState = ISTATE_LOGIN; - } - break; - - // parse the other responses - case 'C': // CAPABILITY - if (tqstrncmp(what, "CAPABILITY", what.size()) == 0) - { - parseCapability (result); - } - break; - - case 'F': // FLAGS - if (tqstrncmp(what, "FLAGS", what.size()) == 0) - { - parseFlags (result); - } - break; - - case 'L': // LIST or LSUB or LISTRIGHTS - if (tqstrncmp(what, "LIST", what.size()) == 0) - { - parseList (result); - } - else if (tqstrncmp(what, "LSUB", what.size()) == 0) - { - parseLsub (result); - } - else if (tqstrncmp(what, "LISTRIGHTS", what.size()) == 0) - { - parseListRights (result); - } - break; - - case 'M': // MYRIGHTS - if (tqstrncmp(what, "MYRIGHTS", what.size()) == 0) - { - parseMyRights (result); - } - break; - case 'S': // SEARCH or STATUS - if (tqstrncmp(what, "SEARCH", what.size()) == 0) - { - parseSearch (result); - } - else if (tqstrncmp(what, "STATUS", what.size()) == 0) - { - parsetStatus (result); - } - break; - - case 'A': // ACL or ANNOTATION - if (tqstrncmp(what, "ACL", what.size()) == 0) - { - parseAcl (result); - } - else if (tqstrncmp(what, "ANNOTATION", what.size()) == 0) - { - parseAnnotation (result); - } - break; - case 'Q': // QUOTA or QUOTAROOT - if ( what.size() > 5 && tqstrncmp(what, "QUOTAROOT", what.size()) == 0) - { - parseQuotaRoot( result ); - } - else if (tqstrncmp(what, "QUOTA", what.size()) == 0) - { - parseQuota( result ); - } - break; - case 'X': // Custom command - { - parseCustom( result ); - } - break; - default: - //better be a number - { - ulong number; - bool valid; - - number = TQCString(what, what.size() + 1).toUInt(&valid); - if (valid) - { - what = parseLiteral (result); - if(!what.isEmpty ()) { - switch (what[0]) - { - case 'E': - if (tqstrncmp(what, "EXISTS", what.size()) == 0) - { - parseExists (number, result); - } - else if (tqstrncmp(what, "EXPUNGE", what.size()) == 0) - { - parseExpunge (number, result); - } - break; - - case 'F': - if (tqstrncmp(what, "FETCH", what.size()) == 0) - { - seenUid = TQString(); - parseFetch (number, result); - } - break; - - case 'S': - if (tqstrncmp(what, "STORE", what.size()) == 0) // deprecated store - { - seenUid = TQString(); - parseFetch (number, result); - } - break; - - case 'R': - if (tqstrncmp(what, "RECENT", what.size()) == 0) - { - parseRecent (number, result); - } - break; - default: - break; - } - } - } - } - break; - } //switch - } -} //func - - -void -imapParser::parseResult (TQByteArray & result, parseString & rest, - const TQString & command) -{ - if (command == "SELECT") - selectInfo.setReadWrite(true); - - if (rest[0] == '[') - { - rest.pos++; - TQCString option = parseOneWordC(rest, TRUE); - - switch (option[0]) - { - case 'A': // ALERT - if (option == "ALERT") - { - rest.pos = rest.data.find(']', rest.pos) + 1; - // The alert text is after [ALERT]. - // Is this correct or do we need to care about litterals? - selectInfo.setAlert( rest.cstr() ); - } - break; - - case 'N': // NEWNAME - if (option == "NEWNAME") - { - } - break; - - case 'P': //PARSE or PERMANENTFLAGS - if (option == "PARSE") - { - } - else if (option == "PERMANENTFLAGS") - { - uint end = rest.data.find(']', rest.pos); - TQCString flags(rest.data.data() + rest.pos, end - rest.pos); - selectInfo.setPermanentFlags (flags); - rest.pos = end; - } - break; - - case 'R': //READ-ONLY or READ-WRITE - if (option == "READ-ONLY") - { - selectInfo.setReadWrite (false); - } - else if (option == "READ-WRITE") - { - selectInfo.setReadWrite (true); - } - break; - - case 'T': //TRYCREATE - if (option == "TRYCREATE") - { - } - break; - - case 'U': //UIDVALIDITY or UNSEEN - if (option == "UIDVALIDITY") - { - ulong value; - if (parseOneNumber (rest, value)) - selectInfo.setUidValidity (value); - } - else if (option == "UNSEEN") - { - ulong value; - if (parseOneNumber (rest, value)) - selectInfo.setUnseen (value); - } - else if (option == "UIDNEXT") - { - ulong value; - if (parseOneNumber (rest, value)) - selectInfo.setUidNext (value); - } - else - break; - - } - if (rest[0] == ']') - rest.pos++; //tie off ] - skipWS (rest); - } - - if (command.isEmpty()) - { - // This happens when parsing an intermediate result line (those that start with '*'). - // No state change involved, so we can stop here. - return; - } - - switch (command[0].latin1 ()) - { - case 'A': - if (command == "AUTHENTICATE") - if (tqstrncmp(result, "OK", result.size()) == 0) - currentState = ISTATE_LOGIN; - break; - - case 'L': - if (command == "LOGIN") - if (tqstrncmp(result, "OK", result.size()) == 0) - currentState = ISTATE_LOGIN; - break; - - case 'E': - if (command == "EXAMINE") - { - if (tqstrncmp(result, "OK", result.size()) == 0) - currentState = ISTATE_SELECT; - else - { - if (currentState == ISTATE_SELECT) - currentState = ISTATE_LOGIN; - currentBox = TQString(); - } - kdDebug(7116) << "imapParser::parseResult - current box is now " << currentBox << endl; - } - break; - - case 'S': - if (command == "SELECT") - { - if (tqstrncmp(result, "OK", result.size()) == 0) - currentState = ISTATE_SELECT; - else - { - if (currentState == ISTATE_SELECT) - currentState = ISTATE_LOGIN; - currentBox = TQString(); - } - kdDebug(7116) << "imapParser::parseResult - current box is now " << currentBox << endl; - } - break; - - default: - break; - } - -} - -void imapParser::parseCapability (parseString & result) -{ - TQCString temp( result.cstr() ); - imapCapabilities = TQStringList::split ( ' ', KPIM::kAsciiToLower( temp.data() ) ); -} - -void imapParser::parseFlags (parseString & result) -{ - selectInfo.setFlags(result.cstr()); -} - -void imapParser::parseList (parseString & result) -{ - imapList this_one; - - if (result[0] != '(') - return; //not proper format for us - - result.pos++; // tie off ( - - this_one.parseAttributes( result ); - - result.pos++; // tie off ) - skipWS (result); - - this_one.setHierarchyDelimiter(parseLiteralC(result)); - this_one.setName (rfcDecoder::fromIMAP(parseLiteralC(result))); // decode modified UTF7 - - listResponses.append (this_one); -} - -void imapParser::parseLsub (parseString & result) -{ - imapList this_one (result.cstr(), *this); - listResponses.append (this_one); -} - -void imapParser::parseListRights (parseString & result) -{ - parseOneWordC (result); // skip mailbox name - parseOneWordC (result); // skip user id - int outlen = 1; - while ( outlen ) { - TQCString word = parseOneWordC (result, false, &outlen); - lastResults.append (word); - } -} - -void imapParser::parseAcl (parseString & result) -{ - parseOneWordC (result); // skip mailbox name - int outlen = 1; - // The result is user1 perm1 user2 perm2 etc. The caller will sort it out. - while ( outlen && !result.isEmpty() ) { - TQCString word = parseLiteralC (result, false, false, &outlen); - lastResults.append (word); - } -} - -void imapParser::parseAnnotation (parseString & result) -{ - parseOneWordC (result); // skip mailbox name - skipWS (result); - parseOneWordC (result); // skip entry name (we know it since we don't allow wildcards in it) - skipWS (result); - if (result.isEmpty() || result[0] != '(') - return; - result.pos++; - skipWS (result); - int outlen = 1; - // The result is name1 value1 name2 value2 etc. The caller will sort it out. - while ( outlen && !result.isEmpty() && result[0] != ')' ) { - TQCString word = parseLiteralC (result, false, false, &outlen); - lastResults.append (word); - } -} - - -void imapParser::parseQuota (parseString & result) -{ - // quota_response ::= "QUOTA" SP astring SP quota_list - // quota_list ::= "(" #quota_resource ")" - // quota_resource ::= atom SP number SP number - TQCString root = parseOneWordC( result ); - if ( root.isEmpty() ) { - lastResults.append( "" ); - } else { - lastResults.append( root ); - } - if (result.isEmpty() || result[0] != '(') - return; - result.pos++; - skipWS (result); - TQStringList triplet; - int outlen = 1; - while ( outlen && !result.isEmpty() && result[0] != ')' ) { - TQCString word = parseLiteralC (result, false, false, &outlen); - triplet.append(word); - } - lastResults.append( triplet.join(" ") ); -} - -void imapParser::parseQuotaRoot (parseString & result) -{ - // quotaroot_response - // ::= "QUOTAROOT" SP astring *(SP astring) - parseOneWordC (result); // skip mailbox name - skipWS (result); - if ( result.isEmpty() ) - return; - TQStringList roots; - int outlen = 1; - while ( outlen && !result.isEmpty() ) { - TQCString word = parseLiteralC (result, false, false, &outlen); - roots.append (word); - } - lastResults.append( roots.isEmpty()? "" : roots.join(" ") ); -} - -void imapParser::parseCustom (parseString & result) -{ - int outlen = 1; - TQCString word = parseLiteralC (result, false, false, &outlen); - lastResults.append( word ); -} - -void imapParser::parseOtherUser (parseString & result) -{ - lastResults.append( parseOneWordC( result ) ); -} - -void imapParser::parseDelegate (parseString & result) -{ - const TQString email = parseOneWordC( result ); - - TQStringList rights; - int outlen = 1; - while ( outlen && !result.isEmpty() ) { - TQCString word = parseLiteralC( result, false, false, &outlen ); - rights.append( word ); - } - - lastResults.append( email + ":" + rights.join( "," ) ); -} - -void imapParser::parseOutOfOffice (parseString & result) -{ - const TQString state = parseOneWordC (result); - parseOneWordC (result); // skip encoding - - int outlen = 1; - TQCString msg = parseLiteralC (result, false, false, &outlen); - - lastResults.append( state + "^" + TQString::fromUtf8( msg ) ); -} - -void imapParser::parseMyRights (parseString & result) -{ - parseOneWordC (result); // skip mailbox name - Q_ASSERT( lastResults.isEmpty() ); // we can only be called once - lastResults.append (parseOneWordC (result) ); -} - -void imapParser::parseSearch (parseString & result) -{ - ulong value; - - while (parseOneNumber (result, value)) - { - lastResults.append (TQString::number(value)); - } -} - -void imapParser::parsetStatus (parseString & inWords) -{ - lasStatus = imapInfo (); - - parseLiteralC(inWords); // swallow the box - if (inWords.isEmpty() || inWords[0] != '(') - return; - - inWords.pos++; - skipWS (inWords); - - while (!inWords.isEmpty() && inWords[0] != ')') - { - ulong value; - - TQCString label = parseOneWordC(inWords); - if (parseOneNumber (inWords, value)) - { - if (label == "MESSAGES") - lasStatus.setCount (value); - else if (label == "RECENT") - lasStatus.setRecent (value); - else if (label == "UIDVALIDITY") - lasStatus.setUidValidity (value); - else if (label == "UNSEEN") - lasStatus.setUnseen (value); - else if (label == "UIDNEXT") - lasStatus.setUidNext (value); - } - } - - if (inWords[0] == ')') - inWords.pos++; - skipWS (inWords); -} - -void imapParser::parseExists (ulong value, parseString & result) -{ - selectInfo.setCount (value); - result.pos = result.data.size(); -} - -void imapParser::parseExpunge (ulong value, parseString & result) -{ - Q_UNUSED(value); - Q_UNUSED(result); -} - -void imapParser::parseAddressList (parseString & inWords, TQPtrList<mailAddress>& list) -{ - if (inWords.isEmpty()) - return; - if (inWords[0] != '(') - { - parseOneWordC (inWords); // parse NIL - } - else - { - inWords.pos++; - skipWS (inWords); - - while (!inWords.isEmpty () && inWords[0] != ')') - { - if (inWords[0] == '(') { - mailAddress *addr = new mailAddress; - parseAddress(inWords, *addr); - list.append(addr); - } else { - break; - } - } - - if (!inWords.isEmpty() && inWords[0] == ')') - inWords.pos++; - skipWS (inWords); - } -} - -const mailAddress& imapParser::parseAddress (parseString & inWords, mailAddress& retVal) -{ - inWords.pos++; - skipWS (inWords); - - retVal.setFullName(parseLiteralC(inWords)); - retVal.setCommentRaw(parseLiteralC(inWords)); - retVal.setUser(parseLiteralC(inWords)); - retVal.setHost(parseLiteralC(inWords)); - - if (!inWords.isEmpty() && inWords[0] == ')') - inWords.pos++; - skipWS (inWords); - - return retVal; -} - -mailHeader * imapParser::parseEnvelope (parseString & inWords) -{ - mailHeader *envelope = 0; - - if (inWords[0] != '(') - return envelope; - inWords.pos++; - skipWS (inWords); - - envelope = new mailHeader; - - //date - envelope->setDate(parseLiteralC(inWords)); - - //subject - envelope->setSubject(parseLiteralC(inWords)); - - TQPtrList<mailAddress> list; - list.setAutoDelete(true); - - //from - parseAddressList(inWords, list); - if (!list.isEmpty()) { - envelope->setFrom(*list.last()); - list.clear(); - } - - //sender - parseAddressList(inWords, list); - if (!list.isEmpty()) { - envelope->setSender(*list.last()); - list.clear(); - } - - //reply-to - parseAddressList(inWords, list); - if (!list.isEmpty()) { - envelope->setReplyTo(*list.last()); - list.clear(); - } - - //to - parseAddressList (inWords, envelope->to()); - - //cc - parseAddressList (inWords, envelope->cc()); - - //bcc - parseAddressList (inWords, envelope->bcc()); - - //in-reply-to - envelope->setInReplyTo(parseLiteralC(inWords)); - - //message-id - envelope->setMessageId(parseLiteralC(inWords)); - - // see if we have more to come - while (!inWords.isEmpty () && inWords[0] != ')') - { - //eat the extensions to this part - if (inWords[0] == '(') - parseSentence (inWords); - else - parseLiteralC (inWords); - } - - if (!inWords.isEmpty() && inWords[0] == ')') - inWords.pos++; - skipWS (inWords); - - return envelope; -} - -// parse parameter pairs into a dictionary -// caller must clean up the dictionary items -TQAsciiDict < TQString > imapParser::parseDisposition (parseString & inWords) -{ - TQCString disposition; - TQAsciiDict < TQString > retVal (17, false); - - // return value is a shallow copy - retVal.setAutoDelete (false); - - if (inWords[0] != '(') - { - //disposition only - disposition = parseOneWordC (inWords); - } - else - { - inWords.pos++; - skipWS (inWords); - - //disposition - disposition = parseOneWordC (inWords); - retVal = parseParameters (inWords); - if (inWords[0] != ')') - return retVal; - inWords.pos++; - skipWS (inWords); - } - - if (!disposition.isEmpty ()) - { - retVal.insert ("content-disposition", new TQString(disposition)); - } - - return retVal; -} - -// parse parameter pairs into a dictionary -// caller must clean up the dictionary items -TQAsciiDict < TQString > imapParser::parseParameters (parseString & inWords) -{ - TQAsciiDict < TQString > retVal (17, false); - - // return value is a shallow copy - retVal.setAutoDelete (false); - - if (inWords[0] != '(') - { - //better be NIL - parseOneWordC (inWords); - } - else - { - inWords.pos++; - skipWS (inWords); - - while (!inWords.isEmpty () && inWords[0] != ')') - { - TQCString l1 = parseLiteralC(inWords); - TQCString l2 = parseLiteralC(inWords); - retVal.insert (l1, new TQString(l2)); - } - - if (inWords[0] != ')') - return retVal; - inWords.pos++; - skipWS (inWords); - } - - return retVal; -} - -mimeHeader * imapParser::parseSimplePart (parseString & inWords, - TQString & inSection, mimeHeader * localPart) -{ - TQCString subtype; - TQCString typeStr; - TQAsciiDict < TQString > parameters (17, false); - ulong size; - - parameters.setAutoDelete (true); - - if (inWords[0] != '(') - return 0; - - if (!localPart) - localPart = new mimeHeader; - - localPart->setPartSpecifier (inSection); - - inWords.pos++; - skipWS (inWords); - - //body type - typeStr = parseLiteralC(inWords); - - //body subtype - subtype = parseLiteralC(inWords); - - localPart->setType (typeStr + "/" + subtype); - - //body parameter parenthesized list - parameters = parseParameters (inWords); - { - TQAsciiDictIterator < TQString > it (parameters); - - while (it.current ()) - { - localPart->setTypeParm (it.currentKey (), *(it.current ())); - ++it; - } - parameters.clear (); - } - - //body id - localPart->setID (parseLiteralC(inWords)); - - //body description - localPart->setDescription (parseLiteralC(inWords)); - - //body encoding - localPart->setEncoding (parseLiteralC(inWords)); - - //body size - if (parseOneNumber (inWords, size)) - localPart->setLength (size); - - // type specific extensions - if (localPart->getType().upper() == "MESSAGE/RFC822") - { - //envelope structure - mailHeader *envelope = parseEnvelope (inWords); - - //body structure - parseBodyStructure (inWords, inSection, envelope); - - localPart->setNestedMessage (envelope); - - //text lines - ulong lines; - parseOneNumber (inWords, lines); - } - else - { - if (typeStr == "TEXT") - { - //text lines - ulong lines; - parseOneNumber (inWords, lines); - } - - // md5 - parseLiteralC(inWords); - - // body disposition - parameters = parseDisposition (inWords); - { - TQString *disposition = parameters["content-disposition"]; - - if (disposition) - localPart->setDisposition (disposition->ascii ()); - parameters.remove ("content-disposition"); - TQAsciiDictIterator < TQString > it (parameters); - while (it.current ()) - { - localPart->setDispositionParm (it.currentKey (), - *(it.current ())); - ++it; - } - - parameters.clear (); - } - - // body language - parseSentence (inWords); - } - - // see if we have more to come - while (!inWords.isEmpty () && inWords[0] != ')') - { - //eat the extensions to this part - if (inWords[0] == '(') - parseSentence (inWords); - else - parseLiteralC(inWords); - } - if (inWords[0] == ')') - inWords.pos++; - skipWS (inWords); - - return localPart; -} - -mimeHeader * imapParser::parseBodyStructure (parseString & inWords, - TQString & inSection, mimeHeader * localPart) -{ - bool init = false; - if (inSection.isEmpty()) - { - // first run - init = true; - // assume one part - inSection = "1"; - } - int section = 0; - - if (inWords[0] != '(') - { - // skip "" - parseOneWordC (inWords); - return 0; - } - inWords.pos++; - skipWS (inWords); - - if (inWords[0] == '(') - { - TQByteArray subtype; - TQAsciiDict < TQString > parameters (17, false); - TQString outSection; - parameters.setAutoDelete (true); - if (!localPart) - localPart = new mimeHeader; - else - { - // might be filled from an earlier run - localPart->clearNestedParts (); - localPart->clearTypeParameters (); - localPart->clearDispositionParameters (); - // an envelope was passed in so this is the multipart header - outSection = inSection + ".HEADER"; - } - if (inWords[0] == '(' && init) - inSection = "0"; - - // set the section - if ( !outSection.isEmpty() ) { - localPart->setPartSpecifier(outSection); - } else { - localPart->setPartSpecifier(inSection); - } - - // is multipart (otherwise its a simplepart and handled later) - while (inWords[0] == '(') - { - outSection = TQString::number(++section); - if (!init) - outSection = inSection + "." + outSection; - mimeHeader *subpart = parseBodyStructure (inWords, outSection, 0); - localPart->addNestedPart (subpart); - } - - // fetch subtype - subtype = parseOneWordC (inWords); - - localPart->setType ("MULTIPART/" + b2c(subtype)); - - // fetch parameters - parameters = parseParameters (inWords); - { - TQAsciiDictIterator < TQString > it (parameters); - - while (it.current ()) - { - localPart->setTypeParm (it.currentKey (), *(it.current ())); - ++it; - } - parameters.clear (); - } - - // body disposition - parameters = parseDisposition (inWords); - { - TQString *disposition = parameters["content-disposition"]; - - if (disposition) - localPart->setDisposition (disposition->ascii ()); - parameters.remove ("content-disposition"); - TQAsciiDictIterator < TQString > it (parameters); - while (it.current ()) - { - localPart->setDispositionParm (it.currentKey (), - *(it.current ())); - ++it; - } - parameters.clear (); - } - - // body language - parseSentence (inWords); - - } - else - { - // is simple part - inWords.pos--; - inWords.data[inWords.pos] = '('; //fake a sentence - if ( localPart ) - inSection = inSection + ".1"; - localPart = parseSimplePart (inWords, inSection, localPart); - inWords.pos--; - inWords.data[inWords.pos] = ')'; //remove fake - } - - // see if we have more to come - while (!inWords.isEmpty () && inWords[0] != ')') - { - //eat the extensions to this part - if (inWords[0] == '(') - parseSentence (inWords); - else - parseLiteralC(inWords); - } - - if (inWords[0] == ')') - inWords.pos++; - skipWS (inWords); - - return localPart; -} - -void imapParser::parseBody (parseString & inWords) -{ - // see if we got a part specifier - if (inWords[0] == '[') - { - TQCString specifier; - TQCString label; - inWords.pos++; - - specifier = parseOneWordC (inWords, TRUE); - - if (inWords[0] == '(') - { - inWords.pos++; - - while (!inWords.isEmpty () && inWords[0] != ')') - { - label = parseOneWordC (inWords); - } - - if (!inWords.isEmpty () && inWords[0] == ')') - inWords.pos++; - } - if (!inWords.isEmpty () && inWords[0] == ']') - inWords.pos++; - skipWS (inWords); - - // parse the header - if (specifier == "0") - { - mailHeader *envelope = 0; - if (lastHandled) - envelope = lastHandled->getHeader (); - - if (!envelope || seenUid.isEmpty ()) - { - kdDebug(7116) << "imapParser::parseBody - discarding " << envelope << " " << seenUid.ascii () << endl; - // don't know where to put it, throw it away - parseLiteralC(inWords, true); - } - else - { - kdDebug(7116) << "imapParser::parseBody - reading " << envelope << " " << seenUid.ascii () << endl; - // fill it up with data - TQString theHeader = parseLiteralC(inWords, true); - mimeIOTQString myIO; - - myIO.setString (theHeader); - envelope->parseHeader (myIO); - - } - } - else if (specifier == "HEADER.FIELDS") - { - // BODY[HEADER.FIELDS (References)] {n} - //kdDebug(7116) << "imapParser::parseBody - HEADER.FIELDS: " - // << TQCString(label.data(), label.size()+1) << endl; - if (label == "REFERENCES") - { - mailHeader *envelope = 0; - if (lastHandled) - envelope = lastHandled->getHeader (); - - if (!envelope || seenUid.isEmpty ()) - { - kdDebug(7116) << "imapParser::parseBody - discarding " << envelope << " " << seenUid.ascii () << endl; - // don't know where to put it, throw it away - parseLiteralC (inWords, true); - } - else - { - TQCString references = parseLiteralC(inWords, true); - int start = references.find ('<'); - int end = references.findRev ('>'); - if (start < end) - references = references.mid (start, end - start + 1); - envelope->setReferences(references.simplifyWhiteSpace()); - } - } - else - { // not a header we care about throw it away - parseLiteralC(inWords, true); - } - } - else - { - if (specifier.find(".MIME") != -1) - { - mailHeader *envelope = new mailHeader; - TQString theHeader = parseLiteralC(inWords, false); - mimeIOTQString myIO; - myIO.setString (theHeader); - envelope->parseHeader (myIO); - if (lastHandled) - lastHandled->setHeader (envelope); - return; - } - // throw it away - kdDebug(7116) << "imapParser::parseBody - discarding " << seenUid.ascii () << endl; - parseLiteralC(inWords, true); - } - - } - else // no part specifier - { - mailHeader *envelope = 0; - if (lastHandled) - envelope = lastHandled->getHeader (); - - if (!envelope || seenUid.isEmpty ()) - { - kdDebug(7116) << "imapParser::parseBody - discarding " << envelope << " " << seenUid.ascii () << endl; - // don't know where to put it, throw it away - parseSentence (inWords); - } - else - { - kdDebug(7116) << "imapParser::parseBody - reading " << envelope << " " << seenUid.ascii () << endl; - // fill it up with data - TQString section; - mimeHeader *body = parseBodyStructure (inWords, section, envelope); - if (body != envelope) - delete body; - } - } -} - -void imapParser::parseFetch (ulong /* value */, parseString & inWords) -{ - if (inWords[0] != '(') - return; - inWords.pos++; - skipWS (inWords); - - delete lastHandled; - lastHandled = 0; - - while (!inWords.isEmpty () && inWords[0] != ')') - { - if (inWords[0] == '(') - parseSentence (inWords); - else - { - TQCString word = parseLiteralC(inWords, false, true); - - if(!word.isEmpty()) { - switch (word[0]) - { - case 'E': - if (word == "ENVELOPE") - { - mailHeader *envelope = 0; - - if (lastHandled) - envelope = lastHandled->getHeader (); - else - lastHandled = new imapCache(); - - if (envelope && !envelope->getMessageId ().isEmpty ()) - { - // we have seen this one already - // or don't know where to put it - parseSentence (inWords); - } - else - { - envelope = parseEnvelope (inWords); - if (envelope) - { - envelope->setPartSpecifier (seenUid + ".0"); - lastHandled->setHeader (envelope); - lastHandled->setUid (seenUid.toULong ()); - } - } - } - break; - - case 'B': - if (word == "BODY") - { - parseBody (inWords); - } - else if (word == "BODY[]" ) - { - // Do the same as with "RFC822" - parseLiteralC(inWords, true); - } - else if (word == "BODYSTRUCTURE") - { - mailHeader *envelope = 0; - - if (lastHandled) - envelope = lastHandled->getHeader (); - - // fill it up with data - TQString section; - mimeHeader *body = - parseBodyStructure (inWords, section, envelope); - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - if (body) body->serialize(stream); - parseRelay(data); - - delete body; - } - break; - - case 'U': - if (word == "UID") - { - seenUid = parseOneWordC(inWords); - mailHeader *envelope = 0; - if (lastHandled) - envelope = lastHandled->getHeader (); - else - lastHandled = new imapCache(); - - if (seenUid.isEmpty ()) - { - // unknown what to do - kdDebug(7116) << "imapParser::parseFetch - UID empty" << endl; - } - else - { - lastHandled->setUid (seenUid.toULong ()); - } - if (envelope) - envelope->setPartSpecifier (seenUid); - } - break; - - case 'R': - if (word == "RFC822.SIZE") - { - ulong size; - parseOneNumber (inWords, size); - - if (!lastHandled) lastHandled = new imapCache(); - lastHandled->setSize (size); - } - else if (word.find ("RFC822") == 0) - { - // might be RFC822 RFC822.TEXT RFC822.HEADER - parseLiteralC(inWords, true); - } - break; - - case 'I': - if (word == "INTERNALDATE") - { - TQCString date = parseOneWordC(inWords); - if (!lastHandled) lastHandled = new imapCache(); - lastHandled->setDate(date); - } - break; - - case 'F': - if (word == "FLAGS") - { - //kdDebug(7116) << "GOT FLAGS " << inWords.cstr() << endl; - if (!lastHandled) lastHandled = new imapCache(); - lastHandled->setFlags (imapInfo::_flags (inWords.cstr())); - } - break; - - default: - parseLiteralC(inWords); - break; - } - } else { - parseLiteralC(inWords); - } - } - } - - // see if we have more to come - while (!inWords.isEmpty () && inWords[0] != ')') - { - //eat the extensions to this part - if (inWords[0] == '(') - parseSentence (inWords); - else - parseLiteralC(inWords); - } - - if (inWords.isEmpty() || inWords[0] != ')') - return; - inWords.pos++; - skipWS (inWords); -} - - -// default parser -void imapParser::parseSentence (parseString & inWords) -{ - bool first = true; - int stack = 0; - - //find the first nesting parentheses - - while (!inWords.isEmpty () && (stack != 0 || first)) - { - first = false; - skipWS (inWords); - - unsigned char ch = inWords[0]; - switch (ch) - { - case '(': - inWords.pos++; - ++stack; - break; - case ')': - inWords.pos++; - --stack; - break; - case '[': - inWords.pos++; - ++stack; - break; - case ']': - inWords.pos++; - --stack; - break; - default: - parseLiteralC(inWords); - skipWS (inWords); - break; - } - } - skipWS (inWords); -} - -void imapParser::parseRecent (ulong value, parseString & result) -{ - selectInfo.setRecent (value); - result.pos = result.data.size(); -} - -void imapParser::parseNamespace (parseString & result) -{ - if ( result[0] != '(' ) - return; - - TQString delimEmpty; - if ( namespaceToDelimiter.contains( TQString() ) ) - delimEmpty = namespaceToDelimiter[TQString()]; - - namespaceToDelimiter.clear(); - imapNamespaces.clear(); - - // remember what section we're in (user, other users, shared) - int ns = -1; - bool personalAvailable = false; - while ( !result.isEmpty() ) - { - if ( result[0] == '(' ) - { - result.pos++; // tie off ( - if ( result[0] == '(' ) - { - // new namespace section - result.pos++; // tie off ( - ++ns; - } - // namespace prefix - TQCString prefix = parseOneWordC( result ); - // delimiter - TQCString delim = parseOneWordC( result ); - kdDebug(7116) << "imapParser::parseNamespace ns='" << prefix << - "',delim='" << delim << "'" << endl; - if ( ns == 0 ) - { - // at least one personal ns - personalAvailable = true; - } - TQString nsentry = TQString::number( ns ) + "=" + TQString(prefix) + - "=" + TQString(delim); - imapNamespaces.append( nsentry ); - if ( prefix.right( 1 ) == delim ) { - // strip delimiter to get a correct entry for comparisons - prefix.resize( prefix.length() ); - } - namespaceToDelimiter[prefix] = delim; - - result.pos++; // tie off ) - skipWS( result ); - } else if ( result[0] == ')' ) - { - result.pos++; // tie off ) - skipWS( result ); - } else if ( result[0] == 'N' ) - { - // drop NIL - ++ns; - parseOneWordC( result ); - } else { - // drop whatever it is - parseOneWordC( result ); - } - } - if ( !delimEmpty.isEmpty() ) { - // remember default delimiter - namespaceToDelimiter[TQString()] = delimEmpty; - if ( !personalAvailable ) - { - // at least one personal ns would be nice - kdDebug(7116) << "imapParser::parseNamespace - registering own personal ns" << endl; - TQString nsentry = "0==" + delimEmpty; - imapNamespaces.append( nsentry ); - } - } -} - -int imapParser::parseLoop () -{ - parseString result; - - if (!parseReadLine(result.data)) return -1; - - //kdDebug(7116) << result.cstr(); // includes \n - - if (result.data.isEmpty()) - return 0; - if (!sentQueue.count ()) - { - // maybe greeting or BYE everything else SHOULD not happen, use NOOP or IDLE - kdDebug(7116) << "imapParser::parseLoop - unhandledResponse: \n" << result.cstr() << endl; - unhandled << result.cstr(); - } - else - { - imapCommand *current = sentQueue.at (0); - switch (result[0]) - { - case '*': - result.data.resize(result.data.size() - 2); // tie off CRLF - parseUntagged (result); - break; - case '+': - continuation.duplicate(result.data); - break; - default: - { - TQCString tag = parseLiteralC(result); - if (current->id() == tag.data()) - { - result.data.resize(result.data.size() - 2); // tie off CRLF - TQByteArray resultCode = parseLiteral (result); //the result - current->setResult (resultCode); - current->setResultInfo(result.cstr()); - current->setComplete (); - - sentQueue.removeRef (current); - completeQueue.append (current); - if (result.length()) - parseResult (resultCode, result, current->command()); - } - else - { - kdDebug(7116) << "imapParser::parseLoop - unknown tag '" << tag << "'" << endl; - TQCString cstr = tag + " " + result.cstr(); - result.data = cstr; - result.pos = 0; - result.data.resize(cstr.length()); - } - } - break; - } - } - - return 1; -} - -void -imapParser::parseRelay (const TQByteArray & buffer) -{ - Q_UNUSED(buffer); - tqWarning - ("imapParser::parseRelay - virtual function not reimplemented - data lost"); -} - -void -imapParser::parseRelay (ulong len) -{ - Q_UNUSED(len); - tqWarning - ("imapParser::parseRelay - virtual function not reimplemented - announcement lost"); -} - -bool imapParser::parseRead (TQByteArray & buffer, ulong len, ulong relay) -{ - Q_UNUSED(buffer); - Q_UNUSED(len); - Q_UNUSED(relay); - tqWarning - ("imapParser::parseRead - virtual function not reimplemented - no data read"); - return FALSE; -} - -bool imapParser::parseReadLine (TQByteArray & buffer, ulong relay) -{ - Q_UNUSED(buffer); - Q_UNUSED(relay); - tqWarning - ("imapParser::parseReadLine - virtual function not reimplemented - no data read"); - return FALSE; -} - -void -imapParser::parseWriteLine (const TQString & str) -{ - Q_UNUSED(str); - tqWarning - ("imapParser::parseWriteLine - virtual function not reimplemented - no data written"); -} - -void -imapParser::parseURL (const KURL & _url, TQString & _box, TQString & _section, - TQString & _type, TQString & _uid, TQString & _validity, TQString & _info) -{ - TQStringList parameters; - - _box = _url.path (); - kdDebug(7116) << "imapParser::parseURL " << _box << endl; - int paramStart = _box.find("/;"); - if ( paramStart > -1 ) - { - TQString paramString = _box.right( _box.length() - paramStart-2 ); - parameters = TQStringList::split (';', paramString); //split parameters - _box.truncate( paramStart ); // strip parameters - } - // extract parameters - for (TQStringList::ConstIterator it (parameters.begin ()); - it != parameters.end (); ++it) - { - TQString temp = (*it); - - int pt = temp.find ('/'); - if (pt > 0) - { - if (temp.findRev ('"', pt) == -1 || temp.find('"', pt) == -1) - { - // if we have non-quoted '/' separator we'll just nuke it - temp.truncate(pt); - } - } - if (temp.find ("section=", 0, false) == 0) - _section = temp.right (temp.length () - 8); - else if (temp.find ("type=", 0, false) == 0) - _type = temp.right (temp.length () - 5); - else if (temp.find ("uid=", 0, false) == 0) - _uid = temp.right (temp.length () - 4); - else if (temp.find ("uidvalidity=", 0, false) == 0) - _validity = temp.right (temp.length () - 12); - else if (temp.find ("info=", 0, false) == 0) - _info = temp.right (temp.length () - 5); - } -// kdDebug(7116) << "URL: section= " << _section << ", type= " << _type << ", uid= " << _uid << endl; -// kdDebug(7116) << "URL: user() " << _url.user() << endl; -// kdDebug(7116) << "URL: path() " << _url.path() << endl; -// kdDebug(7116) << "URL: encodedPathAndQuery() " << _url.encodedPathAndQuery() << endl; - - if (!_box.isEmpty ()) - { - // strip / - if (_box[0] == '/') - _box = _box.right (_box.length () - 1); - if (!_box.isEmpty () && _box[_box.length () - 1] == '/') - _box.truncate(_box.length() - 1); - } - kdDebug(7116) << "URL: box= " << _box << ", section= " << _section << ", type= " - << _type << ", uid= " << _uid << ", validity= " << _validity << ", info= " << _info << endl; -} - - -TQCString imapParser::parseLiteralC(parseString & inWords, bool relay, bool stopAtBracket, int *outlen) { - - if (!inWords.isEmpty() && inWords[0] == '{') - { - TQCString retVal; - long srunLen = inWords.find ('}', 1); // Can return -1, so use a signed long - if (srunLen > 0) - { - ulong runLen = (ulong)srunLen; - bool proper; - ulong runLenSave = runLen + 1; - TQCString tmpstr(runLen); - inWords.takeMidNoResize(tmpstr, 1, runLen - 1); - runLen = tmpstr.toULong (&proper); - inWords.pos += runLenSave; - if (proper) - { - //now get the literal from the server - if (relay) - parseRelay (runLen); - TQByteArray rv; - parseRead (rv, runLen, relay ? runLen : 0); - rv.resize(TQMAX(runLen, rv.size())); // what's the point? - retVal = b2c(rv); - inWords.clear(); - parseReadLine (inWords.data); // must get more - - // no duplicate data transfers - relay = false; - } - else - { - kdDebug(7116) << "imapParser::parseLiteral - error parsing {} - " /*<< strLen*/ << endl; - } - } - else - { - inWords.clear(); - kdDebug(7116) << "imapParser::parseLiteral - error parsing unmatched {" << endl; - } - if (outlen) { - *outlen = retVal.length(); // optimize me - } - skipWS (inWords); - return retVal; - } - - return parseOneWordC(inWords, stopAtBracket, outlen); -} - -// does not know about literals ( {7} literal ) -TQCString imapParser::parseOneWordC (parseString & inWords, bool stopAtBracket, int *outLen) -{ - uint retValSize = 0; - uint len = inWords.length(); - if (len == 0) { - return TQCString(); - } - - if (len > 0 && inWords[0] == '"') - { - unsigned int i = 1; - bool quote = FALSE; - while (i < len && (inWords[i] != '"' || quote)) - { - if (inWords[i] == '\\') quote = !quote; - else quote = FALSE; - i++; - } - if (i < len) - { - TQCString retVal(i); - inWords.pos++; - inWords.takeLeftNoResize(retVal, i - 1); - len = i - 1; - int offset = 0; - for (unsigned int j = 0; j <= len; j++) { - if (retVal[j] == '\\') { - offset++; - j++; - } - retVal[j - offset] = retVal[j]; - } - retVal[len - offset] = 0; - retValSize = len - offset; - inWords.pos += i; - skipWS (inWords); - if (outLen) { - *outLen = retValSize; - } - return retVal; - } - else - { - kdDebug(7116) << "imapParser::parseOneWord - error parsing unmatched \"" << endl; - TQCString retVal = inWords.cstr(); - retValSize = len; - inWords.clear(); - if (outLen) { - *outLen = retValSize; - } - return retVal; - } - } - else - { - // not quoted - unsigned int i; - // search for end - for (i = 0; i < len; ++i) { - char ch = inWords[i]; - if (ch <= ' ' || ch == '(' || ch == ')' || - (stopAtBracket && (ch == '[' || ch == ']'))) - break; - } - - TQCString retVal(i+1); - inWords.takeLeftNoResize(retVal, i); - retValSize = i; - inWords.pos += i; - - if (retVal == "NIL") { - retVal.truncate(0); - retValSize = 0; - } - skipWS (inWords); - if (outLen) { - *outLen = retValSize; - } - return retVal; - } -} - -bool imapParser::parseOneNumber (parseString & inWords, ulong & num) -{ - bool valid; - num = parseOneWordC(inWords, TRUE).toULong(&valid); - return valid; -} - -bool imapParser::hasCapability (const TQString & cap) -{ - TQString c = cap.lower(); -// kdDebug(7116) << "imapParser::hasCapability - Looking for '" << cap << "'" << endl; - for (TQStringList::ConstIterator it = imapCapabilities.begin (); - it != imapCapabilities.end (); ++it) - { -// kdDebug(7116) << "imapParser::hasCapability - Examining '" << (*it) << "'" << endl; - if ( !(kasciistricmp(c.ascii(), (*it).ascii())) ) - { - return true; - } - } - return false; -} - -void imapParser::removeCapability (const TQString & cap) -{ - imapCapabilities.remove(cap.lower()); -} - -TQString imapParser::namespaceForBox( const TQString & box ) -{ - kdDebug(7116) << "imapParse::namespaceForBox " << box << endl; - TQString myNamespace; - if ( !box.isEmpty() ) - { - TQValueList<TQString> list = namespaceToDelimiter.keys(); - TQString cleanPrefix; - for ( TQValueList<TQString>::Iterator it = list.begin(); it != list.end(); ++it ) - { - if ( !(*it).isEmpty() && box.find( *it ) != -1 ) - return (*it); - } - } - return myNamespace; -} - diff --git a/tdeioslaves/imap4/imapparser.h b/tdeioslaves/imap4/imapparser.h deleted file mode 100644 index 623fc8f85..000000000 --- a/tdeioslaves/imap4/imapparser.h +++ /dev/null @@ -1,504 +0,0 @@ -#ifndef _IMAPPARSER_H -#define _IMAPPARSER_H -/********************************************************************** - * - * imapparser.h - IMAP4rev1 Parser - * Copyright (C) 2001-2002 Michael Haeckel <haeckel@kde.org> - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ - -#include <tqstringlist.h> -#include <tqvaluelist.h> -#include <tqptrlist.h> -#include <tqasciidict.h> - -#include <tdeio/authinfo.h> -#include <tdeio/slavebase.h> - -#include "imaplist.h" -#include "imapcommand.h" -#include "imapinfo.h" - -#include "mailheader.h" - -class KURL; -class TQString; -class mailAddress; -class mimeHeader; - - -/** @brief a string used during parsing - * the string allows you to move the effective start of the string using - * str.pos++ and str.pos--. - * @bug it is possible to move past the beginning and end of the string - */ -class parseString -{ -public: - parseString() { pos = 0; } - char operator[](uint i) const { return data[i + pos]; } - bool isEmpty() const { return pos >= data.size(); } - TQCString cstr() const - { - if (pos >= data.size()) return TQCString(); - return TQCString(data.data() + pos, data.size() - pos + 1); - } - int find(char c, int index = 0) - { - int res = data.find(c, index + pos); - return (res == -1) ? res : (res - pos); - } - // Warning: does not check for going past end of "data" - void takeLeft(TQCString& dest, uint len) const - { - dest.resize(len + 1); - tqmemmove(dest.data(), data.data() + pos, len); - } - // Warning: does not check for going past end of "data" - void takeLeftNoResize(TQCString& dest, uint len) const - { - tqmemmove(dest.data(), data.data() + pos, len); - } - // Warning: does not check for going past end of "data" - void takeMid(TQCString& dest, uint start, uint len) const - { - dest.resize(len + 1); - tqmemmove(dest.data(), data.data() + pos + start, len); - } - // Warning: does not check for going past end of "data" - void takeMidNoResize(TQCString& dest, uint start, uint len) const - { - tqmemmove(dest.data(), data.data() + pos + start, len); - } - void clear() - { - data.resize(0); - pos = 0; - } - uint length() - { - if( pos < data.size() ) { - return data.size() - pos; - } else { - return 0; - } - } - void fromString(const TQString &s) - { - clear(); - data.duplicate(s.latin1(), s.length()); - } - TQByteArray data; - uint pos; -}; - -class imapCache -{ -public: - imapCache () - { - myHeader = NULL; - mySize = 0; - myFlags = 0; - myUid = 0; - } - - ~imapCache () - { - if (myHeader) delete myHeader; - } - - mailHeader *getHeader () - { - return myHeader; - } - void setHeader (mailHeader * inHeader) - { - myHeader = inHeader; - } - - ulong getSize () - { - return mySize; - } - void setSize (ulong inSize) - { - mySize = inSize; - } - - ulong getUid () - { - return myUid; - } - void setUid (ulong inUid) - { - myUid = inUid; - } - - ulong getFlags () - { - return myFlags; - } - void setFlags (ulong inFlags) - { - myFlags = inFlags; - } - - TQCString getDate () - { - return myDate; - } - void setDate (const TQCString & _str) - { - myDate = _str; - } - void clear() - { - if (myHeader) delete myHeader; - myHeader = NULL; - mySize = 0; - myFlags = 0; - myDate = TQCString(); - myUid = 0; - } - -protected: - mailHeader * myHeader; - ulong mySize; - ulong myFlags; - ulong myUid; - TQCString myDate; -}; - - -class imapParser -{ - -public: - - /** the different states the client can be in */ - enum IMAP_STATE - { - ISTATE_NO, /**< Not connected */ - ISTATE_CONNECT, /**< Connected but not logged in */ - ISTATE_LOGIN, /**< Logged in */ - ISTATE_SELECT /**< A folder is currently selected */ - }; - -public: - imapParser (); - virtual ~ imapParser (); - - /** @brief Get the current state */ - enum IMAP_STATE getState () { return currentState; } - /** @brief Set the current state */ - void setState(enum IMAP_STATE state) { currentState = state; } - - /* @brief return the currently selected mailbox */ - const TQString getCurrentBox () - { - return rfcDecoder::fromIMAP(currentBox); - }; - - /** - * @brief do setup and send the command to parseWriteLine - * @param aCmd The command to perform - * @return The completed command - */ - imapCommand *sendCommand (imapCommand * aCmd); - /** - * @brief perform a command and wait to parse the result - * @param aCmd The command to perform - * @return The completed command - */ - imapCommand *doCommand (imapCommand * aCmd); - - - /** - * @brief plaintext login - * @param aUser Username - * @param aPass Password - * @param resultInfo The resultinfo from the command - * @return success or failure - */ - bool clientLogin (const TQString & aUser, const TQString & aPass, TQString & resultInfo); - /** - * @brief non-plaintext login - * @param aUser Username - * @param aPass Password - * @param aAuth authentication method - * @param isSSL are we using SSL - * @param resultInfo The resultinfo from the command - * @return success or failure - */ - bool clientAuthenticate (TDEIO::SlaveBase *slave, TDEIO::AuthInfo &ai, const TQString & aFTQDN, - const TQString & aAuth, bool isSSL, TQString & resultInfo); - - /** - * main loop for the parser - * reads one line and dispatches it to the appropriate sub parser - */ - int parseLoop (); - - /** - * @brief parses all untagged responses and passes them on to the - * following parsers - */ - void parseUntagged (parseString & result); - - /** @brief parse a RECENT line */ - void parseRecent (ulong value, parseString & result); - /** @brief parse a RESULT line */ - void parseResult (TQByteArray & result, parseString & rest, - const TQString & command = TQString()); - /** @brief parse a CAPABILITY line */ - void parseCapability (parseString & result); - /** @brief parse a FLAGS line */ - void parseFlags (parseString & result); - /** @brief parse a LIST line */ - void parseList (parseString & result); - /** @brief parse a LSUB line */ - void parseLsub (parseString & result); - /** @brief parse a LISTRIGHTS line */ - void parseListRights (parseString & result); - /** @brief parse a MYRIGHTS line */ - void parseMyRights (parseString & result); - /** @brief parse a SEARCH line */ - void parseSearch (parseString & result); - /** @brief parse a STATUS line */ - void parsetStatus (parseString & result); - /** @brief parse a EXISTS line */ - void parseExists (ulong value, parseString & result); - /** @brief parse a EXPUNGE line */ - void parseExpunge (ulong value, parseString & result); - /** @brief parse a ACL line */ - void parseAcl (parseString & result); - /** @brief parse a ANNOTATION line */ - void parseAnnotation (parseString & result); - /** @brief parse a NAMESPACE line */ - void parseNamespace (parseString & result); - /** @brief parse a QUOTAROOT line */ - void parseQuotaRoot (parseString & result); - /** @brief parse a QUOTA line */ - void parseQuota (parseString & result); - /** @brief parse a custom command line */ - void parseCustom (parseString & result); - /** @brief parse a OTHER-USER line */ - void parseOtherUser (parseString & result); - /** @brief parse a DELEGATE line */ - void parseDelegate (parseString & result); - /** @brief parse a OUT-OF-OFFICE line */ - void parseOutOfOffice (parseString & result); - - /** - * parses the results of a fetch command - * processes it with the following sub parsers - */ - void parseFetch (ulong value, parseString & inWords); - - /** read a envelope from imap and parse the addresses */ - mailHeader *parseEnvelope (parseString & inWords); - /** @brief parse an address list and return a list of addresses */ - void parseAddressList (parseString & inWords, TQPtrList<mailAddress>& list); - /** @brief parse an address and return the ref again */ - const mailAddress& parseAddress (parseString & inWords, mailAddress& buffer); - - /** parse the result of the body command */ - void parseBody (parseString & inWords); - - /** parse the body structure recursively */ - mimeHeader *parseBodyStructure (parseString & inWords, - TQString & section, mimeHeader * inHeader = 0); - - /** parse only one not nested part */ - mimeHeader *parseSimplePart (parseString & inWords, TQString & section, - mimeHeader * localPart = 0); - - /** parse a parameter list (name value pairs) */ - TQAsciiDict < TQString > parseParameters (parseString & inWords); - - /** - * parse the disposition list (disposition (name value pairs)) - * the disposition has the key 'content-disposition' - */ - TQAsciiDict < TQString > parseDisposition (parseString & inWords); - - // reimplement these - - /** relay hook to send the fetched data directly to an upper level */ - virtual void parseRelay (const TQByteArray & buffer); - - /** relay hook to announce the fetched data directly to an upper level - */ - virtual void parseRelay (ulong); - - /** read at least len bytes */ - virtual bool parseRead (TQByteArray & buffer, ulong len, ulong relay = 0); - - /** read at least a line (up to CRLF) */ - virtual bool parseReadLine (TQByteArray & buffer, ulong relay = 0); - - /** write argument to server */ - virtual void parseWriteLine (const TQString &); - - // generic parser routines - - /** parse a parenthesized list */ - void parseSentence (parseString & inWords); - - /** parse a literal or word, may require more data */ - TQCString parseLiteralC(parseString & inWords, bool relay = false, - bool stopAtBracket = false, int *outlen = 0); - inline TQByteArray parseLiteral (parseString & inWords, bool relay = false, - bool stopAtBracket = false) { - int len = 0; // string size - // Choice: we can create an extra TQCString, or we can get the buffer in - // the wrong size to start. Let's try option b. - TQCString tmp = parseLiteralC(inWords, relay, stopAtBracket, &len); - return TQByteArray().duplicate(tmp.data(), len); - } - - // static parser routines, can be used elsewhere - - static TQCString b2c(const TQByteArray &ba) - { return TQCString(ba.data(), ba.size() + 1); } - - /** parse one word (maybe quoted) upto next space " ) ] } */ - static TQCString parseOneWordC (parseString & inWords, - bool stopAtBracket = FALSE, int *len = 0); - - /** parse one number using parseOneWord */ - static bool parseOneNumber (parseString & inWords, ulong & num); - - /** extract the box,section,list type, uid, uidvalidity,info from an url */ - static void parseURL (const KURL & _url, TQString & _box, TQString & _section, - TQString & _type, TQString & _uid, TQString & _validity, - TQString & _info); - - - /** @brief return the last handled foo - * @todo work out what a foo is - */ - imapCache *getLastHandled () - { - return lastHandled; - }; - -/** @brief return the last results */ - const TQStringList & getResults () - { - return lastResults; - }; - - /** @brief return the last status code */ - const imapInfo & geStatus () - { - return lasStatus; - }; - /** return the select info */ - const imapInfo & getSelected () - { - return selectInfo; - }; - - const TQByteArray & getContinuation () - { - return continuation; - }; - - /** @brief see if server has a capability */ - bool hasCapability (const TQString &); - - void removeCapability (const TQString & cap); - - static inline void skipWS (parseString & inWords) - { - char c; - while (!inWords.isEmpty() && - ((c = inWords[0]) == ' ' || c == '\t' || c == '\r' || c == '\n')) - { - inWords.pos++; - } - } - - /** @brief find the namespace for the given box */ - TQString namespaceForBox( const TQString & box ); - - -protected: - - /** the current state we're in */ - enum IMAP_STATE currentState; - - /** the box selected */ - TQString currentBox; - - /** @brief here we store the result from select/examine and unsolicited updates */ - imapInfo selectInfo; - - /** @brief the results from the last status command */ - imapInfo lasStatus; - - /** @brief the results from the capabilities, split at ' ' */ - TQStringList imapCapabilities; - - /** @brief the results from list/lsub/listrights commands */ - TQValueList < imapList > listResponses; - - /** @brief queues handling the running commands */ - TQPtrList < imapCommand > sentQueue; // no autodelete - TQPtrList < imapCommand > completeQueue; // autodelete !! - - /** - * everything we didn't handle, everything but the greeting is bogus - */ - TQStringList unhandled; - - /** the last continuation request (there MUST not be more than one pending) */ - TQByteArray continuation; - - /** the last uid seen while a fetch */ - TQString seenUid; - imapCache *lastHandled; - - ulong commandCounter; - - /** @brief the results from search/acl commands */ - TQStringList lastResults; - - /** - * @brief namespace prefix - delimiter association - * The namespace is cleaned before so that it does not contain the delimiter - */ - TQMap<TQString, TQString> namespaceToDelimiter; - - /** - * @brief list of namespaces in the form: section=namespace=delimiter - * section is 0 (personal), 1 (other users) or 2 (shared) - */ - TQStringList imapNamespaces; - -private: - - /** we don't want to be able to copy this object */ - imapParser & operator = (const imapParser &); // hide the copy ctor - -}; -#endif diff --git a/tdeioslaves/imap4/imaps.protocol b/tdeioslaves/imap4/imaps.protocol deleted file mode 100644 index b6c07040a..000000000 --- a/tdeioslaves/imap4/imaps.protocol +++ /dev/null @@ -1,30 +0,0 @@ -[Protocol] -# The executable, of course -#### Temporary name -exec=tdeio_imap4 -# protocol that will appear in URLs -#### This ioslave is temporarily named imaps, while imaps remains in tdebase -protocol=imaps - -# input/output can be one of: filesystem, stream, none -input=stream -output=filesystem - -# Headings for file listings? -listing=Name,Type,Size,Owner -deleting=true -linking=false -# For now, reading yes, writing no -reading=true -writing=false -# For now, no moving -moving=false - -# Can be source protocol -source=true - -# List of capabilities (e.g. special() commands) -Capabilities=Subscription,ACL,Quota - -Icon=folder_inbox -DocPath=tdeioslave/imaps/index.html diff --git a/tdeioslaves/imap4/mailaddress.cc b/tdeioslaves/imap4/mailaddress.cc deleted file mode 100644 index 0ddd2ff04..000000000 --- a/tdeioslaves/imap4/mailaddress.cc +++ /dev/null @@ -1,323 +0,0 @@ -/********************************************************************** - * - * mailaddress.cc - mail address parser - * Copyright (C) 2000 Sven Carstens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - - -#include "mailaddress.h" -#include "rfcdecoder.h" -#include "mimehdrline.h" -#include <kmime_util.h> - -mailAddress::mailAddress () -{ -} - -mailAddress::mailAddress (const mailAddress & lr): -user (lr.user), -host (lr.host), -rawFullName (lr.rawFullName), -rawComment (lr.rawComment) -{ -// kdDebug(7116) << "mailAddress::mailAddress - " << getStr() << endl; -} - -mailAddress & mailAddress::operator = (const mailAddress & lr) -{ - // Avoid a = a. - if (this == &lr) - return *this; - - user = lr.user; - host = lr.host; - rawFullName = lr.rawFullName; - rawComment = lr.rawComment; - -// kdDebug(7116) << "mailAddress::operator= - " << getStr() << endl; - - return *this; -} - - - - -mailAddress::~mailAddress () -{ -} - -mailAddress::mailAddress (char *aCStr) -{ - parseAddress (aCStr); -} - -int -mailAddress::parseAddress (char *aCStr) -{ - int retVal = 0; - int skip; - uint len; - int pt; - - if (aCStr) - { - //skip leading white space - skip = mimeHdrLine::skipWS ((const char *) aCStr); - if (skip > 0) - { - aCStr += skip; - retVal += skip; - } - while (*aCStr) - { - int advance; - - switch (*aCStr) - { - case '"': - advance = mimeHdrLine::parseQuoted ('"', '"', aCStr); - rawFullName += TQCString (aCStr, advance + 1); - break; - case '(': - advance = mimeHdrLine::parseQuoted ('(', ')', aCStr); - rawComment += TQCString (aCStr, advance + 1); - break; - case '<': - advance = mimeHdrLine::parseQuoted ('<', '>', aCStr); - user = TQCString (aCStr, advance + 1); // copy it - len = advance; - user = user.mid (1, len - 2); // strip <> - len -= 2; - pt = user.find('@'); - host = user.right (len - pt - 1); // split it into host - user.truncate(pt); // and user - break; - default: - advance = mimeHdrLine::parseWord ((const char *) aCStr); - //if we've seen a FQ mailname the rest must be quoted or is just junk - if (user.isEmpty ()) - { - if (*aCStr != ',') - { - rawFullName += TQCString (aCStr, advance + 1); - if (mimeHdrLine::skipWS ((const char *) &aCStr[advance]) > 0) - { - rawFullName += ' '; - } - } - } - break; - } - if (advance) - { - retVal += advance; - aCStr += advance; - } - else - break; - advance = mimeHdrLine::skipWS ((const char *) aCStr); - if (advance > 0) - { - retVal += advance; - aCStr += advance; - } - //reached end of current address - if (*aCStr == ',') - { - advance++; - break; - } - } - //let's see what we've got - if (rawFullName.isEmpty ()) - { - if (user.isEmpty ()) - retVal = 0; - else - { - if (host.isEmpty ()) - { - rawFullName = user; - user.truncate(0); - } - } - } - else if (user.isEmpty ()) - { - pt = rawFullName.find ('@'); - if (pt >= 0) - { - user = rawFullName; - host = user.right (user.length () - pt - 1); - user.truncate(pt); - rawFullName.truncate(0); - } - } - -#if 0 -// dead - if (!rawFullName.isEmpty ()) - { -// if(fullName[0] == '"') -// fullName = fullName.mid(1,fullName.length()-2); -// fullName = fullName.simplifyWhiteSpace().stripWhiteSpace(); -// fullName = rfcDecoder::decodeRFC2047String(fullName.ascii()); - } -#endif - if (!rawComment.isEmpty ()) - { - if (rawComment[0] == '(') - rawComment = rawComment.mid (1, rawComment.length () - 2); - rawComment = rawComment.stripWhiteSpace (); -// comment = rfcDecoder::decodeRFC2047String(comment.ascii()); - } - } - else - { - //debug(); - } - return retVal; -} - -const TQCString -mailAddress::getStr () -{ - TQCString retVal(128); // Should be generally big enough - - if (!rawFullName.isEmpty ()) - { - KMime::addQuotes( rawFullName, false ); - retVal = rawFullName + " "; - } - if (!user.isEmpty ()) - { - retVal += '<'; - retVal += user; - if (!host.isEmpty ()) { - retVal += '@'; - retVal += host; - } - retVal += '>'; - } - if (!rawComment.isEmpty ()) - { - retVal = '(' + rawComment + ')'; - } -// kdDebug(7116) << "mailAddress::getStr - '" << retVal << "'" << endl; - return retVal; -} - -bool -mailAddress::isEmpty () const -{ - return user.isEmpty (); -} - -void -mailAddress::setFullName (const TQString & _str) -{ - rawFullName = rfcDecoder::encodeRFC2047String (_str).latin1 (); -} -const TQString -mailAddress::getFullName () const -{ - return rfcDecoder::decodeRFC2047String (rawFullName); -} - -void -mailAddress::setCommentRaw (const TQCString & _str) -{ - rawComment = _str; -} - -void -mailAddress::setComment (const TQString & _str) -{ - rawComment = rfcDecoder::encodeRFC2047String (_str).latin1 (); -} -const TQString -mailAddress::getComment () const -{ - return rfcDecoder::decodeRFC2047String (rawComment); -} - -const TQCString & -mailAddress::getCommentRaw () const -{ - return rawComment; -} - -TQString -mailAddress::emailAddrAsAnchor (const mailAddress & adr, bool shortAdr) -{ - TQString retVal; - if (!adr.getFullName ().isEmpty ()) - { - // should do some umlaut escaping - retVal += adr.getFullName () + " "; - } - if (!adr.getUser ().isEmpty () && !shortAdr) - { - retVal += "<" + adr.getUser (); - if (!adr.getHost ().isEmpty ()) - retVal += "@" + adr.getHost (); - retVal += "> "; - } - if (!adr.getComment ().isEmpty ()) - { - // should do some umlaut escaping - retVal = '(' + adr.getComment () + ')'; - } - - if (!adr.getUser ().isEmpty ()) - { - TQString mail; - mail = adr.getUser (); - if (!mail.isEmpty () && !adr.getHost ().isEmpty ()) - mail += "@" + adr.getHost (); - if (!mail.isEmpty ()) - retVal = "<A HREF=\"mailto:" + mail + "\">" + retVal + "</A>"; - } - return retVal; -} - -TQString -mailAddress::emailAddrAsAnchor (const TQPtrList < mailAddress > &list, bool value) -{ - TQString retVal; - TQPtrListIterator < mailAddress > it (list); - - while (it.current ()) - { - retVal += emailAddrAsAnchor ((*it.current ()), value) + "<BR></BR>\n"; - ++it; - } - - return retVal; -} - - -void mailAddress::clear() { - user.truncate(0); - host.truncate(0); - rawFullName.truncate(0); - rawComment.truncate(0); -} - diff --git a/tdeioslaves/imap4/mailaddress.h b/tdeioslaves/imap4/mailaddress.h deleted file mode 100644 index 644034b24..000000000 --- a/tdeioslaves/imap4/mailaddress.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _MAILADDRESS_H -#define _MAILADDRESS_H -/********************************************************************** - * - * mailaddress.h - mail address handler - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ - -#include <tqptrlist.h> -#include <tqstring.h> -#include <tqcstring.h> -#include "rfcdecoder.h" - -class mailAddress -{ -public: - mailAddress (); - ~mailAddress (); - mailAddress (char *aCStr); - mailAddress (const mailAddress &); - mailAddress & operator = (const mailAddress &); - - void setUser (const TQCString & aUser) - { - user = aUser; - } - const TQCString & getUser () const - { - return user; - } - void setHost (const TQCString & aHost) - { - host = aHost; - } - const TQCString & getHost () const - { - return host; - } - - void setFullName (const TQString & aFull); - const TQString getFullName () const; - - void setComment (const TQString & aComment); - void setCommentRaw (const TQCString &); - const TQString getComment () const; - const TQCString & getCommentRaw () const; - - int parseAddress (char *); - const TQCString getStr (); - bool isEmpty () const; - - static TQString emailAddrAsAnchor (const mailAddress &, bool); - static TQString emailAddrAsAnchor (const TQPtrList < mailAddress > &, bool); - - void clear(); - -private: - TQCString user; - TQCString host; - TQCString rawFullName; - TQCString rawComment; -}; - -#endif diff --git a/tdeioslaves/imap4/mailheader.cc b/tdeioslaves/imap4/mailheader.cc deleted file mode 100644 index c520b9094..000000000 --- a/tdeioslaves/imap4/mailheader.cc +++ /dev/null @@ -1,203 +0,0 @@ -/*************************************************************************** - mailheader.cc - description - ------------------- - begin : Tue Oct 24 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#include "mailheader.h" -#include "rfcdecoder.h" - -mailHeader::mailHeader () -{ - toAdr.setAutoDelete (true); - ccAdr.setAutoDelete (true); - bccAdr.setAutoDelete (true); - setType ("text/plain"); - gmt_offset = 0; -} - -mailHeader::~mailHeader () -{ -} - -void -mailHeader::addHdrLine (mimeHdrLine * inLine) -{ - mimeHdrLine *addLine = new mimeHdrLine (inLine); - - const TQCString label(addLine->getLabel()); - TQCString value(addLine->getValue()); - - if (!tqstricmp (label, "Return-Path")) { - returnpathAdr.parseAddress (value.data ()); - goto out; - } - if (!tqstricmp (label, "Sender")) { - senderAdr.parseAddress (value.data ()); - goto out; - } - if (!tqstricmp (label, "From")) { - fromAdr.parseAddress (value.data ()); - goto out; - } - if (!tqstricmp (label, "Reply-To")) { - replytoAdr.parseAddress (value.data ()); - goto out; - } - if (!tqstricmp (label, "To")) { - mailHeader::parseAddressList (value, &toAdr); - goto out; - } - if (!tqstricmp (label, "CC")) { - mailHeader::parseAddressList (value, &ccAdr); - goto out; - } - if (!tqstricmp (label, "BCC")) { - mailHeader::parseAddressList (value, &bccAdr); - goto out; - } - if (!tqstricmp (label, "Subject")) { - _subject = value.simplifyWhiteSpace(); - goto out; - } - if (!tqstricmp (label.data (), "Date")) { - mDate = value; - goto out; - } - if (!tqstricmp (label.data (), "Message-ID")) { - int start = value.findRev ('<'); - int end = value.findRev ('>'); - if (start < end) - messageID = value.mid (start, end - start + 1); - else { - tqWarning("bad Message-ID"); - /* messageID = value; */ - } - goto out; - } - if (!tqstricmp (label.data (), "In-Reply-To")) { - int start = value.findRev ('<'); - int end = value.findRev ('>'); - if (start < end) - inReplyTo = value.mid (start, end - start + 1); - goto out; - } - - // everything else is handled by mimeHeader - mimeHeader::addHdrLine (inLine); - delete addLine; - return; - - out: -// cout << label.data() << ": '" << value.data() << "'" << endl; - - //need only to add this line if not handled by mimeHeader - originalHdrLines.append (addLine); -} - -void -mailHeader::outputHeader (mimeIO & useIO) -{ - static const TQCString __returnPath("Return-Path: ", 14); - static const TQCString __from ("From: ", 7); - static const TQCString __sender ("Sender: ", 9); - static const TQCString __replyTo ("Reply-To: ", 11); - static const TQCString __to ("To: ", 5); - static const TQCString __cc ("CC: ", 5); - static const TQCString __bcc ("BCC: ", 6); - static const TQCString __subject ("Subject: ", 10); - static const TQCString __messageId ("Message-ID: ", 13); - static const TQCString __inReplyTo ("In-Reply-To: ", 14); - static const TQCString __references("References: ", 13); - static const TQCString __date ("Date: ", 7); - - if (!returnpathAdr.isEmpty()) - useIO.outputMimeLine(__returnPath + returnpathAdr.getStr()); - if (!fromAdr.isEmpty()) - useIO.outputMimeLine(__from + fromAdr.getStr()); - if (!senderAdr.isEmpty()) - useIO.outputMimeLine(__sender + senderAdr.getStr()); - if (!replytoAdr.isEmpty()) - useIO.outputMimeLine(__replyTo + replytoAdr.getStr()); - - if (toAdr.count()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__to + - mailHeader::getAddressStr(&toAdr))); - if (ccAdr.count()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__cc + - mailHeader::getAddressStr(&ccAdr))); - if (bccAdr.count()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__bcc + - mailHeader::getAddressStr(&bccAdr))); - if (!_subject.isEmpty()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__subject + _subject)); - if (!messageID.isEmpty()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__messageId + messageID)); - if (!inReplyTo.isEmpty()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__inReplyTo + inReplyTo)); - if (!references.isEmpty()) - useIO.outputMimeLine(mimeHdrLine::truncateLine(__references + references)); - - if (!mDate.isEmpty()) - useIO.outputMimeLine(__date + mDate); - mimeHeader::outputHeader(useIO); -} - -int -mailHeader::parseAddressList (const char *inCStr, - TQPtrList < mailAddress > *aList) -{ - int advance = 0; - int skip = 1; - char *aCStr = (char *) inCStr; - - if (!aCStr || !aList) - return 0; - while (skip > 0) - { - mailAddress *aAddress = new mailAddress; - skip = aAddress->parseAddress (aCStr); - if (skip) - { - aCStr += skip; - if (skip < 0) - advance -= skip; - else - advance += skip; - aList->append (aAddress); - } - else - { - delete aAddress; - break; - } - } - return advance; -} - -TQCString -mailHeader::getAddressStr (TQPtrList < mailAddress > *aList) -{ - TQCString retVal; - - TQPtrListIterator < mailAddress > it = TQPtrListIterator < mailAddress > (*aList); - while (it.current ()) - { - retVal += it.current ()->getStr (); - ++it; - if (it.current ()) - retVal += ", "; - } - return retVal; -} diff --git a/tdeioslaves/imap4/mailheader.h b/tdeioslaves/imap4/mailheader.h deleted file mode 100644 index 633d61b78..000000000 --- a/tdeioslaves/imap4/mailheader.h +++ /dev/null @@ -1,190 +0,0 @@ -/*************************************************************************** - mailheader.h - description - ------------------- - begin : Tue Oct 24 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#ifndef MAILHEADER_H -#define MAILHEADER_H - -#include "mimeheader.h" -#include "mailaddress.h" -#include "mimeio.h" -#include "rfcdecoder.h" - -/** - *@author Sven Carstens - */ - -class mailHeader:public mimeHeader -{ -public: - mailHeader (); - ~mailHeader (); - - virtual void addHdrLine (mimeHdrLine *); - virtual void outputHeader (mimeIO &); - - void addTo (const mailAddress & _adr) - { - toAdr.append (new mailAddress (_adr)); - } - void addCC (const mailAddress & _adr) - { - ccAdr.append (new mailAddress (_adr)); - } - void addBCC (const mailAddress & _adr) - { - bccAdr.append (new mailAddress (_adr)); - } - - void setFrom (const mailAddress & _adr) - { - fromAdr = _adr; - } - void setSender (const mailAddress & _adr) - { - senderAdr = _adr; - } - void setReturnPath (const mailAddress & _adr) - { - returnpathAdr = _adr; - } - void setReplyTo (const mailAddress & _adr) - { - replytoAdr = _adr; - } - - const TQCString& getMessageId () - { - return messageID; - } - void setMessageId (const TQCString & _str) - { - messageID = _str; - } - - const TQCString& getInReplyTo () - { - return inReplyTo; - } - void setInReplyTo (const TQCString & _str) - { - inReplyTo = _str; - } - - const TQCString& getReferences () - { - return references; - } - void setReferences (const TQCString & _str) - { - references = _str; - } - - /** - * set a unicode subject - */ - void setSubject (const TQString & _str) - { - _subject = rfcDecoder::encodeRFC2047String(_str).latin1(); - } - /** - * set a encoded subject - */ - void setSubjectEncoded (const TQCString & _str) - { - _subject = _str.simplifyWhiteSpace(); - } - - /** - * get the unicode subject - */ - const TQString getSubject () - { - return rfcDecoder::decodeRFC2047String(_subject); - } - /** - * get the encoded subject - */ - const TQCString& getSubjectEncoded () - { - return _subject; - } - - /** - * set the date - */ - void setDate (const TQCString & _str) - { - mDate = _str; - } - - /** - * get the date - */ - const TQCString& date () - { - return mDate; - } - - static int parseAddressList (const char *, TQPtrList < mailAddress > *); - static TQCString getAddressStr (TQPtrList < mailAddress > *); - TQPtrList < mailAddress > &to () - { - return toAdr; - } - TQPtrList < mailAddress > &cc () - { - return ccAdr; - } - TQPtrList < mailAddress > &bcc () - { - return bccAdr; - } -#ifdef KMAIL_COMPATIBLE - TQString subject () - { - return getSubject (); - } - const mailAddress & from () - { - return fromAdr; - } - const mailAddress & replyTo () - { - return replytoAdr; - } - void readConfig (void) - {; - } -#endif - -private: - TQPtrList < mailAddress > toAdr; - TQPtrList < mailAddress > ccAdr; - TQPtrList < mailAddress > bccAdr; - mailAddress fromAdr; - mailAddress senderAdr; - mailAddress returnpathAdr; - mailAddress replytoAdr; - TQCString _subject; - TQCString mDate; - int gmt_offset; - TQCString messageID; - TQCString inReplyTo; - TQCString references; -}; - -#endif diff --git a/tdeioslaves/imap4/mimehdrline.cc b/tdeioslaves/imap4/mimehdrline.cc deleted file mode 100644 index 9646ed26f..000000000 --- a/tdeioslaves/imap4/mimehdrline.cc +++ /dev/null @@ -1,521 +0,0 @@ -/*************************************************************************** - mimehdrline.cc - description - ------------------- - begin : Wed Oct 11 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#include <config.h> -#include <iostream> -#include <ctype.h> -#include <stdlib.h> -#include <stdio.h> - -#include "mimehdrline.h" -#include "rfcdecoder.h" - -using namespace std; - -const char *wdays[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -const char *months[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -mimeHdrLine::mimeHdrLine (): -mimeValue ((const char *) NULL), mimeLabel ((const char *) NULL) -{ -} - -mimeHdrLine::mimeHdrLine (const TQCString & aLabel, const TQCString & aValue): -mimeValue (aValue), -mimeLabel (aLabel) -{ -} - -mimeHdrLine::mimeHdrLine (mimeHdrLine * aHdrLine): -mimeValue (aHdrLine->mimeValue), mimeLabel (aHdrLine->mimeLabel) -{ -} - -mimeHdrLine::~mimeHdrLine () -{ -} - -int -mimeHdrLine::appendStr (const char *inCStr) -{ - int retVal = 0; - int skip; - char *aCStr = (char *) inCStr; - - if (aCStr) - { - skip = skipWS (aCStr); - if (skip && !mimeLabel.isEmpty ()) - { - if (skip > 0) - { - mimeValue += TQCString (aCStr, skip + 1); - aCStr += skip; - retVal += skip; - skip = parseFullLine (aCStr); - mimeValue += TQCString (aCStr, skip + 1); - retVal += skip; - aCStr += skip; - } - } - else - { - if (mimeLabel.isEmpty ()) - return setStr (aCStr); - } - } - return retVal; -} - -/** parse a Line into the class -move input ptr accordingly -and report characters slurped */ -int -mimeHdrLine::setStr (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; -// char *begin = aCStr; - mimeLabel = TQCString ((const char *) NULL); - mimeValue = TQCString ((const char *) NULL); - - if (aCStr) - { - // can't have spaces on normal lines - if (!skipWS (aCStr)) - { - int label = 0, advance; - while ((advance = parseWord (&aCStr[label]))) - { - label += advance; - } - if (label && aCStr[label - 1] != ':') - retVal = 0; - else - { - mimeLabel = TQCString (aCStr, label); //length including zero - retVal += label; - aCStr += label; - } - } - if (retVal) - { - int skip; - skip = skipWS (aCStr); - if (skip < 0) - skip *= -1; - aCStr += skip; - retVal += skip; - skip = parseFullLine (aCStr); - mimeValue = TQCString (aCStr, skip + 1); - retVal += skip; - aCStr += skip; - } - else - { - //Skip malformed line - while (*aCStr && *aCStr != '\r' && *aCStr != '\n') - { - retVal--; - aCStr++; - } - if (*aCStr == '\r') - { - retVal--; - aCStr++; - } - if (*aCStr == '\n') - { - retVal--; - aCStr++; - } - } - } - else - { - //debug - } - return retVal; -} - -/** slurp one word*/ -int -mimeHdrLine::parseWord (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - - if (aCStr && *aCStr) - { - if (*aCStr == '"') - return mimeHdrLine::parseQuoted ('"', '"', aCStr); - else - return mimeHdrLine::parseHalfWord (aCStr); - } - else - { - //debug(); - } - return retVal; -} - -/** slurp one word*/ -int -mimeHdrLine::parseQuoted (char startQuote, char endQuote, const char *inCStr) -{ - char *aCStr = (char *) inCStr; - int retVal = 0; - - if (aCStr && *aCStr) - { - if (*aCStr == startQuote) - { - aCStr++; - retVal++; - } - else - return 0; - while (*aCStr && *aCStr != endQuote) - { - //skip over backticks - if (*aCStr == '\\') - { - aCStr++; - retVal++; - } - //eat this - aCStr++; - retVal++; - } - if (*aCStr == endQuote) - { - aCStr++; - retVal++; - } - } - else - { - //debug(); - } - return retVal; -} - -/** slurp one alphanumerical word without continuation*/ -int -mimeHdrLine::parseAlphaNum (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - - if (aCStr) - { - while (*aCStr && isalnum (*aCStr)) - { - //skip over backticks - if (*aCStr == '\\') - { - aCStr++; - retVal++; - } - //eat this - aCStr++; - retVal++; - } - } - else - { - //debug(); - } - return retVal; -} - -int -mimeHdrLine::parseHalfWord (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - - if (aCStr && *aCStr) - { - if (isalnum (*aCStr)) - return mimeHdrLine::parseAlphaNum (aCStr); - //skip over backticks - if (*aCStr == '\\') - { - aCStr++; - retVal++; - } - else if (!isspace (*aCStr)) - { - //eat this - aCStr++; - retVal++; - } - } - else - { - //debug(); - } - return retVal; -} - -/** slurp one line without continuation*/ -int -mimeHdrLine::parseHalfLine (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - - if (aCStr) - { - while (*aCStr && *aCStr != '\n') - { - //skip over backticks - if (*aCStr == '\\') - { - aCStr++; - retVal++; - } - //eat this - aCStr++; - retVal++; - } - if (*aCStr == '\n') - { - aCStr++; - retVal++; - } - } - else - { - //debug(); - } - return retVal; -} - -/** skip all white space characters including continuation*/ -int -mimeHdrLine::skipWS (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - - if (aCStr && *aCStr) - { - while (*aCStr == ' ' || *aCStr == '\t') - { - aCStr++; - retVal++; - } - //check out for continuation lines - if (*aCStr == '\r') - { - aCStr++; - retVal++; - } - if (*aCStr++ == '\n') - if (*aCStr == '\t' || *aCStr == ' ') - { - int skip = mimeHdrLine::skipWS (aCStr); - if (skip < 0) - skip *= -1; - retVal += 1 + skip; - } - else - { - retVal = -retVal - 1; - } - } - else - { - //debug(); - } - return retVal; -} - -/** parses continuated lines */ -int -mimeHdrLine::parseFullLine (const char *inCStr) -{ - int retVal = 0; - char *aCStr = (char *) inCStr; - int skip; - - if (aCStr) - { - //skip leading white space - skip = skipWS (aCStr); - if (skip > 0) - { - aCStr += skip; - retVal += skip; - } - while (*aCStr) - { - int advance; - - if ((advance = parseHalfLine (aCStr))) - { - retVal += advance; - aCStr += advance; - } - else if ((advance = skipWS (aCStr))) - { - if (advance > 0) - { - retVal += advance; - aCStr += advance; - } - else - { - retVal -= advance; - break; - } - } - else - break; - } - } - else - { - //debug(); - } - return retVal; -} - -/** parses continuated lines */ -int -mimeHdrLine::parseSeparator (char separator, const char *inCStr) -{ - char *aCStr = (char *) inCStr; - int retVal = 0; - int skip; - - if (aCStr) - { - //skip leading white space - skip = skipWS (aCStr); - if (skip > 0) - { - aCStr += skip; - retVal += skip; - } - while (*aCStr) - { - int advance; - - if (*aCStr != separator) - { - if ((advance = mimeHdrLine::parseWord (aCStr))) - { - retVal += advance; - aCStr += advance; - } - else if ((advance = mimeHdrLine::skipWS (aCStr))) - { - if (advance > 0) - { - retVal += advance; - aCStr += advance; - } - else - { - retVal -= advance; - break; - } - } - else - break; - } - else - { - //include separator in result - retVal++; - aCStr++; - break; - } - } - } - else - { - //debug(); - } - return retVal; -} - -/** return the label */ - -const TQCString& -mimeHdrLine::getLabel () -{ - return mimeLabel; -} - -/** return the value */ -const TQCString& -mimeHdrLine::getValue () -{ - return mimeValue; -} - - -// FIXME: very inefficient still -TQCString -mimeHdrLine::truncateLine(TQCString aLine, unsigned int truncate) -{ - int cutHere; - TQCString retVal; - uint len = aLine.length(); - - // see if we have a line of the form "key: value" (like "Subject: bla") - // then we do not want to truncate between key and value - int validStart = aLine.find(": "); - if (validStart > -1) { - validStart += 2; - } - while (len > truncate) { - cutHere = aLine.findRev(' ', truncate); - if (cutHere < 1 || cutHere < validStart) { - cutHere = aLine.findRev('\t', truncate); - if (cutHere < 1) { - cutHere = aLine.find(' ', 1); - if (cutHere < 1) { - cutHere = aLine.find('\t', 1); - if (cutHere < 1) { - // simply truncate - return aLine.left(truncate); - } - } - } - } - - retVal += aLine.left(cutHere) + '\n'; - int chop = len - cutHere; - aLine = aLine.right(chop); - len -= chop; - } - retVal += aLine; - - return retVal; -} - diff --git a/tdeioslaves/imap4/mimehdrline.h b/tdeioslaves/imap4/mimehdrline.h deleted file mode 100644 index e31c18649..000000000 --- a/tdeioslaves/imap4/mimehdrline.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - mimehdrline.h - description - ------------------- - begin : Wed Oct 11 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#ifndef MIMEHDRLINE_H -#define MIMEHDRLINE_H - - -#include <tqcstring.h> -#include <tqasciidict.h> - -/** - *@author Sven Carstens - */ - -class mimeHdrLine -{ -public: - mimeHdrLine (); - mimeHdrLine (mimeHdrLine *); - mimeHdrLine (const TQCString &, const TQCString &); - ~mimeHdrLine (); - /** parse a Line into the class -and report characters slurped */ - int setStr (const char *); - int appendStr (const char *); - /** return the value */ - const TQCString& getValue (); - /** return the label */ - const TQCString& getLabel (); - static TQCString truncateLine (TQCString, unsigned int truncate = 80); - static int parseSeparator (char, const char *); - static int parseQuoted (char, char, const char *); - /** skip all white space characters */ - static int skipWS (const char *); - /** slurp one word respecting backticks */ - static int parseHalfWord (const char *); - static int parseWord (const char *); - static int parseAlphaNum (const char *); - -protected: // Protected attributes - /** contains the Value - */ - TQCString mimeValue; - /** contains the Label of the line - */ - TQCString mimeLabel; -protected: // Protected methods - /** parses a continuated line */ - int parseFullLine (const char *); - int parseHalfLine (const char *); -}; - -#endif diff --git a/tdeioslaves/imap4/mimeheader.cc b/tdeioslaves/imap4/mimeheader.cc deleted file mode 100644 index d0916ba50..000000000 --- a/tdeioslaves/imap4/mimeheader.cc +++ /dev/null @@ -1,745 +0,0 @@ -/*************************************************************************** - mimeheader.cc - description - ------------------- - begin : Fri Oct 20 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#include "mimeheader.h" -#include "mimehdrline.h" -#include "mailheader.h" -#include "rfcdecoder.h" - -#include <tqregexp.h> - -// #include <iostream.h> -#include <tdeglobal.h> -#include <kinstance.h> -#include <kiconloader.h> -#include <kmimetype.h> -#include <kmimemagic.h> -#include <kmdcodec.h> -#include <kdebug.h> - -mimeHeader::mimeHeader (): -typeList (17, false), dispositionList (17, false) -{ - // Case insensitive hashes are killing us. Also are they too small? - originalHdrLines.setAutoDelete (true); - additionalHdrLines.setAutoDelete (false); // is also in original lines - nestedParts.setAutoDelete (true); - typeList.setAutoDelete (true); - dispositionList.setAutoDelete (true); - nestedMessage = NULL; - contentLength = 0; - contentType = "application/octet-stream"; -} - -mimeHeader::~mimeHeader () -{ -} - -/* -TQPtrList<mimeHeader> mimeHeader::getAllParts() -{ - TQPtrList<mimeHeader> retVal; - - // caller is responsible for clearing - retVal.setAutoDelete( false ); - nestedParts.setAutoDelete( false ); - - // shallow copy - retVal = nestedParts; - - // can't have duplicate pointers - nestedParts.clear(); - - // restore initial state - nestedParts.setAutoDelete( true ); - - return retVal; -} */ - -void -mimeHeader::addHdrLine (mimeHdrLine * aHdrLine) -{ - mimeHdrLine *addLine = new mimeHdrLine (aHdrLine); - if (addLine) - { - originalHdrLines.append (addLine); - if (tqstrnicmp (addLine->getLabel (), "Content-", 8)) - { - additionalHdrLines.append (addLine); - } - else - { - int skip; - const char *aCStr = addLine->getValue ().data (); - TQDict < TQString > *aList = 0; - - skip = mimeHdrLine::parseSeparator (';', aCStr); - if (skip > 0) - { - int cut = 0; - if (skip >= 2) - { - if (aCStr[skip - 1] == '\r') - cut++; - if (aCStr[skip - 1] == '\n') - cut++; - if (aCStr[skip - 2] == '\r') - cut++; - if (aCStr[skip - 1] == ';') - cut++; - } - TQCString mimeValue = TQCString (aCStr, skip - cut + 1); // cutting of one because of 0x00 - - - if (!tqstricmp (addLine->getLabel (), "Content-Disposition")) - { - aList = &dispositionList; - _contentDisposition = mimeValue; - } - else if (!tqstricmp (addLine->getLabel (), "Content-Type")) - { - aList = &typeList; - contentType = mimeValue; - } - else - if (!tqstricmp (addLine->getLabel (), "Content-Transfer-Encoding")) - { - contentEncoding = mimeValue; - } - else if (!tqstricmp (addLine->getLabel (), "Content-ID")) - { - contentID = mimeValue; - } - else if (!tqstricmp (addLine->getLabel (), "Content-Description")) - { - _contentDescription = mimeValue; - } - else if (!tqstricmp (addLine->getLabel (), "Content-MD5")) - { - contentMD5 = mimeValue; - } - else if (!tqstricmp (addLine->getLabel (), "Content-Length")) - { - contentLength = mimeValue.toULong (); - } - else - { - additionalHdrLines.append (addLine); - } -// cout << addLine->getLabel().data() << ": '" << mimeValue.data() << "'" << endl; - - aCStr += skip; - while ((skip = mimeHdrLine::parseSeparator (';', aCStr))) - { - if (skip > 0) - { - addParameter (TQCString (aCStr, skip).simplifyWhiteSpace(), aList); -// cout << "-- '" << aParm.data() << "'" << endl; - mimeValue = TQCString (addLine->getValue ().data (), skip); - aCStr += skip; - } - else - break; - } - } - } - } -} - -void -mimeHeader::addParameter (const TQCString& aParameter, TQDict < TQString > *aList) -{ - if ( !aList ) - return; - - TQString *aValue; - TQCString aLabel; - int pos = aParameter.find ('='); -// cout << aParameter.left(pos).data(); - aValue = new TQString (); - aValue->setLatin1 (aParameter.right (aParameter.length () - pos - 1)); - aLabel = aParameter.left (pos); - if ((*aValue)[0] == '"') - *aValue = aValue->mid (1, aValue->length () - 2); - - aList->insert (aLabel, aValue); -// cout << "=" << aValue->data() << endl; -} - -TQString -mimeHeader::getDispositionParm (const TQCString& aStr) -{ - return getParameter (aStr, &dispositionList); -} - -TQString -mimeHeader::getTypeParm (const TQCString& aStr) -{ - return getParameter (aStr, &typeList); -} - -void -mimeHeader::setDispositionParm (const TQCString& aLabel, const TQString& aValue) -{ - setParameter (aLabel, aValue, &dispositionList); - return; -} - -void -mimeHeader::setTypeParm (const TQCString& aLabel, const TQString& aValue) -{ - setParameter (aLabel, aValue, &typeList); -} - -TQDictIterator < TQString > mimeHeader::getDispositionIterator () -{ - return TQDictIterator < TQString > (dispositionList); -} - -TQDictIterator < TQString > mimeHeader::getTypeIterator () -{ - return TQDictIterator < TQString > (typeList); -} - -TQPtrListIterator < mimeHdrLine > mimeHeader::getOriginalIterator () -{ - return TQPtrListIterator < mimeHdrLine > (originalHdrLines); -} - -TQPtrListIterator < mimeHdrLine > mimeHeader::getAdditionalIterator () -{ - return TQPtrListIterator < mimeHdrLine > (additionalHdrLines); -} - -void -mimeHeader::outputHeader (mimeIO & useIO) -{ - if (!getDisposition ().isEmpty ()) - { - useIO.outputMimeLine (TQCString ("Content-Disposition: ") - + getDisposition () - + outputParameter (&dispositionList)); - } - - if (!getType ().isEmpty ()) - { - useIO.outputMimeLine (TQCString ("Content-Type: ") - + getType () + outputParameter (&typeList)); - } - if (!getDescription ().isEmpty ()) - useIO.outputMimeLine (TQCString ("Content-Description: ") + - getDescription ()); - if (!getID ().isEmpty ()) - useIO.outputMimeLine (TQCString ("Content-ID: ") + getID ()); - if (!getMD5 ().isEmpty ()) - useIO.outputMimeLine (TQCString ("Content-MD5: ") + getMD5 ()); - if (!getEncoding ().isEmpty ()) - useIO.outputMimeLine (TQCString ("Content-Transfer-Encoding: ") + - getEncoding ()); - - TQPtrListIterator < mimeHdrLine > ait = getAdditionalIterator (); - while (ait.current ()) - { - useIO.outputMimeLine (ait.current ()->getLabel () + ": " + - ait.current ()->getValue ()); - ++ait; - } - useIO.outputMimeLine (TQCString ("")); -} - -TQString -mimeHeader::getParameter (const TQCString& aStr, TQDict < TQString > *aDict) -{ - TQString retVal, *found; - if (aDict) - { - //see if it is a normal parameter - found = aDict->find (aStr); - if (!found) - { - //might be a continuated or encoded parameter - found = aDict->find (aStr + "*"); - if (!found) - { - //continuated parameter - TQString decoded, encoded; - int part = 0; - - do - { - TQCString search; - search.setNum (part); - search = aStr + "*" + search; - found = aDict->find (search); - if (!found) - { - found = aDict->find (search + "*"); - if (found) - encoded += rfcDecoder::encodeRFC2231String (*found); - } - else - { - encoded += *found; - } - part++; - } - while (found); - if (encoded.find ('\'') >= 0) - { - retVal = rfcDecoder::decodeRFC2231String (encoded.local8Bit ()); - } - else - { - retVal = - rfcDecoder::decodeRFC2231String (TQCString ("''") + - encoded.local8Bit ()); - } - } - else - { - //simple encoded parameter - retVal = rfcDecoder::decodeRFC2231String (found->local8Bit ()); - } - } - else - { - retVal = *found; - } - } - return retVal; -} - -void -mimeHeader::setParameter (const TQCString& aLabel, const TQString& aValue, - TQDict < TQString > *aDict) -{ - bool encoded = true; - uint vlen, llen; - TQString val = aValue; - - if (aDict) - { - - //see if it needs to get encoded - if (encoded && aLabel.find ('*') == -1) - { - val = rfcDecoder::encodeRFC2231String (aValue); - } - //kdDebug(7116) << "mimeHeader::setParameter() - val = '" << val << "'" << endl; - //see if it needs to be truncated - vlen = val.length(); - llen = aLabel.length(); - if (vlen + llen + 4 > 80 && llen < 80 - 8 - 2 ) - { - const int limit = 80 - 8 - 2 - (int)llen; - // the -2 is there to allow extending the length of a part of val - // by 1 or 2 in order to prevent an encoded character from being - // split in half - int i = 0; - TQString shortValue; - TQCString shortLabel; - - while (!val.isEmpty ()) - { - int partLen; // the length of the next part of the value - if ( limit >= int(vlen) ) { - // the rest of the value fits completely into one continued header - partLen = vlen; - } - else { - partLen = limit; - // make sure that we don't split an encoded char in half - if ( val[partLen-1] == '%' ) { - partLen += 2; - } - else if ( partLen > 1 && val[partLen-2] == '%' ) { - partLen += 1; - } - // make sure partLen does not exceed vlen (could happen in case of - // an incomplete encoded char) - if ( partLen > int(vlen) ) { - partLen = vlen; - } - } - shortValue = val.left( partLen ); - shortLabel.setNum (i); - shortLabel = aLabel + "*" + shortLabel; - val = val.right( vlen - partLen ); - vlen = vlen - partLen; - if (encoded) - { - if (i == 0) - { - shortValue = "''" + shortValue; - } - shortLabel += "*"; - } - //kdDebug(7116) << "mimeHeader::setParameter() - shortLabel = '" << shortLabel << "'" << endl; - //kdDebug(7116) << "mimeHeader::setParameter() - shortValue = '" << shortValue << "'" << endl; - //kdDebug(7116) << "mimeHeader::setParameter() - val = '" << val << "'" << endl; - aDict->insert (shortLabel, new TQString (shortValue)); - i++; - } - } - else - { - aDict->insert (aLabel, new TQString (val)); - } - } -} - -TQCString -mimeHeader::outputParameter (TQDict < TQString > *aDict) -{ - TQCString retVal; - if (aDict) - { - TQDictIterator < TQString > it (*aDict); - while (it.current ()) - { - retVal += (";\n\t" + it.currentKey () + "=").latin1 (); - if (it.current ()->find (' ') > 0 || it.current ()->find (';') > 0) - { - retVal += '"' + it.current ()->utf8 () + '"'; - } - else - { - retVal += it.current ()->utf8 (); - } - // << it.current()->utf8() << "'"; - ++it; - } - retVal += "\n"; - } - return retVal; -} - -void -mimeHeader::outputPart (mimeIO & useIO) -{ - TQPtrListIterator < mimeHeader > nestedParts = getNestedIterator (); - TQCString boundary; - if (!getTypeParm ("boundary").isEmpty ()) - boundary = getTypeParm ("boundary").latin1 (); - - outputHeader (useIO); - if (!getPreBody ().isEmpty ()) - useIO.outputMimeLine (getPreBody ()); - if (getNestedMessage ()) - getNestedMessage ()->outputPart (useIO); - while (nestedParts.current ()) - { - if (!boundary.isEmpty ()) - useIO.outputMimeLine ("--" + boundary); - nestedParts.current ()->outputPart (useIO); - ++nestedParts; - } - if (!boundary.isEmpty ()) - useIO.outputMimeLine ("--" + boundary + "--"); - if (!getPostBody ().isEmpty ()) - useIO.outputMimeLine (getPostBody ()); -} - -int -mimeHeader::parsePart (mimeIO & useIO, const TQString& boundary) -{ - int retVal = 0; - bool mbox = false; - TQCString preNested, postNested; - mbox = parseHeader (useIO); - - kdDebug(7116) << "mimeHeader::parsePart - parsing part '" << getType () << "'" << endl; - if (!tqstrnicmp (getType (), "Multipart", 9)) - { - retVal = parseBody (useIO, preNested, getTypeParm ("boundary")); //this is a message in mime format stuff - setPreBody (preNested); - int localRetVal; - do - { - mimeHeader *aHeader = new mimeHeader; - - // set default type for multipart/digest - if (!tqstrnicmp (getType (), "Multipart/Digest", 16)) - aHeader->setType ("Message/RFC822"); - - localRetVal = aHeader->parsePart (useIO, getTypeParm ("boundary")); - addNestedPart (aHeader); - } - while (localRetVal); //get nested stuff - } - if (!tqstrnicmp (getType (), "Message/RFC822", 14)) - { - mailHeader *msgHeader = new mailHeader; - retVal = msgHeader->parsePart (useIO, boundary); - setNestedMessage (msgHeader); - } - else - { - retVal = parseBody (useIO, postNested, boundary, mbox); //just a simple part remaining - setPostBody (postNested); - } - return retVal; -} - -int -mimeHeader::parseBody (mimeIO & useIO, TQCString & messageBody, - const TQString& boundary, bool mbox) -{ - TQCString inputStr; - TQCString buffer; - TQString partBoundary; - TQString partEnd; - int retVal = 0; //default is last part - - if (!boundary.isEmpty ()) - { - partBoundary = TQString ("--") + boundary; - partEnd = TQString ("--") + boundary + "--"; - } - - while (useIO.inputLine (inputStr)) - { - //check for the end of all parts - if (!partEnd.isEmpty () - && !tqstrnicmp (inputStr, partEnd.latin1 (), partEnd.length () - 1)) - { - retVal = 0; //end of these parts - break; - } - else if (!partBoundary.isEmpty () - && !tqstrnicmp (inputStr, partBoundary.latin1 (), - partBoundary.length () - 1)) - { - retVal = 1; //continue with next part - break; - } - else if (mbox && inputStr.find ("From ") == 0) - { - retVal = 0; // end of mbox - break; - } - buffer += inputStr; - if (buffer.length () > 16384) - { - messageBody += buffer; - buffer = ""; - } - } - - messageBody += buffer; - return retVal; -} - -bool -mimeHeader::parseHeader (mimeIO & useIO) -{ - bool mbox = false; - bool first = true; - mimeHdrLine my_line; - TQCString inputStr; - - kdDebug(7116) << "mimeHeader::parseHeader - starting parsing" << endl; - while (useIO.inputLine (inputStr)) - { - int appended; - if (inputStr.find ("From ") != 0 || !first) - { - first = false; - appended = my_line.appendStr (inputStr); - if (!appended) - { - addHdrLine (&my_line); - appended = my_line.setStr (inputStr); - } - if (appended <= 0) - break; - } - else - { - mbox = true; - first = false; - } - inputStr = (const char *) NULL; - } - - kdDebug(7116) << "mimeHeader::parseHeader - finished parsing" << endl; - return mbox; -} - -mimeHeader * -mimeHeader::bodyPart (const TQString & _str) -{ - // see if it is nested a little deeper - int pt = _str.find('.'); - if (pt != -1) - { - TQString tempStr = _str; - mimeHeader *tempPart; - - tempStr = _str.right (_str.length () - pt - 1); - if (nestedMessage) - { - kdDebug(7116) << "mimeHeader::bodyPart - recursing message" << endl; - tempPart = nestedMessage->nestedParts.at (_str.left(pt).toULong() - 1); - } - else - { - kdDebug(7116) << "mimeHeader::bodyPart - recursing mixed" << endl; - tempPart = nestedParts.at (_str.left(pt).toULong() - 1); - } - if (tempPart) - tempPart = tempPart->bodyPart (tempStr); - return tempPart; - } - - kdDebug(7116) << "mimeHeader::bodyPart - returning part " << _str << endl; - // or pick just the plain part - if (nestedMessage) - { - kdDebug(7116) << "mimeHeader::bodyPart - message" << endl; - return nestedMessage->nestedParts.at (_str.toULong () - 1); - } - kdDebug(7116) << "mimeHeader::bodyPart - mixed" << endl; - return nestedParts.at (_str.toULong () - 1); -} - -void mimeHeader::serialize(TQDataStream& stream) -{ - int nestedcount = nestedParts.count(); - if (nestedParts.isEmpty() && nestedMessage) - nestedcount = 1; - stream << nestedcount << contentType << TQString (getTypeParm ("name")) << _contentDescription - << _contentDisposition << contentEncoding << contentLength << partSpecifier; - // serialize nested message - if (nestedMessage) - nestedMessage->serialize(stream); - - // serialize nested parts - if (!nestedParts.isEmpty()) - { - TQPtrListIterator < mimeHeader > it(nestedParts); - mimeHeader* part; - while ( (part = it.current()) != 0 ) - { - ++it; - part->serialize(stream); - } - } -} - -#ifdef KMAIL_COMPATIBLE -// compatibility subroutines -TQString -mimeHeader::bodyDecoded () -{ - kdDebug(7116) << "mimeHeader::bodyDecoded" << endl; - TQByteArray temp; - - temp = bodyDecodedBinary (); - return TQString::fromLatin1 (temp.data (), temp.count ()); -} - -TQByteArray -mimeHeader::bodyDecodedBinary () -{ - TQByteArray retVal; - - if (contentEncoding.find ("quoted-printable", 0, false) == 0) - retVal = KCodecs::quotedPrintableDecode(postMultipartBody); - else if (contentEncoding.find ("base64", 0, false) == 0) - KCodecs::base64Decode(postMultipartBody, retVal); - else retVal = postMultipartBody; - - kdDebug(7116) << "mimeHeader::bodyDecodedBinary - size is " << retVal.size () << endl; - return retVal; -} - -void -mimeHeader::setBodyEncodedBinary (const TQByteArray & _arr) -{ - setBodyEncoded (_arr); -} - -void -mimeHeader::setBodyEncoded (const TQByteArray & _arr) -{ - TQByteArray setVal; - - kdDebug(7116) << "mimeHeader::setBodyEncoded - in size " << _arr.size () << endl; - if (contentEncoding.find ("quoted-printable", 0, false) == 0) - setVal = KCodecs::quotedPrintableEncode(_arr); - else if (contentEncoding.find ("base64", 0, false) == 0) - KCodecs::base64Encode(_arr, setVal); - else - setVal.duplicate (_arr); - kdDebug(7116) << "mimeHeader::setBodyEncoded - out size " << setVal.size () << endl; - - postMultipartBody.duplicate (setVal); - kdDebug(7116) << "mimeHeader::setBodyEncoded - out size " << postMultipartBody.size () << endl; -} - -TQString -mimeHeader::iconName () -{ - TQString fileName; - - // FIXME: bug? Why throw away this data? - fileName = - KMimeType::mimeType (contentType.lower ())->icon (TQString(), false); - fileName = - TDEGlobal::instance ()->iconLoader ()->iconPath (fileName, TDEIcon::Desktop); -// if (fileName.isEmpty()) -// fileName = TDEGlobal::instance()->iconLoader()->iconPath( "unknown", TDEIcon::Desktop ); - return fileName; -} - -void -mimeHeader::setNestedMessage (mailHeader * inPart, bool destroy) -{ -// if(nestedMessage && destroy) delete nestedMessage; - nestedMessage = inPart; -} - -TQString -mimeHeader::headerAsString () -{ - mimeIOTQString myIO; - - outputHeader (myIO); - return myIO.getString (); -} - -TQString -mimeHeader::magicSetType (bool aAutoDecode) -{ - TQString mimetype; - TQByteArray body; - KMimeMagicResult *result; - - KMimeMagic::self ()->setFollowLinks (TRUE); // is it necessary ? - - if (aAutoDecode) - body = bodyDecodedBinary (); - else - body = postMultipartBody; - - result = KMimeMagic::self ()->findBufferType (body); - mimetype = result->mimeType (); - contentType = mimetype; - return mimetype; -} -#endif diff --git a/tdeioslaves/imap4/mimeheader.h b/tdeioslaves/imap4/mimeheader.h deleted file mode 100644 index bc2fd2bcd..000000000 --- a/tdeioslaves/imap4/mimeheader.h +++ /dev/null @@ -1,337 +0,0 @@ -/*************************************************************************** - mimeheader.h - description - ------------------- - begin : Fri Oct 20 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#ifndef MIMEHEADER_H -#define MIMEHEADER_H - -#include <tqptrlist.h> -#include <tqdict.h> - -#include "mimehdrline.h" -#include "mimeio.h" -#include "rfcdecoder.h" - -/** - *@author Sven Carstens - */ - -class mimeHeader -{ -public: - mimeHeader (); - virtual ~ mimeHeader (); - - virtual void addHdrLine (mimeHdrLine *); - virtual void outputHeader (mimeIO &); - virtual void outputPart (mimeIO &); - - - TQCString outputParameter (TQDict < TQString > *); - - int parsePart (mimeIO &, const TQString&); - int parseBody (mimeIO &, TQCString &, const TQString&, bool mbox = false); - - // parse a header. returns true if it had a leading 'From ' line - bool parseHeader (mimeIO &); - - TQString getDispositionParm (const TQCString&); - void setDispositionParm (const TQCString&, const TQString&); - TQDictIterator < TQString > getDispositionIterator (); - - TQString getTypeParm (const TQCString&); - void setTypeParm (const TQCString&, const TQString&); - TQDictIterator < TQString > getTypeIterator (); - - // recursively serialize all important contents to the TQDataStream - void serialize(TQDataStream& stream); - - const TQCString& getType () - { - return contentType; - } - void setType (const TQCString & _str) - { - contentType = _str; - } - - const TQCString& getDescription () - { - return _contentDescription; - } - void setDescription (const TQCString & _str) - { - _contentDescription = _str; - } - - TQCString getDisposition () - { - return _contentDisposition; - } - void setDisposition (const TQCString & _str) - { - _contentDisposition = _str; - } - - TQCString getEncoding () - { - return contentEncoding; - } - void setEncoding (const TQCString & _str) - { - contentEncoding = _str; - } - - TQCString getMD5 () - { - return contentMD5; - } - void setMD5 (const TQCString & _str) - { - contentMD5 = _str; - } - - TQCString getID () - { - return contentID; - } - void setID (const TQCString & _str) - { - contentID = _str; - } - - unsigned long getLength () - { - return contentLength; - } - void setLength (unsigned long _len) - { - contentLength = _len; - } - - const TQString & getPartSpecifier () - { - return partSpecifier; - } - void setPartSpecifier (const TQString & _str) - { - partSpecifier = _str; - } - - TQPtrListIterator < mimeHdrLine > getOriginalIterator (); - TQPtrListIterator < mimeHdrLine > getAdditionalIterator (); - void setContent (const TQCString &aContent) - { - mimeContent = aContent; - } - TQCString getContent () - { - return mimeContent; - } - - TQCString getBody () - { - return preMultipartBody + postMultipartBody; - } - TQCString getPreBody () - { - return preMultipartBody; - } - void setPreBody (TQCString & inBody) - { - preMultipartBody = inBody; - } - - TQCString getPostBody () - { - return postMultipartBody; - } - void setPostBody (TQCString & inBody) - { - postMultipartBody = inBody; - contentLength = inBody.length (); - } - - mimeHeader *getNestedMessage () - { - return nestedMessage; - } - void setNestedMessage (mimeHeader * inPart, bool destroy = true) - { - if (nestedMessage && destroy) - delete nestedMessage; - nestedMessage = inPart; - } - -// mimeHeader *getNestedPart() { return nestedPart; }; - void addNestedPart (mimeHeader * inPart) - { - nestedParts.append (inPart); - } - TQPtrListIterator < mimeHeader > getNestedIterator () - { - return TQPtrListIterator < mimeHeader > (nestedParts); - } - - // clears all parts and deletes them from memory - void clearNestedParts () - { - nestedParts.clear (); - } - - // clear all parameters to content-type - void clearTypeParameters () - { - typeList.clear (); - } - - // clear all parameters to content-disposition - void clearDispositionParameters () - { - dispositionList.clear (); - } - - // return the specified body part or NULL - mimeHeader *bodyPart (const TQString &); - -#ifdef KMAIL_COMPATIBLE - ulong msgSize () - { - return contentLength; - } - uint numBodyParts () - { - return nestedParts.count (); - } - mimeHeader *bodyPart (int which, mimeHeader ** ret = NULL) - { - if (ret) - (*ret) = nestedParts.at (which); - return nestedParts.at (which); - } - void write (const TQString &) - { - } - TQString typeStr () - { - return TQString (contentType.left (contentType.find ('/'))); - } - void setTypeStr (const TQString & _str) - { - contentType = TQCString (_str.latin1 ()) + "/" + subtypeStr ().latin1 (); - } - TQString subtypeStr () - { - return TQString (contentType. - right (contentType.length () - contentType.find ('/') - - 1)); - } - void setSubtypeStr (const TQString & _str) - { - contentType = TQCString (typeStr ().latin1 ()) + "/" + _str.latin1 (); - } - TQString cteStr () - { - return TQString (getEncoding ()); - } - void setCteStr (const TQString & _str) - { - setEncoding (_str.latin1 ()); - } - TQString contentDisposition () - { - return TQString (_contentDisposition); - } - TQString body () - { - return TQString (postMultipartBody); - } - TQString charset () - { - return getTypeParm ("charset"); - } - TQString bodyDecoded (); - void setBodyEncoded (const TQByteArray &); - void setBodyEncodedBinary (const TQByteArray &); - TQByteArray bodyDecodedBinary (); - TQString name () - { - return TQString (getTypeParm ("name")); - } - void setName (const TQString & _str) - { - setTypeParm ("name", _str); - } - TQString fileName () - { - return TQString (getDispositionParm ("filename")); - } - TQString contentDescription () - { - return TQString (rfcDecoder::decodeRFC2047String (_contentDescription)); - } - void setContentDescription (const TQString & _str) - { - _contentDescription = rfcDecoder::encodeRFC2047String (_str).latin1 (); - } - TQString msgIdMD5 () - { - return TQString (contentMD5); - } - TQString iconName (); - TQString magicSetType (bool aAutoDecode = true); - TQString headerAsString (); - ulong size () - { - return 0; - } - void fromString (const TQByteArray &) - {; - } - void setContentDisposition (const TQString & _str) - { - setDisposition (_str.latin1 ()); - } -#endif - -protected: - static void addParameter (const TQCString&, TQDict < TQString > *); - static TQString getParameter (const TQCString&, TQDict < TQString > *); - static void setParameter (const TQCString&, const TQString&, TQDict < TQString > *); - - TQPtrList < mimeHdrLine > originalHdrLines; - -private: - TQPtrList < mimeHdrLine > additionalHdrLines; - TQDict < TQString > typeList; - TQDict < TQString > dispositionList; - TQCString contentType; - TQCString _contentDisposition; - TQCString contentEncoding; - TQCString _contentDescription; - TQCString contentID; - TQCString contentMD5; - unsigned long contentLength; - TQCString mimeContent; - TQCString preMultipartBody; - TQCString postMultipartBody; - mimeHeader *nestedMessage; - TQPtrList < mimeHeader > nestedParts; - TQString partSpecifier; - -}; - -#endif diff --git a/tdeioslaves/imap4/mimeio.cc b/tdeioslaves/imap4/mimeio.cc deleted file mode 100644 index 757c11a47..000000000 --- a/tdeioslaves/imap4/mimeio.cc +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - mimeio.cc - description - ------------------- - begin : Wed Oct 25 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#include <iostream> -using namespace std; - -#include "mimeio.h" - -mimeIO::mimeIO () -{ - theCRLF = "\r\n"; - crlfLen = 2; -} - -mimeIO::~mimeIO () -{ -} - -int -mimeIO::inputLine (TQCString & aLine) -{ - char input; - - aLine = (const char *) NULL; - while (inputChar (input)) - { - aLine += input; - if (input == '\n') - break; - } -// cout << aLine.length() << " - " << aLine; - return aLine.length (); -} - -int -mimeIO::outputLine (const TQCString & aLine, int len) -{ - int i; - - if (len == -1) { - len = aLine.length(); - } - int start = len; - for (i = 0; i < start; i++) - if (!outputChar (aLine[i])) - break; - return i; -} - -int -mimeIO::outputMimeLine (const TQCString & inLine) -{ - int retVal = 0; - TQCString aLine = inLine; - int len = inLine.length(); - - int theLF = aLine.findRev ('\n'); - if (theLF == len - 1 && theLF != -1) - { - //we have a trailing LF, now check for CR - if (aLine[theLF - 1] == '\r') - theLF--; - //truncate the line - aLine.truncate(theLF); - len = theLF; - theLF = -1; - } - //now truncate the line - { - int start, end, offset; - start = 0; - end = aLine.find ('\n', start); - while (end >= 0) - { - offset = 1; - if (end && aLine[end - 1] == '\r') - { - offset++; - end--; - } - outputLine (aLine.mid (start, end - start) + theCRLF, end - start + crlfLen); - start = end + offset; - end = aLine.find ('\n', start); - } - outputLine (aLine.mid (start, len - start) + theCRLF, len - start + crlfLen); - } - return retVal; -} - -int -mimeIO::inputChar (char &aChar) -{ - if (cin.eof ()) - { -// cout << "EOF" << endl; - return 0; - } - cin.get (aChar); - return 1; -} - -int -mimeIO::outputChar (char aChar) -{ - cout << aChar; - return 1; -} - -void -mimeIO::setCRLF (const char *aCRLF) -{ - theCRLF = aCRLF; - crlfLen = strlen(aCRLF); -} - -mimeIOTQFile::mimeIOTQFile (const TQString & aName): -mimeIO (), -myFile (aName) -{ - myFile.open (IO_ReadOnly); -} - -mimeIOTQFile::~mimeIOTQFile () -{ - myFile.close (); -} - -int -mimeIOTQFile::outputLine (const TQCString &, int) -{ - return 0; -} - -int -mimeIOTQFile::inputLine (TQCString & data) -{ - data.resize( 1024 ); - myFile.readLine (data.data(), 1024); - - return data.length (); -} - -mimeIOTQString::mimeIOTQString () -{ -} - -mimeIOTQString::~mimeIOTQString () -{ -} - -int -mimeIOTQString::outputLine (const TQCString & _str, int len) -{ - if (len == -1) { - len = _str.length(); - } - theString += _str; - return len; -} - -int -mimeIOTQString::inputLine (TQCString & _str) -{ - if (theString.isEmpty ()) - return 0; - - int i = theString.find ('\n'); - - if (i == -1) - return 0; - _str = theString.left (i + 1).latin1 (); - theString = theString.right (theString.length () - i - 1); - return _str.length (); -} diff --git a/tdeioslaves/imap4/mimeio.h b/tdeioslaves/imap4/mimeio.h deleted file mode 100644 index 37a96998f..000000000 --- a/tdeioslaves/imap4/mimeio.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - mimeio.h - description - ------------------- - begin : Wed Oct 25 2000 - copyright : (C) 2000 by Sven Carstens - email : s.carstens@gmx.de - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - -#ifndef MIMEIO_H -#define MIMEIO_H - -#include <tqcstring.h> -#include <tqfile.h> - -/** - *@author Sven Carstens - */ - -class mimeIO -{ -public: - mimeIO (); - virtual ~ mimeIO (); - - virtual int outputLine (const TQCString &, int len = -1); - virtual int outputMimeLine (const TQCString &); - virtual int inputLine (TQCString &); - virtual int outputChar (char); - virtual int inputChar (char &); - - void setCRLF (const char *); - -protected: - TQCString theCRLF; - int crlfLen; -}; - -class mimeIOTQFile:public mimeIO -{ -public: - mimeIOTQFile (const TQString &); - virtual ~ mimeIOTQFile (); - virtual int outputLine (const TQCString &, int len = -1); - virtual int inputLine (TQCString &); - -protected: - TQFile myFile; -}; - -class mimeIOTQString:public mimeIO -{ -public: - mimeIOTQString (); - virtual ~ mimeIOTQString (); - virtual int outputLine (const TQCString &, int len = -1); - virtual int inputLine (TQCString &); - const TQString& getString () const - { - return theString; - } - void setString (const TQString & _str) - { - theString = _str; - } - -protected: - TQString theString; -}; - -#endif diff --git a/tdeioslaves/imap4/rfcdecoder.cc b/tdeioslaves/imap4/rfcdecoder.cc deleted file mode 100644 index 08b641b7d..000000000 --- a/tdeioslaves/imap4/rfcdecoder.cc +++ /dev/null @@ -1,668 +0,0 @@ -/********************************************************************** - * - * rfcdecoder.cc - handler for various rfc/mime encodings - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ -#include "rfcdecoder.h" - -#include <ctype.h> -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> - -#include <tqtextcodec.h> -#include <tqbuffer.h> -#include <tqregexp.h> -#include <kmdcodec.h> - -// This part taken from rfc 2192 IMAP URL Scheme. C. Newman. September 1997. -// adapted to QT-Toolkit by Sven Carstens <s.carstens@gmx.de> 2000 - -static unsigned char base64chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; -#define UNDEFINED 64 -#define MAXLINE 76 - -/* UTF16 definitions */ -#define UTF16MASK 0x03FFUL -#define UTF16SHIFT 10 -#define UTF16BASE 0x10000UL -#define UTF16HIGHSTART 0xD800UL -#define UTF16HIGHEND 0xDBFFUL -#define UTF16LOSTART 0xDC00UL -#define UTF16LOEND 0xDFFFUL - -/* Convert an IMAP mailbox to a Unicode path - */ -TQString rfcDecoder::fromIMAP (const TQString & inSrc) -{ - unsigned char c, i, bitcount; - unsigned long ucs4, utf16, bitbuf; - unsigned char base64[256], utf8[6]; - unsigned long srcPtr = 0; - TQCString dst; - TQCString src = inSrc.ascii (); - uint srcLen = inSrc.length(); - - /* initialize modified base64 decoding table */ - memset (base64, UNDEFINED, sizeof (base64)); - for (i = 0; i < sizeof (base64chars); ++i) - { - base64[(int)base64chars[i]] = i; - } - - /* loop until end of string */ - while (srcPtr < srcLen) - { - c = src[srcPtr++]; - /* deal with literal characters and &- */ - if (c != '&' || src[srcPtr] == '-') - { - /* encode literally */ - dst += c; - /* skip over the '-' if this is an &- sequence */ - if (c == '&') - srcPtr++; - } - else - { - /* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */ - bitbuf = 0; - bitcount = 0; - ucs4 = 0; - while ((c = base64[(unsigned char) src[srcPtr]]) != UNDEFINED) - { - ++srcPtr; - bitbuf = (bitbuf << 6) | c; - bitcount += 6; - /* enough bits for a UTF-16 character? */ - if (bitcount >= 16) - { - bitcount -= 16; - utf16 = (bitcount ? bitbuf >> bitcount : bitbuf) & 0xffff; - /* convert UTF16 to UCS4 */ - if (utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) - { - ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT; - continue; - } - else if (utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) - { - ucs4 += utf16 - UTF16LOSTART + UTF16BASE; - } - else - { - ucs4 = utf16; - } - /* convert UTF-16 range of UCS4 to UTF-8 */ - if (ucs4 <= 0x7fUL) - { - utf8[0] = ucs4; - i = 1; - } - else if (ucs4 <= 0x7ffUL) - { - utf8[0] = 0xc0 | (ucs4 >> 6); - utf8[1] = 0x80 | (ucs4 & 0x3f); - i = 2; - } - else if (ucs4 <= 0xffffUL) - { - utf8[0] = 0xe0 | (ucs4 >> 12); - utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); - utf8[2] = 0x80 | (ucs4 & 0x3f); - i = 3; - } - else - { - utf8[0] = 0xf0 | (ucs4 >> 18); - utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); - utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); - utf8[3] = 0x80 | (ucs4 & 0x3f); - i = 4; - } - /* copy it */ - for (c = 0; c < i; ++c) - { - dst += utf8[c]; - } - } - } - /* skip over trailing '-' in modified UTF-7 encoding */ - if (src[srcPtr] == '-') - ++srcPtr; - } - } - return TQString::fromUtf8 (dst.data ()); -} - -/* replace " with \" and \ with \\ " and \ characters */ -TQString rfcDecoder::quoteIMAP(const TQString &src) -{ - uint len = src.length(); - TQString result; - result.reserve(2 * len); - for (unsigned int i = 0; i < len; i++) - { - if (src[i] == '"' || src[i] == '\\') - result += '\\'; - result += src[i]; - } - //result.squeeze(); - unnecessary and slow - return result; -} - -/* Convert Unicode path to modified UTF-7 IMAP mailbox - */ -TQString rfcDecoder::toIMAP (const TQString & inSrc) -{ - unsigned int utf8pos, utf8total, c, utf7mode, bitstogo, utf16flag; - unsigned long ucs4, bitbuf; - TQCString src = inSrc.utf8 (); - TQString dst; - - ulong srcPtr = 0; - utf7mode = 0; - utf8total = 0; - bitstogo = 0; - utf8pos = 0; - bitbuf = 0; - ucs4 = 0; - while (srcPtr < src.length ()) - { - c = (unsigned char) src[srcPtr++]; - /* normal character? */ - if (c >= ' ' && c <= '~') - { - /* switch out of UTF-7 mode */ - if (utf7mode) - { - if (bitstogo) - { - dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F]; - bitstogo = 0; - } - dst += '-'; - utf7mode = 0; - } - dst += c; - /* encode '&' as '&-' */ - if (c == '&') - { - dst += '-'; - } - continue; - } - /* switch to UTF-7 mode */ - if (!utf7mode) - { - dst += '&'; - utf7mode = 1; - } - /* Encode US-ASCII characters as themselves */ - if (c < 0x80) - { - ucs4 = c; - utf8total = 1; - } - else if (utf8total) - { - /* save UTF8 bits into UCS4 */ - ucs4 = (ucs4 << 6) | (c & 0x3FUL); - if (++utf8pos < utf8total) - { - continue; - } - } - else - { - utf8pos = 1; - if (c < 0xE0) - { - utf8total = 2; - ucs4 = c & 0x1F; - } - else if (c < 0xF0) - { - utf8total = 3; - ucs4 = c & 0x0F; - } - else - { - /* NOTE: can't convert UTF8 sequences longer than 4 */ - utf8total = 4; - ucs4 = c & 0x03; - } - continue; - } - /* loop to split ucs4 into two utf16 chars if necessary */ - utf8total = 0; - do - { - if (ucs4 >= UTF16BASE) - { - ucs4 -= UTF16BASE; - bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT) + UTF16HIGHSTART); - ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART; - utf16flag = 1; - } - else - { - bitbuf = (bitbuf << 16) | ucs4; - utf16flag = 0; - } - bitstogo += 16; - /* spew out base64 */ - while (bitstogo >= 6) - { - bitstogo -= 6; - dst += base64chars[(bitstogo ? (bitbuf >> bitstogo) : bitbuf) & 0x3F]; - } - } - while (utf16flag); - } - /* if in UTF-7 mode, finish in ASCII */ - if (utf7mode) - { - if (bitstogo) - { - dst += base64chars[(bitbuf << (6 - bitstogo)) & 0x3F]; - } - dst += '-'; - } - return quoteIMAP(dst); -} - -//----------------------------------------------------------------------------- -TQString rfcDecoder::decodeQuoting(const TQString &aStr) -{ - TQString result; - unsigned int strLength(aStr.length()); - for (unsigned int i = 0; i < strLength ; i++) - { - if (aStr[i] == "\\") i++; - result += aStr[i]; - } - return result; -} - -//----------------------------------------------------------------------------- -TQTextCodec * -rfcDecoder::codecForName (const TQString & _str) -{ - if (_str.isEmpty ()) - return NULL; - return TQTextCodec::codecForName (_str.lower (). - replace ("windows", "cp").latin1 ()); -} - -//----------------------------------------------------------------------------- -const TQString -rfcDecoder::decodeRFC2047String (const TQString & _str) -{ - TQString throw_away; - - return decodeRFC2047String (_str, throw_away); -} - -//----------------------------------------------------------------------------- -const TQString -rfcDecoder::decodeRFC2047String (const TQString & _str, TQString & charset) -{ - TQString throw_away; - - return decodeRFC2047String (_str, charset, throw_away); -} - -//----------------------------------------------------------------------------- -const TQString -rfcDecoder::decodeRFC2047String (const TQString & _str, TQString & charset, - TQString & language) -{ - //do we have a rfc string - if (_str.find("=?") < 0) - return _str; - - TQCString aStr = _str.ascii (); // TQString.length() means Unicode chars - TQCString result; - char *pos, *beg, *end, *mid = NULL; - TQCString str; - char encoding = 0, ch; - bool valid; - const int maxLen = 200; - int i; - -// result.truncate(aStr.length()); - for (pos = aStr.data (); *pos; pos++) - { - if (pos[0] != '=' || pos[1] != '?') - { - result += *pos; - continue; - } - beg = pos + 2; - end = beg; - valid = TRUE; - // parse charset name - for (i = 2, pos += 2; - i < maxLen && (*pos != '?' && (ispunct (*pos) || isalnum (*pos))); - i++) - pos++; - if (*pos != '?' || i < 4 || i >= maxLen) - valid = FALSE; - else - { - charset = TQCString (beg, i - 1); // -2 + 1 for the zero - int pt = charset.findRev('*'); - if (pt != -1) - { - // save language for later usage - language = charset.right (charset.length () - pt - 1); - - // tie off language as defined in rfc2047 - charset.truncate(pt); - } - // get encoding and check delimiting question marks - encoding = toupper (pos[1]); - if (pos[2] != '?' - || (encoding != 'Q' && encoding != 'B' && encoding != 'q' - && encoding != 'b')) - valid = FALSE; - pos += 3; - i += 3; -// kdDebug(7116) << "rfcDecoder::decodeRFC2047String - charset " << charset << " - language " << language << " - '" << pos << "'" << endl; - } - if (valid) - { - mid = pos; - // search for end of encoded part - while (i < maxLen && *pos && !(*pos == '?' && *(pos + 1) == '=')) - { - i++; - pos++; - } - end = pos + 2; //end now points to the first char after the encoded string - if (i >= maxLen || !*pos) - valid = FALSE; - } - if (valid) - { - ch = *pos; - *pos = '\0'; - str = TQCString (mid).left ((int) (mid - pos - 1)); - if (encoding == 'Q') - { - // decode quoted printable text - for (i = str.length () - 1; i >= 0; i--) - if (str[i] == '_') - str[i] = ' '; -// kdDebug(7116) << "rfcDecoder::decodeRFC2047String - before QP '" << str << "'" << endl; - - str = KCodecs::quotedPrintableDecode(str); -// kdDebug(7116) << "rfcDecoder::decodeRFC2047String - after QP '" << str << "'" << endl; - } - else - { - // decode base64 text - str = KCodecs::base64Decode(str); - } - *pos = ch; - int len = str.length(); - for (i = 0; i < len; i++) - result += (char) (TQChar) str[i]; - - pos = end - 1; - } - else - { -// kdDebug(7116) << "rfcDecoder::decodeRFC2047String - invalid" << endl; - //result += "=?"; - //pos = beg -1; // because pos gets increased shortly afterwards - pos = beg - 2; - result += *pos++; - result += *pos; - } - } - if (!charset.isEmpty ()) - { - TQTextCodec *aCodec = codecForName (charset.ascii ()); - if (aCodec) - { -// kdDebug(7116) << "Codec is " << aCodec->name() << endl; - return aCodec->toUnicode (result); - } - } - return result; -} - - -//----------------------------------------------------------------------------- -const char especials[17] = "()<>@,;:\"/[]?.= "; - -const TQString -rfcDecoder::encodeRFC2047String (const TQString & _str) -{ - if (_str.isEmpty ()) - return _str; - const signed char *latin = reinterpret_cast<const signed char *>(_str.latin1()), *l, *start, *stop; - char hexcode; - int numQuotes, i; - int rptr = 0; - // My stats show this number results in 12 resize() out of 73,000 - int resultLen = 3 * _str.length() / 2; - TQCString result(resultLen); - - while (*latin) - { - l = latin; - start = latin; - while (*l) - { - if (*l == 32) - start = l + 1; - if (*l < 0) - break; - l++; - } - if (*l) - { - numQuotes = 1; - while (*l) - { - /* The encoded word must be limited to 75 character */ - for (i = 0; i < 16; i++) - if (*l == especials[i]) - numQuotes++; - if (*l < 0) - numQuotes++; - /* Stop after 58 = 75 - 17 characters or at "<user@host..." */ - if (l - start + 2 * numQuotes >= 58 || *l == 60) - break; - l++; - } - if (*l) - { - stop = l - 1; - while (stop >= start && *stop != 32) - stop--; - if (stop <= start) - stop = l; - } - else - stop = l; - if (resultLen - rptr - 1 <= start - latin + 1 + 16 /* =?iso-88... */) { - resultLen += (start - latin + 1) * 2 + 20; // more space - result.resize(resultLen); - } - while (latin < start) - { - result[rptr++] = *latin; - latin++; - } - strcpy(&result[rptr], "=?iso-8859-1?q?"); rptr += 15; - if (resultLen - rptr - 1 <= 3*(stop - latin + 1)) { - resultLen += (stop - latin + 1) * 4 + 20; // more space - result.resize(resultLen); - } - while (latin < stop) // can add up to 3 chars/iteration - { - numQuotes = 0; - for (i = 0; i < 16; i++) - if (*latin == especials[i]) - numQuotes = 1; - if (*latin < 0) - numQuotes = 1; - if (numQuotes) - { - result[rptr++] = '='; - hexcode = ((*latin & 0xF0) >> 4) + 48; - if (hexcode >= 58) - hexcode += 7; - result[rptr++] = hexcode; - hexcode = (*latin & 0x0F) + 48; - if (hexcode >= 58) - hexcode += 7; - result[rptr++] = hexcode; - } - else - { - result[rptr++] = *latin; - } - latin++; - } - result[rptr++] = '?'; - result[rptr++] = '='; - } - else - { - while (*latin) - { - if (rptr == resultLen - 1) { - resultLen += 30; - result.resize(resultLen); - } - result[rptr++] = *latin; - latin++; - } - } - } - result[rptr] = 0; - //free (latinStart); - return result; -} - - -//----------------------------------------------------------------------------- -const TQString -rfcDecoder::encodeRFC2231String (const TQString & _str) -{ - if (_str.isEmpty ()) - return _str; - signed char *latin = (signed char *) calloc (1, _str.length () + 1); - char *latin_us = (char *) latin; - strcpy (latin_us, _str.latin1 ()); - signed char *l = latin; - char hexcode; - int i; - bool quote; - while (*l) - { - if (*l < 0) - break; - l++; - } - if (!*l) { - free(latin); - return _str.ascii (); - } - TQCString result; - l = latin; - while (*l) - { - quote = *l < 0; - for (i = 0; i < 16; i++) - if (*l == especials[i]) - quote = true; - if (quote) - { - result += "%"; - hexcode = ((*l & 0xF0) >> 4) + 48; - if (hexcode >= 58) - hexcode += 7; - result += hexcode; - hexcode = (*l & 0x0F) + 48; - if (hexcode >= 58) - hexcode += 7; - result += hexcode; - } - else - { - result += *l; - } - l++; - } - free (latin); - return result; -} - - -//----------------------------------------------------------------------------- -const TQString -rfcDecoder::decodeRFC2231String (const TQString & _str) -{ - int p = _str.find ('\''); - - //see if it is an rfc string - if (p < 0) - return _str; - - int l = _str.findRev ('\''); - - //second is language - if (p >= l) - return _str; - - //first is charset or empty - TQString charset = _str.left (p); - TQString st = _str.mid (l + 1); - TQString language = _str.mid (p + 1, l - p - 1); - - //kdDebug(7116) << "Charset: " << charset << " Language: " << language << endl; - - char ch, ch2; - p = 0; - while (p < (int) st.length ()) - { - if (st.at (p) == 37) - { - ch = st.at (p + 1).latin1 () - 48; - if (ch > 16) - ch -= 7; - ch2 = st.at (p + 2).latin1 () - 48; - if (ch2 > 16) - ch2 -= 7; - st.at (p) = ch * 16 + ch2; - st.remove (p + 1, 2); - } - p++; - } - return st; -} diff --git a/tdeioslaves/imap4/rfcdecoder.h b/tdeioslaves/imap4/rfcdecoder.h deleted file mode 100644 index 2095b2ed2..000000000 --- a/tdeioslaves/imap4/rfcdecoder.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef RFCDECODER_H -#define RFCDECODER_H -/********************************************************************** - * - * rfcdecoder.h - handler for various rfc/mime encodings - * Copyright (C) 2000 s.carstens@gmx.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to s.carstens@gmx.de - * - *********************************************************************/ - -#include <tqstring.h> - -class TQTextCodec; - -/** - * handler for various rfc/mime encodings - * @author Sven Carstens <s.carstens@gmx.de> - * @date 2000 - * @todo rename to rfcCodecs as it encodes too. - */ -class rfcDecoder -{ - -public: - -/** Convert an IMAP mailbox to a Unicode path - */ - static TQString fromIMAP (const TQString & src); -/** Convert Unicode path to modified UTF-7 IMAP mailbox - */ - static TQString toIMAP (const TQString & inSrc); -/** replace " with \" and \ with \\ " and \ characters */ - static TQString quoteIMAP (const TQString & src); - - /** remove \ from a string - * @bug I'm pretty sure this doesn't do what the author meant it to do - */ - static TQString decodeQuoting(const TQString &aStr); - - /** - * fetch a codec by name - * @return Text Codec object - */ - static TQTextCodec *codecForName (const TQString &); - - // decoder for RFC2047 and RFC1522 - /** decode a RFC2047 String */ - static const TQString decodeRFC2047String (const TQString & _str, - TQString & charset, - TQString & language); - /** decode a RFC2047 String */ - static const TQString decodeRFC2047String (const TQString & _str, - TQString & charset); - /** decode a RFC2047 String */ - static const TQString decodeRFC2047String (const TQString & _str); - - // encoder for RFC2047 and RFC1522 - /** encode a RFC2047 String */ - static const TQString encodeRFC2047String (const TQString & _str, - TQString & charset, - TQString & language); - /** encode a RFC2047 String */ - static const TQString encodeRFC2047String (const TQString & _str, - TQString & charset); - /** encode a RFC2047 String */ - static const TQString encodeRFC2047String (const TQString & _str); - - /** encode a RFC2231 String */ - static const TQString encodeRFC2231String (const TQString & _str); - /** decode a RFC2231 String */ - static const TQString decodeRFC2231String (const TQString & _str); -}; - -#endif diff --git a/tdeioslaves/imap4/selectinfo.h b/tdeioslaves/imap4/selectinfo.h deleted file mode 100644 index bf75a85b8..000000000 --- a/tdeioslaves/imap4/selectinfo.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef _IMAPINFO_H -#define _IMAPINFO_H -/********************************************************************** - * - * imapinfo.h - IMAP4rev1 SELECT / EXAMINE handler - * Copyright (C) 2000 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Send comments and bug fixes to - * - *********************************************************************/ - -#include <tqstringlist.h> -#include <tqstring.h> - -//class handling the info we get on EXAMINE and SELECT -class imapInfo -{ -public: - - imapInfo (); - imapInfo (const TQStringList &); - imapInfo (const imapInfo &); - imapInfo & operator = (const imapInfo &); - - ulong _flags (const TQString &) const; - - void setCount (ulong l) - { - countAvailable_ = true; - count_ = l; - } - - void setRecent (ulong l) - { - recentAvailable_ = true; - recent_ = l; - } - - void setUnseen (ulong l) - { - unseenAvailable_ = true; - unseen_ = l; - } - - void setUidValidity (ulong l) - { - uidValidityAvailable_ = true; - uidValidity_ = l; - } - - void setUidNext (ulong l) - { - uidNextAvailable_ = true; - uidNext_ = l; - } - - void setFlags (ulong l) - { - flagsAvailable_ = true; - flags_ = l; - } - - void setFlags (const TQString & inFlag) - { - flagsAvailable_ = true; - flags_ = _flags (inFlag); - } - - void setPermanentFlags (ulong l) - { - permanentFlagsAvailable_ = true; - permanentFlags_ = l; - } - - void setPermanentFlags (const TQString & inFlag) - { - permanentFlagsAvailable_ = true; - permanentFlags_ = _flags (inFlag); - } - - void setReadWrite (bool b) - { - readWriteAvailable_ = true; - readWrite_ = b; - } - - ulong count () const - { - return count_; - } - - ulong recent () const - { - return recent_; - } - - ulong unseen () const - { - return unseen_; - } - - ulong uidValidity () const - { - return uidValidity_; - } - - ulong uidNext () const - { - return uidNext_; - } - - ulong flags () const - { - return flags_; - } - - ulong permanentFlags () const - { - return permanentFlags_; - } - - bool readWrite () const - { - return readWrite_; - } - - ulong countAvailable () const - { - return countAvailable_; - } - - ulong recentAvailable () const - { - return recentAvailable_; - } - - ulong unseenAvailable () const - { - return unseenAvailable_; - } - - ulong uidValidityAvailable () const - { - return uidValidityAvailable_; - } - - ulong uidNextAvailable () const - { - return uidNextAvailable_; - } - - ulong flagsAvailable () const - { - return flagsAvailable_; - } - - ulong permanentFlagsAvailable () const - { - return permanentFlagsAvailable_; - } - - bool readWriteAvailable () const - { - return readWriteAvailable_; - } - -private: - - ulong count_; - ulong recent_; - ulong unseen_; - ulong uidValidity_; - ulong uidNext_; - ulong flags_; - ulong permanentFlags_; - bool readWrite_; - - bool countAvailable_; - bool recentAvailable_; - bool unseenAvailable_; - bool uidValidityAvailable_; - bool uidNextAvailable_; - bool flagsAvailable_; - bool permanentFlagsAvailable_; - bool readWriteAvailable_; -}; - -#endif diff --git a/tdeioslaves/mbox/AUTHORS b/tdeioslaves/mbox/AUTHORS deleted file mode 100644 index 333010f6c..000000000 --- a/tdeioslaves/mbox/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Mart Kelder <mart.kde@hccnet.nl> diff --git a/tdeioslaves/mbox/CMakeLists.txt b/tdeioslaves/mbox/CMakeLists.txt deleted file mode 100644 index e74682fac..000000000 --- a/tdeioslaves/mbox/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/libtdepim - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### other data ################################ - -install( FILES mbox.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) - - -##### tdeio_mbox (module) ######################### - -tde_add_kpart( tdeio_mbox - SOURCES - mbox.cc mboxfile.cc readmbox.cc stat.cc urlinfo.cc - LINK tdeio-shared - DESTINATION ${PLUGIN_INSTALL_DIR} -) diff --git a/tdeioslaves/mbox/Makefile.am b/tdeioslaves/mbox/Makefile.am deleted file mode 100644 index 4dea4644a..000000000 --- a/tdeioslaves/mbox/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -INCLUDES= $(all_includes) - -####### Files - -METASOURCES = AUTO - -kde_module_LTLIBRARIES = tdeio_mbox.la - -tdeio_mbox_la_SOURCES = \ - mbox.cc \ - mboxfile.cc \ - readmbox.cc \ - stat.cc \ - urlinfo.cc -tdeio_mbox_la_LIBADD = $(LIB_TDEIO) $(LIB_QT) $(LIB_TDECORE) -tdeio_mbox_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -module $(KDE_PLUGIN) - -noinst_HEADERS = \ - mbox.h \ - mboxfile.h \ - readmbox.h \ - stat.h \ - urlinfo.h - -kdelnk_DATA = mbox.protocol -kdelnkdir = $(kde_servicesdir) - - -include $(top_srcdir)/admin/Doxyfile.am - diff --git a/tdeioslaves/mbox/README b/tdeioslaves/mbox/README deleted file mode 100644 index d09e81792..000000000 --- a/tdeioslaves/mbox/README +++ /dev/null @@ -1,7 +0,0 @@ -This is a simple tdeioslave for accessing mbox-files with tdeio. - -At the moment, it doesn't support locking or writing, it is just reading and listing messages. - -Usage: - mbox:/path/to/mbox/file For listing the files in a mbox-file - mbox:/path/to/mbox/file/id For getting an id out of a mbox-file. diff --git a/tdeioslaves/mbox/mbox.cc b/tdeioslaves/mbox/mbox.cc deleted file mode 100644 index 5742baffd..000000000 --- a/tdeioslaves/mbox/mbox.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 "mbox.h" - -#include "readmbox.h" -#include "stat.h" -#include "urlinfo.h" - -#include <tqstring.h> -#include <tqcstring.h> - -#include <kdebug.h> -#include <tdelocale.h> -#include <kinstance.h> -#include <tdeglobal.h> -#include <kurl.h> -#include <tdeio/global.h> - -#include <stdlib.h> - -#include "tdepimmacros.h" - -#include "mbox.h" - -extern "C" { KDE_EXPORT int kdemain(int argc, char* argv[]); } - -int kdemain( int argc, char * argv[] ) -{ - TDELocale::setMainCatalogue("tdelibs"); - TDEInstance instance("tdeio_mbox"); - (void) TDEGlobal::locale(); - - if (argc != 4) { - fprintf(stderr, "Usage: tdeio_mbox protocol " - "domain-socket1 domain-socket2\n"); - exit(-1); - } - - MBoxProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - return 0; -} - -MBoxProtocol::MBoxProtocol( const TQCString& arg1, const TQCString& arg2 ) - : TDEIO::SlaveBase( "mbox2", arg1, arg2 ), - m_errorState( true ) -{ - -} - -MBoxProtocol::~MBoxProtocol() -{ -} - -void MBoxProtocol::get( const KURL& url ) -{ - m_errorState = false; - - UrlInfo info( url, UrlInfo::message ); - TQString line; - TQByteArray ba_line; - - if( info.type() == UrlInfo::invalid && !m_errorState ) - { - error( TDEIO::ERR_DOES_NOT_EXIST, info.url() ); - return; - } - - ReadMBox mbox( &info, this ); - - while( !mbox.atEnd() && !m_errorState) - { - line = mbox.currentLine(); - line += '\n'; - ba_line = TQCString( line.utf8() ); - ba_line.truncate( ba_line.size() - 1 ); //Removing training '\0' - data( ba_line ); - mbox.nextLine(); - }; - - if( !m_errorState ) - { - data( TQByteArray() ); - finished(); - } -} - -void MBoxProtocol::listDir( const KURL& url ) -{ - m_errorState = false; - - TDEIO::UDSEntry entry; - UrlInfo info( url, UrlInfo::directory ); - ReadMBox mbox( &info, this, hasMetaData( "onlynew" ), hasMetaData( "savetime" ) ); - - if( m_errorState ) - return; - - if( info.type() != UrlInfo::directory ) - { - error( TDEIO::ERR_DOES_NOT_EXIST, info.url() ); - return; - } - - while( !mbox.atEnd() && !m_errorState ) - { - entry = Stat::stat( mbox, info ); - if( mbox.inListing() ) - listEntry( entry, false ); - } - - listEntry( TDEIO::UDSEntry(), true ); - finished(); -} - -void MBoxProtocol::stat( const KURL& url ) -{ - UrlInfo info( url ); - if( info.type() == UrlInfo::invalid ) - { - error( TDEIO::ERR_DOES_NOT_EXIST, url.path() ); - return; - } else - { - statEntry( Stat::stat( info ) ); - } - finished(); -} - -void MBoxProtocol::mimetype( const KURL& url ) -{ - m_errorState = false; - - UrlInfo info( url ); - - if( m_errorState ) - return; - - if( info.type() == UrlInfo::invalid ) - error( TDEIO::ERR_DOES_NOT_EXIST, i18n( "Invalid URL" ) ); - else - mimeType( info.mimetype() ); - finished(); -} - -void MBoxProtocol::emitError( int errno, const TQString& arg ) -{ - m_errorState = true; - error( errno, arg ); -} - diff --git a/tdeioslaves/mbox/mbox.h b/tdeioslaves/mbox/mbox.h deleted file mode 100644 index 5834b5a07..000000000 --- a/tdeioslaves/mbox/mbox.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 MBOX_H -#define MBOX_H - -#include <tdeio/slavebase.h> - -class TQCString; -class KURL; - -/** - * This class is the main class and implements all function - * which can be called through the user. - */ -class MBoxProtocol : public TDEIO::SlaveBase -{ -public: - /** - * Constructor, for the parameters, See TDEIO::SlaveBase - */ - MBoxProtocol( const TQCString&, const TQCString& ); - /** - * Empty destructor - */ - virtual ~MBoxProtocol(); - - /** - * This functions is used when an user or a program wants to - * get a file from a mbox-file - * @param url The url which points to the virtual file to get - */ - virtual void get( const KURL& url ); - - /** - * This functions gives a listing back. - * @param url The url to the mbox-file. - */ - virtual void listDir( const KURL& url ); - - /** - * This functions gives general properties about a mbox-file, - * or mbox-email back. - */ - virtual void stat( const KURL& url ); - - /** - * This functions determinate the mimetype of a given mbox-file or mbox-email. - * @param url The url to get the mimetype from - */ - virtual void mimetype( const KURL& url ); - - /** - * Through this functions, other class which have an instance to this - * class (classes which are part of tdeio_mbox) can emit an error with - * this function - * @param errno The error number to be thrown - * @param arg The argument of the error message of the error number. - */ - void emitError( int errno, const TQString& arg ); -private: - bool m_errorState; -}; - -#endif - diff --git a/tdeioslaves/mbox/mbox.protocol b/tdeioslaves/mbox/mbox.protocol deleted file mode 100644 index 5b5447dc2..000000000 --- a/tdeioslaves/mbox/mbox.protocol +++ /dev/null @@ -1,14 +0,0 @@ -[Protocol] -exec=tdeio_mbox -protocol=mbox -input=none -output=filesystem -listing=Name,Type,Size -reading=true -writing=false -makedir=false -deleting=false -Icon=folder_inbox -maxInstances=2 -DocPath=tdeioslave/mbox/index.html -Class=:local diff --git a/tdeioslaves/mbox/mboxfile.cc b/tdeioslaves/mbox/mboxfile.cc deleted file mode 100644 index 7297457ef..000000000 --- a/tdeioslaves/mbox/mboxfile.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 "mboxfile.h" - -#include <assert.h> - -MBoxFile::MBoxFile( const UrlInfo* info, MBoxProtocol* parent ) - : m_info( info ), - m_mbox( parent ) -{ - assert( m_info ); -} - -MBoxFile::~MBoxFile() -{ -} - -bool MBoxFile::lock() -{ - //Not implemented - return true; -} - -void MBoxFile::unlock() -{ - //Not implemented -} - - diff --git a/tdeioslaves/mbox/mboxfile.h b/tdeioslaves/mbox/mboxfile.h deleted file mode 100644 index 1defafc9b..000000000 --- a/tdeioslaves/mbox/mboxfile.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 MBOXFILE_H -#define MBOXFILE_H -class MBoxProtocol; -class UrlInfo; - -/** - * This class can be used to lock files when implemented. - * It is a base class for all classes that needs locking and/ir - * an UrlInfo*. - */ -class MBoxFile -{ -public: - /** - * Constructor - * @param info The urlinfo which must be used - * @param parent The MBoxProtocol parent instance, used to throw errors. - */ - MBoxFile( const UrlInfo* info, MBoxProtocol* parent ); - - /** - * Empty destructor - */ - ~MBoxFile(); - -protected: - /** - * When implemented, this function handles the locking of the file. - * @return true if the locking was done succesfully. - */ - bool lock(); - - /** - * When implemented, this function unlocks the file. - */ - void unlock(); - -protected: - /** - * This can be used to get information about the file. - * The file specified here is the file that must be used. - */ - const UrlInfo* const m_info; - - /** - * A instance of the parent protocol, meant to throw errors if neccesairy. - */ - MBoxProtocol* const m_mbox; -}; -#endif diff --git a/tdeioslaves/mbox/readmbox.cc b/tdeioslaves/mbox/readmbox.cc deleted file mode 100644 index 942f369e5..000000000 --- a/tdeioslaves/mbox/readmbox.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 <config.h> - -#include "readmbox.h" - -#include "mbox.h" -#include "urlinfo.h" - -#include <kdebug.h> -#include <tdeio/global.h> - -#include <tqfile.h> -#include <tqfileinfo.h> -#include <tqstring.h> -#include <tqtextstream.h> - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#include <utime.h> - -ReadMBox::ReadMBox( const UrlInfo* info, MBoxProtocol* parent, bool onlynew, bool savetime ) - : MBoxFile( info, parent ), - m_file( 0 ), - m_stream( 0 ), - m_current_line( new TQString( TQString() ) ), - m_current_id( new TQString( TQString() ) ), - m_atend( true ), - m_prev_time( 0 ), - m_only_new( onlynew ), - m_savetime( savetime ), - m_status( false ), - m_prev_status( false ), - m_header( true ) - -{ - if( m_info->type() == UrlInfo::invalid ) - m_mbox->emitError( TDEIO::ERR_DOES_NOT_EXIST, info->url() ); - - if( !open( savetime ) ) - m_mbox->emitError( TDEIO::ERR_CANNOT_OPEN_FOR_READING, info->url() ); - - if( m_info->type() == UrlInfo::message ) - if( !searchMessage( m_info->id() ) ) - m_mbox->emitError( TDEIO::ERR_DOES_NOT_EXIST, info->url() ); -} - -ReadMBox::~ReadMBox() -{ - delete m_current_line; - close(); -} - -TQString ReadMBox::currentLine() const -{ - return *m_current_line; -} - -TQString ReadMBox::currentID() const -{ - return *m_current_id; -} - -bool ReadMBox::nextLine() -{ - if( !m_stream ) - return true; - - *m_current_line = m_stream->readLine(); - m_atend = m_current_line->isNull(); - if( m_atend ) // Cursor was at EOF - { - *m_current_id = TQString(); - m_prev_status = m_status; - return true; - } - - //New message - if( m_current_line->left( 5 ) == "From " ) - { - *m_current_id = *m_current_line; - m_prev_status = m_status; - m_status = true; - m_header = true; - return true; - } else if( m_only_new ) - { - if( m_header && m_current_line->left( 7 ) == "Status:" && - ! m_current_line->contains( "U" ) && ! m_current_line->contains( "N" ) ) - { - m_status = false; - } - } - - if( m_current_line->stripWhiteSpace().isEmpty() ) - m_header = false; - - return false; -} - -bool ReadMBox::searchMessage( const TQString& id ) -{ - if( !m_stream ) - return false; - - while( !m_atend && *m_current_id != id ) - nextLine(); - - return *m_current_id == id; -} - -unsigned int ReadMBox::skipMessage() -{ - unsigned int result = m_current_line->length(); - - if( !m_stream ) - return 0; - - while( !nextLine() ) - result += m_current_line->length(); - - return result; -} - -void ReadMBox::rewind() -{ - if( !m_stream ) - return; //Rewinding not possible - - m_stream->device()->reset(); - m_atend = m_stream->atEnd(); -} - -bool ReadMBox::atEnd() const -{ - if( !m_stream ) - return true; - - return m_atend || ( m_info->type() == UrlInfo::message && *m_current_id != m_info->id() ); -} - -bool ReadMBox::inListing() const -{ - return !m_only_new || m_prev_status; -} - -bool ReadMBox::open( bool savetime ) -{ - if( savetime ) - { - TQFileInfo info( m_info->filename() ); - - m_prev_time = new utimbuf; - m_prev_time->actime = info.lastRead().toTime_t(); - m_prev_time->modtime = info.lastModified().toTime_t(); - } - - if( m_file ) - return false; //File already open - - m_file = new TQFile( m_info->filename() ); - if( !m_file->open( IO_ReadOnly ) ) - { - delete m_file; - m_file = 0; - return false; - } - m_stream = new TQTextStream( m_file ); - skipMessage(); - - return true; -} - -void ReadMBox::close() -{ - if( !m_stream ) - return; - - delete m_stream; m_stream = 0; - m_file->close(); - delete m_file; m_file = 0; - - if( m_prev_time ) - utime( TQFile::encodeName( m_info->filename() ), m_prev_time ); -} - diff --git a/tdeioslaves/mbox/readmbox.h b/tdeioslaves/mbox/readmbox.h deleted file mode 100644 index 0b8872763..000000000 --- a/tdeioslaves/mbox/readmbox.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 READMBOX_H -#define READMBOX_H - -#include "mboxfile.h" - -class UrlInfo; -class MBox; - -class TQFile; -class TQString; -class TQTextStream; - -struct utimbuf; - -/** - * This class handels reading from a mbox-file. - */ -class ReadMBox : public MBoxFile -{ -public: - /** - * Constructor - * - * @param info The information of the file to read - * @param parent The instance of the parent MBoxProtocol. - * @param onlynew Only read new messages from the MBox file. - * @param savetime If true, the atime of the mbox-file is preserved (note that this touch the ctime). - */ - ReadMBox( const UrlInfo* info, MBoxProtocol* parent, bool onlynew = false, bool savetime = false ); - - /** - * Destructor - */ - ~ReadMBox(); - - /** - * This functions return the current line - * @return The line last read, or TQString() if there wasn't such last line - */ - TQString currentLine() const; - - /** - * This function returns the current id. The id is the first line of an email, - * and is used in filenaming. The id normally starts with "From ". - * @return The current ID, or TQString() if no id was found yet. - */ - TQString currentID() const; - - /** - * This function reads the next line. The next line can be read by the currentLine() - * function call. - * - * @return true if succesfull, otherwise false. - */ - bool nextLine(); - - /** - * This function search the file for a certain id. - * If not found, the position is EOF. - * @param id The id of the message to be found. - * @return true if the message was found, false otherwise. - */ - bool searchMessage( const TQString& id ); - - /** - * Skips all lines which belongs to the current message. The cursor is on the first line - * of a new message message at the end of this function, or at EOF if the cursor was already - * on the last message. - * @return The number of bytes read while skipping the message. - */ - unsigned int skipMessage(); - - /** - * Sets the cursor back to the beginning of the file - */ - void rewind(); - - /** - * Returns true if the cursor is at EOF. - * @return true if and only if the cursor is at EOF. - */ - bool atEnd() const; - - /** - * Return true if the message is a new message, or all messages are listed - * @return true if it must be listed - */ - bool inListing() const; -private: - /** - * Opens a file - * @return true Returns true if opening was succesful. - */ - bool open( bool savetime ); - - /** - * Closes a file. - */ - void close(); - -private: - TQFile* m_file; - TQTextStream* m_stream; - TQString* m_current_line; - TQString* m_current_id; - bool m_atend; - - struct utimbuf* m_prev_time; - - bool m_only_new, m_savetime; - - bool m_status, m_prev_status, m_header; -}; -#endif diff --git a/tdeioslaves/mbox/stat.cc b/tdeioslaves/mbox/stat.cc deleted file mode 100644 index 99267ca7d..000000000 --- a/tdeioslaves/mbox/stat.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 "stat.h" - -#include "readmbox.h" -#include "urlinfo.h" - -#include <kdebug.h> -#include <tdeio/global.h> - -#include <sys/stat.h> - -TDEIO::UDSEntry Stat::stat( const UrlInfo& info ) -{ - if( info.type() == UrlInfo::message ) - return Stat::statMessage( info ); - else if( info.type() == UrlInfo::directory ) - return Stat::statDirectory( info ); - else - return TDEIO::UDSEntry(); -} - -TDEIO::UDSEntry Stat::stat( ReadMBox& mbox, const UrlInfo& info ) -{ - kdDebug() << "Stat::stat()" << endl; - TDEIO::UDSEntry entry; - TQString url; - - if( info.type() == UrlInfo::invalid ) - return entry; - else if( info.type() == UrlInfo::message ) - mbox.searchMessage( info.id() ); - - Stat::addAtom( entry, TDEIO::UDS_FILE_TYPE, S_IFREG ); - Stat::addAtom( entry, TDEIO::UDS_MIME_TYPE, "message/rfc822" ); - - url = TQString( "mbox:%1/%2" ).arg( info.filename(), mbox.currentID() ); - Stat::addAtom( entry, TDEIO::UDS_URL, url ); - if( mbox.currentID().isEmpty() ) - Stat::addAtom( entry, TDEIO::UDS_NAME, "foobar" ); - else - Stat::addAtom( entry, TDEIO::UDS_NAME, mbox.currentID() ); - - - Stat::addAtom( entry, TDEIO::UDS_SIZE, mbox.skipMessage() ); - - return entry; -} - -TDEIO::UDSEntry Stat::statDirectory( const UrlInfo& info ) -{ - kdDebug() << "statDirectory()" << endl; - TDEIO::UDSEntry entry; - - //Specific things for a directory - Stat::addAtom( entry, TDEIO::UDS_FILE_TYPE, S_IFDIR ); - Stat::addAtom( entry, TDEIO::UDS_NAME, info.filename() ); - - return entry; -} - -TDEIO::UDSEntry Stat::statMessage( const UrlInfo& info ) -{ - kdDebug() << "statMessage( " << info.url() << " )" << endl; - TDEIO::UDSEntry entry; - TQString url = TQString( "mbox:%1" ).arg( info.url() ); - - //Specific things for a message - Stat::addAtom( entry, TDEIO::UDS_FILE_TYPE, S_IFREG ); - Stat::addAtom( entry, TDEIO::UDS_MIME_TYPE, "message/rfc822" ); - - Stat::addAtom( entry, TDEIO::UDS_URL, url ); - url = url.right( url.length() - url.findRev( "/" ) - 1 ); - Stat::addAtom( entry, TDEIO::UDS_NAME, url ); - - return entry; -} - -void Stat::addAtom( TDEIO::UDSEntry& entry, unsigned int uds, const TQString& str ) -{ - TDEIO::UDSAtom atom; - atom.m_uds = uds; - atom.m_str = str; - atom.m_long = 0; - - entry.append( atom ); -} - - -void Stat::addAtom( TDEIO::UDSEntry& entry, unsigned int uds, long lng ) -{ - TDEIO::UDSAtom atom; - atom.m_uds = uds; - atom.m_str = TQString(); - atom.m_long = lng; - - entry.append( atom ); -} - diff --git a/tdeioslaves/mbox/stat.h b/tdeioslaves/mbox/stat.h deleted file mode 100644 index 4e2c1f020..000000000 --- a/tdeioslaves/mbox/stat.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 STAT_H -#define STAT_H - -#include <tdeio/global.h> - -class ReadMBox; -class UrlInfo; - -class KURL; - -class TQString; - -/** - * This class is used to get the stats of a mbox-email or mbox-file. - * This class only uses static members. - */ -class Stat -{ -public: - /** - * Empty constructor - */ - Stat() {} - - /** - * Emtpy destructor - */ - ~Stat() {} - - /** - * This functions gives information with a given UrlInfo. - * @param info The file information - * @return The information of the file as destribed in UrlInfo. - */ - static TDEIO::UDSEntry stat( const UrlInfo& info ); - /** - * This function gives information with a given ReadMBox and UrlInfo. - * Through this, it is possible to ask the stats of the next message, - * without reopening the mbox-file. - * @param mbox The ReadMBox instance, used to search the mbox-email in. - * @param info The url information. - * @return The requesteds information. - */ - static TDEIO::UDSEntry stat( ReadMBox& mbox, const UrlInfo& info ); - - /** - * This function gets the stats of a given mbox-file in an UDSEntry. - * @param info The location of the mbox-file. - * @return A list of Atoms. - */ - static TDEIO::UDSEntry statDirectory( const UrlInfo& info ); - - /** - * This function gets the stats of a geven mbox-message in a UDSEntry. - * @param info The url of the mbox-message. - * @return Information shipped in an UDSEntry. - */ - static TDEIO::UDSEntry statMessage( const UrlInfo& info ); -private: - static void addAtom( TDEIO::UDSEntry& entry, unsigned int key, const TQString& value ); - static void addAtom( TDEIO::UDSEntry& entry, unsigned int key, const long value ); -}; - -#endif diff --git a/tdeioslaves/mbox/urlinfo.cc b/tdeioslaves/mbox/urlinfo.cc deleted file mode 100644 index 4b359e403..000000000 --- a/tdeioslaves/mbox/urlinfo.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 "urlinfo.h" - -#include <kdebug.h> -#include <kurl.h> - -#include <tqfileinfo.h> -#include <tqstring.h> - -UrlInfo::UrlInfo( const KURL& url, const UrlType type ) - : m_type( invalid ), - m_filename( new TQString ), - m_id( new TQString ) -{ - calculateInfo( url, type ); -} - -UrlInfo::~UrlInfo() -{ - delete m_filename; - delete m_id; -} - -TQString UrlInfo::mimetype() const -{ - switch( m_type ) - { - case message: - return "message/rfc822"; - case directory: - return "inode/directory"; - case invalid: - default: - return "invalid"; - } -} - -TQString UrlInfo::filename() const -{ - return *m_filename; -} - -TQString UrlInfo::id() const -{ - return *m_id; -} - -TQString UrlInfo::url() const -{ - return *m_filename + "/" + *m_id; -} - - -void UrlInfo::calculateInfo( const KURL& url, const UrlType type ) -{ - bool found = false; - - if( !found && type & UrlInfo::message ) - found = isMessage( url ); - if( !found && type & UrlInfo::directory ) - found = isDirectory( url ); - if( !found ) - { - m_type = invalid; - *m_filename = ""; - *m_id = ""; - } -} - -bool UrlInfo::isDirectory( const KURL& url ) -{ - //Check is url is in the form mbox://{filename} - TQString filename = url.path(); - TQFileInfo info; - - //Remove ending / - while( filename.length() > 1 && filename.right( 1 ) == "/" ) - filename.remove( filename.length()-2, 1 ); - - //Is this a directory? - info.setFile( filename ); - if( !info.isFile() ) - return false; - - //Setting paramaters - *m_filename = filename; - *m_id = TQString(); - m_type = directory; - kdDebug() << "urlInfo::isDirectory( " << url << " )" << endl; - return true; -} - -bool UrlInfo::isMessage( const KURL& url ) -{ - TQString path = url.path(); - TQFileInfo info; - int cutindex = path.findRev( '/' ); - - //Does it contain at least one /? - if( cutindex < 0 ) - return false; - - //Does the mbox-file exists? - info.setFile( path.left( cutindex ) ); - if( !info.isFile() ) - return false; - - //Settings parameters - kdDebug() << "urlInfo::isMessage( " << url << " )" << endl; - m_type = message; - *m_id = path.right( path.length() - cutindex - 1 ); - *m_filename = path.left( cutindex ); - - return true; -} - diff --git a/tdeioslaves/mbox/urlinfo.h b/tdeioslaves/mbox/urlinfo.h deleted file mode 100644 index 5de7804fd..000000000 --- a/tdeioslaves/mbox/urlinfo.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This is a simple tdeioslave to handle mbox-files. - * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) - * - * 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 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 URLINFO_H -#define URLINFO_H -class KURL; - -class TQString; - -class UrlInfo -{ -public: - /** - * This enum is used to determe the url type. - */ - enum UrlType { invalid = 0, message = 1, directory = 2 }; - - /** - * Constructor - * - * @param url The url: this url is used to split the location data off. - * @param type The possible types of the url - */ - UrlInfo( const KURL &url, const UrlType type = (UrlType)( message | directory ) ); - - /** - * Destructor - */ - ~UrlInfo(); - - /** - * Returns the type of the url - * @return the type of the url - */ - UrlType type() const { return m_type; } - - /** - * @return the mimetype of the url - */ - TQString mimetype() const; - - /** - * @return The location of the mbox-file - */ - TQString filename() const; - /** - * @return The id given in the url. - */ - TQString id() const; - - /** - * @return the while url as TQString - */ - TQString url() const; -private: - void calculateInfo( const KURL& url, const UrlType type ); - - bool isDirectory( const KURL& url ); - bool isMessage( const KURL& url ); - -private: - UrlType m_type; - TQString *m_filename; - TQString *m_id; -}; - -#endif diff --git a/tdeioslaves/opengroupware/Makefile.am b/tdeioslaves/opengroupware/Makefile.am deleted file mode 100644 index fbe8cee15..000000000 --- a/tdeioslaves/opengroupware/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tderesources/opengroupware/soap \ - $(all_includes) - -noinst_HEADERS = opengroupware.h - -METASOURCES = AUTO - -kdelnkdir = $(kde_servicesdir) -kdelnk_DATA = opengroupware.protocol opengroupwares.protocol - -kde_module_LTLIBRARIES = tdeio_opengroupware.la - -tdeio_opengroupware_la_SOURCES = opengroupware.cpp webdavhandler.cpp -tdeio_opengroupware_la_LIBADD = $(top_builddir)/libkcal/libkcal.la \ - $(top_builddir)/libtdepim/libtdepim.la $(LIB_TDEIO) -tdeio_opengroupware_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) - diff --git a/tdeioslaves/opengroupware/opengroupware.cpp b/tdeioslaves/opengroupware/opengroupware.cpp deleted file mode 100644 index 304ff225f..000000000 --- a/tdeioslaves/opengroupware/opengroupware.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* - This file is part of KDE. - - Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "opengroupware.h" -#include "webdavhandler.h" - -#include <kdebug.h> -#include <kurl.h> -#include <tdeio/job.h> -#include <tdeio/davjob.h> -#include <tdelocale.h> - -#include <libtdepim/tdeabcresourcecached.h> - -#include <libkcal/freebusy.h> -#include <libkcal/icalformat.h> -#include <libkcal/scheduler.h> -#include <libkcal/calendarlocal.h> - -#include <tdeabc/vcardconverter.h> - -#include <kinstance.h> -#include <kdebug.h> -#include <tdelocale.h> -#include <tdetempfile.h> - -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> - -#include <tdepimmacros.h> - -namespace TDEABC { - -class ResourceMemory : public ResourceCached -{ - public: - ResourceMemory() : ResourceCached( 0 ) {} - - Ticket *requestSaveTicket() { return 0; } - bool load() { return true; } - bool save( Ticket * ) { return true; } - void releaseSaveTicket( Ticket * ) {} -}; - -} - - -extern "C" { -KDE_EXPORT int kdemain( int argc, char **argv ); -} - -int kdemain( int argc, char **argv ) -{ - TDEInstance instance( "tdeio_OpenGroupware" ); - - kdDebug(7000) << "Starting tdeio_OpenGroupware(pid: " << getpid() << ")" << endl; - - if (argc != 4) { - fprintf( stderr, "Usage: tdeio_OpenGroupware protocol domain-socket1 domain-socket2\n"); - exit( -1 ); - } - - OpenGroupware slave( argv[1], argv[2], argv[3] ); - slave.dispatchLoop(); - - return 0; -} - -OpenGroupware::OpenGroupware( const TQCString &protocol, const TQCString &pool, - const TQCString &app ) - : SlaveBase( protocol, pool, app ) -{ -} - -void OpenGroupware::get( const KURL &url ) -{ - kdDebug(7000) << "OpenGroupware::get()" << endl; - kdDebug(7000) << " URL: " << url.url() << endl; - #if 1 - kdDebug(7000) << " Path: " << url.path() << endl; - kdDebug(7000) << " Query: " << url.query() << endl; - kdDebug(7000) << " Protocol: " << url.protocol() << endl; - kdDebug(7000) << " Filename: " << url.filename() << endl; - #endif - - mimeType( "text/plain" ); - - TQString path = url.path(); - debugMessage( "Path: " + path ); - - if ( path.startsWith( "/freebusy/" ) ) { - getFreeBusy( url ); - } else if ( path.startsWith( "/calendar/" ) ) { - getCalendar( url ); - } else if ( path.startsWith( "/addressbook/" ) ) { - getAddressbook( url ); - } else { - TQString error = i18n("Unknown path. Known paths are '/freebusy/', " - "'/calendar/' and '/addressbook/'."); - errorMessage( error ); - } - - kdDebug(7000) << "OpenGroupwareCgiProtocol::get() done" << endl; -} - -void OpenGroupware::getFreeBusy( const KURL &url ) -{ - TQString file = url.filename(); - if ( file.right( 4 ) != ".ifb" ) { - TQString error = i18n("Illegal filename. File has to have '.ifb' suffix."); - errorMessage( error ); - } else { - TQString email = file.left( file.length() - 4 ); - debugMessage( "Email: " + email ); - - TQString user = url.user(); - TQString pass = url.pass(); - - debugMessage( "URL: " ); - debugMessage( "User: " + user ); - debugMessage( "Password: " + pass ); - - KCal::FreeBusy *fb = new KCal::FreeBusy; - - if ( user.isEmpty() || pass.isEmpty() ) { - errorMessage( i18n("Need username and password.") ); - } else { - // FIXME get from server - - // FIXME: Read range from configuration or URL parameters. - TQDate start = TQDate::currentDate().addDays( -3 ); - TQDate end = TQDate::currentDate().addDays( 60 ); - - fb->setDtStart( start ); - fb->setDtEnd( end ); - - kdDebug() << "Login" << endl; - - } - -#if 0 - TQDateTime s = TQDateTime( TQDate( 2004, 9, 27 ), TQTime( 10, 0 ) ); - TQDateTime e = TQDateTime( TQDate( 2004, 9, 27 ), TQTime( 11, 0 ) ); - - fb->addPeriod( s, e ); -#endif - - KCal::ICalFormat format; - - TQString ical = format.createScheduleMessage( fb, KCal::Scheduler::Publish ); - - data( ical.utf8() ); - - finished(); - } -} - - -void OpenGroupware::getCalendar( const KURL &_url ) -{ - - KURL url( _url ); // we'll be changing it - TQString user = url.user(); - TQString pass = url.pass(); - - TQDomDocument props = WebdavHandler::createAllPropsRequest(); - - debugMessage( "URL: " ); - debugMessage( "User: " + user ); - debugMessage( "Password: " + pass ); - - url.setProtocol( "webdav" ); - url.setPath ( "/zidestore/dav/till/" ); - - kdDebug(7000) << "getCalendar: " << url.prettyURL() << endl; - - // FIXME do progress handling - mListEventsJob = TDEIO::davPropFind( url, props, "0", false ); - connect( mListEventsJob, TQT_SIGNAL( result( TDEIO::Job * ) ), - TQT_SLOT( slotGetCalendarListingResult( TDEIO::Job * ) ) ); -} - -void OpenGroupware::getAddressbook( const KURL &url ) -{ - -} - -void OpenGroupware::errorMessage( const TQString &msg ) -{ - error( TDEIO::ERR_SLAVE_DEFINED, msg ); -} - -void OpenGroupware::debugMessage( const TQString &msg ) -{ -#if 0 - data( ( msg + "\n" ).utf8() ); -#else - Q_UNUSED( msg ); -#endif -} - - -void OpenGroupware::slotGetCalendarListingResult( TDEIO::Job *job ) -{ - - kdDebug(7000) << k_funcinfo << endl; - - if ( job->error() ) { - job->showErrorDialog( 0 ); - } else { - kdDebug() << "ResourceSlox::slotResult() success" << endl; - - TQDomDocument doc = mListEventsJob->response(); - - } - KCal::ICalFormat format; - KCal::CalendarLocal calendar; - - TQString ical = format.toString( &calendar ); - - data( ical.utf8() ); - - finished(); -} - - -void OpenGroupware::slotGetCalendarResult( TDEIO::Job *job ) -{ - Q_UNUSED( job ); -} -#include "opengroupware.moc" - diff --git a/tdeioslaves/opengroupware/opengroupware.h b/tdeioslaves/opengroupware/opengroupware.h deleted file mode 100644 index 151187dbe..000000000 --- a/tdeioslaves/opengroupware/opengroupware.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - This file is part of KDE. - - Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -#ifndef GROUPWISE_H -#define GROUPWISE_H - -#include <tdeio/slavebase.h> - -#include <tqobject.h> - -namespace TDEIO { - class Job; - class DavJob; -} - - -class OpenGroupware : public TQObject, public TDEIO::SlaveBase -{ - Q_OBJECT - - public: - OpenGroupware( const TQCString &protocol, const TQCString &pool, - const TQCString &app ); - - void get( const KURL &url ); - - protected: - void debugMessage( const TQString & ); - void errorMessage( const TQString & ); - - void getFreeBusy( const KURL &url ); - void getCalendar( const KURL &url ); - void getAddressbook( const KURL &url ); - protected slots: - void slotGetCalendarListingResult( TDEIO::Job* ); - void slotGetCalendarResult( TDEIO::Job* ); - private: - TDEIO::DavJob *mListEventsJob; -}; - -#endif diff --git a/tdeioslaves/opengroupware/opengroupware.protocol b/tdeioslaves/opengroupware/opengroupware.protocol deleted file mode 100644 index 5531f3106..000000000 --- a/tdeioslaves/opengroupware/opengroupware.protocol +++ /dev/null @@ -1,8 +0,0 @@ -[Protocol] -DocPath=tdeioslave/opengroupware/index.html -exec=tdeio_opengroupware -input=none -output=filesystem -protocol=opengroupware -reading=true -Icon=kontact diff --git a/tdeioslaves/opengroupware/opengroupwares.protocol b/tdeioslaves/opengroupware/opengroupwares.protocol deleted file mode 100644 index 03bb4b1db..000000000 --- a/tdeioslaves/opengroupware/opengroupwares.protocol +++ /dev/null @@ -1,8 +0,0 @@ -[Protocol] -DocPath=tdeioslave/opengroupware/index.html -exec=tdeio_opengroupware -input=none -output=filesystem -protocol=opengroupwares -reading=true -Icon=kontact diff --git a/tdeioslaves/opengroupware/webdavhandler.cpp b/tdeioslaves/opengroupware/webdavhandler.cpp deleted file mode 100644 index 9c89174ae..000000000 --- a/tdeioslaves/opengroupware/webdavhandler.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - This file is part of tdepim. - - Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include <config.h> - -#include "webdavhandler.h" - -#include <limits.h> - -#include <libtdepim/kpimprefs.h> - -#include <kdebug.h> -#include <tdeconfig.h> - -#include <tqfile.h> - - -WebdavHandler::WebdavHandler() -{ -} - - -TQDomElement WebdavHandler::addElement( TQDomDocument &doc, TQDomNode &node, - const TQString &tag ) -{ - TQDomElement el = doc.createElement( tag ); - node.appendChild( el ); - return el; -} - -TQDomElement WebdavHandler::addDavElement( TQDomDocument &doc, TQDomNode &node, - const TQString &tag ) -{ - TQDomElement el = doc.createElementNS( "DAV", tag ); - node.appendChild( el ); - return el; -} - -TQDomElement WebdavHandler::addSloxElement( TQDomDocument &doc, TQDomNode &node, - const TQString &tag, - const TQString &text ) -{ - TQDomElement el = doc.createElementNS( "SLOX", tag ); - if ( !text.isEmpty() ) { - TQDomText textnode = doc.createTextNode( text ); - el.appendChild( textnode ); - } - node.appendChild( el ); - return el; -} - -TQDomDocument WebdavHandler::createAllPropsRequest() -{ - TQDomDocument doc; - - TQDomElement root = WebdavHandler::addDavElement( doc, doc, "propfind" ); - TQDomElement prop = WebdavHandler::addDavElement( doc, root, "prop" ); - WebdavHandler::addDavElement( doc, prop, "getcontentlength"); - WebdavHandler::addDavElement( doc, prop, "getlastmodified" ); - WebdavHandler::addDavElement( doc, prop, "displayname" ); - WebdavHandler::addDavElement( doc, prop, "resourcetype" ); - prop.appendChild( doc.createElementNS( "http://apache.org/dav/props/", "executable" ) ); - return doc; -} diff --git a/tdeioslaves/opengroupware/webdavhandler.h b/tdeioslaves/opengroupware/webdavhandler.h deleted file mode 100644 index a86332a32..000000000 --- a/tdeioslaves/opengroupware/webdavhandler.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of tdepim. - - Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -#ifndef WEBDAVHANDLER_H -#define WEBDAVHANDLER_H - -#include <tqvaluelist.h> -#include <tqstring.h> -#include <tqdatetime.h> -#include <tqdom.h> - -class WebdavHandler -{ - public: - WebdavHandler(); - - - static TQDomElement addElement( TQDomDocument &, TQDomNode &, - const TQString &tag ); - static TQDomElement addDavElement( TQDomDocument &, TQDomNode &, - const TQString &tag ); - static TQDomElement addSloxElement( TQDomDocument &, TQDomNode &, - const TQString &tag, - const TQString &text = TQString() ); - static TQDomDocument createAllPropsRequest(); -}; - -#endif diff --git a/tdeioslaves/sieve/CMakeLists.txt b/tdeioslaves/sieve/CMakeLists.txt deleted file mode 100644 index 7e6628c83..000000000 --- a/tdeioslaves/sieve/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -################################################# -# -# (C) 2010-2011 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/libtdepim - ${TDE_INCLUDE_DIR} - ${TQT_INCLUDE_DIRS} -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### other data ################################ - -install( FILES sieve.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) - - -##### tdeio_sieve (module) ######################## - -tde_add_kpart( tdeio_sieve - SOURCES sieve.cpp - LINK tdeio-shared ${SASL_LIBRARY} - DESTINATION ${PLUGIN_INSTALL_DIR} -) diff --git a/tdeioslaves/sieve/Makefile.am b/tdeioslaves/sieve/Makefile.am deleted file mode 100644 index 0db2e374d..000000000 --- a/tdeioslaves/sieve/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(all_includes) - -kde_module_LTLIBRARIES = tdeio_sieve.la - -tdeio_sieve_la_SOURCES = sieve.cpp -tdeio_sieve_la_LIBADD = $(LIB_TDEIO) $(SASL2_LIBS) $(LIB_QT) $(LIB_TDECORE) -tdeio_sieve_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) - -noinst_HEADERS = sieve.h - -kdelnk_DATA = sieve.protocol -kdelnkdir = $(kde_servicesdir) - -messages: - $(XGETTEXT) *.cpp -o $(podir)/tdeio_sieve.pot diff --git a/tdeioslaves/sieve/configure.in.in b/tdeioslaves/sieve/configure.in.in deleted file mode 100644 index ffc1b4b7e..000000000 --- a/tdeioslaves/sieve/configure.in.in +++ /dev/null @@ -1,18 +0,0 @@ -AC_MSG_CHECKING(if we need to talk to broken timsieved's) -AC_ARG_ENABLE(broken-timsieved-workaround, -[AC_HELP_STRING([--enable-broken-timsieved-workaround], - [versions <= 1.1.0 of the timsieved (part of the Cyrus - IMAP suite) do not interpret the HAVESPACE command of - the sieve protocol. This option makes the sieve - TDEIO::Slave simply omit that command.])], -[case "${enableval}" in - yes) AC_MSG_RESULT(yes) - need_broken_timsieved_support="yes" ;; - no) AC_MSG_RESULT(no) ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-broken-timsieved-workaround]) ;; -esac],[AC_MSG_RESULT(no)]) - -if test "$need_broken_timsieved_support" = "yes"; then - AC_SUBST(HAVE_BROKEN_TIMSIEVED) - AC_DEFINE(HAVE_BROKEN_TIMSIEVED,1,[Define if the sieve TDEIO::Slave must be able to talk to timsieved <= 1.1.0]) -fi diff --git a/tdeioslaves/sieve/draft-daboo-sieve-include.txt b/tdeioslaves/sieve/draft-daboo-sieve-include.txt deleted file mode 100644 index 83a08dfb8..000000000 --- a/tdeioslaves/sieve/draft-daboo-sieve-include.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-daboo-sieve-include.txt diff --git a/tdeioslaves/sieve/draft-daboo-sieve-spamtest.txt b/tdeioslaves/sieve/draft-daboo-sieve-spamtest.txt deleted file mode 100644 index 8f22e5607..000000000 --- a/tdeioslaves/sieve/draft-daboo-sieve-spamtest.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-daboo-sieve-spamtest.txt diff --git a/tdeioslaves/sieve/draft-degener-sieve-body-00.txt b/tdeioslaves/sieve/draft-degener-sieve-body-00.txt deleted file mode 100644 index 7b1ee844e..000000000 --- a/tdeioslaves/sieve/draft-degener-sieve-body-00.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-degener-sieve-body-00.txt diff --git a/tdeioslaves/sieve/draft-degener-sieve-copy.txt b/tdeioslaves/sieve/draft-degener-sieve-copy.txt deleted file mode 100644 index 8c23855c8..000000000 --- a/tdeioslaves/sieve/draft-degener-sieve-copy.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-degener-sieve-copy.txt diff --git a/tdeioslaves/sieve/draft-degener-sieve-editheader.txt b/tdeioslaves/sieve/draft-degener-sieve-editheader.txt deleted file mode 100644 index 6e9674f9d..000000000 --- a/tdeioslaves/sieve/draft-degener-sieve-editheader.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-degener-sieve-editheader.txt diff --git a/tdeioslaves/sieve/draft-degener-sieve-multiscript.txt b/tdeioslaves/sieve/draft-degener-sieve-multiscript.txt deleted file mode 100644 index 53a838226..000000000 --- a/tdeioslaves/sieve/draft-degener-sieve-multiscript.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-degener-sieve-multiscript.txt diff --git a/tdeioslaves/sieve/draft-homme-sieve-variables.txt b/tdeioslaves/sieve/draft-homme-sieve-variables.txt deleted file mode 100644 index cccaa59c8..000000000 --- a/tdeioslaves/sieve/draft-homme-sieve-variables.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-homme-sieve-variables.txt diff --git a/tdeioslaves/sieve/draft-martin-managesieve-04.txt b/tdeioslaves/sieve/draft-martin-managesieve-04.txt deleted file mode 100644 index 82684ad57..000000000 --- a/tdeioslaves/sieve/draft-martin-managesieve-04.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-martin-managesieve-04.txt diff --git a/tdeioslaves/sieve/draft-martin-sieve-notify-01.txt b/tdeioslaves/sieve/draft-martin-sieve-notify-01.txt deleted file mode 100644 index 6eb1cac33..000000000 --- a/tdeioslaves/sieve/draft-martin-sieve-notify-01.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-martin-sieve-notify-01.txt diff --git a/tdeioslaves/sieve/draft-melnikov-sieve-imapflags.txt b/tdeioslaves/sieve/draft-melnikov-sieve-imapflags.txt deleted file mode 100644 index 71cfbb3ce..000000000 --- a/tdeioslaves/sieve/draft-melnikov-sieve-imapflags.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-melnikov-sieve-imapflags.txt diff --git a/tdeioslaves/sieve/draft-murchison-sieve-regex-06.txt b/tdeioslaves/sieve/draft-murchison-sieve-regex-06.txt deleted file mode 100644 index b3e922ee8..000000000 --- a/tdeioslaves/sieve/draft-murchison-sieve-regex-06.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-murchison-sieve-regex-06.txt diff --git a/tdeioslaves/sieve/draft-murchison-sieve-subaddress-05.txt b/tdeioslaves/sieve/draft-murchison-sieve-subaddress-05.txt deleted file mode 100644 index 95cea85a7..000000000 --- a/tdeioslaves/sieve/draft-murchison-sieve-subaddress-05.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-murchison-sieve-subaddress-05.txt diff --git a/tdeioslaves/sieve/draft-showalter-sieve-vacation-04.txt b/tdeioslaves/sieve/draft-showalter-sieve-vacation-04.txt deleted file mode 100644 index bd2d33593..000000000 --- a/tdeioslaves/sieve/draft-showalter-sieve-vacation-04.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/draft-showalter-sieve-vacation-04.txt diff --git a/tdeioslaves/sieve/rfc3028.txt b/tdeioslaves/sieve/rfc3028.txt deleted file mode 100644 index b861e2e14..000000000 --- a/tdeioslaves/sieve/rfc3028.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/rfc3028.txt diff --git a/tdeioslaves/sieve/rfc3431.txt b/tdeioslaves/sieve/rfc3431.txt deleted file mode 100644 index 3f11c3259..000000000 --- a/tdeioslaves/sieve/rfc3431.txt +++ /dev/null @@ -1 +0,0 @@ -http://ktown.kde.org/~dirk/sieve/rfc3431.txt diff --git a/tdeioslaves/sieve/sieve.cpp b/tdeioslaves/sieve/sieve.cpp deleted file mode 100644 index b36336400..000000000 --- a/tdeioslaves/sieve/sieve.cpp +++ /dev/null @@ -1,1343 +0,0 @@ -/*************************************************************************** - sieve.cpp - description - ------------------- - begin : Thu Dec 20 18:47:08 EST 2001 - copyright : (C) 2001 by Hamish Rodda - email : meddie@yoyo.cc.monash.edu.au - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - ***************************************************************************/ - -/** - * Portions adapted from the SMTP ioslave. - * Copyright (c) 2000, 2001 Alex Zepeda <jazepeda@pacbell.net> - * Copyright (c) 2001 Michael Häckel <Michael@Haeckel.Net> - * All rights reserved. - * - * Policy: the function where the error occurs calls error(). A result of - * false, where it signifies an error, thus doesn't need to call error() itself. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -extern "C" { -#include <sasl/sasl.h> -} -#include "sieve.h" - -#include <kdebug.h> -#include <kinstance.h> -#include <tdelocale.h> -#include <kurl.h> -#include <kmdcodec.h> -#include <tdeglobal.h> -#include <tdemessagebox.h> - -#include <tqcstring.h> -#include <tqregexp.h> - -#include <cstdlib> -using std::exit; -#include <sys/stat.h> -#include <cassert> - -#include <tdepimmacros.h> - -static const int debugArea = 7122; - -static inline -#ifdef NDEBUG - kndbgstream ksDebug() { return kdDebug( debugArea ); } - kndbgstream ksDebug( bool cond ) { return kdDebug( cond, debugArea ); } -#else - kdbgstream ksDebug() { return kdDebug( debugArea ); } - kdbgstream ksDebug( bool cond ) { return kdDebug( cond, debugArea ); } -#endif - -#define SIEVE_DEFAULT_PORT 2000 - -static sasl_callback_t callbacks[] = { - { SASL_CB_ECHOPROMPT, NULL, NULL }, - { SASL_CB_NOECHOPROMPT, NULL, NULL }, - { SASL_CB_GETREALM, NULL, NULL }, - { SASL_CB_USER, NULL, NULL }, - { SASL_CB_AUTHNAME, NULL, NULL }, - { SASL_CB_PASS, NULL, NULL }, - { SASL_CB_CANON_USER, NULL, NULL }, - { SASL_CB_LIST_END, NULL, NULL } -}; - -static const unsigned int SIEVE_DEFAULT_RECIEVE_BUFFER = 512; - -using namespace TDEIO; -extern "C" -{ - KDE_EXPORT int kdemain(int argc, char **argv) - { - TDEInstance instance("tdeio_sieve" ); - - ksDebug() << "*** Starting tdeio_sieve " << endl; - - if (argc != 4) { - ksDebug() << "Usage: tdeio_sieve protocol domain-socket1 domain-socket2" << endl; - exit(-1); - } - - if ( sasl_client_init( NULL ) != SASL_OK ) { - fprintf(stderr, "SASL library initialization failed!\n"); - ::exit (-1); - } - - tdeio_sieveProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - sasl_done(); - - ksDebug() << "*** tdeio_sieve Done" << endl; - return 0; - } -} - -/* ---------------------------------------------------------------------------------- */ -tdeio_sieveResponse::tdeio_sieveResponse() -{ - clear(); -} - -/* ---------------------------------------------------------------------------------- */ -const uint& tdeio_sieveResponse::getType() const -{ - return rType; -} - -/* ---------------------------------------------------------------------------------- */ -const uint tdeio_sieveResponse::getQuantity() const -{ - return quantity; -} - -/* ---------------------------------------------------------------------------------- */ -const TQCString& tdeio_sieveResponse::getAction() const -{ - return key; -} - -/* ---------------------------------------------------------------------------------- */ -const TQCString& tdeio_sieveResponse::getKey() const -{ - return key; -} - -/* ---------------------------------------------------------------------------------- */ -const TQCString& tdeio_sieveResponse::getVal() const -{ - return val; -} - -/* ---------------------------------------------------------------------------------- */ -const TQCString& tdeio_sieveResponse::getExtra() const -{ - return extra; -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::setQuantity(const uint& newTQty) -{ - rType = QUANTITY; - quantity = newTQty; -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::setAction(const TQCString& newAction) -{ - rType = ACTION; - key = newAction.copy(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::setKey(const TQCString& newKey) -{ - rType = KEY_VAL_PAIR; - key = newKey.copy(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::setVal(const TQCString& newVal) -{ - val = newVal.copy(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::setExtra(const TQCString& newExtra) -{ - extra = newExtra.copy(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveResponse::clear() -{ - rType = NONE; - extra = key = val = TQCString(""); - quantity = 0; -} - -/* ---------------------------------------------------------------------------------- */ -tdeio_sieveProtocol::tdeio_sieveProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : TCPSlaveBase( SIEVE_DEFAULT_PORT, "sieve", pool_socket, app_socket, false) - , m_connMode(NORMAL) - , m_supportsTLS(false) - , m_shouldBeConnected(false) - , m_allowUnencrypted(false) -{ -} - -/* ---------------------------------------------------------------------------------- */ -tdeio_sieveProtocol::~tdeio_sieveProtocol() -{ - if ( isConnectionValid() ) - disconnect(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::setHost (const TQString &host, int port, const TQString &user, const TQString &pass) -{ - if ( isConnectionValid() && - ( m_sServer != host || - m_iPort != port || - m_sUser != user || - m_sPass != pass ) ) { - disconnect(); - } - m_sServer = host; - m_iPort = port ? port : m_iDefaultPort; - m_sUser = user; - m_sPass = pass; - m_supportsTLS = false; -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::openConnection() -{ - m_connMode = CONNECTION_ORIENTED; - connect(); -} - -bool tdeio_sieveProtocol::parseCapabilities(bool requestCapabilities/* = false*/) -{ - ksDebug() << k_funcinfo << endl; - - // Setup... - bool ret = false; - - if (requestCapabilities) { - sendData("CAPABILITY"); - } - - while (receiveData()) { - ksDebug() << "Looping receive" << endl; - - if (r.getType() == tdeio_sieveResponse::ACTION) { - if ( r.getAction().contains("ok", false) != -1 ) { - ksDebug() << "Sieve server ready & awaiting authentication." << endl; - break; - } else - ksDebug() << "Unknown action " << r.getAction() << "." << endl; - - } else if (r.getKey() == "IMPLEMENTATION") { - if (r.getVal().contains("sieve", false) != -1) { - ksDebug() << "Connected to Sieve server: " << r.getVal() << endl; - ret = true; - setMetaData("implementation", r.getVal()); - m_implementation = r.getVal(); - } - - } else if (r.getKey() == "SASL") { - // Save list of available SASL methods - m_sasl_caps = TQStringList::split(' ', r.getVal()); - ksDebug() << "Server SASL authentication methods: " << m_sasl_caps.join(", ") << endl; - setMetaData("saslMethods", r.getVal()); - - } else if (r.getKey() == "SIEVE") { - // Save script capabilities; report back as meta data: - ksDebug() << "Server script capabilities: " << TQStringList::split(' ', r.getVal()).join(", ") << endl; - setMetaData("sieveExtensions", r.getVal()); - - } else if (r.getKey() == "STARTTLS") { - // The server supports TLS - ksDebug() << "Server supports TLS" << endl; - m_supportsTLS = true; - setMetaData("tlsSupported", "true"); - - } else { - ksDebug() << "Unrecognised key." << endl; - } - } - - if (!m_supportsTLS) { - setMetaData("tlsSupported", "false"); - } - - return ret; -} - - -/* ---------------------------------------------------------------------------------- */ -/** - * Checks if connection parameters have changed. - * If it it, close the current connection - */ -void tdeio_sieveProtocol::changeCheck( const KURL &url ) -{ - TQString auth; - - if (!metaData("sasl").isEmpty()) - auth = metaData("sasl").upper(); - else { - TQString query = url.query(); - if ( query.startsWith("?") ) query.remove( 0, 1 ); - TQStringList q = TQStringList::split( ",", query ); - TQStringList::iterator it; - - for ( it = q.begin(); it != q.end(); ++it ) { - if ( TQString( (*it).section('=',0,0) ).lower() == "x-mech" ) { - auth = TQString( (*it).section('=',1) ).upper(); - break; - } - } - } - ksDebug() << "auth: " << auth << " m_sAuth: " << m_sAuth << endl; - if ( m_sAuth != auth ) { - m_sAuth = auth; - if ( isConnectionValid() ) - disconnect(); - } - - // For TLS, only disconnect if we are unencrypted and are - // no longer allowed (otherwise, it's still fine): - const bool allowUnencryptedNow = url.queryItem("x-allow-unencrypted") == "true" ; - if ( m_allowUnencrypted && !allowUnencryptedNow ) - if ( isConnectionValid() ) - disconnect(); - m_allowUnencrypted = allowUnencryptedNow; -} - -/* ---------------------------------------------------------------------------------- */ -/** - * Connects to the server. - * returns false and calls error() if an error occurred. - */ -bool tdeio_sieveProtocol::connect(bool useTLSIfAvailable) -{ - ksDebug() << k_funcinfo << endl; - - if (isConnectionValid()) return true; - - infoMessage(i18n("Connecting to %1...").arg( m_sServer)); - - if (m_connMode == CONNECTION_ORIENTED && m_shouldBeConnected) { - error(ERR_CONNECTION_BROKEN, i18n("The connection to the server was lost.")); - return false; - } - - setBlockConnection(true); - - if (!connectToHost(m_sServer, m_iPort, true)) { - return false; - } - - if (!parseCapabilities()) { - closeDescriptor(); - error(ERR_UNSUPPORTED_PROTOCOL, i18n("Server identification failed.")); - return false; - } - - // Attempt to start TLS - if ( !m_allowUnencrypted && !canUseTLS() ) { - error( ERR_SLAVE_DEFINED, i18n("Can not use TLS. Please enable TLS in the TDE cryptography setting.") ); - disconnect(); - return false; - } - - if ( !m_allowUnencrypted && useTLSIfAvailable && canUseTLS() && !m_supportsTLS && - messageBox( WarningContinueCancel, - i18n("TLS encryption was requested, but your Sieve server does not advertise TLS in its capabilities.\n" - "You can choose to try to initiate TLS negotiations nonetheless, or cancel the operation."), - i18n("Server Does Not Advertise TLS"), i18n("&Start TLS nonetheless"), i18n("&Cancel") ) != KMessageBox::Continue ) - { - error( ERR_USER_CANCELED, i18n("TLS encryption requested, but not supported by server.") ); - disconnect(); - return false; - } - - // FIXME find a test server and test that this works - if (useTLSIfAvailable && canUseTLS()) { - sendData("STARTTLS"); - if (operationSuccessful()) { - ksDebug() << "TLS has been accepted. Starting TLS..." << endl - << "WARNING this is untested and may fail." << endl; - int retval = startTLS(); - if (retval == 1) { - ksDebug() << "TLS enabled successfully." << endl; - // reparse capabilities: - parseCapabilities( requestCapabilitiesAfterStartTLS() ); - } else { - ksDebug() << "TLS initiation failed, code " << retval << endl; - if ( m_allowUnencrypted ) { - disconnect(true); - return connect(false); - } - if ( retval != -3 ) - messageBox( Information, - i18n("Your Sieve server claims to support TLS, " - "but negotiation was unsuccessful."), - i18n("Connection Failed") ); - disconnect(true); - return false; - } - } else if ( !m_allowUnencrypted ) { - ksDebug() << "Server incapable of TLS." << endl; - disconnect(); - error( ERR_SLAVE_DEFINED, i18n("The server does not seem to support TLS. " - "Disable TLS if you want to connect without encryption.") ); - return false; - } else - ksDebug() << "Server incapable of TLS. Transmitted documents will be unencrypted." << endl; - } else - ksDebug() << "We are incapable of TLS. Transmitted documents will be unencrypted." << endl; - - assert( m_allowUnencrypted || usingTLS() ); - - infoMessage(i18n("Authenticating user...")); - if (!authenticate()) { - disconnect(); - error(ERR_COULD_NOT_AUTHENTICATE, i18n("Authentication failed.")); - return false; - } - - m_shouldBeConnected = true; - return true; -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::closeConnection() -{ - m_connMode = CONNECTION_ORIENTED; - disconnect(); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::disconnect(bool forcibly) -{ - if (!forcibly) { - sendData("LOGOUT"); - - // This crashes under certain conditions as described in - // http://intevation.de/roundup/kolab/issue2442 - // Fixing TDEIO::TCPSlaveBase::atEnd() for !fd would also work but 3.x is on life support. - //if (!operationSuccessful()) - // ksDebug() << "Server did not logout cleanly." << endl; - } - - closeDescriptor(); - m_shouldBeConnected = false; -} - -/* ---------------------------------------------------------------------------------- */ -/*void tdeio_sieveProtocol::slave_status() -{ - slaveStatus(isConnectionValid() ? m_sServer : "", isConnectionValid()); - - finished(); -}*/ - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::special(const TQByteArray &data) -{ - int tmp; - TQDataStream stream(data, IO_ReadOnly); - KURL url; - - stream >> tmp; - - switch (tmp) { - case 1: - stream >> url; - if (!activate(url)) - return; - break; - case 2: - if (!deactivate()) - return; - break; - case 3: - parseCapabilities(true); - break; - } - - infoMessage(i18n("Done.")); - - finished(); -} - -/* ---------------------------------------------------------------------------------- */ -bool tdeio_sieveProtocol::activate(const KURL& url) -{ - changeCheck( url ); - if (!connect()) - return false; - - infoMessage(i18n("Activating script...")); - - TQString filename = url.fileName(false); - - if (filename.isEmpty()) { - error(ERR_DOES_NOT_EXIST, url.prettyURL()); - return false; - } - - if (!sendData("SETACTIVE \"" + filename.utf8() + "\"")) - return false; - - if (operationSuccessful()) { - ksDebug() << "Script activation complete." << endl; - return true; - } else { - error(ERR_INTERNAL_SERVER, i18n("There was an error activating the script.")); - return false; - } -} - -/* ---------------------------------------------------------------------------------- */ -bool tdeio_sieveProtocol::deactivate() -{ - if (!connect()) - return false; - - if (!sendData("SETACTIVE \"\"")) - return false; - - if (operationSuccessful()) { - ksDebug() << "Script deactivation complete." << endl; - return true; - } else { - error(ERR_INTERNAL_SERVER, i18n("There was an error deactivating the script.")); - return false; - } -} - -static void append_lf2crlf( TQByteArray & out, const TQByteArray & in ) { - if ( in.isEmpty() ) - return; - const unsigned int oldOutSize = out.size(); - out.resize( oldOutSize + 2 * in.size() ); - const char * s = in.begin(); - const char * const end = in.end(); - char * d = out.begin() + oldOutSize; - char last = '\0'; - while ( s < end ) { - if ( *s == '\n' && last != '\r' ) - *d++ = '\r'; - *d++ = last = *s++; - } - out.resize( d - out.begin() ); -} - -void tdeio_sieveProtocol::put(const KURL& url, int /*permissions*/, bool /*overwrite*/, bool /*resume*/) -{ - changeCheck( url ); - if (!connect()) - return; - - infoMessage(i18n("Sending data...")); - - TQString filename = url.fileName(false); - - if (filename.isEmpty()) { - error(ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - TQByteArray data; - for (;;) { - dataReq(); - TQByteArray buffer; - const int newSize = readData(buffer); - append_lf2crlf( data, buffer ); - if ( newSize < 0 ) { - // read error: network in unknown state so disconnect - error(ERR_COULD_NOT_READ, i18n("TDEIO data supply error.")); - return; - } - if ( newSize == 0 ) - break; - } - - // script size - int bufLen = (int)data.size(); - totalSize(bufLen); - - // timsieved 1.1.0: - // C: HAVESPACE "rejected" 74 - // S: NO "Number expected" - // C: HAVESPACE 74 - // S: NO "Missing script name" - // S: HAVESPACE "rejected" "74" - // C: NO "Number expected" - // => broken, we can't use it :-( - // (will be fixed in Cyrus 2.1.10) -#ifndef HAVE_BROKEN_TIMSIEVED - // first, check quota (it's a SHOULD in draft std) - if (!sendData("HAVESPACE \"" + filename.utf8() + "\" " - + TQCString().setNum( bufLen ))) - return; - - if (!operationSuccessful()) { - error(ERR_DISK_FULL, i18n("Quota exceeded")); - return; - } -#endif - - if (!sendData("PUTSCRIPT \"" + filename.utf8() + "\" {" - + TQCString().setNum( bufLen ) + "+}")) - return; - - // atEnd() lies so the code below doesn't work. - /*if (!atEnd()) { - // We are not expecting any data here, so if the server has responded - // with anything but OK we treat it as an error. - char * buf = new char[2]; - while (!atEnd()) { - ksDebug() << "Reading..." << endl; - read(buf, 1); - ksDebug() << "Trailing [" << buf[0] << "]" << endl; - } - ksDebug() << "End of data." << endl; - delete[] buf; - - if (!operationSuccessful()) { - error(ERR_UNSUPPORTED_PROTOCOL, i18n("A protocol error occurred " - "while trying to negotiate script uploading.\n" - "The server responded:\n%1") - .arg(r.getAction().right(r.getAction().length() - 3))); - return; - } - }*/ - - // upload data to the server - if (write(data, bufLen) != bufLen) { - error(ERR_COULD_NOT_WRITE, i18n("Network error.")); - disconnect(true); - return; - } - - // finishing CR/LF - if (!sendData("")) - return; - - processedSize(bufLen); - - infoMessage(i18n("Verifying upload completion...")); - - if (operationSuccessful()) - ksDebug() << "Script upload complete." << endl; - - else { - /* The managesieve server parses received scripts and rejects - * scripts which are not syntactically correct. Here we expect - * to receive a message detailing the error (only the first - * error is reported. */ - if (r.getAction().length() > 3) { - // make a copy of the extra info - TQCString extra = r.getAction().right(r.getAction().length() - 3); - - // send the extra message off for re-processing - receiveData(false, &extra); - - if (r.getType() == tdeio_sieveResponse::QUANTITY) { - // length of the error message - uint len = r.getQuantity(); - - TQCString errmsg(len + 1); - - read(errmsg.data(), len); - - error(ERR_INTERNAL_SERVER, - i18n("The script did not upload successfully.\n" - "This is probably due to errors in the script.\n" - "The server responded:\n%1").arg(TQString(errmsg))); - - // clear the rest of the incoming data - receiveData(); - } else if (r.getType() == tdeio_sieveResponse::KEY_VAL_PAIR) { - error(ERR_INTERNAL_SERVER, - i18n("The script did not upload successfully.\n" - "This is probably due to errors in the script.\n" - "The server responded:\n%1").arg(TQString(r.getKey()))); - } else - error(ERR_INTERNAL_SERVER, - i18n("The script did not upload successfully.\n" - "The script may contain errors.")); - } else - error(ERR_INTERNAL_SERVER, - i18n("The script did not upload successfully.\n" - "The script may contain errors.")); - } - - //if ( permissions != -1 ) - // chmod( url, permissions ); - - infoMessage(i18n("Done.")); - - finished(); -} - -static void inplace_crlf2lf( TQByteArray & in ) { - if ( in.isEmpty() ) - return; - TQByteArray & out = in; // inplace - const char * s = in.begin(); - const char * const end = in.end(); - char * d = out.begin(); - char last = '\0'; - while ( s < end ) { - if ( *s == '\n' && last == '\r' ) - --d; - *d++ = last = *s++; - } - out.resize( d - out.begin() ); -} - -/* ---------------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::get(const KURL& url) -{ - changeCheck( url ); - if (!connect()) - return; - - infoMessage(i18n("Retrieving data...")); - - TQString filename = url.fileName(false); - - if (filename.isEmpty()) { - error(ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - //SlaveBase::mimetype( TQString("text/plain") ); // "application/sieve"); - - if (!sendData("GETSCRIPT \"" + filename.utf8() + "\"")) - return; - - if (receiveData() && r.getType() == tdeio_sieveResponse::QUANTITY) { - // determine script size - ssize_t total_len = r.getQuantity(); - totalSize( total_len ); - - int recv_len = 0; - do { - // wait for data... - if ( !waitForResponse( 600 ) ) { - error( TDEIO::ERR_SERVER_TIMEOUT, m_sServer ); - disconnect( true ); - return; - } - - // ...read data... - // Only read as much as we need, otherwise we slurp in the OK that - // operationSuccessful() is expecting below. - TQByteArray dat( kMin( total_len - recv_len, ssize_t(64 * 1024 )) ); - ssize_t this_recv_len = read( dat.data(), dat.size() ); - - if ( this_recv_len < 1 && !isConnectionValid() ) { - error( TDEIO::ERR_CONNECTION_BROKEN, m_sServer ); - disconnect( true ); - return; - } - - dat.resize( this_recv_len ); - inplace_crlf2lf( dat ); - // send data to slaveinterface - data( dat ); - - recv_len += this_recv_len; - processedSize( recv_len ); - } while ( recv_len < total_len ); - - infoMessage(i18n("Finishing up...") ); - data(TQByteArray()); - - if (operationSuccessful()) - ksDebug() << "Script retrieval complete." << endl; - else - ksDebug() << "Script retrieval failed." << endl; - } else { - error(ERR_UNSUPPORTED_PROTOCOL, i18n("A protocol error occurred " - "while trying to negotiate script downloading.")); - return; - } - - infoMessage(i18n("Done.")); - finished(); -} - -void tdeio_sieveProtocol::del(const KURL &url, bool isfile) -{ - if (!isfile) { - error(ERR_INTERNAL, i18n("Folders are not supported.")); - return; - } - - changeCheck( url ); - if (!connect()) - return; - - infoMessage(i18n("Deleting file...")); - - TQString filename = url.fileName(false); - - if (filename.isEmpty()) { - error(ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - if (!sendData("DELETESCRIPT \"" + filename.utf8() + "\"")) - return; - - if (operationSuccessful()) - ksDebug() << "Script deletion successful." << endl; - else { - error(ERR_INTERNAL_SERVER, i18n("The server would not delete the file.")); - return; - } - - infoMessage(i18n("Done.")); - - finished(); -} - -void tdeio_sieveProtocol::chmod(const KURL& url, int permissions) -{ - switch ( permissions ) { - case 0700: // activate - activate(url); - break; - case 0600: // deactivate - deactivate(); - break; - default: // unsupported - error(ERR_CANNOT_CHMOD, i18n("Cannot chmod to anything but 0700 (active) or 0600 (inactive script).")); - return; - } - - finished(); -} - -#if defined(_AIX) && defined(stat) -#undef stat -#endif - -void tdeio_sieveProtocol::stat(const KURL& url) -{ - changeCheck( url ); - if (!connect()) - return; - - UDSEntry entry; - - TQString filename = url.fileName(false); - - if (filename.isEmpty()) { - UDSAtom atom; - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = "/"; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = 0700; - entry.append(atom); - - statEntry(entry); - - } else { - if (!sendData("LISTSCRIPTS")) - return; - - while(receiveData()) { - if (r.getType() == tdeio_sieveResponse::ACTION) { - if (r.getAction().contains("OK", false) == 1) - // Script list completed - break; - - } else - if (filename == TQString::fromUtf8(r.getKey())) { - entry.clear(); - - UDSAtom atom; - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = TQString::fromUtf8(r.getKey()); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - if ( r.getExtra() == "ACTIVE" ) - atom.m_long = 0700; // mark exec'able - else - atom.m_long = 0600; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MIME_TYPE; - atom.m_str = "application/sieve"; - entry.append(atom); - - //setMetaData("active", (r.getExtra() == "ACTIVE") ? "yes" : "no"); - - statEntry(entry); - // cannot break here because we need to clear - // the rest of the incoming data. - } - } - } - - finished(); -} - -void tdeio_sieveProtocol::listDir(const KURL& url) -{ - changeCheck( url ); - if (!connect()) - return; - - if (!sendData("LISTSCRIPTS")) - return; - - UDSEntry entry; - - while(receiveData()) { - if (r.getType() == tdeio_sieveResponse::ACTION) { - if (r.getAction().contains("OK", false) == 1) - // Script list completed. - break; - - } else { - entry.clear(); - - UDSAtom atom; - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = TQString::fromUtf8(r.getKey()); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - if ( r.getExtra() == "ACTIVE" ) - atom.m_long = 0700; // mark exec'able - else - atom.m_long = 0600; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MIME_TYPE; - atom.m_str = "application/sieve"; - entry.append(atom); - - //asetMetaData("active", (r.getExtra() == "ACTIVE") ? "true" : "false"); - - ksDebug() << "Listing script " << r.getKey() << endl; - listEntry(entry , false); - } - } - - listEntry(entry, true); - - finished(); -} - -/* ---------------------------------------------------------------------------------- */ -bool tdeio_sieveProtocol::saslInteract( void *in, AuthInfo &ai ) -{ - ksDebug() << "sasl_interact" << endl; - sasl_interact_t *interact = ( sasl_interact_t * ) in; - - //some mechanisms do not require username && pass, so it doesn't need a popup - //window for getting this info - for ( ; interact->id != SASL_CB_LIST_END; interact++ ) { - if ( interact->id == SASL_CB_AUTHNAME || - interact->id == SASL_CB_PASS ) { - - if (m_sUser.isEmpty() || m_sPass.isEmpty()) { - if (!openPassDlg(ai)) { - error(ERR_ABORTED, i18n("No authentication details supplied.")); - return false; - } - m_sUser = ai.username; - m_sPass = ai.password; - } - break; - } - } - - interact = ( sasl_interact_t * ) in; - while( interact->id != SASL_CB_LIST_END ) { - ksDebug() << "SASL_INTERACT id: " << interact->id << endl; - switch( interact->id ) { - case SASL_CB_USER: - case SASL_CB_AUTHNAME: - ksDebug() << "SASL_CB_[AUTHNAME|USER]: '" << m_sUser << "'" << endl; - interact->result = strdup( m_sUser.utf8() ); - interact->len = strlen( (const char *) interact->result ); - break; - case SASL_CB_PASS: - ksDebug() << "SASL_CB_PASS: [hidden] " << endl; - interact->result = strdup( m_sPass.utf8() ); - interact->len = strlen( (const char *) interact->result ); - break; - default: - interact->result = NULL; interact->len = 0; - break; - } - interact++; - } - return true; -} - -#define SASLERROR error(ERR_COULD_NOT_AUTHENTICATE, i18n("An error occurred during authentication: %1").arg( \ - TQString::fromUtf8( sasl_errdetail( conn ) ))); - -bool tdeio_sieveProtocol::authenticate() -{ - int result; - sasl_conn_t *conn = NULL; - sasl_interact_t *client_interact = NULL; - const char *out = NULL; - uint outlen; - const char *mechusing = NULL; - TQByteArray challenge, tmp; - - /* Retrieve authentication details from user. - * Note: should this require realm as well as user & pass details - * before it automatically skips the prompt? - * Note2: encoding issues with PLAIN login? */ - AuthInfo ai; - ai.url.setProtocol("sieve"); - ai.url.setHost(m_sServer); - ai.url.setPort(m_iPort); - ai.username = m_sUser; - ai.password = m_sPass; - ai.keepPassword = true; - ai.caption = i18n("Sieve Authentication Details"); - ai.comment = i18n("Please enter your authentication details for your sieve account " - "(usually the same as your email password):"); - - result = sasl_client_new( "sieve", - m_sServer.latin1(), - 0, 0, callbacks, 0, &conn ); - - if ( result != SASL_OK ) { - ksDebug() << "sasl_client_new failed with: " << result << endl; - SASLERROR - return false; - } - - TQStringList strList; -// strList.append("NTLM"); - - if ( !m_sAuth.isEmpty() ) - strList.append( m_sAuth ); - else - strList = m_sasl_caps; - - do { - result = sasl_client_start(conn, strList.join(" ").latin1(), &client_interact, - &out, &outlen, &mechusing); - - if (result == SASL_INTERACT) - if ( !saslInteract( client_interact, ai ) ) { - sasl_dispose( &conn ); - return false; - }; - } while ( result == SASL_INTERACT ); - - if ( result != SASL_CONTINUE && result != SASL_OK ) { - ksDebug() << "sasl_client_start failed with: " << result << endl; - SASLERROR - sasl_dispose( &conn ); - return false; - } - - ksDebug() << "Preferred authentication method is " << mechusing << "." << endl; - - TQString firstCommand = "AUTHENTICATE \"" + TQString::fromLatin1( mechusing ) + "\""; - tmp.setRawData( out, outlen ); - KCodecs::base64Encode( tmp, challenge ); - tmp.resetRawData( out, outlen ); - if ( !challenge.isEmpty() ) { - firstCommand += " \""; - firstCommand += TQString::fromLatin1( challenge.data(), challenge.size() ); - firstCommand += "\""; - } - - if (!sendData( firstCommand.latin1() )) - return false; - - TQCString command; - - do { - receiveData(); - - if (operationResult() != OTHER) - break; - - ksDebug() << "Challenge len " << r.getQuantity() << endl; - - if (r.getType() != tdeio_sieveResponse::QUANTITY) { - sasl_dispose( &conn ); - error(ERR_SLAVE_DEFINED, - i18n("A protocol error occurred during authentication.\n" - "Choose a different authentication method to %1.").arg(mechusing)); - return false; - } - - uint qty = r.getQuantity(); - - receiveData(); - - if (r.getType() != tdeio_sieveResponse::ACTION && r.getAction().length() != qty) { - sasl_dispose( &conn ); - error(ERR_UNSUPPORTED_PROTOCOL, - i18n("A protocol error occurred during authentication.\n" - "Choose a different authentication method to %1.").arg(mechusing)); - return false; - } - - tmp.setRawData( r.getAction().data(), qty ); - KCodecs::base64Decode( tmp, challenge ); - tmp.resetRawData( r.getAction().data(), qty ); -// ksDebug() << "S: [" << r.getAction() << "]." << endl; -// ksDebug() << "S-1: [" << TQCString(challenge.data(), challenge.size()+1) << "]." << endl; - - do { - result = sasl_client_step(conn, challenge.isEmpty() ? 0 : challenge.data(), - challenge.size(), - &client_interact, - &out, &outlen); - - if (result == SASL_INTERACT) - if ( !saslInteract( client_interact, ai ) ) { - sasl_dispose( &conn ); - return false; - }; - } while ( result == SASL_INTERACT ); - - ksDebug() << "sasl_client_step: " << result << endl; - if ( result != SASL_CONTINUE && result != SASL_OK ) { - ksDebug() << "sasl_client_step failed with: " << result << endl; - SASLERROR - sasl_dispose( &conn ); - return false; - } - - tmp.setRawData( out, outlen ); - KCodecs::base64Encode( tmp, challenge ); - tmp.resetRawData( out, outlen ); - sendData("\"" + TQCString( challenge.data(), challenge.size()+1 ) + "\""); -// ksDebug() << "C: [" << TQCString(challenge.data(), challenge.size()+1) << "]." << endl; -// ksDebug() << "C-1: [" << out << "]." << endl; - } while ( true ); - - ksDebug() << "Challenges finished." << endl; - sasl_dispose( &conn ); - - if (operationResult() == OK) { - // Authentication succeeded. - return true; - } else { - // Authentication failed. - error(ERR_COULD_NOT_AUTHENTICATE, i18n("Authentication failed.\nMost likely the password is wrong.\nThe server responded:\n%1").arg( TQString(r.getAction()) ) ); - return false; - } -} - -/* --------------------------------------------------------------------------- */ -void tdeio_sieveProtocol::mimetype(const KURL & url) -{ - ksDebug() << "Requesting mimetype for " << url.prettyURL() << endl; - - if (url.fileName(false).isEmpty()) - mimeType( "inode/directory" ); - else - mimeType( "application/sieve" ); - - finished(); -} - - -/* --------------------------------------------------------------------------- */ -bool tdeio_sieveProtocol::sendData(const TQCString &data) -{ - TQCString write_buf = data + "\r\n"; - - //ksDebug() << "C: " << data << endl; - - // Write the command - ssize_t write_buf_len = write_buf.length(); - if (write(write_buf.data(), write_buf_len) != write_buf_len) { - error(ERR_COULD_NOT_WRITE, i18n("Network error.")); - disconnect(true); - return false; - } - - return true; -} - -/* --------------------------------------------------------------------------- */ -bool tdeio_sieveProtocol::receiveData(bool waitForData, TQCString *reparse) -{ - TQCString interpret; - int start, end; - - if (!reparse) { - if (!waitForData) - // is there data waiting? - if (atEnd()) return false; - - // read data from the server - char buffer[SIEVE_DEFAULT_RECIEVE_BUFFER]; - readLine(buffer, SIEVE_DEFAULT_RECIEVE_BUFFER - 1); - buffer[SIEVE_DEFAULT_RECIEVE_BUFFER-1] = '\0'; - - // strip LF/CR - interpret = TQCString(buffer).left(tqstrlen(buffer) - 2); - - } else { - interpret = reparse->copy(); - } - - r.clear(); - - //ksDebug() << "S: " << interpret << endl; - - switch(interpret[0]) { - case '{': - { - // expecting {quantity} - start = 0; - end = interpret.find("+}", start + 1); - // some older versions of Cyrus enclose the literal size just in { } instead of { +} - if ( end == -1 ) - end = interpret.find('}', start + 1); - - bool ok = false; - r.setQuantity(interpret.mid(start + 1, end - start - 1).toUInt( &ok )); - if (!ok) { - disconnect(); - error(ERR_INTERNAL_SERVER, i18n("A protocol error occurred.")); - return false; - } - - return true; - } - case '"': - // expecting "key" "value" pairs - break; - default: - // expecting single string - r.setAction(interpret); - return true; - } - - start = 0; - - end = interpret.find(34, start + 1); - if (end == -1) { - ksDebug() << "Possible insufficient buffer size." << endl; - r.setKey(interpret.right(interpret.length() - start)); - return true; - } - - r.setKey(interpret.mid(start + 1, end - start - 1)); - - start = interpret.find(34, end + 1); - if (start == -1) { - if ((int)interpret.length() > end) - // skip " and space - r.setExtra(interpret.right(interpret.length() - end - 2)); - - return true; - } - - end = interpret.find(34, start + 1); - if (end == -1) { - ksDebug() << "Possible insufficient buffer size." << endl; - r.setVal(interpret.right(interpret.length() - start)); - return true; - } - - r.setVal(interpret.mid(start + 1, end - start - 1)); - return true; -} - -bool tdeio_sieveProtocol::operationSuccessful() -{ - while (receiveData(false)) { - if (r.getType() == tdeio_sieveResponse::ACTION) { - TQCString response = r.getAction().left(2); - if (response == "OK") { - return true; - } else if (response == "NO") { - return false; - } - } - } - return false; -} - -int tdeio_sieveProtocol::operationResult() -{ - if (r.getType() == tdeio_sieveResponse::ACTION) { - TQCString response = r.getAction().left(2); - if (response == "OK") { - return OK; - } else if (response == "NO") { - return NO; - } else if (response == "BY"/*E*/) { - return BYE; - } - } - - return OTHER; -} - -bool tdeio_sieveProtocol::requestCapabilitiesAfterStartTLS() const -{ - // Cyrus didn't send CAPABILITIES after STARTTLS until 2.3.11, which is - // not standard conform, but we need to support that anyway. - // m_implementation looks like this 'Cyrus timsieved v2.2.12' for Cyrus btw. - TQRegExp regExp( "Cyrus\\stimsieved\\sv(\\d+)\\.(\\d+)\\.(\\d+)([-\\w]*)", false ); - if ( regExp.search( m_implementation ) >= 0 ) { - const int major = regExp.cap( 1 ).toInt(); - const int minor = regExp.cap( 2 ).toInt(); - const int patch = regExp.cap( 3 ).toInt(); - const TQString vendor = regExp.cap( 4 ); - if ( major < 2 || (major == 2 && (minor < 3 || (minor == 3 && patch < 11))) || (vendor == "-kolab-nocaps") ) { - ksDebug() << k_funcinfo << "Enabling compat mode for Cyrus < 2.3.11 or Cyrus marked as \"kolab-nocaps\"" << endl; - return true; - } - } - return false; -} diff --git a/tdeioslaves/sieve/sieve.h b/tdeioslaves/sieve/sieve.h deleted file mode 100644 index 09cf3060b..000000000 --- a/tdeioslaves/sieve/sieve.h +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************** - sieve.h - description - ------------------- - begin : Thu Dec 20 18:47:08 EST 2001 - copyright : (C) 2001 by Hamish Rodda - email : meddie@yoyo.cc.monash.edu.au - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - ***************************************************************************/ -#ifndef __sieve_h__ -#define __sieve_h__ - -#include <tdeio/tcpslavebase.h> -#include <tdeio/authinfo.h> - -#include <tqstring.h> -#include <tqcstring.h> -#include <tqstringlist.h> - -class KDESasl; -class KURL; - - -class tdeio_sieveResponse -{ -public: - enum responses { NONE, KEY_VAL_PAIR, ACTION, QUANTITY }; - - tdeio_sieveResponse(); - - const uint& getType() const; - - const TQCString& getAction() const; - const uint getQuantity() const; - const TQCString& getKey() const; - const TQCString& getVal() const; - const TQCString& getExtra() const; - - void setQuantity(const uint& quantity); - void setAction(const TQCString& newAction); - void setKey(const TQCString& newKey); - void setVal(const TQCString& newVal); - void setExtra(const TQCString& newExtra); - - void clear(); - -protected: - uint rType; - uint quantity; - TQCString key; - TQCString val; - TQCString extra; -}; - -class tdeio_sieveProtocol : public TDEIO::TCPSlaveBase -{ - -public: - enum connectionModes { NORMAL, CONNECTION_ORIENTED }; - enum Results { OK, NO, BYE, OTHER }; - - tdeio_sieveProtocol(const TQCString &pool_socket, const TQCString &app_socket); - virtual ~tdeio_sieveProtocol(); - - virtual void mimetype(const KURL& url); - virtual void get(const KURL& url); - virtual void put(const KURL& url, int permissions, bool overwrite, bool resume); - virtual void del(const KURL &url, bool isfile); - - virtual void listDir(const KURL& url); - virtual void chmod(const KURL& url, int permissions); - virtual void stat(const KURL& url); - - virtual void setHost(const TQString &host, int port, const TQString &user, const TQString &pass); - virtual void openConnection(); - virtual void closeConnection(); - //virtual void slave_status(); - - /** - * Special commands supported by this slave: - * 1 - activate script - * 2 - deactivate (all - only one active at any one time) scripts - * 3 - request capabilities, returned as metadata - */ - virtual void special(const TQByteArray &data); - bool activate(const KURL& url); - bool deactivate(); - -protected: - bool connect(bool useTLSIfAvailable = true); - bool authenticate(); - void disconnect(bool forcibly = false); - void changeCheck( const KURL &url ); - - bool sendData(const TQCString &data); - bool receiveData(bool waitForData = true, TQCString *reparse = 0); - bool operationSuccessful(); - int operationResult(); - - bool parseCapabilities(bool requestCapabilities = false); - bool saslInteract( void *in, TDEIO::AuthInfo &ai ); - - // IOSlave global data - uint m_connMode; - - // Host-specific data - TQStringList m_sasl_caps; - bool m_supportsTLS; - - // Global server respose class - tdeio_sieveResponse r; - - // connection details - TQString m_sServer; - TQString m_sUser; - TQString m_sPass; - TQString m_sAuth; - bool m_shouldBeConnected; - bool m_allowUnencrypted; - -private: - bool requestCapabilitiesAfterStartTLS() const; - - TQString m_implementation; -}; - -#endif diff --git a/tdeioslaves/sieve/sieve.protocol b/tdeioslaves/sieve/sieve.protocol deleted file mode 100644 index 572c41ea9..000000000 --- a/tdeioslaves/sieve/sieve.protocol +++ /dev/null @@ -1,54 +0,0 @@ -[Protocol] -exec=tdeio_sieve -protocol=sieve -input=none -output=filesystem -listing=Name,Access,Type,MimeType, -reading=true -writing=true -makedir=false -deleting=true -linking=false -moving=false -Icon=remote -Description=An ioslave for the Sieve mail filtering protocol -Description[af]='n <i>IOSlave</i> vir die Sieve e-pos filter protokol -Description[ca]=Un ioslave pel protocol de filtrar de correu Sieve -Description[cs]=ioslave pro protokol filtrování zpráv Sieve -Description[da]=En ioslave for Sieve mail filtreringsprotokollen -Description[de]=Ein-/Ausgabemodul für das E-Mail-Filterprotokoll "Sieve" -Description[el]=Ένας ioslave για το πρωτόκολλο φιλτραρίσματος αλληλογραφίας Sieve -Description[es]=Un ioslave para el protocolo de filtrado de correo Sieve -Description[et]=Sieve e-kirjade filtreerimise protokolli IO-moodul -Description[eu]=Sieve posta iragazketa protokoloarentztko irteerako/sarrerako mendeko bat -Description[fa]=یک ioslave برای قرارداد پالایش نامۀ Sieve -Description[fi]=Siirräntätyöskentelijä Sieve-sähköpostiensuodatusyhteyskäytännölle -Description[fr]=Un ioslave pour le protocole de filtrage de messagerie Sieve -Description[fy]=In ioslave foar it Sieve-mailfilterprotokol -Description[gl]=Un esclavo io para o protocolo de filtraxe de correo Sieve -Description[hu]=KDE-protokoll a Sieve levélszűrő protokollhoz -Description[is]=Ioslave fyrir Sieve tölvupóstsíu samskiptaregluna -Description[it]=Un ioslave per il protocollo di filtraggio posta Sieve -Description[ja]=Sieve メールフィルタプロトコル用 ioslave -Description[kk]=Sieve поштаны сүзгілеу протоколының ioslave модулі -Description[km]=ioslave សម្រាប់ពិធីការត្រងសំបុត្រ Sieve -Description[ms]=Hamba io untuk protokol tapisan mel saringan -Description[nb]=En i/u-slave for e-postfilterprotokollen Sieve -Description[nds]=In-/Utgaavmoduul för't Nettpostfilter-Protokoll Sieve -Description[ne]=मेल फिल्टरिङ प्रोटोकल सिभ गर्नका लागि एउटा आइओस्लेभ -Description[nl]=Een ioslave voor het Sieve-mailfilterprotocol -Description[nn]=Ein i/u-slave for e-postfilterprotokollen Sieve -Description[pl]=Wtyczka protokołu filtrowania poczty Sieve -Description[pt]=Um 'ioslave' para o protocolo de filtragem de correio Sieve -Description[pt_BR]=Um IO-Slave para o protocolo de filtragem de email Sieve -Description[ru]=Канал протокола фильтра почты Sieve -Description[sk]=ioslave pre protokol Sieve filtrovanie pošty -Description[sl]=ioslave za protokol poštnega filtriranja Sieve -Description[sr]=IOslave протокола за филтрирање поште Sieve -Description[sr@Latn]=IOslave protokola za filtriranje pošte Sieve -Description[sv]=En I/O-slav för brevfiltreringsprotokollet Sieve -Description[ta]=Sieve அஞ்சல் வடிகட்டும் நெறிமுறைக்கான ஒரு ioslave -Description[tr]=Sieve e-posta filtreleme protokolü için bir ioslave -Description[uk]=Підлеглий В/В для протоколу фільтрування пошти Sieve -Description[zh_CN]=邮件过滤协议仆人 -DocPath=tdeioslave/sieve/index.html |