[plt-scheme] imap NOOP support

From: Anton van Straaten (anton at appsolutions.com)
Date: Tue Jun 17 19:40:30 EDT 2003

According to the IMAP4rev1 spec (RFC 3501 and its predecessor RFC 2060), the
NOOP command is the preferred mechanism for polling for new messages in an
already-selected IMAP folder.  In at least some IMAP server implementations,
NOOP is quite a bit more efficient than e.g. SELECT or STATUS.  With the UW
IMAP server I'm using, a SELECT or STATUS on a very large mailbox can take
tens of seconds (on slow server hardware), whereas a NOOP takes a couple
hundred milliseconds.

However, the PLT IMAP module doesn't seem to support the NOOP command
directly.  So, I wrote the following, which adds an imap-noop function as a
variation on imap-reselect.  This also made it easy to add (untested)
support for the EXAMINE command.  The following code replaces the existing
imap-reselect function in net/imap-unit.ss.  Of course, corresponding
exports must be added to the unit signature.

      (define (imap-reselect imap inbox)
        (imap-selectish-command imap (format "SELECT ~a" (str->arg inbox))))

      (define (imap-examine imap inbox)
        (imap-selectish-command imap (format "EXAMINE ~a" (str->arg
inbox))))

      ;; returns (values #f #f) if no change since last check
      (define (imap-noop imap)
        (imap-selectish-command imap "NOOP"))

      ;; icky name, someone think of something better!
      (define (imap-selectish-command imap command-string)
        (let ([r (imap-connection-r imap)]
              [w (imap-connection-w imap)])
          (let ([init-count #f]
                [init-recent #f])
            (check-ok (imap-send r w command-string
                                (lambda (i)
                                  (when (and (list? i) (= 2 (length i)))
                                    (cond
                                      [(tag-eq? (cadr i) 'EXISTS)
                                       (set! init-count (car i))]
                                      [(tag-eq? (cadr i) 'RECENT)
                                       (set! init-recent (car i))])))))
                      (values init-count init-recent))))

Could something like this be added to the official distribution?  If the
above needs any improvements or docs, please let me know.

Anton



Posted on the users mailing list.