void mail::imap::findFolder(string folder, mail::callback::folderList &callback1, mail::callback &callback2) { if (!ready(callback2)) return; if (folder.size() == 0) // Top level hierarchy { mail::imapFolder f(*this, "", "", "", -1); f.hasMessages(false); f.hasSubFolders(true); vector<const mail::folder *> list; list.push_back(&f); callback1.success(list); callback2.success("OK"); return; } installForegroundTask( smap ? (imapHandler *) new mail::smapLISToneFolder(folder, callback1, callback2) : new mail::imapListHandler(callback1, callback2, folder_chset(), folder, true)); }
void mail::mbox::findFolder(string path, mail::callback::folderList &callback1, mail::callback &callback2) { if (path.size() == 0) path=rootPath; else if (path[0] != '/' && path != "INBOX") path=rootPath + "/" + path; folder *f=new folder(path, *this); if (!f) { callback2.fail(path + ": " + strerror(errno)); return; } try { vector<const mail::folder *> folder_list; folder_list.push_back(f); callback1.success(folder_list); callback2.success("OK"); delete f; } catch (...) { delete f; LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); } }
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"); }
void mail::mbox::readTopLevelFolders(mail::callback::folderList &callback1, class mail::callback &callback2) { vector<const mail::folder *> folder_list; if (magicInbox) folder_list.push_back( &inboxFolder ); if (rootPath.size() > 0) folder_list.push_back( &hierarchyFolder ); callback1.success(folder_list); callback2.success("OK"); }
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"); }
void mail::mbox::folder::createSubFolder(string name, bool isDirectory, mail::callback::folderList &callback1, mail::callback &callback2) const { string fpath; char *p=libmail_u_convert_tobuf(name.c_str(), unicode_default_chset(), unicode_x_imap_modutf7 " ./~:", NULL); if (!p) LIBMAIL_THROW("Out of memory."); try { fpath=path + "/" + p; free(p); } catch (...) { free(p); LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); } if (isDirectory) { if (mkdir(fpath.c_str(), 0700) < 0) { callback2.fail(fpath + ": " + strerror(errno)); return; } } else { int fd= ::open(fpath.c_str(), O_RDWR|O_CREAT|O_EXCL, 0600); if (fd < 0) { callback2.fail(fpath + ": " + strerror(errno)); return; } close(fd); } folder newFolder(fpath, mboxAccount); vector<const mail::folder *> folderList; folderList.push_back(&newFolder); callback1.success(folderList); callback2.success("OK"); }
void mail::imap::readTopLevelFolders(mail::callback::folderList &callback1, mail::callback &callback2) { vector<const mail::folder *> folders; vector<mail::imapFolder>::iterator b, e; b=namespaces.begin(); e=namespaces.end(); while (b != e) { folders.push_back(&*b); b++; } callback1.success(folders); callback2.success("OK"); }
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"); }
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"); } }
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::mbox::folder::renameFolder(const mail::folder *newParent, std::string newName, mail::callback::folderList &callback1, mail::callback &callback) const { if (isDestroyed(callback)) return; if (path == "INBOX") { callback.fail("Not implemented."); return; } if (mboxAccount.currentFolder.size() > 0) { if (mboxAccount.currentFolder == path || (path + "/") == mboxAccount.currentFolder.substr(0, path.size()+1)) { callback.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: string nameutf7=mail::iconvert::convert(newName, unicode_default_chset(), unicode_x_imap_modutf7 " ./~:"); string newpath=(newParent ? newParent->getPath() + "/": string("")) + nameutf7; if (newpath.size() == 0 || newpath[0] != '/') newpath=mboxAccount.rootPath + "/" + newpath; struct stat stat_buf; if (stat(path.c_str(), &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) { if (rename(path.c_str(), newpath.c_str()) < 0) { callback.fail(strerror(errno)); return; } mail::mbox::folder newFolder(newpath, mboxAccount); vector<const mail::folder *> folders; folders.push_back(&newFolder); callback1.success( folders ); callback.success("Mail folder renamed."); return; } mboxAccount.installTask(new mail::mbox::RenameTask(mboxAccount, callback1, callback, path, newpath, newName)); }
void mail::mbox::folder::readSubFolders( mail::callback::folderList &callback1, mail::callback &callback2) const { if (isDestroyed(callback2)) return; if (path.size() == 0) { mboxAccount.readTopLevelFolders(callback1, callback2); return; } vector<folder *> folderList; vector<folder *>::iterator b, e; DIR *dirp=opendir(path.c_str()); try { struct dirent *de; while (dirp && (de=readdir(dirp)) != NULL) { char *p; if (strcmp(de->d_name, "..") == 0 || strcmp(de->d_name, ".") == 0 || ((p=strrchr(de->d_name, '~')) && p[1] == 0)) continue; for (p=de->d_name; *p; p++) if (*p == '.') if (strcmp(p, ".lock") == 0 || strncmp(p, ".lock.", 6) == 0) break; if (*p) continue; string name=de->d_name; string fpath=path + "/" + name; folder *f=new folder(fpath, mboxAccount); if (!f) LIBMAIL_THROW("Out of memory."); try { folderList.push_back(f); } catch (...) { delete f; LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); } } vector<const mail::folder *> folders; b=folderList.begin(); e=folderList.end(); while (b != e) folders.push_back(*b++); callback1.success(folders); b=folderList.begin(); e=folderList.end(); while (b != e) delete *b++; if (dirp) closedir(dirp); } catch (...) { b=folderList.begin(); e=folderList.end(); while (b != e) delete *b++; if (dirp) closedir(dirp); LIBMAIL_THROW(LIBMAIL_THROW_EMPTY); } callback2.success("OK"); }