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/imapidle.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/imapidle.C')
| -rw-r--r-- | libmail/imapidle.C | 197 | 
1 files changed, 197 insertions, 0 deletions
| diff --git a/libmail/imapidle.C b/libmail/imapidle.C new file mode 100644 index 0000000..2409754 --- /dev/null +++ b/libmail/imapidle.C @@ -0,0 +1,197 @@ +/* +** Copyright 2003, Double Precision Inc. +** +** See COPYING for distribution information. +*/ +#include "libmail_config.h" +#include "imap.H" +#include "imaphandler.H" +#include "imapidle.H" + +using namespace std; + +mail::imapIdleHandler::imapIdleHandler(bool idleOnOffArg, +				       mail::callback *callbackArg) +	: idleOnOff(idleOnOffArg), idling(false), +	  shouldTerminate(false), terminating(false), +	  callback(callbackArg) +{ +} + +const char *mail::imapIdleHandler::getName() +{ +	return "IDLE"; +} + +bool mail::imapIdleHandler::getTimeout(imap &imapAccount, +				       int &ioTimeout) +{ +	if (waiting) +	{ +		struct timeval tv; + +		gettimeofday(&tv, NULL); + +		if (tv.tv_sec > waitingUntil.tv_sec || +		    (tv.tv_sec == waitingUntil.tv_sec && +		     tv.tv_usec >= waitingUntil.tv_usec)) +		{ +			waiting=false; + +			imapAccount.imapcmd("IDLE", "IDLE\r\n"); +			ioTimeout=0; +			return false; +		} +		else +		{ +			struct timeval t=waitingUntil; + +			t.tv_usec -= tv.tv_usec; + +			if (t.tv_usec < 0) +			{ +				t.tv_usec += 1000000; +				--t.tv_sec; +			} +			t.tv_sec -= tv.tv_sec; + +			ioTimeout=t.tv_sec * 1000 + t.tv_usec / 1000; + +			if (ioTimeout == 0) +				ioTimeout=100; +			return false; +		} +	} + +	ioTimeout = 15 * 60 * 1000; +	return false; +} + +void mail::imapIdleHandler::timedOut(const char *errmsg) +{ +	mail::callback *c=callback; + +	callback=NULL; + +	if (c) +		callbackTimedOut(*c, errmsg); +} + +mail::imapIdleHandler::~imapIdleHandler() +{ +	mail::callback *c=callback; + +	callback=NULL; + +	if (c) +		c->success("OK"); +} + +bool mail::imapIdleHandler::untaggedMessage(imap &imapAccount, +					    std::string name) +{ +	return false; +} + +void mail::imapIdleHandler::installed(imap &imapAccount) +{ +	if (!idleOnOff || !imapAccount.wantIdleMode +	    || shouldTerminate || !imapAccount.task_queue.empty()) +	{ +		imapAccount.uninstallHandler(this); +		return; +	} + +	waiting=true; + +	// Wait 1/10th of a second before issuing an IDLE.  When we're in +	// IDLE mode, and a new task is started, we terminate and a requeue +	// ourselves after the pending command.  We don't want to immediately +	// reenter the IDLE mode because if the first task queues up a second +	// task we would have to immediately get out of IDLE mode right away, +	// so wait 1/10th of a second to see if anything is up. + +	gettimeofday(&waitingUntil, NULL); +	if ((waitingUntil.tv_usec += 100000) > 1000000) +	{ +		waitingUntil.tv_usec %= 1000000; +		++waitingUntil.tv_sec; +	} +} + + +bool mail::imapIdleHandler::taggedMessage(imap &imapAccount, std::string name, +					  std::string message, +					  bool okfail, std::string errmsg) +{ +	mail::callback *c=callback; + +	callback=NULL; + +	imapAccount.uninstallHandler(this); + +	if (imapAccount.wantIdleMode) +	{ +		// Reinstall, when we're done + +		imapAccount.installForegroundTask(new imapIdleHandler(true, +								      NULL)); +		c=NULL; +	} + +	if (c) +	{ +		if (okfail) +			c->success(errmsg); +		else +			c->fail(errmsg); +	} +	return true; +} +		 +bool mail::imapIdleHandler::continuationRequest(imap &imapAccount, +					    std::string request) +{ +	idling=true; +	if (shouldTerminate) +		terminateIdle(imapAccount); + +	mail::callback *c=callback; + +	callback=NULL; + +	if (c) +		c->success("Monitoring folder for changes..."); + +	return true; +} + +void mail::imapIdleHandler::anotherHandlerInstalled(imap &imapAccount) +{ +	if (waiting) +	{ +		imapAccount.uninstallHandler(this); +		return; +	} + +	shouldTerminate=true; +	if (idling) +		terminateIdle(imapAccount); +} + +void mail::imapIdleHandler::terminateIdle(imap &imapAccount) +{ +	if (terminating) +		return; +	terminating=true; + +	mail::callback *c=callback; + +	callback=NULL; + +	if (c) +		c->success("OK"); + +	imapAccount.imapcmd("", "DONE\r\n"); +} + | 
