diff options
Diffstat (limited to 'kbiff/kbiffmonitor.h')
-rw-r--r-- | kbiff/kbiffmonitor.h | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/kbiff/kbiffmonitor.h b/kbiff/kbiffmonitor.h new file mode 100644 index 0000000..cf7ed11 --- /dev/null +++ b/kbiff/kbiffmonitor.h @@ -0,0 +1,535 @@ +/* + * kbiffmonitor.h + * Copyright (C) 1999-2001 Kurt Granroth <granroth@kde.org> + * + * $Id$ + * + */ +#ifndef KBIFFMONITOR_H +#define KBIFFMONITOR_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> // Needed on some systems. +#endif + +#include <sys/time.h> + +#include <qobject.h> +#include <qlist.h> +#include <qfileinfo.h> + +#ifdef USE_SSL +#include <kssl.h> +#endif + +class KBiffURL; +class QString; + +/** + * @internal + * Internal class to store UIDL list + */ +class KBiffUidlList : public QList<QString> +{ +protected: + int compareItems(Item s1, Item s2) + { + QString *str1, *str2; + str1 = (QString *)s1; + str2 = (QString *)s2; + if((*str1) == (*str2)) + return 0; + else + return -1; + } +}; + +/** + * @internal + */ + +#define SOCKET_TIMEOUT 5 + +class KBiffSocket +{ +public: + KBiffSocket(); + virtual ~KBiffSocket(); + + bool connectSocket(const QString& host, unsigned short int port); + bool active(); + + bool isAsync(); + void setAsync(bool on); + +#ifdef USE_SSL + bool isSSL(); + void setSSL(bool on); +#endif // USE_SSL + + int numberOfMessages(); + int numberOfNewMessages(); + + void close(); + +protected: + QString readLine(); + int writeLine(const QString& line); + + bool async; + + struct timeval socketTO; + + int socketFD; + fd_set socketFDS; + int messages; + int newMessages; + QString banner; // the first line read from a new connection + +#ifdef USE_SSL + bool usessl; + KSSL *ssltunnel; +#endif // USE_SSL +}; + +/** + * @internal + */ +class KBiffImap : public KBiffSocket +{ +public: + KBiffImap(); + virtual ~KBiffImap(); + + bool command(const QString& line, unsigned int seq); + QString mungeUserPass(const QString& old_user); + void resetNumbers(); + /** + * @internal + * + * @brief Encapsulates all authentication to the IMAP server + * + * All authentication, including the determination of which authentication + * mechanism to use, is performed in this method. To add an + * authentication method, one will need to modify this method, + * KBiffMonitor::checkImap and KBiffImap::command + * + * @param pseq a pointer to the number of the next IMAP command. + * This value will be incremented depending on the number of + * commands necessary for authentication. + * @param user the user name required for authentication + * @param pass the password required for authentication + */ + bool authenticate(int *pseq, const QString& user, const QString& pass); + +protected: + /** + * @internal + * + * @brief does the IMAP server support AUTH=CRAM-MD5 ? + */ + bool auth_cram_md5; + + /** + * @internal + * + * @brief the CRAM-MD5 challenge (base64 decoded) as issued by the server + */ + QString chall_cram_md5; +}; + +/** + * @internal + */ +class KBiffPop : public KBiffSocket +{ +public: + KBiffPop(); + virtual ~KBiffPop(); + + bool command(const QString& line); + KBiffUidlList getUidlList() const; + + void close(); + + // Parses the banner message in the initial server response + bool parseBanner(void); + // Unset to disable APOP authentication + void setApop( bool enabled ); + /** + * @internal + * + * @brief Encapsulates all authentication to the POP3 server + * + * All authentication, including the determination of which authentication + * mechanism to use, is performed in this method. To add an + * authentication method, one will need to modify this method, + * KBiffMonitor::checkPop and KBiffPop::command + * + * @param user the user name required for authentication + * @param pass the password required for authentication + */ + bool authenticate(const QString& user, const QString& pass); + +protected: + KBiffUidlList uidlList; + /** + * @internal + * @brief does the server support APOP authentication ? + */ + bool auth_apop; + /** + * @internal + * @brief the APOP challenge from the server + */ + QCString chall_apop; + /** + * @internal + * @brief does the server support CRAM-MD5 authentication ? + */ + bool auth_cram_md5; + /** + * @internal + * @brief the CRAM-MD5 challenge (base64 decoded) + */ + QString chall_cram_md5; // the CRAM-MD5 challenge (base64 decoded) + /** + * @internal + * @brief does the user want APOP authentication + */ + bool use_apop; +}; + +/** + * @internal + */ +class KBiffNntp : public KBiffSocket +{ +public: + virtual ~KBiffNntp(); + + bool command(const QString& line); + int first() const; + int last() const; +protected: + int firstMsg; + int lastMsg; +}; + +typedef enum +{ + NewMail = 0, + NoMail, + OldMail, + NoConn, + UnknownState +} KBiffMailState; + +/** + * A "biff"-like class that can monitor local and remote mailboxes for new + * mail. KBiffMonitor currently supports eight protocols. + * + * <UL> + * <LI>mbox</LI> Unix style mailbox files + * <LI>pop3</LI> POP3 + * <LI>imap4</LI> imap4 + * <LI>maildir</LI> Mailboxes in maildir format + * <LI>mh</LI> Mailboxes in MH format + * <LI>file</LI> Simple files (no parsing) + * <LI>nntp</LI> USENET newsgroups + * <LI>imap4s</LI> imap4 over SSL + * <LI>pop3s</LI> POP3 over SSL + * </UL> + * + * A typical usage would look like so: + * + * <PRE> + * KBiffMonitor mon; + * mon.setMailbox("imap4://user:password@some.host.net/mailbox"); + * mon.setPollInterval(15); + * mon.start(); + * + * connect(&mon, SIGNAL(signal_newMail()), this, SLOT(processNewMail())); + * connect(&mon, SIGNAL(signal_oldMail()), this, SLOT(processOldMail())); + * connect(&mon, SIGNAL(signal_noMail()), this, SLOT(processNoMail())); + * connect(&mon, SIGNAL(signal_noConn()), this, SLOT(processNoConn())); + * </PRE> + * + * @short A "biff" class that monitors local and remote mailboxes + * @author Kurt Granroth <granroth@kde.org> + * @version $Id$ + */ +class KBiffMonitor : public QObject +{ + + Q_OBJECT +public: + + /** + * Constructor. Does not take any arguments + */ + KBiffMonitor(); + + /** + * Destructor. + */ + virtual ~KBiffMonitor(); + + /** + * Returns the current state of the mailbox (NewMail, OldMail, NoMail, or + * UnknownState) + */ + KBiffMailState getMailState() const { return mailState; } + + /** + * Returns the simpleURL of current mailbox being monitored + */ + const QString getMailbox() const { return simpleURL; } + + /** + * Sets or Returns the key of current mailbox being monitored + */ + const QString getMailboxKey() const { return key; } + + /** + * Returns the type of mailbox being monitored + */ + const QString getProtocol() const { return protocol; } + /** + * Returns <CODE>true</CODE> is KBiffMonitor is currently monitoring + * a mailbox. + */ + bool isRunning() { return started; } + + /** + * Returns the number of new messages for the current mailbox + */ + int newMessages() { return newCount; } + + /** + * Returns the number of messages for the current mailbox + */ + int curMessages() { return curCount; } + + + void saveConfig(); + void readConfig(); + +public slots: + /** + * Sets the mailbox to monitor. It uses a KBiffURL to specify the + * protocol, host, username, password, port and path (depending on + * protocol type). KBiffMonitor recognizes eight protocols: + * + * <UL> + * <LI>mbox</LI> Unix style mailbox files + * <LI>pop3</LI> POP3 + * <LI>imap4</LI> IMAP4 + * <LI>maildir</LI> Mailboxes in maildir format + * <LI>mh</LI> Mailboxes in MH format + * <LI>nttp</LI> USENET newsgroups + * <LI>imap4s</LI> imap4 over SSL + * <LI>pop3s</LI> POP3 over SSL + * </UL> + * + * Some examples: + * <PRE> + * mbox:/var/spool/mail/granroth + * </PRE> + * + * This would monitor a local file called '/var/spool/mail/granroth' + * + * <PRE> + * pop3://granroth:password@host.net:1234 + * </PRE> + * + * This would monitor POP3 mailbox 'granroth' on server 'host.net' + * using 1234 as the port and 'password' as the password. + * + * <PRE> + * imap4://granroth:password@host.net/Mail/mailbox + * </PRE> + * + * This would monitor IMAP4 mailbox 'Mail/mailbox' on server 'host.net' + * with 'granroth' as the user and 'password' as the password. + */ + void setMailbox(KBiffURL& url); + + /** + * Overloaded for convenience + */ + void setMailbox(const QString& url); + void setMailboxKey(const QString& k); + + /** + * Sets the password for the POP3 and IMAP4 protocols. + */ + void setPassword(const QString& password); + + /** + * Set the interval between mailbox reads. This is in seconds. + */ + void setPollInterval(const int interval); + + /** + * Start monitoring the mailbox + */ + void start(); + + /** + * Stop monitoring the mailbox + */ + void stop(); + + /** + * Fakes KBiffMonitor into thinking that the mailbox was just read + */ + void setMailboxIsRead(); + + /** + * Forces a mailbox check + */ + void checkMailNow(); + +signals: + /** + * This will get <CODE>emit</CODE>ed when new mail arrives + */ + void signal_newMail(); + + /** + * This will get <CODE>emit</CODE>ed when new mail arrives + */ + void signal_newMail(const int num_new, const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when no mail exists + */ + void signal_noMail(); + + /** + * This will get <CODE>emit</CODE>ed when no mail exists + */ + void signal_noMail(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when the mailbox is read + */ + void signal_oldMail(); + + /** + * This will get <CODE>emit</CODE>ed when the mailbox is read + */ + void signal_oldMail(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when no connection can be + * established + */ + void signal_noConn(); + + /** + * This will get <CODE>emit</CODE>ed when no connection can + * be established + */ + void signal_noConn(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed everytime mail will be + * fetched externally + */ + void signal_fetchMail(const QString& fetchClient); + + /** + * This will get <CODE>emit</CODE>ed everytime the mailbox + * should be checked (determined by @ref #setPollInterval) + */ + void signal_checkMail(); + + /** + * This will get <CODE>emit</CODE>ed everytime the mailbox is + * checked. It contains the current mailbox name, state, and number + * of new messages + */ + void signal_currentStatus(const int, const QString& , const KBiffMailState); + + /** + * This will get <CODE>emit</CODE>ed everytime there was an + * invalid login or incomplete connection to a remote server. + */ + void signal_invalidLogin(const QString& mailbox); + +protected: + void timerEvent(QTimerEvent *); + +protected slots: + void checkLocal(); + void checkMbox(); + void checkPop(); + void checkMaildir(); + void checkImap(); + void checkMHdir(); + void checkNntp(); + +protected: + // protected (non-slot) functions + void determineState(unsigned int size, const QDateTime& last_read, + const QDateTime& last_modified); + void determineState(unsigned int size); + + void determineState(KBiffUidlList uidl_list); + void determineState(KBiffMailState state); + void onStateChanged(); + int mboxMessages(); + + void invalidLogin(); + +private: + // General stuff + int poll; + int oldTimer; + bool started; + int newCount; + int curCount; + int oldCount; + bool firstRun; + + // Mailbox stuff + QString key; + QString simpleURL; + QString protocol; + QString mailbox; + QString server; + QString user; + QString password; + QString fetchCommand; + unsigned short int port; + bool preauth; + bool keepalive; + + // New state cache + unsigned int new_lastSize; + QDateTime new_lastRead; + QDateTime new_lastModified; + KBiffUidlList new_uidlList; + bool b_new_lastSize; + bool b_new_lastRead; + bool b_new_lastModified; + bool b_new_uidlList; + // State variables + KBiffMailState mailState; + unsigned int lastSize; + QDateTime lastRead; + QDateTime lastModified; + KBiffUidlList uidlList; + + // Socket protocols + KBiffImap *imap; + KBiffPop *pop; + KBiffNntp *nntp; +}; + +#endif // KBIFFMONITOR_H |