diff options
Diffstat (limited to 'libmail/mail.C')
| -rw-r--r-- | libmail/mail.C | 820 |
1 files changed, 0 insertions, 820 deletions
diff --git a/libmail/mail.C b/libmail/mail.C deleted file mode 100644 index 8514303..0000000 --- a/libmail/mail.C +++ /dev/null @@ -1,820 +0,0 @@ -/* -** Copyright 2002-2004, Double Precision Inc. -** -** See COPYING for distribution information. -*/ -#include "mail.H" -#include "sync.H" - -#include "driver.H" -#include "mbox.H" - -#include "runlater.H" -#include "logininfo.H" -#include <iostream> -#include <errno.h> -#include <netinet/in.h> -#include <unistd.h> -#include <pwd.h> -#include <arpa/inet.h> -#include "rfc822/rfc822.h" -#include "unicode/courier-unicode.h" -#include "maildir/maildiraclt.h" -#include "misc.H" -#include <fstream> - -using namespace std; - -list<mail::account *> mail::account::mailaccount_list; - -// -// Initialize mail::folder's default. mail::folder is a superclass for -// mail folder objects. Each mail account type is expected to use a -// subclass for the actual implementation. -// -// Each mail::folder object is associated with a corresponding mail::account -// object. The constructor saves a pointer, and provides methods that -// the subclass can use to determine whether the mail::account object still exists - -mail::folder::folder(mail::account *ptr) : myServer(ptr) -{ -} - -mail::folder::~folder() -{ -} - -// -// The first order of business for any mail::folder method call is to -// determine whether the mail::account object still exists. This method is -// a shortcut for most methods that receive a mail::callback object. -// If the mail::account object was destroyed, callback's fail method is called -// appropriately. - -bool mail::folder::isDestroyed(mail::callback &callback) const -{ - if (myServer.isDestroyed()) - { - callback.fail("Server connection closed."); - return true; - } - - return false; -} - -bool mail::folder::isDestroyed() const -{ - return myServer.isDestroyed(); -} - -string mail::folder::isNewsgroup() const -{ - return ""; -} - -void mail::folder::getMyRights(mail::callback &getCallback, - std::string &rights) const -{ - getCallback.fail("This server does not implement access control lists."); - -} - -void mail::folder::getRights(mail::callback &getCallback, - std::list<std::pair<std::string, std::string> > - &rights) const -{ - rights.clear(); - getCallback.fail("This server does not implement access control lists."); -} - -void mail::folder::setRights(mail::callback &setCallback, - string &errorIdentifier, - vector<std::string> &errorRights, - string identifier, - string rights) const -{ - errorIdentifier=""; - errorRights.clear(); - setCallback.fail("This server does not implement access control lists."); -} - -void mail::folder::delRights(mail::callback &setCallback, - string &errorIdentifier, - vector<std::string> &errorRights, - std::string identifier) const -{ - errorIdentifier=""; - errorRights.clear(); - setCallback.fail("This server does not implement access control lists."); -} - -// -// callback::folder miscellania - -mail::callback::folder::folder() -{ -} - -mail::callback::folder::~folder() -{ -} - -void mail::callback::folder::saveSnapshot(std::string snapshotId) -{ -} - -// mail::callback::folderList miscellania - -mail::callback::folderList::folderList() -{ -} - -mail::callback::folderList::~folderList() -{ -} - -// mail::callback::folderInfo miscellania - -mail::callback::folderInfo::folderInfo() - : messageCount(0), unreadCount(0), fastInfo(false) -{ -} - -mail::callback::folderInfo::~folderInfo() -{ -} - -void mail::callback::folderInfo::success() -{ -} - -// messageInfo miscellania - -mail::messageInfo::messageInfo() -{ - uid=""; - draft=replied=marked=deleted=unread=recent=false; -} - -mail::messageInfo::messageInfo(string s) -{ - uid=""; - draft=replied=marked=deleted=unread=recent=false; - - string::iterator b=s.begin(), e=s.end(); - - while (b != e) - { - switch (*b++) { - case 'D': - draft=true; - break; - case 'R': - replied=true; - break; - case 'M': - marked=true; - break; - case 'T': - deleted=true; - break; - case 'U': - unread=true; - break; - case 'C': - recent=true; - break; - case ':': - uid=string(b, e); - b=e; - break; - } - } -} - -mail::messageInfo::~messageInfo() -{ -} - -mail::messageInfo::operator string() const -{ - string s; - - if (draft) s += "D"; - if (replied) s += "R"; - if (marked) s += "M"; - if (deleted) s += "T"; - if (unread) s += "U"; - if (recent) s += "C"; - - return s + ":" + uid; -} - - -// -// mail::account superclass constructor. The main task at hand is to save -// a reference to the disconnect callback, for later use, and to initialize -// the default character set. -// - -mail::account::account(mail::callback::disconnect &callbackArg) - : disconnect_callback(callbackArg) -{ - my_mailaccount_p=mailaccount_list.insert(mailaccount_list.end(), this); -} - -mail::account::~account() -{ - // We can't just remove (this) from mailaccount_list, because we - // might be iterating mail:;account::process(). - - *my_mailaccount_p=NULL; -} - -////////////////////////////////////////////////////////////////////////////// -// -// Utility functions. -// -////////////////////////////////////////////////////////////////////////////// - -LIBMAIL_START - -string hostname() -{ - char h[512]; - - h[sizeof(h)-1]=0; - - if (gethostname(h, sizeof(h)-1) < 0) - strcpy(h, "localhost"); - return h; -} - -string homedir() -{ - const char *h=getenv("HOME"); - - struct passwd *pw=getpwuid(getuid()); - - if (!pw) - return ""; - - if (h == NULL || !*h) - h=pw->pw_dir; - - return h; -} - -void upper(string &w) -{ - for (string::iterator b=w.begin(), e=w.end(); b != e; ++b) - if (*b >= 'a' && *b <= 'z') - *b += 'A'-'a'; -} -LIBMAIL_END - -static const char x[]="0123456789ABCDEF"; - -static string encword(string w) -{ - string ww=""; - - string::iterator b=w.begin(), e=w.end(), c; - - while (b != e) - { - for (c=b; c != e; c++) - if ( *c == '@' || *c == '/' || *c == '%' || *c == ':') - break; - - ww.append(b, c); - - b=c; - - if (b != e) - { - ww += '%'; - ww += x[ (*b / 16) & 15 ]; - ww += x[ *b & 15]; - b++; - } - } - - return ww; -} - -LIBMAIL_START -string loginUrlEncode(string method, string server, string uid, - string pwd) -{ - return (method + "://" + - (uid.size() > 0 ? encword(uid) - + (pwd.size() > 0 ? ":" + encword(pwd):"") + "@":"") - + server); -} -LIBMAIL_END - -static string decword(string w) -{ - string ww=""; - - string::iterator b=w.begin(), e=w.end(), c; - - while (b != e) - { - for (c=b; c != e; c++) - if ( *c == '%' && e-c > 2) - break; - - ww.append(b, c); - - b=c; - - if (b != e) - { - b++; - - const char *c1= strchr(x, *b++); - const char *c2= strchr(x, *b++); - - char c=0; - - if (c1) c= (c1-x) * 16; - if (c2) c += c2-x; - - ww += c; - } - } - - return ww; -} - -LIBMAIL_START - -// Parse url format: method://uid:pwd@server/option/option... - -bool loginUrlDecode(string url, mail::loginInfo &loginInfo) -{ - size_t n=url.find(':'); - - if (n == std::string::npos) - return false; - - loginInfo.method=url.substr(0, n); - - if (url.size() - n < 3 || url[n+1] != '/' || url[n+2] != '/') - return false; - - string serverStr=url.substr(n+3); - string options=""; - - n=serverStr.find('/'); - - if (n != std::string::npos) - { - options=serverStr.substr(n+1); - serverStr.erase(n); - } - - n=serverStr.rfind('@'); - string uidpwd=""; - - if (n != std::string::npos) - { - uidpwd=serverStr.substr(0, n); - serverStr=serverStr.substr(n+1); - } - loginInfo.server=serverStr; - - n=uidpwd.find(':'); - - string pwd=""; - - if (n != std::string::npos) - { - pwd=uidpwd.substr(n+1); - uidpwd=uidpwd.substr(0, n); - } - - loginInfo.uid=decword(uidpwd); - loginInfo.pwd=decword(pwd); - - while (options.size() > 0) - { - n=options.find('/'); - - string option; - - if (n == std::string::npos) - { - option=options; - options=""; - } - else - { - option=options.substr(0, n); - options=options.substr(n+1); - } - - string optionVal; - - n=option.find('='); - - if (n != std::string::npos) - { - optionVal=option.substr(n+1); - option=option.substr(0, n); - } - - loginInfo.options.insert(make_pair(option, optionVal)); - } - return true; -} - -LIBMAIL_END - -mail::account::openInfo::openInfo() : loginCallbackObj(NULL) -{ -} - -mail::account::openInfo::~openInfo() -{ -} - -mail::account *mail::account::open(mail::account::openInfo oi, - mail::callback &callback, - mail::callback::disconnect - &disconnectCallback) -{ - mail::driver **l=mail::driver::get_driver_list(); - - while (*l) - { - mail::account *a; - - if ( (*(*l)->open_func)(a, oi, callback, disconnectCallback)) - { - if (!a) - callback.fail(strerror(errno)); - return a; - } - - l++; - } - - callback.fail("Invalid mail account URL."); - return NULL; -} - -bool mail::account::isRemoteUrl(std::string url) -{ - mail::driver **l=mail::driver::get_driver_list(); - - while (*l) - { - bool flag; - - if ( (*(*l)->isRemote_func)(url, flag)) - return flag; - - l++; - } - - return false; -} - -// Default implementation of getSendFolder: no such luck. - -mail::folder *mail::account::getSendFolder(const class mail::smtpInfo &info, - const mail::folder *folder, - string &errmsg) -{ - errno=ENOENT; - errmsg="Not implemented."; - return NULL; -} - -// -// The main function. Where everything good happens. -// -// mail::account::process calls each existing mail::account object's handler method. -// -void mail::account::process(vector<pollfd> &fds, int &timeout) -{ - list<mail::account *>::iterator b, e, cur; - - fds.clear(); - b=mailaccount_list.begin(); - e=mailaccount_list.end(); - - while (b != e) - { - // mail::account may destroy itself, so increment the iterator - // before invoking the method - - cur=b; - b++; - - if (*cur == NULL) - mailaccount_list.erase(cur); - else - { - (*cur)->handler(fds, timeout); - } - } - - // Postponed handlers. - mail::runLater::checkRunLater(timeout); -} - -// -// Resume after suspend. -// - -void mail::account::resume() -{ - list<mail::account *>::iterator b, e, cur; - - b=mailaccount_list.begin(); - e=mailaccount_list.end(); - - while (b != e) - { - // mail::account may destroy itself, so increment the iterator - // before invoking the method - - cur=b; - ++b; - - if (*cur) - (*cur)->resumed(); - } -} - -void mail::account::updateNotify(bool enableDisable, callback &callbackArg) -{ - callbackArg.success("OK"); -} - -void mail::account::moveMessagesTo(const std::vector<size_t> &messages, - mail::folder *copyTo, - mail::callback &callback) -{ - generic::genericMoveMessages(this, messages, copyTo, callback); -} - -#if 0 -void mail::account::removeMessages(const std::vector<size_t> &messages, - callback &cb) -{ - cb.fail("TODO"); -} - -#endif - -void mail::account::updateKeywords(const vector<size_t> &messages, - const set<string> &keywords, - bool setOrChange, - // false: set, true: see changeTo - bool changeTo, - mail::callback &cb) -{ - cb.fail("Not implemented"); -} - -void mail::account::updateKeywords(const vector<size_t> &messages, - const vector<string> &keywords, - bool setOrChange, - bool changeTo, - mail::callback &cb) -{ - set<string> s; - - s.insert(keywords.begin(), keywords.end()); - - updateKeywords(messages, s, setOrChange, changeTo, cb); -} - - -void mail::account::updateKeywords(const vector<size_t> &messages, - const list<string> &keywords, - bool setOrChange, - bool changeTo, - mail::callback &cb) -{ - set<string> s; - - s.insert(keywords.begin(), keywords.end()); - - updateKeywords(messages, s, setOrChange, changeTo, cb); -} - -void mail::account::getFolderKeywordInfo(size_t messageNum, - set<string> &keywordRet) -{ - keywordRet.clear(); -} - - - - -// -// Must provide default methods for mail::callback::message, not all -// subclasses must implement every method. -// - -mail::callback::message::message() -{ -} - -mail::callback::message::~message() -{ -} - -void mail::callback::message::messageEnvelopeCallback(size_t n, - const mail::envelope - &env) -{ -} - -void mail::callback::message::messageReferencesCallback(size_t n, - const vector<string> - &references) -{ -} - -void mail::callback::message::messageStructureCallback(size_t n, - const mail::mimestruct - &mstruct) -{ -} - -void mail::callback::message::messageTextCallback(size_t n, string text) -{ -} - -void mail::callback::message -::messageArrivalDateCallback(size_t messageNumber, - time_t datetime) -{ -} - -void mail::callback::message::messageSizeCallback(size_t messageNumber, - unsigned long messagesize) -{ -} - -LIBMAIL_START - -string toutf8(string s) -{ - string u; - - char *p=unicode_convert_toutf8(s.c_str(), - unicode_default_chset(), NULL); - - try { - u=p; - free(p); - } catch (...) { - free(p); - LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); - } - return u; -} - -string fromutf8(string s) -{ - string u; - - char *p=unicode_convert_fromutf8(s.c_str(), unicode_default_chset(), - NULL); - - try { - u=p; - free(p); - } catch (...) { - free(p); - LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); - } - return u; -} -LIBMAIL_END - -// -// Common code for mbox and maildir -// - -string mail::mbox::translatePathCommon(string path, - const char *verbotten, - const char *sep) -{ - string newpath; - - do - { - string component; - - size_t n=path.find('/'); - - if (n == std::string::npos) - { - component=path; - path=""; - } - else - { - component=path.substr(0, n); - path=path.substr(n+1); - } - - vector<unicode_char> ucvec; - - unicode_char *uc; - size_t ucsize; - unicode_convert_handle_t h; - - if ((h=unicode_convert_tou_init(unicode_default_chset(), - &uc, &ucsize, 1)) == NULL) - { - uc=NULL; - } - else - { - unicode_convert(h, component.c_str(), - component.size()); - - if (unicode_convert_deinit(h, NULL)) - uc=NULL; - } - - if (!uc) - { - errno=EINVAL; - return ""; - } - - try { - size_t n; - - for (n=0; uc[n]; n++) - ; - - ucvec.insert(ucvec.end(), uc, uc+n); - - for (n=0; n<ucvec.size(); ) - { - if (ucvec[n] == '\\' && n+1 < ucvec.size()) - { - ucvec.erase(ucvec.begin()+n, - ucvec.begin()+n+1); - n++; - continue; - } - if (ucvec[n] == '%') - { - unicode_char ucnum=0; - size_t o=n+1; - - while (o < ucvec.size()) - { - if ((unsigned char)ucvec[o] - != ucvec[o]) - break; - if (!isdigit(ucvec[o])) - break; - - ucnum=ucnum * 10 + - ucvec[o]-'0'; - ++o; - } - - if (o < ucvec.size() && - ucvec[o] == ';') - ++o; - - ucvec[n++]=ucnum; - ucvec.erase(ucvec.begin()+n, - ucvec.begin()+o); - continue; - } - n++; - } - } catch (...) { - free(uc); - LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); - } - - free(uc); - std::string p(mail::iconvert::convert(ucvec, - std::string(unicode_x_imap_modutf7 " ") - + verbotten)); - - - if (newpath.size() > 0) - newpath += sep; - newpath += p; - } while (path.size() > 0); - - return newpath; -} |
