Exemple #1
0
void mail::addressbook::getEntry( string uid,
				  vector<T> &addrListArg,
				  mail::callback &callback)
{
	size_t n=index.size();
	size_t i;

	for (i=0; i<n; i++)
		if (server->getFolderIndexInfo(i).uid == uid)
		{
			GetAddressList<T> *get=
				new GetAddressList<T>(this, i,
						      addrListArg,
						      callback);

			if (!get)
			{
				callback.fail(strerror(errno));
				return;
			}

			try {
				get->go();
			} catch (...) {
				delete get;
				LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
			}
			return;
		}

	callback.success("NOT FOUND.");
}
Exemple #2
0
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");
}
Exemple #3
0
void mail::maildir::saveFolderIndexInfo(size_t msgNum,
					const mail::messageInfo &info,
					mail::callback &callback)
{
	if (msgNum >= index.size())
	{
		callback.success("OK");
		return;
	}

	mail::messageInfo &newFlags=index[msgNum];

#define DOFLAG(dummy, field, dummy2) \
		newFlags.field=info.field;

	LIBMAIL_MSGFLAGS;

#undef DOFLAG

	string errmsg="Message updated";

	if (!updateFlags(msgNum))
		errmsg="Folder opened in read-only mode.";

	callback.success(errmsg);
}
Exemple #4
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);
	}
}
Exemple #5
0
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");
}
Exemple #6
0
void mail::maildir::folder::create(bool isDirectory,
				   mail::callback &callback) const
{
	if (!doCreate(isDirectory))
	{
		callback.fail(strerror(errno));
	}
	else
	{
		callback.success("Mail folder created");
	}
}
Exemple #7
0
void mail::imapFolder::createSubFolder(string name, bool isDirectory,
				       mail::callback::folderList &callback1,
				       mail::callback &callback2) const
{
	if (isDestroyed(callback2))
		return;

	if (!imapAccount.ready(callback2))
		return;

	if (imapAccount.smap)
	{
		mail::smapCREATE *h=
			new mail::smapCREATE(path, name, isDirectory,
					     callback1, callback2);

		if (!h)
		{
			callback2.fail(strerror(errno));
			return;
		}

		try {
			imapAccount.installForegroundTask(h);
		} catch (...) {
			delete h;
			throw;
		}

		return;
	}

	mail::imapCREATE *h=new mail::imapCREATE(path + hiersep,
						 name,
						 !isDirectory,
						 isDirectory,
						 callback1,
						 callback2);
	if (!h)
	{
		callback2.fail(strerror(errno));
		return;
	}

	try {
		imapAccount.installForegroundTask(h);
	} catch (...) {
		delete h;
		throw;
	}
}
Exemple #8
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");
}
Exemple #9
0
void mail::mbox::folder::open(mail::callback &openCallback,
			      snapshot *restoreSnapshot,
			      mail::callback::folder &folderCallback) const
{
	if (mboxAccount.currentFolder.size() == 0 &&
	    mboxAccount.folderDirty)
	{
		closeCallback *cc=new closeCallback(&mboxAccount,
						    openCallback,
						    folderCallback,
						    path);

		if (!cc)
		{
			openCallback.fail("Out of memory.");
			return;
		}

		try {
			mboxAccount
				.installTask(new mail::mbox
					     ::ExpungeTask(mboxAccount, *cc,
							   false, NULL));
		} catch (...) {
			delete cc;
			LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
		}
		return;
	}

	mboxAccount.installTask(new mail::mbox::OpenTask(mboxAccount, path, openCallback,
						  &folderCallback));
}
Exemple #10
0
void mail::addressbook::searchNickname( string nickname,
					vector<T> &addrListArg,
					mail::callback &callback)
{
	Search<T> *s=new Search<T>(this, addrListArg, callback);

	if (!s)
	{
		callback.fail(strerror(errno));
		return;
	}

	try {
		size_t n=index.size();
		size_t i;

		for (i=0; i<n; i++)
			if (index[i].nickname == nickname)
				s->uidList.push_back(server->
						     getFolderIndexInfo(i)
						     .uid);
		s->go();
	} catch (...) {
		delete s;
		LIBMAIL_THROW(LIBMAIL_THROW_EMPTY);
	}
}
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));
}
Exemple #12
0
void mail::mbox::saveFolderIndexInfo(size_t messageNum,
				     const mail::messageInfo &info,
				     mail::callback &callback)
{
	MONITOR(mail::mbox);

	if (messageNum < index.size())
	{
		folderDirty=true;

#define DOFLAG(dummy1, field, dummy2) \
		(index[messageNum].field= info.field)

		LIBMAIL_MSGFLAGS;

#undef DOFLAG

	}

	callback.success(currentFolderReadOnly ?
			 "Folder opened in read-only mode.":
			 "Message updated.");

	if (! DESTROYED() && messageNum < index.size()
	    && currentFolderCallback)
		currentFolderCallback->messageChanged(messageNum);
}
Exemple #13
0
void mail::addressbook::addEntry(Entry &newEntry, string olduid,
				 mail::callback &callback)
{
	vector<Index>::iterator b=index.begin(), e=index.end();

	while (b != e)
	{
		Index &i= *b++;

		if (olduid.size() > 0 && i.uid == olduid)
			continue;

		if (newEntry.nickname == i.nickname)
		{
			callback.fail("Address book entry with the same name already exists.");
			return;
		}
	}

	Add *add=new Add(this, newEntry, olduid, callback);

	try {
		add->go();
	} catch (...) {
		delete add;
	}
}
Exemple #14
0
void mail::imapFolder::destroy(mail::callback &callback, bool subdirs) const
{
	if (isDestroyed(callback))
		return;

	if (!imapAccount.ready(callback))
		return;

	imapHandler *h=imapAccount.smap ? (imapHandler *)
		new mail::smapDELETE(path, subdirs, callback)
		: new mail::imapDELETE(callback,
				       path + (subdirs ? hiersep:""));

	if (!h)
	{
		callback.fail(strerror(errno));
		return;
	}
	try {
		imapAccount.installForegroundTask(h);
	} catch (...) {
		delete h;
		throw;
	}
}
Exemple #15
0
mail::maildir::maildir(mail::callback::disconnect &disconnect_callback,
		       mail::callback &callback,
		       string pathArg)
	: mail::account(disconnect_callback), CONSTRUCTOR
{
	if (init(callback, pathArg))
		callback.success("Mail folders opened");
}
Exemple #16
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");
}
Exemple #17
0
void mail::maildir::updateNotify(bool enableDisable,
				 mail::callback &callback)
{
	updateNotify(enableDisable);
	if (!enableDisable)
		updateFolderIndexInfo(&callback, false);
	else
		callback.success("OK");
}
Exemple #18
0
void mail::mbox::updateFolderIndexInfo(mail::callback &callback)
{
	if (currentFolder.size() == 0)
	{
		callback.success("Mail folder updated");
		return;
	}

	installTask(new ExpungeTask(*this, callback, true, NULL));
}
Exemple #19
0
void mail::imapFolder::create(bool isDirectory, mail::callback &callback2)
	const
{
	if (isDestroyed(callback2))
		return;
	if (!imapAccount.ready(callback2))
		return;

	if (imapAccount.smap)
	{
		mail::smapCREATE *h=
			new mail::smapCREATE(path, isDirectory, callback2);

		if (!h)
		{
			callback2.fail(strerror(errno));
			return;
		}

		try {
			imapAccount.installForegroundTask(h);
		} catch (...) {
			delete h;
			throw;
		}
		return;
	}

	mail::imapRECREATE *h=new mail::imapRECREATE(path + (isDirectory ?
							     hiersep:""),
						     callback2);
	if (!h)
	{
		callback2.fail(strerror(errno));
		return;
	}
	try {
		imapAccount.installForegroundTask(h);
	} catch (...) {
		delete h;
		throw;
	}
}
Exemple #20
0
void mail::maildir::logout(mail::callback &callback)
{
	updateNotify(false);

	if (!calledDisconnected)
	{
		calledDisconnected=true;
		disconnect_callback.disconnected("");
	}
	callback.success("OK");
}
Exemple #21
0
void mail::mbox::logout(mail::callback &callback)
{
	if (!folderDirty)
	{
		callback.success("Mail folder closed.");
		return;
	}

	// Something dirty needs to be saved.

	installTask(new ExpungeTask(*this, callback, false, NULL));
}
Exemple #22
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");
}
Exemple #23
0
void mail::mbox::folder::create(bool isDirectory,
				mail::callback &callback) const
{
	if (isDirectory) {
		if (mkdir(path.c_str(), 0700) < 0)
		{
			callback.fail(path + ": " + strerror(errno));
			return;
		}
	} else {
		int fd= ::open(path.c_str(), O_RDWR|O_CREAT|O_EXCL, 0600);

		if (fd < 0)
		{
			callback.fail(path + ": " + strerror(errno));
			return;
		}
		close(fd);
	}

	callback.success("OK");
}
Exemple #24
0
void mail::imapFolder::readFolderInfo(mail::callback::folderInfo &callback1,
				      mail::callback &callback2) const
{
	if (isDestroyed(callback2))
		return;

	if (imapAccount.currentFolder &&
	    imapAccount.currentFolder->path == path)
	{
		imapFOLDERinfo *f=imapAccount.currentFolder;

		vector<imapFOLDERinfo::indexInfo>::iterator b, e;

		b=f->index.begin();
		e=f->index.end();

		callback1.messageCount=f->index.size();
		callback1.unreadCount=0;

		while (b != e)
		{
			if (b->unread)
				++callback1.unreadCount;
			b++;
		}
		callback1.success();
		callback2.success("OK");
		return;
	}

	if (!imapAccount.smap && callback1.fastInfo &&
	    !imapAccount.hasCapability(LIBMAIL_CHEAPSTATUS))
	{
		callback2.success("OK");
		return;
	}

	imapAccount.folderStatus(path, callback1, callback2);
}
Exemple #25
0
void mail::mbox::updateFolderIndexFlags(const vector<size_t> &messages,
					bool doFlip,
					bool enableDisable,
					const mail::messageInfo &flags,
					mail::callback &callback)
{
	vector<size_t>::const_iterator b, e;

	b=messages.begin();
	e=messages.end();

	size_t n=index.size();

	while (b != e)
	{
		size_t i= *b++;

		if (i < n)
		{
#define DOFLAG(dummy, field, dummy2) \
			if (flags.field) \
			{ \
				index[i].field=\
					doFlip ? !index[i].field\
					       : enableDisable; \
			}

			LIBMAIL_MSGFLAGS;
#undef DOFLAG
		}
	}

	folderDirty=true;
	b=messages.begin();
	e=messages.end();

	MONITOR(mail::mbox);

	while (!DESTROYED() && b != e)
	{
		size_t i= *b++;

		if (i < n && currentFolderCallback)
			currentFolderCallback->messageChanged(i);
	}

	callback.success(!DESTROYED() && currentFolderReadOnly ?
			 "Folder opened in read-only mode.":
			 "Message updated.");
}
Exemple #26
0
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);
}
Exemple #27
0
void mail::mbox::genericGetMessageStruct(string uid,
					 size_t messageNumber,
					 struct rfc2045 *&structRet,
					 mail::callback &callback)
{
	if (uid == cachedMessageUid && cachedMessageRfcp)
	{
		structRet=cachedMessageRfcp;
		callback.success("OK");
		return;
	}

	installTask(new GenericGetMessageTask(*this, callback,
					      uid, messageNumber,
					      true,
					      NULL, &structRet));
}
Exemple #28
0
void mail::addressbook::getIndex( list< pair<string, std::string> > &listArg,
	       mail::callback &callback)
{
	size_t n=index.size();
	size_t i;

	for (i=0; i<n; i++)
	{
		string nickname=index[i].nickname;
		string uid=index[i].uid;

		if (nickname.size() > 0 && uid.size() > 0)
			listArg.push_back( make_pair(nickname, uid));
	}

	callback.success("Address book index retrieved");
}
Exemple #29
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");
}
Exemple #30
0
void mail::mbox::genericGetMessageFd(string uid,
				     size_t messageNumber,
				     bool peek,
				     int &fdRet,
				     mail::callback &callback)
{
	if (uid == cachedMessageUid && cachedMessageFp)
	{
		fdRet=fileno(cachedMessageFp);
		callback.success("OK");
		return;
	}

	installTask(new GenericGetMessageTask(*this, callback,
					      uid, messageNumber,
					      peek,
					      &fdRet, NULL));
}