diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /libmail/smapopen.C | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'libmail/smapopen.C')
| -rw-r--r-- | libmail/smapopen.C | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/libmail/smapopen.C b/libmail/smapopen.C new file mode 100644 index 0000000..b41a932 --- /dev/null +++ b/libmail/smapopen.C @@ -0,0 +1,280 @@ +/* +** Copyright 2003, Double Precision Inc. +** +** See COPYING for distribution information. +*/ + +#include "smap.H" +#include "smapopen.H" +#include "smapnewmail.H" +#include "snapshot.H" +#include "imapfolder.H" +#include <string.h> +#include <errno.h> +#include <sstream> + +using namespace std; + +///////////////////////////////////////////////////////////////////////// +// +// Helper for restoring snapshots + + +class mail::smapOPEN::SnapshotRestoreHelper : public mail::snapshot::restore { + +public: + mail::imap &myimap; + mail::imapFOLDERinfo *myFolderInfo; + bool aborted; + + SnapshotRestoreHelper(mail::imapFOLDERinfo *myFolderInfoArg, + mail::imap &myimapArg); + ~SnapshotRestoreHelper(); + void restoreIndex(size_t msgNum, + const mail::messageInfo &info); + void restoreKeywords(size_t msgNum, + const std::set<std::string> &set); + void abortRestore(); +}; + +mail::smapOPEN::SnapshotRestoreHelper:: +SnapshotRestoreHelper(mail::imapFOLDERinfo *myFolderInfoArg, + mail::imap &myimapArg) + : myimap(myimapArg), myFolderInfo(myFolderInfoArg), aborted(false) +{ +} + +mail::smapOPEN::SnapshotRestoreHelper:: +~SnapshotRestoreHelper() +{ +} + +void mail::smapOPEN::SnapshotRestoreHelper:: +restoreIndex(size_t msgNum, + const mail::messageInfo &info) +{ + if (msgNum < myFolderInfo->index.size()) + ((mail::messageInfo &)myFolderInfo->index[msgNum])=info; +} + +void mail::smapOPEN::SnapshotRestoreHelper:: +restoreKeywords(size_t msgNum, + const set<string> &kset) +{ + if (msgNum < myFolderInfo->index.size()) + { + myFolderInfo->index[msgNum].keywords + .setFlags(myimap.keywordHashtable, + kset); + } +} + +void mail::smapOPEN::SnapshotRestoreHelper::abortRestore() +{ + aborted=true; +} + +///////////////////////////////////////////////////////////////////////// + +const char *mail::smapOPEN::getName() +{ + return "OPEN"; +} + +mail::smapOPEN::smapOPEN(string pathArg, + mail::snapshot *restoreSnapshotArg, + mail::callback &openCallbackArg, + mail::callback::folder &folderCallbackArg) + : path(pathArg), restoreSnapshot(restoreSnapshotArg), + folderCallback(folderCallbackArg), newSmapFolder(NULL), exists(0), + restoringSnapshot(false) +{ + defaultCB= &openCallbackArg; +} + +mail::smapOPEN::~smapOPEN() +{ + if (newSmapFolder) + delete newSmapFolder; +} + +void mail::smapOPEN::installed(imap &imapAccount) +{ + newSmapFolder=new smapFOLDER(path, folderCallback, imapAccount); + + if (!newSmapFolder) + LIBMAIL_THROW((strerror(errno))); + + vector<string> words; + + path2words(path, words); + + vector<string>::iterator b=words.begin(), e=words.end(); + + string pstr=""; + + while (b != e) + { + pstr += " "; + pstr += imapAccount.quoteSMAP( *b ); + b++; + } + + if (imapAccount.currentFolder) + imapAccount.currentFolder->closeInProgress=true; + + string snapshotId; + + if (restoreSnapshot) + { + size_t nMessages; + + restoreSnapshot->getSnapshotInfo(snapshotId, nMessages); + + if (snapshotId.size() > 0) + { + newSmapFolder->index.resize(nMessages); + + SnapshotRestoreHelper myHelper(newSmapFolder, + imapAccount); + restoreSnapshot->restoreSnapshot(myHelper); + + if (myHelper.aborted) + snapshotId=""; + } + + vector<imapFOLDERinfo::indexInfo>::iterator + b=newSmapFolder->index.begin(), + e=newSmapFolder->index.end(); + + while (b != e) + { + if (b->uid.size() == 0) + { + snapshotId=""; // Bad restore. + break; + } + b++; + } + + if (snapshotId.size() == 0) + newSmapFolder->index.clear(); + + imapAccount.imapcmd("", "SOPEN " + + mail::imap::quoteSMAP(snapshotId) + + " " + pstr + "\n"); + } + else + imapAccount.imapcmd("", "OPEN" + pstr + "\n"); +} + +bool mail::smapOPEN::processLine(imap &imapAccount, + std::vector<const char *> &words) +{ + if (words.size() >= 3 && strcmp(words[0], "*") == 0 && + strcasecmp(words[1], "SNAPSHOTEXISTS") == 0) + { + restoringSnapshot=true; + presnapshotExists=exists=newSmapFolder->index.size(); + return true; + } + + if (words.size() >= 3 && strcmp(words[0], "*") == 0 && + strcasecmp(words[1], "EXISTS") == 0) + { + string n(words[2]); + istringstream i(n); + i >> exists; + + if (restoringSnapshot && exists > newSmapFolder->index.size()) + newSmapFolder->index.resize(exists); + return true; + } + + if (restoringSnapshot) + { + imapFOLDERinfo *saveCurrentFolder= + imapAccount.currentFolder; + + bool rc; + + imapAccount.currentFolder=newSmapFolder; + + try { + rc=smapHandler::processLine(imapAccount, words); + } catch (...) { + imapAccount.currentFolder=saveCurrentFolder; + throw; + } + imapAccount.currentFolder=saveCurrentFolder; + return rc; + } + + return smapHandler::processLine(imapAccount, words); +} + +void mail::smapOPEN::messagesRemoved(vector< pair<size_t, size_t> > + &removedList) +{ + // Restoring a SNAPSHOT + + vector< pair<size_t, size_t> >::iterator + b=removedList.begin(), + e=removedList.end(); + + while (b != e) + { + --e; + + size_t i=e->first; + size_t j=e->second+1; + + if (exists >= j) + exists -= j - i; + else if (exists > i) + exists=i; + + if (restoringSnapshot) + { + if (presnapshotExists >= j) + presnapshotExists -= j - i; + else if (presnapshotExists > i) + presnapshotExists=i; + } + } +} + +void mail::smapOPEN::messageChanged(size_t msgNum) +{ +} + +bool mail::smapOPEN::ok(std::string s) +{ + smapFOLDER *f=newSmapFolder; + + newSmapFolder=NULL; + + myimap->currentFolder=f; + myimap->installBackgroundTask(f); + + if (!restoringSnapshot) + { + f->exists=0; + f->index.clear(); + } + else + { + f->exists=presnapshotExists; + } + + if (exists > (restoringSnapshot ? presnapshotExists:0)) + { + f->index.resize(exists); + myimap->installForegroundTask(new smapNEWMAIL(defaultCB, + true)); + defaultCB=NULL; + } + + return smapHandler::ok(s); +} + |
