;;; -*-Scheme-*-
;;;
-;;; $Id: imail-imap.scm,v 1.55 2000/05/18 19:59:37 cph Exp $
+;;; $Id: imail-imap.scm,v 1.56 2000/05/18 22:11:14 cph Exp $
;;;
;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
;;;
initial-value #f)
(port define standard
initial-value #f)
+ (greeting define standard
+ initial-value #f)
(sequence-number define standard
initial-value 0)
(response-queue define accessor
(user-id (imap-connection-user-id connection)))
(let ((port
(open-tcp-stream-socket host (or ip-port "imap2") #f "\n")))
- (read-line port) ;discard server announcement
+ (set-imap-connection-greeting!
+ connection
+ (let ((response (imap:read-server-response port)))
+ (if (imap:response:ok? response)
+ (imap:response:response-text-string response)
+ response)))
(set-imap-connection-port! connection port)
(reset-imap-connection connection)
(if (not (memq 'IMAP4REV1 (imap:command:capability connection)))
(define (imap-connection-open? connection)
(imap-connection-port connection))
+
+(define (imap-connection-server-type connection)
+ (let ((greeting (imap-connection-greeting connection)))
+ (cond ((not (string? greeting)) #f)
+ ((string-search-forward " Cyrus " greeting) 'CYRUS)
+ (else #f))))
\f
(define (call-with-memoized-passphrase connection receiver)
(let ((passphrase (imap-connection-passphrase connection)))
(imap-url-mailbox url)))
(define-method %delete-folder ((url <imap-url>))
- (imap:command:create (get-imap-connection url)
+ (imap:command:delete (get-imap-connection url)
(imap-url-mailbox url)))
(define-method %rename-folder ((url <imap-url>) (new-url <imap-url>))
((imail-message-wrapper "Expunging messages")
(lambda ()
(imap:command:no-response connection 'EXPUNGE))))
-
+\f
(define (imap:command:noop connection)
(imap:command:no-response connection 'NOOP))
(define (imap:command:create connection mailbox)
- (imap:command:no-response connection 'CREATE mailbox))
+ (imap:command:no-response connection 'CREATE
+ (adjust-mailbox-name connection mailbox)))
(define (imap:command:delete connection mailbox)
- (imap:command:no-response connection 'DELETE mailbox))
+ (imap:command:no-response connection 'DELETE
+ (adjust-mailbox-name connection mailbox)))
(define (imap:command:rename connection from to)
- (imap:command:no-response connection 'RENAME from to))
+ (imap:command:no-response connection 'RENAME
+ (adjust-mailbox-name connection from)
+ (adjust-mailbox-name connection to)))
(define (imap:command:copy connection index mailbox)
- (imap:command:no-response connection 'COPY (+ index 1) mailbox))
+ (imap:command:no-response connection 'COPY (+ index 1)
+ (adjust-mailbox-name connection mailbox)))
(define (imap:command:append connection mailbox flags time text)
(imap:command:no-response connection
'APPEND
- mailbox
+ (adjust-mailbox-name connection mailbox)
(and (pair? flags) flags)
(imap:universal-time->date-time time)
(cons 'LITERAL text)))
(define (imap:command:search connection . key-plist)
(apply imap:command:single-response imap:response:search?
connection 'SEARCH key-plist))
+
+(define (adjust-mailbox-name connection mailbox)
+ (case (imap-connection-server-type connection)
+ ((CYRUS)
+ (if (or (string-ci=? "inbox" mailbox)
+ (string-prefix-ci? "inbox." mailbox)
+ (string-prefix-ci? "user." mailbox))
+ mailbox
+ (string-append "inbox." mailbox)))
+ (else mailbox)))
\f
(define (imap:command:no-response connection command . arguments)
(let ((response
(apply imap:command:no-response-1 connection command arguments)))
(if (not (imap:response:ok? response))
- (error "Server signalled a command error:" response))))
+ (imap:server-error response))))
(define (imap:command:no-response-1 connection command . arguments)
(let ((responses (apply imap:command connection command arguments)))
(null? (cddr responses)))
(cadr responses)
(error "Malformed response from IMAP server:" responses))
- (error "Server signalled a command error:" (car responses)))))
+ (imap:server-error (car responses)))))
(define (imap:command:multiple-response predicate
connection command . arguments)
(if (for-all? (cdr responses) predicate)
(cdr responses)
(error "Malformed response from IMAP server:" responses))
- (error "Server signalled a command error:" (car responses)))))
+ (imap:server-error (car responses)))))
+
+(define (imap:server-error response)
+ (let ((msg
+ (string-append "Server signalled a command error: "
+ (imap:response:response-text-string response)))
+ (code (imap:response:response-text-code response)))
+ (if code
+ (error msg code)
+ (error msg))))
(define (imap:command connection command . arguments)
(bind-condition-handler (list condition-type:system-call-error)
;;; -*-Scheme-*-
;;;
-;;; $Id: imail-top.scm,v 1.64 2000/05/18 19:53:27 cph Exp $
+;;; $Id: imail-top.scm,v 1.65 2000/05/18 22:11:15 cph Exp $
;;;
;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
;;;
\\[imail-forward] Forward this message to another user.
\\[imail-continue] Continue composing outgoing message started before.
+\\[imail-create-folder] Create a new folder.
+\\[imail-delete-folder] Delete an existing folder.
\\[imail-output] Output this message to a specified folder (append it).
\\[imail-input] Append messages from a specified folder.
(define-key 'imail #\m-s 'imail-search)
(define-key 'imail #\o 'imail-output)
(define-key 'imail #\i 'imail-input)
+(define-key 'imail #\+ 'imail-create-folder)
+(define-key 'imail #\- 'imail-delete-folder)
(define-key 'imail #\q 'imail-quit)
(define-key 'imail #\? 'describe-mode)
"sInput from folder"
(lambda (url-string)
(let ((folder (selected-folder)))
- (let ((folder* (open-folder url-string))
+ (let ((folder* (open-folder (imail-parse-partial-url url-string)))
(url (folder-url folder)))
(let ((n (folder-length folder*)))
(do ((index 0 (+ index 1)))
"sOutput to folder"
(lambda (url-string)
(let ((message (selected-message)))
- (append-message message url-string)
+ (append-message message (imail-parse-partial-url url-string))
(message-filed message)
(if (ref-variable imail-delete-after-output)
((ref-command imail-delete-forward) #f)))))
+
+(define-command imail-create-folder
+ "Create a new folder with the specified name.
+An error if signalled if the folder already exists."
+ "sCreate folder"
+ (lambda (url-string)
+ (create-folder (imail-parse-partial-url url-string))))
+
+(define-command imail-delete-folder
+ "Delete a specified folder."
+ "sDelete folder"
+ (lambda (url-string)
+ (delete-folder (imail-parse-partial-url url-string))))
\f
;;;; Sending mail