summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorErwin Hoffmann <feh@fehcom.de>2023-09-21 17:36:16 +0200
committerErwin Hoffmann <feh@fehcom.de>2023-09-21 17:36:16 +0200
commit44388ac49531af9e2565f76ef99ff7afb757b3fb (patch)
tree4eeb294db5bc3dbd075d0df5fea13c664cc331e2 /src/include
parent889d69a87d51c8df531885cf1ac3d12d64a0cff7 (diff)
all sources
Diffstat (limited to 'src/include')
-rw-r--r--src/include/address.h29
-rw-r--r--src/include/argparser.h69
-rw-r--r--src/include/authenticate.h18
-rw-r--r--src/include/base64.h18
-rw-r--r--src/include/broker.h84
-rw-r--r--src/include/convert.h298
-rw-r--r--src/include/depot.h154
-rw-r--r--src/include/globals.h25
-rw-r--r--src/include/imapparser.h171
-rw-r--r--src/include/imapserver.h37
-rw-r--r--src/include/iodevice.h382
-rw-r--r--src/include/iofactory.h53
-rw-r--r--src/include/mailbox.h136
-rw-r--r--src/include/maildir.h190
-rw-r--r--src/include/maildirmessage.h309
-rw-r--r--src/include/message.h151
-rw-r--r--src/include/mime-inputsource.h141
-rw-r--r--src/include/mime-utils.h27
-rw-r--r--src/include/mime.h121
-rw-r--r--src/include/multilogdevice.h29
-rw-r--r--src/include/operators.h476
-rw-r--r--src/include/pendingupdates.h107
-rw-r--r--src/include/recursivedescent.h64
-rw-r--r--src/include/regmatch.h17
-rw-r--r--src/include/session.h116
-rw-r--r--src/include/status.h50
-rw-r--r--src/include/stdiodevice.h31
-rw-r--r--src/include/syslogdevice.h41
-rw-r--r--src/include/tools.h23
29 files changed, 3367 insertions, 0 deletions
diff --git a/src/include/address.h b/src/include/address.h
new file mode 100644
index 0000000..a8aded9
--- /dev/null
+++ b/src/include/address.h
@@ -0,0 +1,29 @@
+/** --------------------------------------------------------------------
+ * @file address.h
+ * @brief Declaration of the Address class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef address_h_included
+#define address_h_included
+#include <string>
+
+namespace Binc {
+
+ //------------------------------------------------------------------------
+ class Address {
+ public:
+ std::string name;
+ std::string local;
+ std::string host;
+
+ //--
+ std::string toParenList(void) const;
+
+ //--
+ Address(const std::string &name, const std::string &addr);
+ Address(const std::string &wholeaddr);
+ };
+}
+
+#endif
diff --git a/src/include/argparser.h b/src/include/argparser.h
new file mode 100644
index 0000000..6106974
--- /dev/null
+++ b/src/include/argparser.h
@@ -0,0 +1,69 @@
+/** --------------------------------------------------------------------
+ * @file argparser.h
+ * @brief Declaration of the argument parser class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef ARGPARSER_H_INCLUDED
+#define ARGPARSER_H_INCLUDED
+#include <map>
+#include <string>
+#include <vector>
+
+namespace Binc {
+ class ArgOpts {
+ public:
+ std::string c;
+ bool b;
+ bool o;
+ std::string desc;
+
+ inline ArgOpts(const std::string &chr, bool boolean, bool optional,
+ const std::string &descr)
+ {
+ c = chr;
+ b = boolean;
+ o = optional;
+ desc = descr;
+ }
+ };
+
+ class CommandLineArgs {
+ public:
+ CommandLineArgs(void);
+
+ bool parse(int argc, char *argv[]);
+ std::string errorString(void) const;
+
+ int argc(void) const;
+
+ const std::string operator [](const std::string &arg) const;
+
+ void addOptional(const std::string &arg, const std::string &desc,
+ bool boolean);
+ void addRequired(const std::string &arg, const std::string &desc,
+ bool boolean);
+ bool hasArg(const std::string &arg) const;
+
+ std::string usageString(void) const;
+
+ void setTail(const std::string &str);
+
+ const std::vector<std::string> &getUnqualifiedArgs() const;
+
+ private:
+ void registerArg(const std::string &arg, const std::string &desc,
+ bool boolean, bool optional);
+
+ std::string errString;
+ std::map<std::string, ArgOpts> reg;
+ std::map<std::string, std::string> args;
+ std::map<std::string, bool> passedArgs;
+ std::vector<std::string> unqualified;
+ std::string tail;
+ std::string head;
+ int ac;
+ };
+}
+
+#endif
diff --git a/src/include/authenticate.h b/src/include/authenticate.h
new file mode 100644
index 0000000..0ef6796
--- /dev/null
+++ b/src/include/authenticate.h
@@ -0,0 +1,18 @@
+/** --------------------------------------------------------------------
+ * @file authenticate.h
+ * @brief Declaration of the common authentication mechanism.
+ * @author Andreas Aardal Hanssen, Erwin Hoffmann
+ * @date 2002-2005, 2023
+ * ----------------------------------------------------------------- **/
+#ifndef authenticate_h_included
+#define authenticate_h_included
+#include <string>
+
+#include "depot.h"
+
+namespace Binc {
+ int authenticate(Depot &, const std::string &username,
+ const std::string &password, const std::string &challenge);
+}
+
+#endif
diff --git a/src/include/base64.h b/src/include/base64.h
new file mode 100644
index 0000000..25b0ff4
--- /dev/null
+++ b/src/include/base64.h
@@ -0,0 +1,18 @@
+/** --------------------------------------------------------------------
+ * @file base64.h
+ * @brief Declaration of base64 Utilities
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef base64_h_included
+#define base64_h_included
+#include <string>
+
+namespace Binc {
+
+ std::string base64decode(const std::string &s_in);
+ std::string base64encode(const std::string &s_in);
+
+}
+
+#endif
diff --git a/src/include/broker.h b/src/include/broker.h
new file mode 100644
index 0000000..6d148ae
--- /dev/null
+++ b/src/include/broker.h
@@ -0,0 +1,84 @@
+/** --------------------------------------------------------------------
+ * @file broker.h
+ * @brief Declaration of the Broker class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef broker_h_included
+#define broker_h_included
+#include "depot.h"
+#include "operators.h"
+
+#include <string>
+#include <map>
+
+namespace Binc {
+
+ class Request;
+ class Broker;
+
+ //------------------------------------------------------------------
+ class BrokerFactory {
+ private:
+ std::map<int, Broker *> brokers;
+
+ //--
+ BrokerFactory(void);
+
+ mutable std::string lastError;
+
+ public:
+ Broker *getBroker(int state);
+ void assign(const std::string &fname, Operator *o);
+ void addCapability(const std::string &c);
+ Operator *getOperator(int state, const std::string &name) const;
+
+ inline const std::string &getLastError(void) const;
+ inline void setLastError(const std::string &error) const;
+
+ //--
+ static BrokerFactory &getInstance(void);
+ ~BrokerFactory(void);
+ };
+
+ //------------------------------------------------------------------
+ inline const std::string &BrokerFactory::getLastError(void) const
+ {
+ return lastError;
+ }
+
+ //------------------------------------------------------------------
+ inline void BrokerFactory::setLastError(const std::string &error) const
+ {
+ lastError = error;
+ }
+
+ //------------------------------------------------------------------
+ class Broker {
+ private:
+ std::map<std::string, Operator *> operators;
+ std::map<std::string, bool> deletables;
+
+ public:
+ Operator * get(const std::string &name) const;
+ void assign(const std::string &fname, Operator *o, bool deletable = false);
+ Operator::ParseResult parseStub(Request &cmd);
+
+ //--
+ inline Broker(Broker &);
+ inline Broker(const Broker &);
+ Broker(void);
+ ~Broker(void);
+ };
+
+ inline Broker::Broker(Broker &)
+ {
+ }
+
+ inline Broker::Broker(const Broker &)
+ {
+ }
+
+}
+
+#endif
diff --git a/src/include/convert.h b/src/include/convert.h
new file mode 100644
index 0000000..cea2906
--- /dev/null
+++ b/src/include/convert.h
@@ -0,0 +1,298 @@
+/** --------------------------------------------------------------------
+ * @file convert.h
+ * @brief Declaration of miscellaneous convertion functions.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+
+#ifndef convert_h_included
+#define convert_h_included
+#include <cstring>
+#include <string>
+#include <vector>
+#include <iomanip>
+#include <iostream>
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "address.h"
+#include "depot.h"
+
+namespace Binc {
+
+ //----------------------------------------------------------------------
+ inline std::string toString(int i_in)
+ {
+ char intbuf[16];
+ snprintf(intbuf, sizeof(intbuf), "%d", i_in);
+ return std::string(intbuf);
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toString(unsigned int i_in)
+ {
+ char intbuf[16];
+ snprintf(intbuf, sizeof(intbuf), "%u", i_in);
+ return std::string(intbuf);
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toString(unsigned long i_in)
+ {
+ char longbuf[40];
+ snprintf(longbuf, sizeof(longbuf), "%lu", i_in);
+ return std::string(longbuf);
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toString(const char *i_in)
+ {
+ return std::string(i_in);
+ }
+
+ //----------------------------------------------------------------------
+ inline int atoi(const std::string &s_in)
+ {
+ return ::atoi(s_in.c_str());
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toHex(const std::string &s)
+ {
+ const char hexchars[] = "0123456789abcdef";
+ std::string tmp;
+ for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
+ unsigned char c = (unsigned char)*i;
+ tmp += hexchars[((c & 0xf0) >> 4)];
+ tmp += hexchars[c & 0x0f];
+ }
+
+ return tmp;
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string fromHex(const std::string &s)
+ {
+ // const
+ char hexchars[] = "0123456789abcdef";
+ std::string tmp;
+ for (std::string::const_iterator i = s.begin();
+ i != s.end() && i + 1 != s.end(); i += 2) {
+ int n;
+ unsigned char c = *i;
+ unsigned char d = *(i + 1);
+
+ char *t;
+ if ((t = strchr(hexchars, c)) == 0) return "out of range";
+ n = (t - hexchars) << 4;
+
+ if ((t = strchr(hexchars, d)) == 0) return "out of range";
+ n += (t - hexchars);
+
+ if (n >= 0 && n <= 255)
+ tmp += (char) n;
+ else
+ return "out of range";
+ }
+
+ return tmp;
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toImapString(const std::string &s_in)
+ {
+ for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+ unsigned char c = (unsigned char)*i;
+ if (c <= 31 || c >= 127 || c == '\"' || c == '\\')
+ return "{" + toString(s_in.length()) + "}\r\n" + s_in;
+ }
+
+ return "\"" + s_in + "\"";
+ }
+
+ //----------------------------------------------------------------------
+ inline void uppercase(std::string &input)
+ {
+ for (std::string::iterator i = input.begin(); i != input.end(); ++i)
+ *i = toupper(*i);
+ }
+
+ //----------------------------------------------------------------------
+ inline void lowercase(std::string &input)
+ {
+ for (std::string::iterator i = input.begin(); i != input.end(); ++i)
+ *i = tolower(*i);
+ }
+
+ //----------------------------------------------------------------------
+ inline void chomp(std::string &s_in, const std::string &chars = " \t\r\n")
+ {
+ int n = s_in.length();
+ while (n > 1 && chars.find(s_in[n - 1]) != std::string::npos)
+ s_in.resize(n-- - 1);
+ }
+
+ //----------------------------------------------------------------------
+ inline void trim(std::string &s_in, const std::string &chars = " \t\r\n")
+ {
+ while (s_in != "" && chars.find(s_in[0]) != std::string::npos)
+ s_in = s_in.substr(1);
+ chomp(s_in, chars);
+ }
+
+ //----------------------------------------------------------------------
+ inline const std::string unfold(const std::string &a,
+ bool removecomment = true)
+ {
+ std::string tmp;
+ bool incomment = false;
+ bool inquotes = false;
+ for (std::string::const_iterator i = a.begin(); i != a.end(); ++i) {
+ unsigned char c = (unsigned char)*i;
+ if (!inquotes && removecomment) {
+ if (c == '(') {
+ incomment = true;
+ tmp += " ";
+ } else if (c == ')') {
+ incomment = false;
+ } else if (c != 0x0a && c != 0x0d) {
+ tmp += *i;
+ }
+ } else if (c != 0x0a && c != 0x0d) {
+ tmp += *i;
+ }
+
+ if (!incomment) {
+ if (*i == '\"')
+ inquotes = !inquotes;
+ }
+ }
+
+ trim(tmp);
+ return tmp;
+ }
+
+ //----------------------------------------------------------------------
+ inline void split(const std::string &s_in, const std::string &delim,
+ std::vector<std::string> &dest, bool skipempty = true)
+ {
+ std::string token;
+ for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+ if (delim.find(*i) != std::string::npos) {
+ if (!skipempty || token != "")
+ dest.push_back(token);
+ token = "";
+ } else
+ token += *i;
+ }
+
+ if (token != "")
+ dest.push_back(token);
+ }
+
+ //----------------------------------------------------------------------
+ inline void splitAddr(const std::string &s_in,
+ std::vector<std::string> &dest, bool skipempty = true)
+ {
+ static const std::string delim = ",";
+ std::string token;
+ bool inquote = false;
+ for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+ if (inquote && *i == '\"') inquote = false;
+ else if (!inquote && *i == '\"') inquote = true;
+
+ if (!inquote && delim.find(*i) != std::string::npos) {
+ if (!skipempty || token != "") dest.push_back(token);
+ token = "";
+ } else
+ token += *i;
+ }
+ if (token != "")
+ dest.push_back(token);
+ }
+
+ //----------------------------------------------------------------------
+ inline std::string toCanonMailbox(const std::string &s_in)
+ {
+ if (s_in.find("..") != std::string::npos) return "";
+
+ if (s_in.length() >= 5) {
+ std::string a = s_in.substr(0, 5);
+ uppercase(a);
+ return a == "INBOX" ?
+ a + (s_in.length() > 5 ? s_in.substr(5) : "") : s_in;
+ }
+
+ return s_in;
+ }
+
+ //------------------------------------------------------------------------
+ inline std::string toRegex(const std::string &s_in, char delimiter)
+ {
+ std::string regex = "^";
+ for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+ if (*i == '.' || *i == '[' || *i == ']' || *i == '{' || *i == '}' ||
+ *i == '(' || *i == ')' || *i == '^' || *i == '$' || *i == '?' ||
+ *i == '+' || *i == '\\') {
+ regex += "\\";
+ regex += *i;
+ } else if (*i == '*')
+ regex += ".*?";
+ else if (*i == '%') {
+ regex += "(\\";
+ regex += delimiter;
+ regex += "){0,1}";
+ regex += "[^\\";
+ regex += delimiter;
+ regex += "]*?";
+ } else
+ regex += *i;
+ }
+
+ if (regex[regex.length() - 1] == '?')
+ regex[regex.length() - 1] = '$';
+ else
+ regex += "$";
+
+ return regex;
+ }
+
+ //------------------------------------------------------------------------
+ class BincStream {
+ private:
+ std::string nstr;
+
+ public:
+ //--
+ BincStream &operator << (std::ostream&(*)(std::ostream&));
+ BincStream &operator << (const std::string &t);
+ BincStream &operator << (unsigned long t);
+ BincStream &operator << (unsigned int t);
+ BincStream &operator << (int t);
+ BincStream &operator << (char t);
+
+ //--
+ std::string popString(unsigned int size);
+
+ //--
+ char popChar(void);
+ void unpopChar(char c);
+ void unpopStr(const std::string &s);
+
+ //--
+ const std::string &str(void) const;
+
+ //--
+ unsigned int getSize(void) const;
+
+ //--
+ void clear(void);
+
+ //--
+ BincStream(void);
+ ~BincStream(void);
+ };
+}
+
+#endif
diff --git a/src/include/depot.h b/src/include/depot.h
new file mode 100644
index 0000000..844a987
--- /dev/null
+++ b/src/include/depot.h
@@ -0,0 +1,154 @@
+/** --------------------------------------------------------------------
+ * @filec depot.h
+ * @file Declaration of the Depot class (the mail storage)
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef depot_h_included
+#define depot_h_included
+#include <map>
+#include <string>
+#include <vector>
+
+#include <dirent.h>
+
+namespace Binc {
+
+ class Mailbox;
+ class Depot;
+ class Status;
+
+ //------------------------------------------------------------------
+ class DepotFactory {
+ private:
+ std::vector<Depot *> depots;
+ DepotFactory(void);
+
+ public:
+ void assign(Depot *);
+ Depot *get(const std::string &name) const;
+
+ static DepotFactory &getInstance(void);
+ ~DepotFactory(void);
+ };
+
+ //------------------------------------------------------------------
+ class Depot {
+ public:
+ //--
+ class iterator {
+ public:
+ std::string operator * (void) const;
+ void operator ++ (void);
+ bool operator != (iterator) const;
+ bool operator == (iterator) const;
+
+ iterator(void);
+ iterator(const iterator &copy);
+ iterator(DIR *, struct dirent *);
+ ~iterator(void);
+
+ void deref(void);
+
+ iterator &operator =(const iterator &copy);
+
+ friend class Depot;
+
+ private:
+ DIR *dirp;
+ struct dirent *direntp;
+ int *ref;
+ };
+
+ private:
+ iterator enditerator;
+ std::vector<Mailbox *> backends;
+ Mailbox *defaultmailbox;
+ Mailbox *selectedmailbox;
+ std::vector<std::string> subscribed;
+ std::string personalNamespace;
+ std::string othersNamespace;
+ std::string sharedNamespace;
+
+ protected:
+ mutable std::string lastError;
+ std::string name;
+ char delimiter;
+ mutable std::map<std::string, Status> mailboxstatuses;
+
+ public:
+ virtual iterator begin(const std::string &) const;
+ virtual const iterator &end(void) const;
+
+ void setDelimiter(char);
+ const char getDelimiter(void) const;
+
+ virtual void assign(Mailbox *);
+
+ bool setDefaultType(const std::string &n);
+ Mailbox *getDefault(void) const;
+ virtual Mailbox *get(const std::string &path) const;
+
+ virtual bool setSelected(Mailbox *);
+ virtual Mailbox *getSelected(void) const;
+ void resetSelected(void);
+
+ bool getStatus(const std::string &s_in, Status &dest) const;
+
+ const std::string &getName(void) const;
+
+ virtual const std::string &getPersonalNamespace(void) const;
+ virtual const std::string &getOthersNamespace(void) const;
+ virtual const std::string &getSharedNamespace(void) const;
+
+ virtual std::string mailboxToFilename(const std::string &m) const = 0;
+ virtual std::string filenameToMailbox(const std::string &m) const = 0;
+
+ virtual bool createMailbox(const std::string &m) const;
+ virtual bool deleteMailbox(const std::string &m) const;
+ virtual bool renameMailbox(const std::string &m, const std::string &n) const;
+
+ const std::string &getLastError(void) const;
+ void setLastError(const std::string &error) const;
+
+ virtual std::vector<std::string> getSubscriptions(void) const;
+ virtual void subscribeTo(const std::string mailbox);
+ virtual bool unsubscribeTo(const std::string mailbox);
+ virtual void loadSubscribes(void);
+ virtual bool saveSubscribes(void) const;
+
+ //--
+ Depot(void);
+ Depot(const std::string &name);
+ virtual ~Depot(void);
+ };
+
+ //------------------------------------------------------------------
+ class MaildirPPDepot : public Depot {
+ public:
+ std::string mailboxToFilename(const std::string &m) const;
+ std::string filenameToMailbox(const std::string &m) const;
+
+ const std::string &getPersonalNamespace(void) const;
+
+ //--
+ MaildirPPDepot();
+ ~MaildirPPDepot();
+ private:
+ std::string privateNamespace;
+ };
+
+ //------------------------------------------------------------------
+ class IMAPdirDepot : public Depot {
+ public:
+ std::string mailboxToFilename(const std::string &m) const;
+ std::string filenameToMailbox(const std::string &m) const;
+
+ //--
+ IMAPdirDepot();
+ ~IMAPdirDepot();
+ };
+
+}
+
+#endif
diff --git a/src/include/globals.h b/src/include/globals.h
new file mode 100644
index 0000000..dd63b5f
--- /dev/null
+++ b/src/include/globals.h
@@ -0,0 +1,25 @@
+/** --------------------------------------------------------------------
+ * @file globals.h
+ * @brief Global constants.
+ * @author Andreas Aardal Hanssen, Erwin Hoffmann
+ * @date 2002-2005, 2023
+ * ----------------------------------------------------------------- **/
+#ifndef GLOBAL_H_INCLUDED
+#define GLOBAL_H_INCLUDED
+
+#define BINC_VERSION "2.0.14"
+#define IMAP_VERSION "IMAP4rev1"
+#define BINC_CACHE "BINC-CACHE-1.0"
+#define IMAP_PORT "143"
+#define IMAPS_PORT "993"
+
+namespace Binc {
+ static const int IDLE_TIMEOUT = 30*60;
+ static const int AUTH_TIMEOUT = 60;
+ static const int AUTH_PENALTY = 5;
+ static const int TRANSFER_TIMEOUT = 20*60;
+ static const int TRANSFER_BUFFER_SIZE = 1024;
+ static const int INPUT_BUFFER_LIMIT = 8192;
+
+};
+#endif
diff --git a/src/include/imapparser.h b/src/include/imapparser.h
new file mode 100644
index 0000000..4f77985
--- /dev/null
+++ b/src/include/imapparser.h
@@ -0,0 +1,171 @@
+/** --------------------------------------------------------------------
+ * @file imapparser.h
+ * @brief Declaration of the common items for parsing IMAP input
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef imapparser_h_included
+#define imapparser_h_included
+
+/* stl includes */
+#include <string>
+#include <map>
+#include <vector>
+
+namespace Binc {
+ //------------------------------------------------------------------------
+ class SequenceSet {
+ public:
+ void addRange(unsigned int a_in, unsigned int b_in);
+ bool isInSet(unsigned int n) const;
+ void addNumber(unsigned int a_in);
+ inline bool isLimited(void) const { return limited; }
+
+ static SequenceSet &all(void);
+
+ static SequenceSet &null(void);
+
+ SequenceSet &operator = (const SequenceSet &copy);
+
+ SequenceSet(void);
+ SequenceSet(const SequenceSet &copy);
+ ~SequenceSet(void);
+
+ protected:
+ bool isNull(void) const;
+
+ private:
+ bool limited;
+ bool nullSet;
+
+ class Range {
+ public:
+ unsigned int from;
+ unsigned int to;
+ Range(unsigned int from, unsigned int to);
+ };
+
+ std::vector<Range> internal;
+ };
+
+ //------------------------------------------------------------------------
+ class BincImapParserFetchAtt {
+ public:
+ std::string type;
+ std::string section;
+ std::string sectiontext;
+ std::vector<std::string> headerlist;
+ unsigned int offsetstart;
+ unsigned int offsetlength;
+ bool hassection;
+
+ BincImapParserFetchAtt(const std::string &typeName = "");
+
+ std::string toString(void);
+ };
+
+ //------------------------------------------------------------------------
+ class BincImapParserSearchKey {
+ public:
+ std::string name;
+ std::string date;
+ std::string astring;
+ std::string bstring;
+ int type;
+ unsigned int number;
+ SequenceSet bset;
+ enum {KEY_AND, KEY_OR, KEY_NOT, KEY_OTHER, KEY_SET};
+
+ std::vector<BincImapParserSearchKey> children;
+
+ const SequenceSet& getSet(void) const;
+
+ BincImapParserSearchKey(void);
+ };
+
+ //------------------------------------------------------------------------
+ class BincImapParserData {
+ public:
+ virtual ~BincImapParserData(void) {}
+ };
+
+ //------------------------------------------------------------------------
+ class Request {
+ private:
+ std::string tag;
+ std::string name;
+ std::string mode;
+ std::string date;
+ std::string userid;
+ std::string password;
+ std::string mailbox;
+ std::string newmailbox;
+ std::string authtype;
+ std::string listmailbox;
+ std::string charset;
+ std::string literal;
+ std::string contextInfo;
+ bool uidmode;
+
+ public:
+ BincImapParserData * extra;
+ std::vector<std::string> flags;
+ std::vector<std::string> statuses;
+
+ SequenceSet bset;
+ BincImapParserSearchKey searchkey;
+ std::vector<BincImapParserFetchAtt> fatt;
+
+ void setUidMode(void);
+ bool getUidMode(void) const;
+
+ void setTag(std::string &t_in);
+ const std::string &getTag(void) const;
+
+ void setMode(const std::string &m_in);
+ const std::string &getMode(void) const;
+
+ void setName(const std::string &s_in);
+ const std::string &getName(void) const;
+
+ void setLiteral(const std::string &s_in);
+ const std::string &getLiteral(void) const;
+
+ void setDate(const std::string &s_in);
+ const std::string &getDate(void) const;
+
+ void setCharSet(const std::string &s_in);
+ const std::string &getCharSet(void) const;
+
+ void setUserID(const std::string &s_in);
+ const std::string &getUserID(void) const;
+
+ void setPassword(const std::string &s_in);
+ const std::string &getPassword(void) const;
+
+ void setMailbox(const std::string &s_in);
+ const std::string &getMailbox(void) const;
+
+ void setAuthType(const std::string &s_in);
+ const std::string &getAuthType(void) const;
+
+ void setNewMailbox(const std::string &s_in);
+ const std::string &getNewMailbox(void) const;
+
+ void setListMailbox(const std::string &s_in);
+ const std::string &getListMailbox(void) const;
+
+ void setContextInfo(const std::string &s_in);
+ const std::string &getContextInfo(void) const;
+
+ SequenceSet &getSet(void);
+
+ std::vector<std::string> &getFlags(void);
+ std::vector<std::string> &getStatuses(void);
+
+ Request(void);
+ ~Request(void);
+ };
+}
+
+#endif
diff --git a/src/include/imapserver.h b/src/include/imapserver.h
new file mode 100644
index 0000000..940234e
--- /dev/null
+++ b/src/include/imapserver.h
@@ -0,0 +1,37 @@
+/** --------------------------------------------------------------------
+ * @file imapserver.h
+ * @brief Declaration of the IMAPServer class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+
+namespace Binc {
+
+ class IMAPServer {
+ public:
+ IMAPServer(int argc, char *argv[]);
+ ~IMAPServer(void);
+
+ int initialize(void);
+ int runStub(void);
+ int run(void);
+
+ enum ServerStatus {
+ OK,
+ RequestError,
+ RequestIgnore, // required for StartTLS, premature answer
+ RequestRejected,
+ ClientDisconnected,
+ Timeout
+ };
+
+ private:
+ void prepareForNextRequest(void);
+
+ int argc;
+ char **argv;
+ bool stubMode;
+
+ ServerStatus serverStatus;
+ };
+}
diff --git a/src/include/iodevice.h b/src/include/iodevice.h
new file mode 100644
index 0000000..070ac3f
--- /dev/null
+++ b/src/include/iodevice.h
@@ -0,0 +1,382 @@
+/** --------------------------------------------------------------------
+ * @file iodevice.h
+ * @brief Declaration of the IODevice class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002, 2003
+ * ----------------------------------------------------------------- **/
+#ifndef iodevice_h_included
+#define iodevice_h_included
+
+#include "convert.h" // BincStream
+//#include <iostream>
+#include <string>
+#include <unistd.h> // ::write
+
+const char CMS_END_OF_LINE[4] = { 0x0d, '\n', 0x00, 0x00 };
+
+namespace Binc {
+ /*!
+ \class IODevice
+ \brief The IODevice class provides a framework for reading and
+ writing to device.
+
+ Implement new devices by inheriting this class and overloading all
+ virtual methods.
+
+ service() returns the service that the specific device is used
+ for. Two values are "log" and "client".
+
+ \sa IOFactory, MultilogDevice, SyslogDevice, StdIODevice, SSLDevice
+ */
+ class IODevice {
+ public:
+ /*!
+ Standard options for an IODevice.
+ */
+ enum Flags {
+ None = 0,
+ FlushesOnEndl = 1 << 0,
+ HasInputLimit = 1 << 1,
+ HasOutputLimit = 1 << 2,
+ IsEnabled = 1 << 3,
+ HasTimeout = 1 << 4
+ };
+
+ /*!
+ Errors from when an operation returned false.
+ */
+ enum Error {
+ Unknown,
+ Timeout
+ };
+
+ /*!
+ Constructs an invalid IODevice.
+
+ Instances of IODevice perform no operations, and all boolean
+ functions always return false. This constructor is only useful
+ if called from a subclass that reimplements all virtual methods.
+ */
+ IODevice(int f = 0);
+
+ /*!
+ Destructs an IODevice; does nothing.
+ */
+ virtual ~IODevice(void);
+
+ /*!
+ Clears all data in the input and output buffers.
+ */
+ void clear(void);
+
+ /*!
+ Sets one or more flags.
+ \param f A bitwise OR of flags from the Flags enum.
+ */
+ void setFlags(unsigned int f);
+
+ /*!
+ Clears one or more flags.
+ \param f A bitwise OR of flags from the Flags enum.
+ */
+ void clearFlags(unsigned int f);
+
+ /*!
+ Sets the maximum allowed input buffer size. If this size is
+ non-zero and exceeded, reading from the device will fail. This
+ functionality is used to prevent clients from forcing this class
+ to consume so much memory that the program crashes.
+
+ Setting the max input buffer size to 0 disables the input size
+ limit.
+
+ \param max The maximum input buffer size in bytes.
+ */
+ void setMaxInputBufferSize(unsigned int max);
+
+ /*!
+ Sets the maximum allowed output buffer size. If this size is
+ non-zero and exceeded, flush() is called implicitly.
+
+ Setting the max output buffer size to 0 disables the output size
+ limit. This is generally discouraged.
+
+ As a contrast to setMaxInputBufferSize(), this function is used
+ to bundle up consequent write calls, allowing more efficient use
+ of the underlying device as larger blocks of data are written at
+ a time.
+
+ \param max The maximum output buffer size in bytes.
+ */
+ void setMaxOutputBufferSize(unsigned int max);
+
+ /*!
+ Sets the device's internal timeout in seconds. This timeout is
+ used both when waiting for data to read and for waiting for the
+ ability to write.
+
+ If this timeout is exceeded, the read or write function that
+ triggered the timeout will fail.
+
+ Setting the timeout to 0 disables the timeout.
+
+ \param t The timeout in seconds.
+ \sa getTimeout()
+ */
+ void setTimeout(unsigned int t);
+
+ /*!
+ Returns the timeout in seconds, or 0 if there is no timeout.
+
+ \sa setTimeout()
+ */
+ unsigned int getTimeout(void) const;
+
+ enum LogLevel {
+ ErrorLevel,
+ InfoLevel,
+ WarningLevel,
+ DebugLevel
+ };
+
+ /*!
+ Sets the output level for the following write operations on this
+ device.
+
+ The output level is a number which gives the following write
+ operations a priority. You can use setOutputLevelLimit() to
+ filter the write operations valid for different operating modes.
+ This enables you to have certain write operations ignored.
+
+ For instance, if the output level is set to 0, then "Hello" is
+ written, and the output level is set to 1, followed by writing
+ "Daisy", the output level limit value will decive wether only
+ "Hello" is written, or if also "Daisy" is written.
+
+ A low value of the level gives higher priority, and a high level
+ will give low priority. The default value is 0, and write
+ operations that are done with output level 0 are never ignored.
+
+ \param level The output level
+ \sa getOutputLevel(), setOutputLevelLimit()
+ */
+ void setOutputLevel(LogLevel level);
+
+ /*!
+ Returns the current output level.
+
+ \sa setOutputLevel()
+ */
+ LogLevel getOutputLevel(void) const;
+
+ /*!
+ Sets the current output level limit. Write operations with a
+ level higher than the output level limit are ignored.
+
+ \param level The output level limit
+ \sa setOutputLevel()
+ */
+ void setOutputLevelLimit(LogLevel level);
+
+ /*!
+ Returns the current output level limit.
+
+ \sa setOutputLevelLimit()
+ */
+ LogLevel getOutputLevelLimit(void) const;
+
+ /*!
+ Returns the number of bytes that have been read from this device
+ since it was created.
+ */
+ unsigned int getReadCount(void) const;
+
+ /*!
+ Returns the number of bytes that have been written to this
+ device since it was created.
+ */
+ unsigned int getWriteCount(void) const;
+
+ /*!
+ Calling this function enables the built-in protocol dumping feature in
+ the device. All input and output to this device will be dumped to a file
+ in /tmp.
+ */
+ void enableProtocolDumping(void);
+
+ /*!
+ Writes data to the device. Depending on the value of the max
+ output buffer size, the data may not be written immediately.
+
+ \sa setMaxOutputBufferSize()
+ */
+ template <class T> IODevice &operator << (const T &source);
+
+ /*!
+ Writes data to the device. This function specializes on standard
+ ostream derivates, such as std::endl.
+ */
+ IODevice &operator << (std::ostream &(*source)(std::ostream &));
+
+ /*!
+ Returns true if data can be read from the device; otherwise
+ returns false.
+ */
+ virtual bool canRead(void) const;
+
+ /*!
+ Reads data from the device, and stores this in a string. Returns
+ true on success; otherwise returns false.
+
+ \param dest The incoming data is stored in this string.
+ \param max No more than this number of bytes is read from the
+ device.
+ */
+ bool readStr(std::string *dest, unsigned int max = 0);
+
+ /*!
+ Reads exactly one byte from the device and stores this in a
+ char. Returns true on success; otherwise returns false.
+
+ \param dest The incoming byte is stored in this char.
+ */
+ bool readChar(char *dest = 0);
+
+ /*!
+ FIXME: add docs
+ */
+ void unreadChar(char c);
+
+ /*!
+ FIXME: add docs
+ */
+ void unreadStr(const std::string &s);
+
+ /*!
+ Reads characters from the device, until and including one
+ certain character is found. All read characters are discarded.
+
+ This function can be used to skip to the beginning of a line,
+ with the terminating character being '\n'.
+
+ \param The certain character.
+ */
+ bool skipTo(char c);
+
+ /*!
+ Flushes the output buffer. Writes all data in the output buffer
+ to the device.
+ */
+ bool flush(void);
+
+ /*!
+ Returns the type of error that most recently occurred.
+ */
+ Error getLastError(void) const;
+
+ /*!
+ Returns a human readable description of the error that most
+ recently occurred. If no known error has occurred, this method
+ returns "Unknown error".
+ */
+ std::string getLastErrorString(void) const;
+
+ /*!
+ Returns the type of service provided by this device. Two valid
+ return values are "client" and "log".
+ */
+ virtual std::string service(void) const;
+
+ protected:
+ /*!
+ Waits until data can be written to the device. If the timeout is
+ 0, this function waits indefinitely. Otherwise, it waits until
+ the timeout has expired.
+
+ If this function returns true, data can be written to the
+ device; otherwise, getLastError() must be checked to determine
+ whether a timeout occurred or whether an error with the device
+ prevents further writing.
+ */
+ virtual bool waitForWrite(void) const;
+
+ /*!
+ Waits until data can be read from the device.
+
+ \sa waitForWrite()
+ */
+ virtual bool waitForRead(void) const;
+
+ /*!
+ Types of results from a write.
+ */
+ enum WriteResult {
+ WriteWait = 0,
+ WriteDone = 1 << 0,
+ WriteError = 1 << 1
+ };
+
+ /*!
+ Writes as much data as possible to the device. If some but not
+ all data was written, returns WriteWait. If all data was
+ written, returns WriteDone. If an error occurred, returns
+ WriteError.
+ */
+ virtual WriteResult write(void);
+
+ /*!
+ Reads data from the device, and stores it in the input buffer.
+ Returns true on success; otherwise returns false.
+
+ This method will fail if there is no more data available, if a
+ timeout occurred or if an error with the device prevents more
+ data from being read.
+
+ The number of bytes read from the device is undefined.
+ */
+ virtual bool fillInputBuffer(void);
+
+ BincStream inputBuffer;
+ BincStream outputBuffer;
+
+ protected:
+ unsigned int flags;
+ unsigned int maxInputBufferSize;
+ unsigned int maxOutputBufferSize;
+
+ unsigned int timeout;
+
+ unsigned int readCount;
+ unsigned int writeCount;
+
+ LogLevel outputLevel;
+ LogLevel outputLevelLimit;
+
+ mutable Error error;
+ mutable std::string errorString;
+
+ int dumpfd;
+ };
+
+ //----------------------------------------------------------------------
+ template <class T> IODevice &IODevice::operator << (const T &source)
+ {
+ if ((flags & IsEnabled) && outputLevel <= outputLevelLimit) {
+ outputBuffer << source;
+
+ if (dumpfd) {
+ BincStream ss;
+ ss << source;
+ ::write(dumpfd, ss.str().c_str(), ss.getSize());
+ }
+
+ if (flags & HasInputLimit)
+ if (outputBuffer.getSize() > maxOutputBufferSize)
+ flush();
+ }
+
+ return *this;
+ }
+}
+
+#endif
diff --git a/src/include/iofactory.h b/src/include/iofactory.h
new file mode 100644
index 0000000..6ebccaa
--- /dev/null
+++ b/src/include/iofactory.h
@@ -0,0 +1,53 @@
+/** --------------------------------------------------------------------
+ * @file iofactory.h
+ * @brief Declaration of the IOFactory class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002, 2003
+ * ----------------------------------------------------------------- **/
+#ifndef IOFACTORY_H_INCLUDED
+#define IOFACTORY_H_INCLUDED
+#include <map>
+#include <string>
+
+#include "iodevice.h"
+
+namespace Binc {
+ class IOFactory {
+ public:
+ ~IOFactory(void);
+
+ static void addDevice(IODevice *dev);
+ static IOFactory &getInstance(void);
+ static IODevice &getClient(void);
+ static IODevice &getLogger(void);
+
+ private:
+ IOFactory(void);
+
+ std::map<std::string, IODevice *> devices;
+ };
+}
+
+#define bincClient \
+ IOFactory::getClient()
+
+#if defined (DEBUG)
+//#define bincError if (false) std::cout
+#define bincError std::cerr
+// #define bincWarning if (false) std::cout
+#define bincWarning std::cerr
+#define bincDebug std::cerr
+//#define bincDebug if (false) std::cout
+#else
+#define bincError \
+ IOFactory::getLogger().setOutputLevel(IODevice::ErrorLevel);IOFactory::getLogger()
+#define bincWarning \
+ IOFactory::getLogger().setOutputLevel(IODevice::WarningLevel);IOFactory::getLogger()
+#define bincDebug \
+ IOFactory::getLogger().setOutputLevel(IODevice::DebugLevel);IOFactory::getLogger()
+#endif
+
+#define bincLog \
+ IOFactory::getLogger().setOutputLevel(IODevice::InfoLevel);IOFactory::getLogger()
+
+#endif
diff --git a/src/include/mailbox.h b/src/include/mailbox.h
new file mode 100644
index 0000000..db98cc0
--- /dev/null
+++ b/src/include/mailbox.h
@@ -0,0 +1,136 @@
+/** --------------------------------------------------------------------
+ * @file mailbox.h
+ * @brief Declaration of the Mailbox class (Mailbox is logical container)
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef mailbox_h_included
+#define mailbox_h_included
+
+#include <map>
+#include <string>
+#include <queue>
+#include <vector>
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "imapparser.h"
+
+namespace Binc {
+
+ class Message;
+ class Status;
+ class PendingUpdates;
+ class File;
+
+ //------------------------------------------------------------------------
+ class Mailbox {
+ public:
+
+ //----------------------------------------------------------------------
+ class BaseIterator {
+ public:
+ BaseIterator(int sqn = 0);
+ virtual ~BaseIterator(void);
+
+ virtual Message &operator *(void) = 0;
+ virtual void operator ++(void) = 0;
+ virtual bool operator !=(const BaseIterator &d) const = 0;
+ virtual bool operator ==(const BaseIterator &d) const = 0;
+
+ virtual void erase(void) = 0;
+
+ unsigned int sqnr;
+ };
+
+ //----------------------------------------------------------------------
+ class iterator {
+ public:
+ iterator(BaseIterator &i);
+
+ Message &operator *(void);
+ void operator ++(void);
+ bool operator ==(const iterator &) const;
+ bool operator !=(const iterator &) const;
+
+ unsigned int getSqnr() const;
+
+ void erase(void);
+
+ protected:
+ BaseIterator &realIterator;
+ };
+
+ enum Iterator {
+ INCLUDE_EXPUNGED = 1,
+ SKIP_EXPUNGED = 2
+ };
+
+ enum Mode {
+ UID_MODE = 4,
+ SQNR_MODE = 8
+ };
+
+ virtual iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE) const = 0;
+ virtual iterator end(void) const = 0;
+
+ //-- Generic for one mailbox type
+ virtual bool getStatus(const std::string &, Status &) const = 0;
+ virtual bool isMailbox(const std::string &) const = 0;
+ virtual bool isMarked(const std::string &) const = 0;
+ virtual unsigned int getStatusID(const std::string &) const = 0;
+ virtual void bumpUidValidity(const std::string &) const = 0;
+
+ //-- Specific for one mailbox
+ void setReadOnly(bool readOnly);
+ bool isReadOnly(void) const;
+
+ virtual const std::string getTypeName(void) const = 0;
+ const std::string getName(void) const;
+ void setName(const std::string &name);
+
+ virtual unsigned int getMaxUid(void) const = 0;
+ virtual unsigned int getMaxSqnr(void) const = 0;
+ virtual unsigned int getUidNext(void) const = 0;
+ virtual unsigned int getUidValidity(void) const = 0;
+
+ virtual bool getUpdates(bool scan, unsigned int type,
+ PendingUpdates &updates, bool forceScan) = 0;
+
+ virtual void updateFlags(void) = 0;
+ virtual void expungeMailbox(void) = 0;
+ virtual bool selectMailbox(const std::string &name, const std::string &s_in) = 0;
+ virtual bool createMailbox(const std::string &s, mode_t mode, uid_t owner = 0, gid_t group = 0, bool root = false) = 0;
+ virtual bool deleteMailbox(const std::string &s) = 0;
+ virtual void closeMailbox(void) = 0;
+
+ virtual Message *createMessage(const std::string &mbox, time_t idate = 0) = 0;
+ virtual bool commitNewMessages(const std::string &mbox) = 0;
+ virtual bool rollBackNewMessages(void) = 0;
+ virtual bool fastCopy(Message &source, Mailbox &desttype, const std::string &destname) = 0;
+
+ const std::string &getLastError(void) const;
+ void setLastError(const std::string &error) const;
+
+ //--
+ Mailbox(void);
+ virtual ~Mailbox(void);
+
+ friend class Mailbox::iterator;
+
+ protected:
+ bool readOnly;
+
+ private:
+ Mailbox(const Mailbox &copy);
+
+ mutable std::string lastError;
+
+ std::string name;
+ };
+}
+
+#endif
diff --git a/src/include/maildir.h b/src/include/maildir.h
new file mode 100644
index 0000000..4a262b5
--- /dev/null
+++ b/src/include/maildir.h
@@ -0,0 +1,190 @@
+/** --------------------------------------------------------------------
+ * @file maildir.h
+ * @brief Declaration of the Maildir class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef maildir_h_included
+#define maildir_h_included
+#include <string>
+#include <vector>
+#include <map>
+
+#include "mailbox.h"
+#include "maildirmessage.h"
+
+namespace Binc {
+ static const std::string CACHEFILEVERSION = "1.0.5";
+ static const std::string UIDVALFILEVERSION = "1.0.5";
+
+ //----------------------------------------------------------------------
+ class Lock {
+ public:
+ Lock(const std::string &path);
+ ~Lock();
+
+ private:
+ std::string lock;
+ };
+
+ //------------------------------------------------------------------------
+ class MaildirIndexItem {
+ public:
+ unsigned int uid;
+ std::string fileName;
+ };
+
+ //------------------------------------------------------------------------
+ class MaildirIndex
+ {
+ private:
+ std::map<std::string, MaildirIndexItem> idx;
+
+ public:
+ void insert(const std::string &unique, unsigned int uid,
+ const std::string &fileName = "");
+ void remove(const std::string &unique);
+ void clear(void);
+ void clearFileNames(void);
+ void clearUids(void);
+ unsigned int getSize(void) const;
+ MaildirIndexItem *find(const std::string &unique);
+ };
+
+ //------------------------------------------------------------------------
+ class Maildir : public Mailbox {
+ public:
+ typedef std::map<unsigned int, MaildirMessage> MessageMap;
+
+ class iterator : public BaseIterator {
+ public:
+ iterator(void);
+ iterator(Maildir *home, MessageMap::iterator i,
+ const SequenceSet &bset,
+ unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE);
+ iterator(const iterator &copy);
+ ~iterator(void);
+
+ Message &operator *(void);
+ void operator ++(void);
+ bool operator ==(const BaseIterator &) const;
+ bool operator !=(const BaseIterator &) const;
+
+ iterator &operator =(const iterator &copy);
+
+ void erase(void);
+
+ friend class Maildir;
+
+ protected:
+ void reposition(void);
+ MaildirMessage &curMessage(void);
+
+ private:
+ Maildir *mailbox;
+ SequenceSet bset;
+ int mod;
+
+ MessageMap::iterator i;
+ unsigned int uidmax;
+ unsigned int sqnrmax;
+
+ iterator(iterator &external);
+ };
+
+ const std::string getTypeName(void) const;
+
+ Mailbox::iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE) const;
+ Mailbox::iterator end(void) const;
+
+ unsigned int getMaxUid(void) const;
+ unsigned int getMaxSqnr(void) const;
+ unsigned int getUidValidity(void) const;
+ unsigned int getUidNext(void) const;
+
+ bool getUpdates(bool doscan, unsigned int type,
+ PendingUpdates &updates, bool forceScan);
+
+ const std::string &getPath(void) const;
+ void setPath(const std::string &path_in);
+
+ void bumpUidValidity(const std::string &) const;
+
+ unsigned int getStatusID(const std::string &) const;
+ bool getStatus(const std::string &, Status &) const;
+ void updateFlags(void);
+
+ bool isMailbox(const std::string &) const;
+ bool isMarked(const std::string &) const;
+ bool selectMailbox(const std::string &name, const std::string &s_in);
+ void closeMailbox(void);
+ void expungeMailbox(void);
+ bool createMailbox(const std::string &s, mode_t mode, uid_t owner = 0, gid_t group = 0, bool root = false);
+ bool deleteMailbox(const std::string &s);
+
+ Message *createMessage(const std::string &mbox, time_t idate = 0);
+ bool commitNewMessages(const std::string &mbox);
+ bool rollBackNewMessages(void);
+
+ bool fastCopy(Message &source, Mailbox &desttype, const std::string &destname);
+
+ //--
+ Maildir(void);
+ ~Maildir(void);
+
+ friend class Maildir::iterator;
+ friend class MaildirMessage;
+
+ protected:
+ enum ReadCacheResult {
+ Ok,
+ NoCache,
+ Error
+ };
+
+ ReadCacheResult readCache(void);
+ bool writeCache(void);
+ bool scanFileNames(void) const;
+
+ enum ScanResult {
+ Success = 0,
+ TemporaryError = 1,
+ PermanentError = 2
+ };
+
+ ScanResult scan(bool forceScan = false);
+
+ MaildirMessage *get(const std::string &id);
+ void add(MaildirMessage &m);
+
+ private:
+ std::vector<MaildirMessage> newMessages;
+
+ unsigned int uidvalidity;
+ unsigned int uidnext;
+ bool selected;
+ std::string path;
+
+ mutable iterator beginIterator;
+ mutable iterator endIterator;
+
+ mutable bool firstscan;
+ mutable bool cacheRead;
+ mutable MaildirIndex index;
+ mutable MessageMap messages;
+
+ mutable unsigned int oldrecent;
+ mutable unsigned int oldexists;
+
+ mutable time_t old_bincimap_cache_st_mtime;
+ mutable time_t old_bincimap_cache_st_ctime;
+ mutable time_t old_cur_st_mtime;
+ mutable time_t old_cur_st_ctime;
+ mutable time_t old_new_st_mtime;
+ mutable time_t old_new_st_ctime;
+
+ mutable bool mailboxchanged;
+ };
+}
+
+#endif
diff --git a/src/include/maildirmessage.h b/src/include/maildirmessage.h
new file mode 100644
index 0000000..9e9c717
--- /dev/null
+++ b/src/include/maildirmessage.h
@@ -0,0 +1,309 @@
+/** --------------------------------------------------------------------
+ * @file maildirmessage.h
+ * @brief Declaration of the MaildirMessage class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef maildirmessage_h_included
+#define maildirmessage_h_included
+#include <string>
+#include <map>
+#include <vector>
+#include <exception>
+#include <iostream>
+#include <time.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "message.h"
+#include "address.h"
+#include "mime.h"
+
+namespace Binc {
+
+ class Maildir;
+
+ /*!
+ \class MaildirMessage
+ \brief The MaildirMessage class provides an interface for
+ IMAP messages.
+
+ Mailbox independent operations and properties are available
+ through this interface.
+
+ \sa Message
+ */
+ class MaildirMessage : public Message {
+ public:
+ /*!
+ Sets the UID of a message.
+ \param uid The UID that will be set.
+ */
+ void setUID(unsigned int uid);
+
+ /*!
+ Returns the UID of a message.
+ */
+ unsigned int getUID(void) const;
+
+ /*!
+ Sets the size of the message. This size must be consistent with
+ the size reported when fetching the full message.
+
+ \param size The size of the message in characters, after
+ any conversion to CRLF.
+ */
+ void setSize(unsigned int size);
+
+ /*!
+ Returns the size of the message, optionally determining the size
+ if it is not yet known.
+
+ \param determine If render is true and the size is unknown, the
+ size will be calculated and stored implicitly. Otherwise if the
+ size is unknown, 0 is returned.
+ */
+ unsigned int getSize(bool determine = false) const;
+
+ /*!
+ Adds one or more flags to a message.
+
+ \param flags This is a bitmask of flags from the Flags enum.
+ */
+ void setStdFlag(unsigned char flags);
+
+ /*!
+ Resets all flags on a message.
+ */
+ void resetStdFlags(void);
+
+ /*!
+ Returns the flags that are set on a message.
+ */
+ unsigned char getStdFlags(void) const;
+
+ /*
+ */
+ void setCustomFlag(const std::string &flag);
+ void removeCustomFlag(const std::string &flag);
+ void resetCustomFlags(void);
+ std::vector<std::string> getCustomFlags(void) const;
+
+ /*!
+ Sets the internal flags.
+
+ \param flags a bitmask of the Flags enum.
+ */
+ void setInternalFlag(unsigned char flags);
+
+ /*!
+ Removes the internal flags.
+
+ \param flags a bitmask of the Flags enum.
+ */
+ void clearInternalFlag(unsigned char flags);
+
+ /*!
+ Returns the internal flags.
+ */
+ unsigned char getInternalFlags(void) const;
+
+ /*!
+ Sets a state in a message that indicates that no flags have been
+ changed. Used together with hasFlagsChanged() to check if the
+ flags in this message have been changed.
+ */
+ void setFlagsUnchanged(void);
+
+ /*!
+ Returns true if flags have been added or reset since the last
+ call to setFlagsUnchanged(), otherwise returns false.
+ */
+ bool hasFlagsChanged(void) const;
+
+ /*!
+ Sets the internal date of a message. This is usually the date in
+ which the message arrived in the mailbox.
+
+ \param internaldate The internal date of the message in seconds
+ since the epoch.
+ */
+ void setInternalDate(time_t internaldate);
+
+ /*!
+ Returns the internal date of the message in seconds since the
+ epoch.
+ */
+ time_t getInternalDate(void) const;
+
+ /*!
+ Reads a chunk of up to 4096 bytes from a message. Call close()
+ before readChunk() to read the first chunk from a message.
+
+ readChunk() is used for copying or appending a message to a
+ mailbox.
+
+ \param chunk The characters are stored in this string.
+ */
+ int readChunk(std::string &chunk);
+
+ /*!
+ Appends a chunk of bytes to a message. appendChunk() is used for
+ copying or appending a message to a mailbox.
+
+ \param chunk The content of this string is appended to the
+ message.
+ */
+ bool appendChunk(const std::string &chunk);
+
+ /*!
+ Resets a message and frees all allocated resources.
+ */
+ void close(void);
+
+ /*!
+ Marks the message as expunged. Equivalent to calling
+ setStdFlag() with F_EXPUNGED.
+ */
+ void setExpunged(void);
+
+ /*!
+ Removes the F_EXPUNGED flag from the message.
+ */
+ void setUnExpunged(void);
+
+ /*!
+ Returns true if the message is marked as expunged, otherwise
+ returns false.
+ */
+ bool isExpunged(void) const;
+
+ /*!
+ Returns the first occurrance of a MIME header in a message,
+ counting from the top of the message and downwards, or "" if no
+ such header is found.
+ \param header The name of the header to be fetched.
+ */
+ const std::string &getHeader(const std::string &header);
+
+ bool headerContains(const std::string &header,
+ const std::string &text);
+
+ bool bodyContains(const std::string &text);
+ bool textContains(const std::string &text);
+
+ bool printBodyStructure(bool extended = true) const;
+
+ bool printEnvelope(void) const;
+
+ bool printHeader(const std::string &section,
+ std::vector<std::string> headers,
+ bool includeHeaders = false,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool mime = false) const;
+
+ unsigned int getHeaderSize(const std::string &section,
+ std::vector<std::string> headers,
+ bool includeHeaders = false,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool mime = false) const;
+
+ bool printBody(const std::string &section = "",
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX) const;
+ unsigned int getBodySize(const std::string &section,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX) const;
+
+ bool printDoc(unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool onlyText = false) const;
+
+ unsigned int getDocSize(unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool onlyText = false) const;
+
+ void setUnique(const std::string &s_in);
+ const std::string &getUnique(void) const;
+
+ //--
+ MaildirMessage(Maildir &home);
+ ~MaildirMessage(void);
+
+ friend class Maildir;
+
+ bool operator < (const MaildirMessage &a) const;
+
+ MaildirMessage(const MaildirMessage &copy);
+ MaildirMessage &operator = (const MaildirMessage &copy);
+
+ enum Flags {
+ None = 0x00,
+ Expunged = 0x01,
+ FlagsChanged = 0x02,
+ JustArrived = 0x04,
+ WasWrittenTo = 0x08,
+ Committed = 0x10,
+ CustomFlagsChanged = 0x20
+ };
+
+ protected:
+ bool parseFull(void) const;
+ bool parseHeaders(void) const;
+
+ std::string getFixedFilename(void) const;
+ std::string getFileName(void) const;
+
+ void setFile(int fd);
+ int getFile(void) const;
+
+ void setSafeName(const std::string &name);
+ const std::string &getSafeName(void) const;
+
+ private:
+ mutable int fd;
+ mutable MimeDocument *doc;
+ mutable unsigned char internalFlags;
+ mutable unsigned char stdflags;
+ mutable unsigned int uid;
+ mutable unsigned int size;
+ mutable std::string unique;
+ mutable std::string safeName;
+ time_t internaldate;
+
+ Maildir &home;
+ static std::string storage;
+ std::vector<std::string> *customFlags;
+ };
+
+ //------------------------------------------------------------------------
+ class MaildirMessageCache
+ {
+ public:
+ ~MaildirMessageCache();
+
+ enum ParseStatus {
+ NotParsed,
+ HeaderParsed,
+ AllParsed
+ };
+
+ static MaildirMessageCache &getInstance(void);
+
+ void removeStatus(const MaildirMessage *);
+ void addStatus(const MaildirMessage *, ParseStatus pstat);
+ ParseStatus getStatus(const MaildirMessage *) const;
+ void clear(void);
+
+ private:
+ MaildirMessageCache();
+
+ mutable std::map<const MaildirMessage *, ParseStatus> statuses;
+ mutable std::deque<const MaildirMessage *> parsed;
+ };
+}
+
+#endif
diff --git a/src/include/message.h b/src/include/message.h
new file mode 100644
index 0000000..76607e5
--- /dev/null
+++ b/src/include/message.h
@@ -0,0 +1,151 @@
+/** --------------------------------------------------------------------
+ * @file message.h
+ * @brief Declaration of the Message class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef message_h_included
+#define message_h_included
+#include <vector>
+#include <string>
+#include <time.h>
+
+#ifndef UINTMAX
+#define UINTMAX ((unsigned int)-1)
+#endif
+
+namespace Binc {
+
+ /*!
+ \class Message
+ \brief The Message class provides an interface for
+ IMAP messages.
+
+ Mailbox independent operations and properties are available
+ through this interface.
+
+ This class is an abstract, and has no implementation.
+
+ \sa MaildirMessage
+ */
+ class Message {
+ public:
+
+ /*!
+ Standard IMAP message flags.
+
+ */
+ enum Flags {
+ F_NONE = 0x00, /*!< No flag is set */
+ F_SEEN = 0x01, /*!< The message has been seen */
+ F_ANSWERED = 0x02, /*!< The message has been answered */
+ F_DELETED = 0x04, /*!< The message is marked as deleted */
+ F_DRAFT = 0x08, /*!< The message is a draft */
+ F_RECENT = 0x10, /*!< The message arrived recently */
+ F_FLAGGED = 0x20, /*!< The message is flagged / important */
+ F_EXPUNGED = 0x40, /*!< The message has been expunged */
+ F_PASSED = 0x80 /*!< The message has been bounced */
+ };
+
+ virtual void setUID(unsigned int) = 0;
+ virtual unsigned int getUID(void) const = 0;
+
+ virtual void setSize(unsigned int) = 0;
+ virtual unsigned int getSize(bool render = false) const = 0;
+
+ virtual void setStdFlag(unsigned char) = 0;
+ virtual void resetStdFlags(void) = 0;
+ virtual unsigned char getStdFlags(void) const = 0;
+
+ virtual void setCustomFlag(const std::string &flag) = 0;
+ virtual void removeCustomFlag(const std::string &flag) = 0;
+ virtual void resetCustomFlags(void) = 0;
+ virtual std::vector<std::string> getCustomFlags(void) const = 0;
+
+ virtual void setFlagsUnchanged(void) = 0;
+ virtual bool hasFlagsChanged(void) const = 0;
+
+ virtual void setInternalDate(time_t) = 0;
+ virtual time_t getInternalDate(void) const = 0;
+
+ // virtual void rewind(void) = 0;
+ virtual int readChunk(std::string &) = 0;
+ virtual bool appendChunk(const std::string &) = 0;
+ virtual void close(void) = 0;
+
+ virtual void setExpunged(void) = 0;
+ virtual void setUnExpunged(void) = 0;
+ virtual bool isExpunged(void) const = 0;
+
+ virtual const std::string &getHeader(const std::string &header) = 0;
+
+ virtual bool headerContains(const std::string &header,
+ const std::string &text) = 0;
+
+ virtual bool bodyContains(const std::string &text) = 0;
+ virtual bool textContains(const std::string &text) = 0;
+
+ virtual bool printBodyStructure(bool extended = true) const = 0;
+
+ virtual bool printEnvelope(void) const = 0;
+
+ virtual bool printHeader(const std::string &section,
+ std::vector<std::string> headers,
+ bool includeHeaders = false,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool mime = false) const = 0;
+
+ virtual unsigned int getHeaderSize(const std::string &section,
+ std::vector<std::string> headers,
+ bool includeHeaders = false,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool mime = false) const = 0;
+
+ virtual bool printBody(const std::string &section,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX) const = 0;
+
+ virtual unsigned int getBodySize(const std::string &section,
+ unsigned int startOffset = 0,
+ unsigned int length = UINTMAX) const = 0;
+
+ virtual bool printDoc(unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool onlyText = false) const = 0;
+
+ virtual unsigned int getDocSize(unsigned int startOffset = 0,
+ unsigned int length = UINTMAX,
+ bool onlyText = false) const = 0;
+
+ Message(void);
+ virtual ~Message(void);
+
+ void setLastError(const std::string &) const;
+ const std::string &getLastError(void) const;
+
+ private:
+ static std::string lastError;
+ };
+
+ inline Message::Message(void)
+ {
+ }
+
+ inline Message::~Message(void)
+ {
+ }
+
+ inline void Message::setLastError(const std::string &error) const
+ {
+ lastError = error;
+ }
+
+ inline const std::string &Message::getLastError(void) const
+ {
+ return lastError;
+ }
+}
+
+#endif
diff --git a/src/include/mime-inputsource.h b/src/include/mime-inputsource.h
new file mode 100644
index 0000000..e37d508
--- /dev/null
+++ b/src/include/mime-inputsource.h
@@ -0,0 +1,141 @@
+/** --------------------------------------------------------------------
+ * @file mime-inputsource.h
+ * @brief The base class of the MIME input source
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef mime_inputsource_h_included
+#define mime_inputsource_h_included
+
+#include <string.h>
+#include <unistd.h>
+
+namespace Binc {
+
+ class MimeInputSource {
+ public:
+ inline MimeInputSource(int fd, unsigned int start = 0);
+ virtual inline ~MimeInputSource(void);
+
+ virtual inline bool fillInputBuffer(void);
+ virtual inline void reset(void);
+
+ inline void seek(unsigned int offset);
+ inline bool getChar(char *c);
+ inline void ungetChar(void);
+ inline int getFileDescriptor(void) const;
+
+ inline unsigned int getOffset(void) const;
+
+ private:
+ int fd;
+ char data[16384];
+ unsigned int offset;
+ unsigned int tail;
+ unsigned int head;
+ unsigned int start;
+ char lastChar;
+ };
+
+ inline MimeInputSource::MimeInputSource(int fd, unsigned int start)
+ {
+ this->fd = fd;
+ this->start = start;
+ offset = 0;
+ tail = 0;
+ head = 0;
+ lastChar = '\0';
+ memset(data, '\0', sizeof(data));
+
+ seek(start);
+ }
+
+ inline MimeInputSource::~MimeInputSource(void)
+ {
+ }
+
+ inline bool MimeInputSource::fillInputBuffer(void)
+ {
+ char raw[4096];
+ ssize_t nbytes = read(fd, raw, sizeof(raw));
+ if (nbytes <= 0) {
+ // FIXME: If ferror(crlffile) we should log this.
+ return false;
+ }
+
+ for (ssize_t i = 0; i < nbytes; ++i) {
+ const char c = raw[i];
+ if (c == '\r') {
+ if (lastChar == '\r') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ }
+ } else if (c == '\n') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ } else {
+ if (lastChar == '\r') {
+ data[tail++ & (0x4000-1)] = '\r';
+ data[tail++ & (0x4000-1)] = '\n';
+ }
+ data[tail++ & (0x4000-1)] = c;
+ }
+
+ lastChar = c;
+ }
+
+ return true;
+ }
+
+ inline void MimeInputSource::reset(void)
+ {
+ offset = head = tail = 0;
+ lastChar = '\0';
+
+ if (fd != -1)
+ lseek(fd, 0, SEEK_SET);
+ }
+
+ inline void MimeInputSource::seek(unsigned int seekToOffset)
+ {
+ if (offset > seekToOffset)
+ reset();
+
+ char c;
+ int n = 0;
+ while (seekToOffset > offset) {
+ if (!getChar(&c)) break;
+ ++n;
+ }
+ }
+
+ inline bool MimeInputSource::getChar(char *c)
+ {
+ if (head == tail && !fillInputBuffer())
+ return false;
+
+ *c = data[head++ & (0x4000-1)];
+ ++offset;
+ return true;
+ }
+
+ inline void MimeInputSource::ungetChar()
+ {
+ --head;
+ --offset;
+ }
+
+ inline int MimeInputSource::getFileDescriptor(void) const
+ {
+ return fd;
+ }
+
+ inline unsigned int MimeInputSource::getOffset(void) const
+ {
+ return offset;
+ }
+}
+
+extern Binc::MimeInputSource *mimeSource;
+
+#endif
diff --git a/src/include/mime-utils.h b/src/include/mime-utils.h
new file mode 100644
index 0000000..732234a
--- /dev/null
+++ b/src/include/mime-utils.h
@@ -0,0 +1,27 @@
+/** --------------------------------------------------------------------
+ * @file mime.cc
+ * @brief Implementation of main mime parser components
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef mime_utils_h_included
+#define mime_utils_h_included
+
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+
+using namespace ::std;
+
+inline bool compareStringToQueue(const char *s_in, char *bqueue,
+ int pos, int size)
+{
+ for (int i = 0; i < size; ++i)
+ if (s_in[i] != bqueue[(pos + i) % size])
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/src/include/mime.h b/src/include/mime.h
new file mode 100644
index 0000000..2033442
--- /dev/null
+++ b/src/include/mime.h
@@ -0,0 +1,121 @@
+/** --------------------------------------------------------------------
+ * @file mime.h
+ * @brief Declaration of main mime parser components
+ * @author Andreas Aardal Hanssen
+ * @date Andreas Aardal Hanssen
+ * ----------------------------------------------------------------- **/
+#ifndef mime_h_included
+#define mime_h_included
+#include <string>
+#include <vector>
+#include <map>
+#include <stdio.h>
+
+namespace Binc {
+ //----------------------------------------------------------------------
+ class HeaderItem {
+ private:
+ mutable std::string key;
+ mutable std::string value;
+
+ public:
+ inline const std::string &getKey(void) const { return key; }
+ inline const std::string &getValue(void) const { return value; }
+
+ //--
+ HeaderItem(void);
+ HeaderItem(const std::string &key, const std::string &value);
+ };
+
+ //----------------------------------------------------------------------
+ class Header {
+ private:
+ mutable std::vector<HeaderItem> content;
+
+ public:
+ bool getFirstHeader(const std::string &key, HeaderItem &dest) const;
+ bool getAllHeaders(const std::string &key, std::vector<HeaderItem> &dest) const;
+ void add(const std::string &name, const std::string &content);
+ void clear(void) const;
+
+ //--
+ Header(void);
+ ~Header(void);
+ };
+
+ //----------------------------------------------------------------------
+ class IODevice;
+ class MimeDocument;
+ class MimePart {
+ protected:
+ public:
+ mutable bool multipart;
+ mutable bool messagerfc822;
+ mutable std::string subtype;
+ mutable std::string boundary;
+
+ mutable unsigned int headerstartoffsetcrlf;
+ mutable unsigned int headerlength;
+
+ mutable unsigned int bodystartoffsetcrlf;
+ mutable unsigned int bodylength;
+ mutable unsigned int nlines;
+ mutable unsigned int nbodylines;
+ mutable unsigned int size;
+
+ public:
+ enum FetchType {
+ FetchBody,
+ FetchHeader,
+ FetchMime
+ };
+
+ mutable Header h;
+
+ mutable std::vector<MimePart> members;
+
+ inline const std::string &getSubType(void) const { return subtype; }
+ inline bool isMultipart(void) const { return multipart; }
+ inline bool isMessageRFC822(void) const { return messagerfc822; }
+ inline unsigned int getSize(void) const { return bodylength; }
+ inline unsigned int getNofLines(void) const { return nlines; }
+ inline unsigned int getNofBodyLines(void) const { return nbodylines; }
+ inline unsigned int getBodyLength(void) const { return bodylength; }
+ inline unsigned int getBodyStartOffset(void) const { return bodystartoffsetcrlf; }
+
+ void printBody(int fd, Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
+ void printHeader(int fd, Binc::IODevice &output, std::vector<std::string> headers,
+ bool includeheaders, unsigned int startoffset, unsigned int length, std::string &storage) const;
+ void printDoc(int fd, Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
+ virtual void clear(void) const;
+
+ const MimePart *getPart(const std::string &findpart, std::string genpart, FetchType fetchType = FetchBody) const;
+ virtual int parseOnlyHeader(const std::string &toboundary) const;
+ virtual int parseFull(const std::string &toboundary, int &boundarysize) const;
+
+ MimePart(void);
+ virtual ~MimePart(void);
+ };
+
+ //----------------------------------------------------------------------
+ class MimeDocument : public MimePart {
+ private:
+ mutable bool headerIsParsed;
+ mutable bool allIsParsed;
+
+ public:
+ void parseOnlyHeader(int fd) const;
+ void parseFull(int fd) const;
+ void clear(void) const;
+
+ inline bool isHeaderParsed(void) { return headerIsParsed; }
+ inline bool isAllParsed(void) { return allIsParsed; }
+
+ //--
+ MimeDocument(void);
+ ~MimeDocument(void);
+ };
+
+};
+
+#endif
diff --git a/src/include/multilogdevice.h b/src/include/multilogdevice.h
new file mode 100644
index 0000000..a6f29f2
--- /dev/null
+++ b/src/include/multilogdevice.h
@@ -0,0 +1,29 @@
+/** --------------------------------------------------------------------
+ * @file multilogdevice.h
+ * @brief Declaration of the MultilogDevice class.
+ * @author Andreas Aardal Hanssen
+ * @date Andreas Aardal Hanssen
+ * ----------------------------------------------------------------- **/
+#ifndef multilogdevice_h_included
+#define multilogdevice_h_included
+
+#include "iodevice.h"
+
+namespace Binc {
+ class MultilogDevice : public IODevice {
+ public:
+ MultilogDevice(int flags);
+ ~MultilogDevice();
+
+ std::string service(void) const;
+
+ protected:
+ bool waitForWrite(void) const;
+ bool waitForRead(void) const;
+
+ WriteResult write(void);
+ bool fillInputBuffer(void);
+ };
+}
+
+#endif
diff --git a/src/include/operators.h b/src/include/operators.h
new file mode 100644
index 0000000..c030918
--- /dev/null
+++ b/src/include/operators.h
@@ -0,0 +1,476 @@
+/** --------------------------------------------------------------------
+ * @file operators.h
+ * @brief Declaration of all operators.
+ * @author Andreas Aardal Hanssen, Erwin Hoffmann
+ * @date 2002-2005, 2023
+ * ----------------------------------------------------------------- **/
+#ifndef operators_h_included
+#define operators_h_included
+#include <string>
+#include <vector>
+
+#include "imapparser.h"
+#include "depot.h"
+#include "message.h"
+
+namespace Binc {
+
+ //--------------------------------------------------------------------
+ class Operator {
+ public:
+ enum ProcessResult {OK, BAD, NO, NOTHING, ABORT};
+ enum ParseResult {ACCEPT, REJECT, ERROR, TIMEOUT};
+
+ virtual ProcessResult process(Depot &, Request &) = 0;
+ virtual ParseResult parse(Request &) const = 0;
+ virtual int getState(void) const = 0;
+ virtual const std::string getName(void) const = 0;
+
+ //--
+ virtual ~Operator(void) {};
+ };
+
+ //--------------------------------------------------------------------
+ class AppendOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ AppendOperator(void);
+ ~AppendOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class AuthenticateOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ ProcessResult Login(std::string& username, std::string& password);
+ ProcessResult Plain(std::string& username, std::string& password);
+ ProcessResult Cram(std::string& username, std::string& password,
+ std::string& challenge);
+
+ AuthenticateOperator(void);
+ ~AuthenticateOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class CapabilityOperator : public Operator {
+ std::vector<std::string> capabilities;
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ void addCapability(const std::string &cap);
+
+ CapabilityOperator(void);
+ ~CapabilityOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class CheckOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ CheckOperator(void);
+ ~CheckOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class CreateOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ CreateOperator(void);
+ ~CreateOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class CloseOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ CloseOperator(void);
+ ~CloseOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class CopyOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ CopyOperator(void);
+ ~CopyOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class DeleteOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ DeleteOperator(void);
+ ~DeleteOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class ExpungeOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ ExpungeOperator(void);
+ ~ExpungeOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class FetchOperator : public Operator {
+ protected:
+ ParseResult expectSectionText(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectSection(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectFetchAtt(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectOffset(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectHeaderList(BincImapParserFetchAtt &f_in) const;
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ FetchOperator(void);
+ ~FetchOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class IdOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ IdOperator(void);
+ ~IdOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class IdleOperator : public Operator {
+ protected:
+ ParseResult expectSectionText(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectSection(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectFetchAtt(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectOffset(BincImapParserFetchAtt &f_in) const;
+ ParseResult expectHeaderList(BincImapParserFetchAtt &f_in) const;
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ IdleOperator(void);
+ ~IdleOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class ListOperator : public Operator {
+ protected:
+ enum MailboxFlags {
+ DIR_SELECT = 0x01,
+ DIR_MARKED = 0x02,
+ DIR_NOINFERIORS = 0x04,
+ DIR_LEAF = 0x08
+ };
+
+ std::map<std::string, unsigned int> cache;
+ time_t cacheTimeout;
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ ListOperator(void);
+ ~ListOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class LoginOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ LoginOperator(void);
+ ~LoginOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class LogoutOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ LogoutOperator(void);
+ ~LogoutOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class LsubOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ LsubOperator(void);
+ ~LsubOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class NamespaceOperator : public Operator {
+ public:
+ virtual ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ NamespaceOperator(void);
+ ~NamespaceOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class NoopOperator : public Operator {
+ public:
+ virtual ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ NoopOperator(void);
+ ~NoopOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class NoopPendingOperator : public NoopOperator {
+ public:
+ ProcessResult process(Depot &, Request &);
+
+ NoopPendingOperator(void);
+ ~NoopPendingOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class RenameOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ RenameOperator(void);
+ ~RenameOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class SearchOperator : public Operator {
+ protected:
+ ParseResult expectSearchKey(BincImapParserSearchKey &s_in) const;
+
+ //------------------------------------------------------------------
+ class SearchNode {
+
+ std::string date;
+ std::string astring;
+ std::string bstring;
+ unsigned int number;
+
+ int type;
+ mutable int weight;
+ const SequenceSet *bset;
+
+ std::vector<SearchNode> children;
+
+ public:
+ enum {
+ S_ALL, S_ANSWERED, S_BCC, S_BEFORE, S_BODY, S_CC, S_DELETED,
+ S_FLAGGED, S_FROM, S_KEYWORD, S_NEW, S_OLD, S_ON, S_RECENT,
+ S_SEEN, S_SINCE, S_SUBJECT, S_TEXT, S_TO, S_UNANSWERED,
+ S_UNDELETED, S_UNFLAGGED, S_UNKEYWORD, S_UNSEEN, S_DRAFT,
+ S_HEADER, S_LARGER, S_NOT, S_OR, S_SENTBEFORE, S_SENTON,
+ S_SENTSINCE, S_SMALLER, S_UID, S_UNDRAFT, S_SET, S_AND
+ };
+
+ static bool convertDate(const std::string &date, time_t &t, const std::string &delim = "-");
+ static bool convertDateHeader(const std::string &d_in, time_t &t);
+
+ void order(void);
+
+ bool match(Mailbox *, Message *,
+ unsigned seqnr, unsigned int lastmessage,
+ unsigned int lastuid) const;
+
+ int getType(void) const;
+ int getWeight(void) const;
+ void setWeight(int i);
+
+ void init(const BincImapParserSearchKey &a);
+
+ //-
+ static bool compareNodes(const SearchNode &a,
+ const SearchNode &b)
+ {
+ return a.getWeight() < b.getWeight();
+ }
+
+ SearchNode(void);
+ SearchNode(const BincImapParserSearchKey &a);
+ };
+
+ public:
+
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ SearchOperator(void);
+ ~SearchOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class SelectOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ SelectOperator(void);
+ ~SelectOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class ExamineOperator : public SelectOperator {
+ public:
+ const std::string getName(void) const;
+ ExamineOperator(void);
+ ~ExamineOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class StarttlsOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+ int goStartTLS(void) const;
+
+ StarttlsOperator(void);
+ ~StarttlsOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class StatusOperator : public Operator {
+
+ std::map<int, Status> statuses;
+
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ StatusOperator(void);
+ ~StatusOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class StoreOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ StoreOperator(void);
+ ~StoreOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class SubscribeOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ SubscribeOperator(void);
+ ~SubscribeOperator(void);
+ };
+
+ //--------------------------------------------------------------------
+ class UnsubscribeOperator : public Operator {
+ public:
+ ProcessResult process(Depot &, Request &);
+ virtual ParseResult parse(Request &) const;
+
+ const std::string getName(void) const;
+ int getState(void) const;
+
+ UnsubscribeOperator(void);
+ ~UnsubscribeOperator(void);
+ };
+}
+
+#endif
diff --git a/src/include/pendingupdates.h b/src/include/pendingupdates.h
new file mode 100644
index 0000000..ea192de
--- /dev/null
+++ b/src/include/pendingupdates.h
@@ -0,0 +1,107 @@
+/** --------------------------------------------------------------------
+ * @file pendingupdates.h
+ * @brief <--->
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#include <map>
+#include <vector>
+
+#ifndef pendingupdates_h_included
+#define pendingupdates_h_included
+
+namespace Binc {
+ class Mailbox;
+
+ //------------------------------------------------------------------------
+ class PendingUpdates {
+ public:
+ enum {
+ EXPUNGE = 0x01,
+ FLAGS = 0x02,
+ EXISTS = 0x04,
+ RECENT = 0x08
+ };
+
+ //----------------------------------------------------------------------
+ class expunged_const_iterator {
+ private:
+ std::vector<unsigned int>::iterator internal;
+
+ public:
+ unsigned int operator * (void) const;
+ void operator ++ (void);
+ bool operator != (expunged_const_iterator) const;
+ bool operator == (expunged_const_iterator) const;
+
+ //--
+ expunged_const_iterator(void);
+ expunged_const_iterator(std::vector<unsigned int>::iterator i);
+ };
+
+ //--
+ expunged_const_iterator beginExpunged(void);
+ expunged_const_iterator endExpunged(void);
+
+ //----------------------------------------------------------------------
+ class flagupdates_const_iterator {
+ private:
+ std::map<unsigned int, unsigned int>::iterator internal;
+ std::map<unsigned int, unsigned int> *sqnrtouid;
+ std::map<unsigned int, std::vector<std::string> > *sqnrtocflags;
+
+ public:
+ unsigned int first(void) const;
+ unsigned int second(void) const;
+ std::vector<std::string> getCustomFlags(void) const;
+ unsigned int getUID(void) const;
+
+ void operator ++ (void);
+ bool operator != (flagupdates_const_iterator) const;
+
+ //--
+ flagupdates_const_iterator(void);
+ flagupdates_const_iterator(std::map<unsigned int, unsigned int>::iterator i,
+ std::map<unsigned int, std::vector<std::string> > *,
+ std::map<unsigned int, unsigned int> *);
+ };
+
+ //--
+ flagupdates_const_iterator beginFlagUpdates(void);
+ flagupdates_const_iterator endFlagUpdates(void);
+
+ //--
+ void addExpunged(unsigned int uid);
+ void addFlagUpdates(unsigned int sqnr, unsigned int uid,
+ unsigned int flags,
+ const std::vector<std::string> &cflags);
+ void setExists(unsigned int n);
+ void setRecent(unsigned int n);
+ unsigned int getExists(void) const;
+ unsigned int getRecent(void) const;
+ bool newExists(void) const;
+ bool newRecent(void) const;
+
+ //--
+ PendingUpdates(void);
+ ~PendingUpdates(void);
+
+ private:
+ std::vector<unsigned int> expunges;
+ std::map<unsigned int, unsigned int> flagupdates;
+ std::map<unsigned int, unsigned int> sqnrtouid;
+ std::map<unsigned int, std::vector<std::string> > sqnrtocflags;
+
+ unsigned int exists;
+ unsigned int recent;
+ bool newexists;
+ bool newrecent;
+ };
+
+ bool pendingUpdates(Mailbox *, int type, bool rescan,
+ bool showAll = false,
+ bool forceScan = false,
+ bool uidfetchflags = false);
+}
+
+#endif
diff --git a/src/include/recursivedescent.h b/src/include/recursivedescent.h
new file mode 100644
index 0000000..ea8fe33
--- /dev/null
+++ b/src/include/recursivedescent.h
@@ -0,0 +1,64 @@
+/** --------------------------------------------------------------------
+ * @file recursivedescent.h
+ * @brief Declaration of a recursive descent IMAP command parser.
+ * @author Andreas Aardal Hanssen
+ * @date Andreas Aardal Hanssen
+ * ----------------------------------------------------------------- **/
+#ifndef expectcommand_h_inluded
+#define expectcommand_h_inluded
+#include <stack>
+#include <string>
+
+#include "imapparser.h"
+#include "operators.h"
+
+namespace Binc {
+
+ extern std::stack<int> inputBuffer;
+ extern int charnr;
+
+ int readChar(void);
+ void unReadChar(int c_in);
+ void unReadChar(const std::string &s_in);
+
+ Operator::ParseResult expectTag(std::string &s_in);
+ Operator::ParseResult expectTagChar(int &c_in);
+ Operator::ParseResult expectSPACE(void);
+
+ Operator::ParseResult expectFlag(std::vector<std::string> &v_in);
+
+ Operator::ParseResult expectListMailbox(std::string &s_in);
+ Operator::ParseResult expectListWildcards(int &c_in);
+
+ Operator::ParseResult expectDateTime(std::string &s_in);
+ Operator::ParseResult expectTime(std::string &s_in);
+ Operator::ParseResult expectZone(std::string &s_in);
+
+ Operator::ParseResult expectMailbox(std::string &s_in);
+ Operator::ParseResult expectAstring(std::string &s_in);
+ Operator::ParseResult expectAtom(std::string &s_in);
+ Operator::ParseResult expectAtomChar(int &i_in);
+ Operator::ParseResult expectString(std::string &s_in);
+
+ Operator::ParseResult expectDate(std::string &s_in);
+
+ Operator::ParseResult expectNumber(unsigned int &i_in);
+ Operator::ParseResult expectDigit(unsigned int &i_in);
+ Operator::ParseResult expectDigitNZ(unsigned int &i_in);
+
+ Operator::ParseResult expectLiteral(std::string &s_in);
+ Operator::ParseResult expectQuoted(std::string &s_in);
+ Operator::ParseResult expectQuotedChar(int &c_in);
+
+ Operator::ParseResult expectSet(SequenceSet &s_in);
+ Operator::ParseResult expectSequenceNum(unsigned int &i_in);
+ Operator::ParseResult expectNZNumber(unsigned int &i_in);
+
+ Operator::ParseResult expectCRLF(void);
+ Operator::ParseResult expectCR(void);
+ Operator::ParseResult expectLF(void);
+
+ Operator::ParseResult expectThisString(const std::string &s_in);
+}
+
+#endif
diff --git a/src/include/regmatch.h b/src/include/regmatch.h
new file mode 100644
index 0000000..1471e90
--- /dev/null
+++ b/src/include/regmatch.h
@@ -0,0 +1,17 @@
+/** --------------------------------------------------------------------
+ * @file regex.h
+ * @brief Declaration of miscellaneous regexp functions.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef regex_h_included
+#define regex_h_included
+
+#include <string>
+
+namespace Binc {
+
+ int regexMatch(const std::string &data_in, const std::string &p_in);
+}
+
+#endif
diff --git a/src/include/session.h b/src/include/session.h
new file mode 100644
index 0000000..94825cd
--- /dev/null
+++ b/src/include/session.h
@@ -0,0 +1,116 @@
+/** --------------------------------------------------------------------
+ * @file session.h
+ * @brief <--->
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef session_h_included
+#define session_h_included
+#include <string>
+#include <vector>
+#include <map>
+#include <sys/types.h>
+
+#include "argparser.h"
+
+namespace Binc {
+
+ class Depot;
+
+ //--------------------------------------------------------------------
+ class Session {
+ public:
+ std::map<std::string, std::string> attrs;
+
+ char **unparsedArgs;
+
+ struct {
+ bool help;
+ bool version;
+ bool ssl;
+ } command;
+
+ bool mailboxchanges;
+
+ enum State {
+ NONAUTHENTICATED = 0x01,
+ AUTHENTICATED = 0x02,
+ SELECTED = 0x04,
+ LOGOUT = 0x00
+ };
+
+ CommandLineArgs args;
+
+ int timeout() const;
+
+ bool hasEnv(const std::string &key) const;
+ std::string getEnv(const std::string &key);
+ void setEnv(const std::string &key, const std::string &value);
+
+ const int getState(void) const;
+ void setState(int n);
+ bool parseCommandLine(int argc, char * argv[]);
+ void assignCommandLineArgs(void);
+ int getWriteBytes(void) const;
+ int getReadBytes(void) const;
+ void addWriteBytes(int);
+ void addReadBytes(int);
+ int getBodies(void) const;
+ int getStatements(void) const;
+ void addBody(void);
+ void addStatement(void);
+ void setLogFacility(int facility);
+ int getLogFacility(void) const;
+
+ const std::string &getLastError(void) const;
+ const std::string &getResponseCode(void) const;
+ const std::string &getIP(void) const;
+ const std::string &getUserID() const;
+ pid_t getPid(void);
+ const std::string &getHostname(void);
+ void setLastError(const std::string &error) const;
+ void setResponseCode(const std::string &error) const;
+ void clearResponseCode(void) const;
+ void setIP(const std::string &ip);
+ void setUserID(const std::string &s);
+
+ inline Depot *getDepot(void) const;
+
+ //--
+ static Session &getInstance(void);
+
+ bool initialize(int argc, char *argv[]);
+
+ private:
+ //--
+ int state;
+ std::string userid;
+ std::string ip;
+ char **argv;
+ int argc;
+
+ int logfacility;
+
+ int readbytes;
+ int writebytes;
+ int statements;
+ int bodies;
+
+ Depot *depot;
+
+ mutable std::string lastError;
+ mutable std::string responseCode;
+
+ pid_t pid;
+ std::string hostname;
+
+ Session(void);
+ };
+
+ inline Depot *Session::getDepot(void) const
+ {
+ return depot;
+ }
+}
+
+#endif
diff --git a/src/include/status.h b/src/include/status.h
new file mode 100644
index 0000000..f7f9e1f
--- /dev/null
+++ b/src/include/status.h
@@ -0,0 +1,50 @@
+/** --------------------------------------------------------------------
+ * @file status.h
+ * @brief Declaration of the Status class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#ifndef status_h_included
+#define status_h_included
+
+namespace Binc {
+
+ //------------------------------------------------------------------------
+ class Status {
+
+ //--
+ int recent;
+ int messages;
+ int unseen;
+ int uidvalidity;
+ int uidnext;
+
+ //--
+ int statusid;
+
+ public:
+
+ //--
+ inline void setMessages(int i) { messages = i; }
+ inline void setRecent(int i) { recent = i; }
+ inline void setStatusID(int i) { statusid = i; }
+ inline void setUnseen(int i) { unseen = i; }
+ inline void setUidValidity(int i) { uidvalidity = i; }
+ inline void setUidNext(int i) { uidnext = i; }
+
+ //--
+ inline int getMessages(void) const { return messages; }
+ inline int getRecent(void) const { return recent; }
+ inline int getStatusID(void) const { return statusid; }
+ inline int getUnseen(void) const { return unseen; }
+ inline int getUidValidity(void) const { return uidvalidity; }
+ inline int getUidNext(void) const { return uidnext; }
+
+
+ //--
+ Status(void);
+ ~Status(void);
+ };
+}
+
+#endif
diff --git a/src/include/stdiodevice.h b/src/include/stdiodevice.h
new file mode 100644
index 0000000..026386c
--- /dev/null
+++ b/src/include/stdiodevice.h
@@ -0,0 +1,31 @@
+/** --------------------------------------------------------------------
+ * @file stdiodevice.h
+ * @brief Declaration of the StdIODevice class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002, 2003
+ * ----------------------------------------------------------------- **/
+#ifndef stdiodevice_h_included
+#define stdiodevice_h_included
+
+#include "iodevice.h"
+
+namespace Binc {
+ class StdIODevice : public IODevice {
+ public:
+ StdIODevice(int flags);
+ ~StdIODevice();
+
+ std::string service(void) const;
+
+ bool canRead(void) const;
+
+ protected:
+ bool waitForWrite(void) const;
+ bool waitForRead(void) const;
+
+ WriteResult write(void);
+ bool fillInputBuffer(void);
+ };
+}
+
+#endif
diff --git a/src/include/syslogdevice.h b/src/include/syslogdevice.h
new file mode 100644
index 0000000..2269fb2
--- /dev/null
+++ b/src/include/syslogdevice.h
@@ -0,0 +1,41 @@
+/** --------------------------------------------------------------------
+ * @file Syslogdevice.h
+ * @brief Declaration of the SyslogDevice class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002, 2003
+ * ----------------------------------------------------------------- **/
+#ifndef syslogdevice_h_included
+#define syslogdevice_h_included
+
+#include "iodevice.h"
+#include <syslog.h>
+
+namespace Binc {
+ class SyslogDevice : public IODevice {
+ public:
+ SyslogDevice(int flags, const char *ident = "bincimap",
+ int option = LOG_NDELAY | LOG_PID,
+ int facility = LOG_USER);
+ ~SyslogDevice();
+
+ void setPriority(int p);
+
+ std::string service(void) const;
+
+ protected:
+ bool waitForWrite(void) const;
+ bool waitForRead(void) const;
+
+ WriteResult write(void);
+ bool fillInputBuffer(void);
+
+ private:
+ static std::string ident;
+
+ int option;
+ int facility;
+ int priority;
+ };
+}
+
+#endif
diff --git a/src/include/tools.h b/src/include/tools.h
new file mode 100644
index 0000000..67ed91e
--- /dev/null
+++ b/src/include/tools.h
@@ -0,0 +1,23 @@
+/** --------------------------------------------------------------------
+ * @file tools.h
+ * @brief Declaration of miscellaneous tools.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#include <string>
+
+namespace Binc {
+
+ class Tools {
+ private:
+ Tools(void);
+
+ public:
+ void setenv(const std::string &key, const std::string &value) const;
+ std::string getenv(const std::string &key) const;
+
+ //--
+ static Tools &getInstance(void);
+ };
+
+}