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/smapidle.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/smapidle.C')
| -rw-r--r-- | libmail/smapidle.C | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/libmail/smapidle.C b/libmail/smapidle.C new file mode 100644 index 0000000..ebb4357 --- /dev/null +++ b/libmail/smapidle.C @@ -0,0 +1,184 @@ +/* +** Copyright 2003, Double Precision Inc. +** +** See COPYING for distribution information. +*/ +#include "libmail_config.h" +#include "smap.H" +#include "smapidle.H" +#include <iostream> + +using namespace std; + +mail::smapIdleHandler::smapIdleHandler(bool idleOnOffArg, + mail::callback *callbackArg) + : idleOnOff(idleOnOffArg), idling(false), + shouldTerminate(false), terminating(false) +{ + defaultCB=callbackArg; +} + +const char *mail::smapIdleHandler::getName() +{ + return "IDLE"; +} + +bool mail::smapIdleHandler::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\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::smapIdleHandler::timedOut(const char *errmsg) +{ + mail::callback *c=defaultCB; + + defaultCB=NULL; + + if (c) + callbackTimedOut(*c, errmsg); +} + +mail::smapIdleHandler::~smapIdleHandler() +{ + mail::callback *c=defaultCB; + + defaultCB=NULL; + + if (c) + c->success("OK"); +} + +void mail::smapIdleHandler::installed(imap &imapAccount) +{ + if (!idleOnOff || !imapAccount.wantIdleMode + || shouldTerminate || !imapAccount.task_queue.empty()) + { + imapAccount.uninstallHandler(this); + return; + } + + // 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; + } + waiting=true; +} + +bool mail::smapIdleHandler::ok(std::string msg) +{ + if (!idling) // Response to the IDLE command + { + idling=true; + if (shouldTerminate) + terminateIdle(*myimap); + + mail::callback *c=defaultCB; + + defaultCB=NULL; + + if (c) + c->success("Monitoring folder for changes..."); + + doDestroy=false; + return true; + } + + // Response to the RESUME command + + mail::callback *c=defaultCB; + + defaultCB=NULL; + + if (myimap->wantIdleMode) + { + // Reinstall, when we're done + + myimap->installForegroundTask(new smapIdleHandler(true, + NULL)); + c=NULL; + } + + if (c) + c->success(msg); + + return true; +} + +void mail::smapIdleHandler::anotherHandlerInstalled(imap &imapAccount) +{ + if (waiting) + { + imapAccount.uninstallHandler(this); + return; + } + + shouldTerminate=true; + if (idling) + terminateIdle(imapAccount); +} + +void mail::smapIdleHandler::terminateIdle(imap &imapAccount) +{ + if (terminating) + return; + + terminating=true; + + mail::callback *c=defaultCB; + + defaultCB=NULL; + + if (c) + c->success("OK"); + + imapAccount.imapcmd("", "RESUME\n"); +} + |
