Beispiel #1
0
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));
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
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");
}
Beispiel #4
0
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");
}
Beispiel #5
0
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");
}
Beispiel #6
0
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");
}
Beispiel #7
0
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");
}
Beispiel #8
0
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");
}
Beispiel #9
0
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");
	}
}
Beispiel #10
0
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++;
	}
}
Beispiel #11
0
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));
}
Beispiel #12
0
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");
}