summaryrefslogtreecommitdiffstats
path: root/libmail/maildirfolder.C
diff options
context:
space:
mode:
Diffstat (limited to 'libmail/maildirfolder.C')
-rw-r--r--libmail/maildirfolder.C1003
1 files changed, 1003 insertions, 0 deletions
diff --git a/libmail/maildirfolder.C b/libmail/maildirfolder.C
new file mode 100644
index 0000000..9c54e31
--- /dev/null
+++ b/libmail/maildirfolder.C
@@ -0,0 +1,1003 @@
+/*
+** Copyright 2002-2004, Double Precision Inc.
+**
+** See COPYING for distribution information.
+*/
+#include "libmail_config.h"
+#include "maildir/config.h"
+#include "maildir/maildirmisc.h"
+#include "unicode/unicode.h"
+#include "maildirfolder.H"
+#include "maildiradd.H"
+#include "mbox.H"
+#include "misc.H"
+#include <list>
+#include <algorithm>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <iostream>
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+using namespace std;
+
+mail::maildir::folder::folder(mail::maildir *maildirArg,
+ string pathArg)
+ : mail::folder(maildirArg),
+ maildirAccount(maildirArg),
+ path(pathArg),
+ hasMessagesFlag(true),
+ hasSubfoldersFlag(true)
+{
+ name=pathArg;
+
+ size_t p=name.rfind('.');
+
+ if (p != std::string::npos)
+ name=name.substr(p+1);
+
+ // Convert the name of the folder from modified UTF-7
+ // (Courier compatibility) to the current charset.
+
+ char *s=libmail_u_convert_tobuf(name.c_str(),
+ unicode_x_imap_modutf7,
+ unicode_default_chset(),
+ NULL);
+
+ if (s)
+ {
+ try {
+ name=s;
+ free(s);
+ } catch (...) {
+ free(s);
+ }
+ }
+}
+
+mail::maildir::folder::~folder()
+{
+}
+
+void mail::maildir::folder::sameServerAsHelperFunc() const
+{
+}
+
+string mail::maildir::folder::getName() const
+{
+ if (path == "INBOX")
+ return hasSubFolders() ? "Folders":"INBOX";
+
+ return name;
+}
+
+string mail::maildir::folder::getPath() const
+{
+ return path;
+}
+
+bool mail::maildir::folder::hasMessages() const
+{
+ return hasMessagesFlag;
+}
+
+bool mail::maildir::folder::hasSubFolders() const
+{
+ return hasSubfoldersFlag;
+}
+
+bool mail::maildir::folder::isParentOf(string otherPath) const
+{
+ string s=path + ".";
+
+ return (strncmp(otherPath.c_str(), s.c_str(), s.size()) == 0);
+}
+
+void mail::maildir::folder::hasMessages(bool flag)
+{
+ hasMessagesFlag=flag;
+}
+
+void mail::maildir::folder::hasSubFolders(bool flag)
+{
+ hasSubfoldersFlag=flag;
+}
+
+class mail::maildir::indexSort {
+public:
+ indexSort();
+ ~indexSort();
+
+ bool operator()(const mail::maildir::maildirMessageInfo &a,
+ const mail::maildir::maildirMessageInfo &b);
+};
+
+mail::maildir::indexSort::indexSort()
+{
+}
+
+mail::maildir::indexSort::~indexSort()
+{
+}
+
+// Sort messages in some reasonable order. Rely on the timestamp component
+// of the maildirfilename.
+
+bool mail::maildir::indexSort::operator()
+ (const mail::maildir::maildirMessageInfo &a,
+ const mail::maildir::maildirMessageInfo &b)
+{
+ unsigned long at=atol(a.lastKnownFilename.c_str()),
+ bt=atol(b.lastKnownFilename.c_str());
+
+ if ( at != bt)
+ return at < bt;
+
+ return strcmp(a.lastKnownFilename.c_str(),
+ b.lastKnownFilename.c_str()) < 0;
+}
+
+// Scan a maildirAccount
+
+bool mail::maildir::scan(string folderStr, vector<maildirMessageInfo> &index,
+ bool scanNew)
+{
+ string p;
+
+ char *d=maildir_name2dir(path.c_str(), folderStr.c_str());
+
+ if (!d)
+ return false;
+
+ try {
+ p=d;
+ free(d);
+ } catch (...) {
+ free(d);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ static const char * const subdirs[]={"/cur","/new"};
+
+ size_t i;
+
+ for (i=0; i<(scanNew ? 2:1); i++)
+ {
+ string n=p + subdirs[i];
+
+ DIR *dirp=opendir(n.c_str());
+
+ try {
+ struct dirent *de;
+
+ while (dirp && (de=readdir(dirp)) != NULL)
+ {
+ if (de->d_name[0] == '.')
+ continue;
+
+
+ maildirMessageInfo newInfo;
+
+ newInfo.lastKnownFilename=de->d_name;
+
+ // Use the filename as the uid
+
+ newInfo.uid=de->d_name;
+
+ size_t p=newInfo.uid.find(MDIRSEP[0]);
+
+ if (p != std::string::npos)
+ newInfo.uid=newInfo.uid.substr(0, p);
+
+ mail::maildir::updateFlags(de->d_name,
+ newInfo);
+ newInfo.recent= i > 0;
+ index.push_back(newInfo);
+ }
+
+ if (dirp)
+ closedir(dirp);
+ } catch (...) {
+ if (dirp)
+ closedir(dirp);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+ }
+
+ sort(index.begin(), index.end(), indexSort());
+ return true;
+}
+
+void mail::maildir::folder::getParentFolder(callback::folderList &callback1,
+ callback &callback2) const
+{
+ if (isDestroyed(callback2))
+ return;
+
+ size_t n;
+
+ n=path.rfind('.');
+
+ if (n == std::string::npos)
+ n=0;
+
+ maildirAccount->findFolder(path.substr(0, n),
+ callback1,
+ callback2);
+}
+
+void mail::maildir::folder::readFolderInfo( mail::callback::folderInfo
+ &callback1,
+ mail::callback &callback2) const
+{
+ if (isDestroyed(callback2))
+ return;
+
+ callback1.messageCount=0;
+ callback1.unreadCount=0;
+
+ vector<maildirMessageInfo> dummyIndex;
+
+ if (!maildirAccount->scan(path, dummyIndex, true))
+ {
+ callback1.success();
+ callback2.fail("Invalid folder");
+ return;
+ }
+
+ vector<maildirMessageInfo>::iterator b=dummyIndex.begin(),
+ e=dummyIndex.end();
+
+ while (b != e)
+ {
+ callback1.messageCount++;
+ if ( b->unread)
+ callback1.unreadCount++;
+ b++;
+ }
+
+ callback1.success();
+ callback2.success("OK");
+}
+
+mail::maildir::folder::listinfo::listinfo()
+{
+}
+
+mail::maildir::folder::listinfo::~listinfo()
+{
+}
+
+// Callback that lists maildirAccount folders.
+// The callback filters only the folders under the list path
+
+void mail::maildir::folder::maildir_list_callback(const char *folder,
+ void *vp)
+{
+ mail::maildir::folder::listinfo *li=
+ (mail::maildir::folder::listinfo *)vp;
+
+ if (strncmp(folder, li->path.c_str(), li->path.size()) ||
+ folder[li->path.size()] != '.')
+ return; // Outside the hierarchy being listed.
+
+ folder += li->path.size();
+ ++folder;
+
+ // If the remaining portion of the name has another period, there's
+ // a subdirectory there. Otherwise, it's a file.
+ // It's ok when we get multiple folders in the same subdirectory,
+ // subdirs is a STL set, which gets rid of duplicates
+
+ const char *p=strchr(folder, '.');
+
+ if (p)
+ li->subdirs.insert(string(folder, p));
+ else
+ li->list.insert(string(folder));
+}
+
+void mail::maildir::folder::readSubFolders( mail::callback::folderList
+ &callback1,
+ mail::callback &callback2) const
+{
+ if (isDestroyed(callback2))
+ return;
+
+ if (path.size() == 0)
+ {
+ maildirAccount->readTopLevelFolders(callback1, callback2);
+ return;
+ }
+
+ listinfo li;
+
+ li.path=path;
+
+ maildir_list(maildirAccount->path.c_str(),
+ &mail::maildir::folder::maildir_list_callback,
+ &li);
+
+ list<mail::folder *> folderList;
+ list<mail::folder *>::iterator b, e;
+
+ try {
+ // Create a list of folder objects from the list of folder
+ // names in listinfo. Create a list in two passes.
+
+ // First pass - build names of folders. If the folder is
+ // also found in the subdirectory list, make it a dual-purpose
+ // folder/directory.
+
+ buildFolderList(folderList, &li.list, &li.subdirs);
+
+ // Second pass - build remaining subdirs.
+
+ buildFolderList(folderList, NULL, &li.subdirs);
+
+ // Cleanup for the callback
+ vector<const mail::folder *> myList;
+
+ b=folderList.begin();
+ e=folderList.end();
+
+ while (b != e)
+ myList.push_back(*b++);
+
+ callback1.success(myList);
+ callback2.success("OK");
+
+ } catch (...) {
+ b=folderList.begin();
+ e=folderList.end();
+
+ while (b != e)
+ {
+ delete *b;
+
+ b++;
+ }
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ b=folderList.begin();
+ e=folderList.end();
+
+ while (b != e)
+ {
+ delete *b;
+
+ b++;
+ }
+}
+
+void mail::maildir::folder::buildFolderList(list<mail::folder *> &folderList,
+ set<string> *folders,
+ set<string> *dirs) const
+{
+ set<string>::iterator b, e;
+
+ if (folders)
+ {
+ b=folders->begin();
+ e=folders->end();
+ }
+ else
+ {
+ b=dirs->begin();
+ e=dirs->end();
+ }
+
+ while (b != e)
+ {
+ string name= *b++;
+
+ folder *p=new folder(maildirAccount, path + "." + name);
+
+ if (!p)
+ LIBMAIL_THROW(strerror(errno));
+
+ try {
+ if (folders)
+ {
+ p->hasMessages(true);
+ p->hasSubFolders(false);
+
+ if (dirs->count(name) > 0)
+ // Also a subdir
+ {
+ p->hasSubFolders(true);
+ dirs->erase(name);
+ // Don't add this folder when we do
+ // a directory.
+ }
+ }
+ else
+ {
+ p->hasMessages(false);
+ p->hasSubFolders(true);
+ }
+
+ folderList.push_back(p);
+ } catch (...) {
+ delete p;
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+ }
+}
+
+mail::addMessage *mail::maildir::folder::addMessage(mail::callback
+ &callback) const
+{
+ if (isDestroyed(callback))
+ return NULL;
+
+ string folderPath;
+
+ char *p=maildir_name2dir(maildirAccount->path.c_str(), path.c_str());
+
+ if (!p)
+ {
+ callback.fail(strerror(errno));
+ return NULL;
+ }
+
+ try {
+ folderPath=p;
+ free(p);
+ } catch (...) {
+ free(p);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ mail::maildir::addmessage *m=new
+ mail::maildir::addmessage(maildirAccount, folderPath, callback);
+
+ if (!m)
+ {
+ callback.fail(strerror(errno));
+ return NULL;
+ }
+
+ return m;
+}
+
+void mail::maildir::moveMessagesTo(const vector<size_t> &messages,
+ mail::folder *copyTo,
+ mail::callback &callback)
+{
+ sameServerFolderPtr=NULL;
+ copyTo->sameServerAsHelperFunc();
+
+ if (sameServerFolderPtr == NULL)
+ {
+ mail::account::moveMessagesTo(messages, copyTo, callback);
+ return;
+ }
+
+ string destFolderPath;
+
+ char *p=maildir_name2dir(path.c_str(),
+ sameServerFolderPtr->path.c_str());
+
+ if (!p)
+ {
+ callback.fail(strerror(errno));
+ return;
+ }
+
+ try {
+ destFolderPath=p;
+ free(p);
+ } catch (...) {
+ free(p);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ vector<size_t>::const_iterator b=messages.begin(), e=messages.end();
+
+ while (b != e)
+ {
+ size_t n=*b++;
+
+ string messageFn=getfilename(n);
+
+ if (messageFn.size() > 0)
+ {
+ string destName= destFolderPath
+ + messageFn.substr(messageFn.rfind('/'));
+
+ rename(messageFn.c_str(), destName.c_str());
+ }
+ }
+ updateFolderIndexInfo(&callback, false);
+}
+
+void mail::maildir::folder::createSubFolder(string name, bool isDirectory,
+ mail::callback::folderList
+ &callback1,
+ mail::callback &callback2) const
+{
+ if (isDestroyed(callback2))
+ return;
+
+ // The name of the folder is translated from the local charset
+ // to modified UTF-7 (Courier-IMAP compatibility), with the following
+ // blacklisted characters:
+
+ char *p=libmail_u_convert_tobuf(name.c_str(), unicode_default_chset(),
+ unicode_x_imap_modutf7 " ./~:", NULL);
+
+ if (!p)
+ {
+ callback2.fail(strerror(errno));
+ return;
+ }
+
+ std::string nameutf7;
+
+ errno=ENOMEM;
+ try {
+ nameutf7=p;
+ free(p);
+ } catch (...) {
+ free(p);
+ callback2.fail(strerror(errno));
+ return;
+ }
+
+ mail::maildir::folder newFolder(maildirAccount, path + "." + nameutf7);
+
+ newFolder.hasMessagesFlag= ! (newFolder.hasSubfoldersFlag=
+ isDirectory);
+
+ if (!newFolder.doCreate(isDirectory))
+ {
+ callback2.fail(strerror(errno));
+ return;
+ }
+
+ vector<const mail::folder *> folders;
+
+ folders.push_back(&newFolder);
+ callback1.success( folders );
+ callback2.success("Mail folder created");
+}
+
+bool mail::maildir::folder::doCreate(bool isDirectory) const
+{
+ if (isDirectory)
+ return true; // Pretend
+
+ if (maildirAccount->ispop3maildrop)
+ {
+ errno=EPERM;
+ return false; // POP3 maildrops don't have folders.
+ }
+
+ string subdir;
+
+ char *d=maildir_name2dir(maildirAccount->path.c_str(), path.c_str());
+ // Checks for name validity.
+
+ if (!d)
+ return false;
+
+ try {
+ subdir=d;
+ free(d);
+ } catch (...) {
+ free(d);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ return mail::maildir::maildirmake(subdir, true);
+}
+
+
+bool mail::maildir::maildirmake(string subdir, bool isFolder)
+{
+ string nsubdir=subdir + "/new",
+ csubdir=subdir + "/cur",
+ tsubdir=subdir + "/tmp";
+
+ if (mkdir(subdir.c_str(), 0700) == 0)
+ {
+ if (mkdir(nsubdir.c_str(), 0700) == 0)
+ {
+ if (mkdir(tsubdir.c_str(), 0700) == 0)
+ {
+ if (mkdir(csubdir.c_str(), 0700) == 0)
+ {
+ if (!isFolder)
+ return true;
+
+ string f=subdir +
+ "/maildirfolder";
+
+ int fd=::open(f.c_str(),
+ O_CREAT |
+ O_RDWR, 0666);
+
+ if (fd >= 0)
+ {
+ close(fd);
+ return true;
+ }
+ rmdir(csubdir.c_str());
+ }
+ rmdir(tsubdir.c_str());
+ }
+ rmdir(nsubdir.c_str());
+ }
+ rmdir(subdir.c_str());
+ }
+
+ return false;
+}
+
+void mail::maildir::folder::create(bool isDirectory,
+ mail::callback &callback) const
+{
+ if (!doCreate(isDirectory))
+ {
+ callback.fail(strerror(errno));
+ }
+ else
+ {
+ callback.success("Mail folder created");
+ }
+}
+
+void mail::maildir::folder::destroy(mail::callback &callback,
+ bool destroyDir) const
+{
+ if (isDestroyed(callback))
+ return;
+
+ if (!destroyDir) // Folder directories are imaginary, cannot be nuked
+ {
+ string s;
+ char *d=maildir_name2dir(maildirAccount->path.c_str(),
+ path.c_str());
+ if (!d)
+ {
+ callback.fail(strerror(errno));
+ return;
+ }
+
+ try {
+ s=d;
+ free(d);
+ } catch (...) {
+ free(d);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ if (!mail::maildir::maildirdestroy(s))
+ {
+ callback.fail(strerror(errno));
+ return;
+ }
+ }
+
+ callback.success("Mail folder deleted");
+}
+
+void mail::maildir::folder::renameFolder(const mail::folder *newParent,
+ std::string newName,
+ mail::callback::folderList &callback1,
+ mail::callback &callback2) const
+{
+ if (isDestroyed(callback2))
+ return;
+
+ if (maildirAccount->folderPath.size() > 0)
+ {
+ size_t l=path.size();
+
+ if (strncmp(maildirAccount->folderPath.c_str(),
+ path.c_str(), l) == 0 &&
+ ((maildirAccount->folderPath.c_str())[l] == 0 ||
+ (maildirAccount->folderPath.c_str())[l] == '.'))
+ {
+ callback2.fail("Cannot RENAME currently open folder.");
+ return;
+ }
+ }
+
+ // The name of the folder is translated from the local charset
+ // to modified UTF-7 (Courier-IMAP compatibility), with the following
+ // blacklisted characters:
+
+ char *s=libmail_u_convert_tobuf(newName.c_str(),
+ unicode_default_chset(),
+ unicode_x_imap_modutf7 " ./~:", NULL);
+
+ if (!s)
+ {
+ callback2.fail(strerror(errno));
+ return;
+ }
+
+ std::string nameutf7;
+
+ errno=ENOMEM;
+ try {
+ nameutf7=s;
+ free(s);
+ } catch (...) {
+ free(s);
+ callback2.fail(strerror(errno));
+ return;
+ }
+
+ mail::maildir::folder newFolder(maildirAccount,
+ (newParent ?
+ newParent->getPath() + ".":
+ string("")) + nameutf7);
+
+ newFolder.hasMessages( hasMessages() );
+ newFolder.hasSubFolders( hasSubFolders() );
+
+ vector<const mail::folder *> folders;
+
+ // Paths are INBOX.foo
+
+ string from, to;
+
+ char *p=maildir_name2dir(".", path.c_str());
+
+ if (p)
+ try {
+ from=p+2; // Skip ./
+ free(p);
+ } catch (...) {
+ free(p);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ p=maildir_name2dir(".", newFolder.path.c_str());
+ if (p)
+ try {
+ to=p+2; // Skip ./
+ free(p);
+ } catch (...) {
+ free(p);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+
+ if (from.size() > 0 &&
+ to.size() > 0 &&
+ maildir_rename(maildirAccount->path.c_str(),
+ from.c_str(), to.c_str(),
+ MAILDIR_RENAME_FOLDER |
+ MAILDIR_RENAME_SUBFOLDERS, NULL))
+ {
+ callback2.fail(strerror(errno));
+ }
+ else
+ {
+ folders.push_back(&newFolder);
+ callback1.success( folders );
+ callback2.success("Mail folder renamed");
+ }
+}
+
+bool mail::maildir::maildirdestroy(string d)
+{
+ list<string> contents;
+
+ DIR *dirp=opendir(d.c_str());
+
+ try {
+ struct dirent *de;
+
+ while (dirp && (de=readdir(dirp)) != NULL)
+ {
+ if (strcmp(de->d_name, ".") == 0)
+ continue;
+ if (strcmp(de->d_name, "..") == 0)
+ continue;
+
+ contents.push_back(de->d_name);
+ }
+
+ if (dirp)
+ closedir(dirp);
+ } catch (...) {
+ if (dirp)
+ closedir(dirp);
+ LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
+ }
+
+ list<string>::iterator b=contents.begin(), e=contents.end();
+
+ while (b != e)
+ {
+ string s=d + "/" + *b++;
+
+ if (unlink(s.c_str()) < 0 && errno != ENOENT)
+ {
+ if (errno == EISDIR)
+ {
+ if (!maildirdestroy(s))
+ return false;
+ continue;
+ }
+ return false;
+ }
+ }
+ rmdir(d.c_str());
+ return true;
+}
+
+mail::folder *mail::maildir::folder::clone() const
+{
+ if (isDestroyed())
+ return NULL;
+
+ mail::maildir::folder *p=new mail::maildir::folder(maildirAccount,
+ path);
+
+ if (p)
+ {
+ p->hasMessagesFlag=hasMessagesFlag;
+ p->hasSubfoldersFlag=hasSubfoldersFlag;
+ return p;
+ }
+ return NULL;
+}
+
+
+void mail::maildir::findFolder(string folder,
+ mail::callback::folderList &callback1,
+ mail::callback &callback2)
+{
+ mail::maildir::folder tempFolder(this, folder);
+
+ vector<const mail::folder *> folderList;
+
+ folderList.push_back(&tempFolder);
+
+ callback1.success(folderList);
+ callback2.success("OK");
+}
+
+string mail::maildir::translatePath(string path)
+{
+ return mail::mbox::translatePathCommon(path, ":/.~", ".");
+}
+
+static string encword(string s)
+{
+ string r="";
+
+ string::iterator b=s.begin(), e=s.end();
+ string::iterator p=b;
+
+ while ( b != e )
+ {
+ if ( *b == ':' || *b == '\\')
+ {
+ r.insert(r.end(), p, b);
+ r += "\\";
+ p=b;
+ }
+ b++;
+ }
+
+ r.insert(r.end(), p, b);
+ return r;
+}
+
+
+static string getword(string &s)
+{
+ string r="";
+
+ string::iterator b=s.begin(), e=s.end(), p=b;
+
+ while (b != e)
+ {
+ if (*b == ':')
+ break;
+
+ if (*b == '\\')
+ {
+ r.insert(r.end(), p, b);
+
+ b++;
+ p=b;
+
+ if (b == e)
+ break;
+ }
+ b++;
+ }
+
+ r.insert(r.end(), p, b);
+
+ if (b != e)
+ {
+ b++;
+ s=string(b, s.end());
+ }
+
+ return r;
+}
+
+string mail::maildir::folder::toString() const
+{
+ return encword(path) + ":" + encword(name) + ":" +
+ (hasMessagesFlag ? "M":"") +
+ (hasSubfoldersFlag ? "S":"");
+}
+
+
+mail::folder *mail::maildir::folderFromString(string folderName)
+{
+ string path=getword(folderName);
+ string name=getword(folderName);
+
+ mail::maildir::folder *f=new mail::maildir::folder(this, path);
+
+ if (!f)
+ return NULL;
+
+ f->hasMessagesFlag= folderName.find('M') != std::string::npos;
+ f->hasSubfoldersFlag= folderName.find('S') != std::string::npos;
+
+ return f;
+}
+
+void mail::maildir::folder::open(mail::callback &openCallback,
+ mail::snapshot *restoreSnapshot,
+ mail::callback::folder &folderCallback) const
+{
+ if (isDestroyed(openCallback))
+ return;
+
+ maildirAccount->open(path, openCallback, folderCallback);
+}
+
+
+void mail::maildir::readTopLevelFolders(mail::callback::folderList &callback1,
+ mail::callback &callback2)
+{
+ mail::maildir::folder inbox(this, INBOX);
+ mail::maildir::folder folders(this, INBOX);
+
+ inbox.hasSubfoldersFlag=false;
+ folders.hasMessagesFlag=false;
+
+ vector<const mail::folder *> folderList;
+
+ folderList.push_back(&inbox);
+
+ if (!ispop3maildrop)
+ folderList.push_back(&folders);
+
+ callback1.success(folderList);
+ callback2.success("OK");
+}