summaryrefslogtreecommitdiffstats
path: root/kbiff/kbiffmonitor.h
diff options
context:
space:
mode:
Diffstat (limited to 'kbiff/kbiffmonitor.h')
-rw-r--r--kbiff/kbiffmonitor.h535
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