X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fimap.el;h=1079cd2c71dc982553d440a4bb4225e193e29d0f;hb=8d5b94488b8fe507a83eb5475ecaa54afb8a98b8;hp=ec2585bdfadfdf64328458d021fecb1b4f947ba1;hpb=88e473dcbcd21bbcea29f32069cfc9abd7fb00c8;p=elisp%2Fgnus.git- diff --git a/lisp/imap.el b/lisp/imap.el index ec2585b..1079cd2 100644 --- a/lisp/imap.el +++ b/lisp/imap.el @@ -44,7 +44,7 @@ ;; ;; Mailbox commands: ;; -;; imap-mailbox-get, imap-mailbox-map, imap-current-mailbox, +;; imap-mailbox-get, imap-mailbox-map, imap-current-mailbox, ;; imap-current-mailbox-p, imap-search, imap-mailbox-select, ;; imap-mailbox-examine, imap-mailbox-unselect, imap-mailbox-expunge ;; imap-mailbox-close, imap-mailbox-create, imap-mailbox-delete @@ -57,7 +57,7 @@ ;; imap-fetch-asynch, imap-fetch, ;; imap-current-message, imap-list-to-message-set, ;; imap-message-get, imap-message-map -;; imap-message-envelope-date, imap-message-envelope-subject, +;; imap-message-envelope-date, imap-message-envelope-subject, ;; imap-message-envelope-from, imap-message-envelope-sender, ;; imap-message-envelope-reply-to, imap-message-envelope-to, ;; imap-message-envelope-cc, imap-message-envelope-bcc @@ -120,7 +120,7 @@ ;; => "X-Sieve: cmu-sieve 1.3^M\nX-Username: ^M\r...." ;; ;; Todo: -;; +;; ;; o Parse UIDs as strings? We need to overcome the 28 bit limit somehow. ;; o Don't use `read' at all (important places already fixed) ;; o Accept list of articles instead of message set string in most @@ -187,10 +187,10 @@ the list is tried until a successful connection is made." :group 'imap :type '(repeat string)) -(defcustom imap-ssl-program '("openssl s_client -ssl3 -connect %s:%p" - "openssl s_client -ssl2 -connect %s:%p" - "s_client -ssl3 -connect %s:%p" - "s_client -ssl2 -connect %s:%p") +(defcustom imap-ssl-program '("openssl s_client -quiet -ssl3 -connect %s:%p" + "openssl s_client -quiet -ssl2 -connect %s:%p" + "s_client -quiet -ssl3 -connect %s:%p" + "s_client -quiet -ssl2 -connect %s:%p") "A string, or list of strings, containing commands for SSL connections. Within a string, %s is replaced with the server address and %p with port number on server. The program should accept IMAP commands on @@ -213,6 +213,11 @@ until a successful connection is made." :group 'imap :type '(repeat string)) +(defcustom imap-process-connection-type nil + "*Value for `process-connection-type' to use for Kerberos4 and GSSAPI." + :group 'imap + :type 'boolean) + (defvar imap-shell-host "gateway" "Hostname of rlogin proxy.") @@ -245,7 +250,7 @@ NAME names the stream, CHECK is a function returning non-nil if the server support the stream and OPEN is a function for opening the stream.") -(defvar imap-authenticators '(gssapi +(defvar imap-authenticators '(gssapi kerberos4 digest-md5 cram-md5 @@ -253,7 +258,7 @@ stream.") anonymous) "Priority of authenticators to consider when authenticating to server.") -(defvar imap-authenticator-alist +(defvar imap-authenticator-alist '((gssapi imap-gssapi-auth-p imap-gssapi-auth) (kerberos4 imap-kerberos4-auth-p imap-kerberos4-auth) (cram-md5 imap-cram-md5-p imap-cram-md5-auth) @@ -309,7 +314,7 @@ encoded mailboxes which doesn't translate into ISO-8859-1.") (defvar imap-username nil) (defvar imap-password nil) (defvar imap-calculate-literal-size-first nil) -(defvar imap-state 'closed +(defvar imap-state 'closed "IMAP state. Valid states are `closed', `initial', `nonauth', `auth', `selected' and `examine'.") @@ -350,7 +355,7 @@ and `examine'.") (defvar imap-reached-tag 0 "Lower limit on command tags that have been parsed.") -(defvar imap-failed-tags nil +(defvar imap-failed-tags nil "Alist of tags that failed. Each element is a list with four elements; tag (a integer), response state (a symbol, `OK', `NO' or `BAD'), response code (a string), and @@ -398,7 +403,7 @@ If ARGS, PROMPT is used as an argument to `format'." (and string (condition-case () (utf7-encode string t) - (error (message + (error (message "imap: Could not UTF7 encode `%s', using it unencoded..." string) string))) @@ -438,6 +443,7 @@ If ARGS, PROMPT is used as an argument to `format'." (message "Opening Kerberos 4 IMAP connection with `%s'..." cmd) (erase-buffer) (let* ((port (or port imap-default-port)) + (process-connection-type imap-process-connection-type) (process (as-binary-process (start-process name buffer shell-file-name shell-command-switch @@ -453,9 +459,10 @@ If ARGS, PROMPT is used as an argument to `format'." (setq imap-client-eol "\n" imap-calculate-literal-size-first t) (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) - ;; cyrus 1.6.x (13? < x <= 22) queries capabilities - (or (while (looking-at "^C:") + ;; cyrus 1.6.x (13? < x <= 22) queries capabilities + (or (while (looking-at "^C:") (forward-line)) t) ;; cyrus 1.6 imtest print "S: " before server greeting @@ -488,7 +495,7 @@ If ARGS, PROMPT is used as an argument to `format'." (delete-process process) nil))))) done)) - + (defun imap-gssapi-stream-p (buffer) (imap-capability 'AUTH=GSSAPI buffer)) @@ -498,6 +505,7 @@ If ARGS, PROMPT is used as an argument to `format'." (while (and (not done) (setq cmd (pop cmds))) (message "Opening GSSAPI IMAP connection with `%s'..." cmd) (let* ((port (or port imap-default-port)) + (process-connection-type imap-process-connection-type) (process (as-binary-process (start-process name buffer shell-file-name shell-command-switch @@ -513,9 +521,10 @@ If ARGS, PROMPT is used as an argument to `format'." (setq imap-client-eol "\n" imap-calculate-literal-size-first t) (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) - ;; cyrus 1.6.x (13? < x <= 22) queries capabilities - (or (while (looking-at "^C:") + ;; cyrus 1.6.x (13? < x <= 22) queries capabilities + (or (while (looking-at "^C:") (forward-line)) t) ;; cyrus 1.6 imtest print "S: " before server greeting @@ -553,6 +562,7 @@ If ARGS, PROMPT is used as an argument to `format'." (let ((cmds (if (listp imap-ssl-program) imap-ssl-program (list imap-ssl-program))) cmd done) + (ignore-errors (require 'ssl)) (while (and (not done) (setq cmd (pop cmds))) (message "imap: Opening SSL connection with `%s'..." cmd) (let* ((port (or port imap-default-ssl-port)) @@ -578,6 +588,7 @@ If ARGS, PROMPT is used as an argument to `format'." (with-current-buffer buffer (goto-char (point-min)) (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-max)) (forward-line -1) (not (imap-parse-greeting))) @@ -595,7 +606,7 @@ If ARGS, PROMPT is used as an argument to `format'." (progn (message "imap: Opening SSL connection with `%s'...done" cmd) done) - (message "imap: Opening SSL connection with `%s'...failed" cmd) + (message "imap: Opening SSL connection with `%s'...failed" cmd) nil))) (defun imap-network-p (buffer) @@ -606,6 +617,7 @@ If ARGS, PROMPT is used as an argument to `format'." (process (open-network-stream-as-binary name buffer server port))) (when process (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) (not (imap-parse-greeting))) (accept-process-output process 1) @@ -640,16 +652,17 @@ If ARGS, PROMPT is used as an argument to `format'." ?l imap-default-user)))))) (when process (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) (not (imap-parse-greeting))) (accept-process-output process 1) (sit-for 1)) - (erase-buffer) (and imap-log (with-current-buffer (get-buffer-create imap-log) (buffer-disable-undo) (goto-char (point-max)) (insert-buffer-substring buffer))) + (erase-buffer) (when (memq (process-status process) '(open run)) (setq done process))))) (if done @@ -675,6 +688,7 @@ If ARGS, PROMPT is used as an argument to `format'." (message "imap: Connecting with STARTTLS...") (when process (while (and (memq (process-status process) '(open run)) + (set-buffer buffer) ;; XXX "blue moon" nntp.el bug (goto-char (point-min)) (not (imap-parse-greeting))) (accept-process-output process 1) @@ -700,7 +714,7 @@ If ARGS, PROMPT is used as an argument to `format'." done) (message "imap: Connecting with STARTTLS...failed") nil))) - + ;; Server functions; authenticator stuff: (defun imap-interactive-login (buffer loginfunc) @@ -709,18 +723,18 @@ LOGINFUNC is passed a username and a password, it should return t if it where sucessful authenticating itself to the server, nil otherwise. Returns t if login was successful, nil otherwise." (with-current-buffer buffer - (make-variable-buffer-local 'imap-username) - (make-variable-buffer-local 'imap-password) + (make-local-variable 'imap-username) + (make-local-variable 'imap-password) (let (user passwd ret) ;; (condition-case () (while (or (not user) (not passwd)) (setq user (or imap-username - (read-from-minibuffer + (read-from-minibuffer (concat "IMAP username for " imap-server ": ") (or user imap-default-user)))) (setq passwd (or imap-password (imap-read-passwd - (concat "IMAP password for " user "@" + (concat "IMAP password for " user "@" imap-server ": ")))) (when (and user passwd) (if (funcall loginfunc user passwd) @@ -742,7 +756,14 @@ Returns t if login was successful, nil otherwise." ret))) (defun imap-gssapi-auth-p (buffer) - (imap-capability 'AUTH=GSSAPI buffer)) + (and (imap-capability 'AUTH=GSSAPI buffer) + (catch 'imtest-found + (let (prg (prgs imap-gssapi-program)) + (while (setq prg (pop prgs)) + (condition-case () + (and (call-process (substring prg 0 (string-match " " prg))) + (throw 'imtest-found t)) + (error nil))))))) (defun imap-gssapi-auth (buffer) (message "imap: Authenticating using GSSAPI...%s" @@ -750,7 +771,14 @@ Returns t if login was successful, nil otherwise." (eq imap-stream 'gssapi)) (defun imap-kerberos4-auth-p (buffer) - (imap-capability 'AUTH=KERBEROS_V4 buffer)) + (and (imap-capability 'AUTH=KERBEROS_V4 buffer) + (catch 'imtest-found + (let (prg (prgs imap-kerberos4-program)) + (while (setq prg (pop prgs)) + (condition-case () + (and (call-process (substring prg 0 (string-match " " prg))) + (throw 'imtest-found t)) + (error nil))))))) (defun imap-kerberos4-auth (buffer) (message "imap: Authenticating using Kerberos 4...%s" @@ -794,10 +822,10 @@ Returns t if login was successful, nil otherwise." (defun imap-login-auth (buffer) "Login to server using the LOGIN command." (message "imap: Plaintext authentication...") - (imap-interactive-login buffer + (imap-interactive-login buffer (lambda (user passwd) - (imap-ok-p (imap-send-command-wait - (concat "LOGIN \"" user "\" \"" + (imap-ok-p (imap-send-command-wait + (concat "LOGIN \"" user "\" \"" passwd "\"")))))) (defun imap-anonymous-p (buffer) @@ -807,7 +835,7 @@ Returns t if login was successful, nil otherwise." (message "imap: Loging in anonymously...") (with-current-buffer buffer (imap-ok-p (imap-send-command-wait - (concat "LOGIN anonymous \"" (concat (user-login-name) "@" + (concat "LOGIN anonymous \"" (concat (user-login-name) "@" (system-name)) "\""))))) (defun imap-digest-md5-p (buffer) @@ -822,7 +850,7 @@ Returns t if login was successful, nil otherwise." (imap-interactive-login buffer (lambda (user passwd) - (let ((tag + (let ((tag (imap-send-command (list "AUTHENTICATE DIGEST-MD5" @@ -847,7 +875,7 @@ Returns t if login was successful, nil otherwise." imap-current-message nil imap-state 'initial imap-process (condition-case () - (funcall (nth 2 (assq imap-stream + (funcall (nth 2 (assq imap-stream imap-stream-alist)) "imap" buffer imap-server imap-port) ((error quit) nil))) @@ -877,7 +905,7 @@ necessery. If nil, the buffer name is generated." (with-current-buffer (get-buffer-create buffer) (if (imap-opened buffer) (imap-close buffer)) - (mapcar 'make-variable-buffer-local imap-local-variables) + (mapcar 'make-local-variable imap-local-variables) (set-buffer-multibyte nil) (buffer-disable-undo) (setq imap-server (or server imap-server)) @@ -894,7 +922,7 @@ necessery. If nil, the buffer name is generated." (let ((streams imap-streams)) (while (setq stream (pop streams)) (if (funcall (nth 1 (assq stream imap-stream-alist)) buffer) - (setq stream-changed (not (eq (or imap-stream + (setq stream-changed (not (eq (or imap-stream imap-default-stream) stream)) imap-stream stream @@ -907,7 +935,7 @@ necessery. If nil, the buffer name is generated." (if (imap-open-1 buffer) (message "imap: Reconnecting with stream `%s'...done" imap-stream) - (message "imap: Reconnecting with stream `%s'...failed" + (message "imap: Reconnecting with stream `%s'...failed" imap-stream)) (setq imap-capability nil)) (if (imap-opened buffer) @@ -915,7 +943,7 @@ necessery. If nil, the buffer name is generated." (when (and (null imap-auth) (not (eq imap-state 'auth))) (let ((auths imap-authenticators)) (while (setq auth (pop auths)) - (if (funcall (nth 1 (assq auth imap-authenticator-alist)) + (if (funcall (nth 1 (assq auth imap-authenticator-alist)) buffer) (setq imap-auth auth auths nil))) @@ -947,8 +975,8 @@ password is remembered in the buffer." (or (eq imap-state 'auth) (eq imap-state 'select) (eq imap-state 'examine)) - (make-variable-buffer-local 'imap-username) - (make-variable-buffer-local 'imap-password) + (make-local-variable 'imap-username) + (make-local-variable 'imap-password) (if user (setq imap-username user)) (if passwd (setq imap-password passwd)) (if (funcall (nth 2 (assq imap-auth imap-authenticator-alist)) buffer) @@ -1018,7 +1046,7 @@ If BUFFER is nil, the current buffer is assumed." (defun imap-mailbox-map-1 (func &optional mailbox-decoder buffer) (with-current-buffer (or buffer (current-buffer)) (let (result) - (mapatoms + (mapatoms (lambda (s) (push (funcall func (if mailbox-decoder (funcall mailbox-decoder (symbol-name s)) @@ -1054,7 +1082,7 @@ If EXAMINE is non-nil, do a read-only select." imap-current-mailbox (setq imap-current-mailbox mailbox) (if (imap-ok-p (imap-send-command-wait - (concat (if examine "EXAMINE" "SELECT") " \"" + (concat (if examine "EXAMINE" "SELECT") " \"" mailbox "\""))) (progn (setq imap-message-data (make-vector imap-message-prime 0) @@ -1063,18 +1091,18 @@ If EXAMINE is non-nil, do a read-only select." ;; Failed SELECT/EXAMINE unselects current mailbox (setq imap-current-mailbox nil)))) -(defun imap-mailbox-select (mailbox &optional examine buffer) +(defun imap-mailbox-select (mailbox &optional examine buffer) (with-current-buffer (or buffer (current-buffer)) - (imap-utf7-decode + (imap-utf7-decode (imap-mailbox-select-1 (imap-utf7-encode mailbox) examine)))) (defun imap-mailbox-examine-1 (mailbox &optional buffer) (with-current-buffer (or buffer (current-buffer)) - (imap-mailbox-select-1 mailbox 'exmine))) + (imap-mailbox-select-1 mailbox 'examine))) (defun imap-mailbox-examine (mailbox &optional buffer) "Examine MAILBOX on server in BUFFER." - (imap-mailbox-select mailbox 'exmine buffer)) + (imap-mailbox-select mailbox 'examine buffer)) (defun imap-mailbox-unselect (&optional buffer) "Close current folder in BUFFER, without expunging articles." @@ -1082,7 +1110,7 @@ If EXAMINE is non-nil, do a read-only select." (when (or (eq imap-state 'auth) (and (imap-capability 'UNSELECT) (imap-ok-p (imap-send-command-wait "UNSELECT"))) - (and (imap-ok-p + (and (imap-ok-p (imap-send-command-wait (concat "EXAMINE \"" imap-current-mailbox "\""))) @@ -1137,7 +1165,7 @@ If BUFFER is nil the current buffer is assumed." (imap-send-command-wait (list "RENAME \"" oldname "\" " "\"" newname "\"")))))) -(defun imap-mailbox-lsub (&optional root reference add-delimiter buffer) +(defun imap-mailbox-lsub (&optional root reference add-delimiter buffer) "Return a list of subscribed mailboxes on server in BUFFER. If ROOT is non-nil, only list matching mailboxes. If ADD-DELIMITER is non-nil, a hierarchy delimiter is added to root. REFERENCE is a @@ -1151,7 +1179,7 @@ implementation-specific string that has to be passed to lsub command." (imap-mailbox-map-1 (lambda (mailbox) (imap-mailbox-put 'lsub nil mailbox))) (when (imap-ok-p - (imap-send-command-wait + (imap-send-command-wait (concat "LSUB \"" reference "\" \"" (imap-utf7-encode root) (and add-delimiter (imap-mailbox-get-1 'delimiter root)) "%\""))) @@ -1175,7 +1203,7 @@ passed to list command." (imap-mailbox-map-1 (lambda (mailbox) (imap-mailbox-put 'list nil mailbox))) (when (imap-ok-p - (imap-send-command-wait + (imap-send-command-wait (concat "LIST \"" reference "\" \"" (imap-utf7-encode root) (and add-delimiter (imap-mailbox-get-1 'delimiter root)) "%\""))) @@ -1189,7 +1217,7 @@ passed to list command." "Send the SUBSCRIBE command on the mailbox to server in BUFFER. Returns non-nil if successful." (with-current-buffer (or buffer (current-buffer)) - (imap-ok-p (imap-send-command-wait (concat "SUBSCRIBE \"" + (imap-ok-p (imap-send-command-wait (concat "SUBSCRIBE \"" (imap-utf7-encode mailbox) "\""))))) @@ -1197,7 +1225,7 @@ Returns non-nil if successful." "Send the SUBSCRIBE command on the mailbox to server in BUFFER. Returns non-nil if successful." (with-current-buffer (or buffer (current-buffer)) - (imap-ok-p (imap-send-command-wait (concat "UNSUBSCRIBE " + (imap-ok-p (imap-send-command-wait (concat "UNSUBSCRIBE " (imap-utf7-encode mailbox) "\""))))) @@ -1208,13 +1236,13 @@ the STATUS data items -- ie 'messages, 'recent, 'uidnext, 'uidvalidity or 'unseen. If ITEMS is a list of symbols, a list of values is returned, if ITEMS is a symbol only it's value is returned." (with-current-buffer (or buffer (current-buffer)) - (when (imap-ok-p + (when (imap-ok-p (imap-send-command-wait (list "STATUS \"" (imap-utf7-encode mailbox) "\" " (format "%s" (if (listp items) - items + items (list items)))))) (if (listp items) (mapcar (lambda (item) @@ -1273,8 +1301,8 @@ returned, if ITEMS is a symbol only it's value is returned." (mapconcat (lambda (item) (if (consp item) - (format "%d:%d" - (car item) (cdr item)) + (format "%d:%d" + (car item) (cdr item)) (format "%d" item))) (if (and (listp range) (not (listp (cdr range)))) (list range) ;; make (1 . 2) into ((1 . 2)) @@ -1294,7 +1322,7 @@ returned, if ITEMS is a symbol only it's value is returned." UIDS can be a string, number or a list of numbers. If RECEIVE is non-nil return theese properties." (with-current-buffer (or buffer (current-buffer)) - (when (imap-ok-p (imap-send-command-wait + (when (imap-ok-p (imap-send-command-wait (format "%sFETCH %s %s" (if nouidfetch "" "UID ") (if (listp uids) (imap-list-to-message-set uids) @@ -1311,7 +1339,7 @@ is non-nil return theese properties." (imap-message-get uid receive))) uids) (imap-message-get uids receive)))))) - + (defun imap-message-put (uid propname value &optional buffer) (with-current-buffer (or buffer (current-buffer)) (if imap-message-data @@ -1385,7 +1413,9 @@ is non-nil return theese properties." (imap-mailbox-put 'search 'dummy) (when (imap-ok-p (imap-send-command-wait (concat "UID SEARCH " predicate))) (if (eq (imap-mailbox-get-1 'search imap-current-mailbox) 'dummy) - (error "Missing SEARCH response to a SEARCH command") + (progn + (message "Missing SEARCH response to a SEARCH command (server not RFC compliant)...") + nil) (imap-mailbox-get-1 'search imap-current-mailbox))))) (defun imap-message-flag-permanent-p (flag &optional mailbox buffer) @@ -1459,7 +1489,7 @@ first element, rest of list contain the saved articles' UIDs." (imap-ok-p (imap-send-command-wait cmd))))) (or no-copyuid (imap-message-copyuid-1 mailbox))))))) - + (defun imap-message-appenduid-1 (mailbox) (if (imap-capability 'UIDPLUS) (imap-mailbox-get-1 'appenduid mailbox) @@ -1488,11 +1518,11 @@ on failure." (let ((mailbox (imap-utf7-encode mailbox))) (with-current-buffer (or buffer (current-buffer)) (and (let ((imap-current-target-mailbox mailbox)) - (imap-ok-p - (imap-send-command-wait + (imap-ok-p + (imap-send-command-wait (list "APPEND \"" mailbox "\" " article)))) (imap-message-appenduid-1 mailbox))))) - + (defun imap-body-lines (body) "Return number of lines in article by looking at the mime bodystructure BODY." (if (listp body) @@ -1512,8 +1542,8 @@ on failure." (and from (concat (aref from 0) (if (aref from 0) " <") - (aref from 2) - "@" + (aref from 2) + "@" (aref from 3) (if (aref from 0) ">")))) @@ -1552,7 +1582,7 @@ on failure." (replace-match eol))) (if (not calcfirst) (setq size (buffer-size)))) - (setq cmdstr + (setq cmdstr (concat cmdstr (format "{%d}" size)))) (unwind-protect (progn @@ -1592,19 +1622,19 @@ on failure." (defun imap-wait-for-tag (tag &optional buffer) (with-current-buffer (or buffer (current-buffer)) (while (and (null imap-continuation) + (memq (process-status imap-process) '(open run)) (< imap-reached-tag tag)) - (or (and (not (memq (process-status imap-process) '(open run))) - (sit-for 1)) - (let ((len (/ (point-max) 1024)) - message-log-max) - (unless (< len 10) - (message "imap read: %dk" len)) - (accept-process-output imap-process 1)))) + (let ((len (/ (point-max) 1024)) + message-log-max) + (unless (< len 10) + (message "imap read: %dk" len)) + (accept-process-output imap-process 1))) (message "") - (or (assq tag imap-failed-tags) - (if imap-continuation - 'INCOMPLETE - 'OK)))) + (and (memq (process-status imap-process) '(open run)) + (or (assq tag imap-failed-tags) + (if imap-continuation + 'INCOMPLETE + 'OK))))) (defun imap-sentinel (process string) (delete-process process)) @@ -1648,7 +1678,7 @@ Return nil if no complete line has arrived." (eq imap-state 'examine)) (imap-parse-response)) (t - (message "Unknown state %s in arrival filter" + (message "Unknown state %s in arrival filter" imap-state))) (delete-region (point-min) (point-max)))))))) @@ -1735,7 +1765,7 @@ Return nil if no complete line has arrived." (defsubst imap-parse-astring () (or (imap-parse-string) - (buffer-substring (point) + (buffer-substring (point) (if (re-search-forward "[(){ \r\n%*\"\\]" nil t) (goto-char (1- (match-end 0))) (end-of-line) @@ -1795,7 +1825,7 @@ Return nil if no complete line has arrived." (when (eq (char-after) ?\)) (imap-forward) (nreverse addresses))) - (assert (imap-parse-nil)))) + (assert (imap-parse-nil) t "In imap-parse-address-list"))) ;; mailbox = "INBOX" / astring ;; ; INBOX is case-insensitive. All case variants of @@ -1848,13 +1878,13 @@ Return nil if no complete line has arrived." ;; resp-cond-bye = "BYE" SP resp-text ;; ;; mailbox-data = "FLAGS" SP flag-list / -;; "LIST" SP mailbox-list / +;; "LIST" SP mailbox-list / ;; "LSUB" SP mailbox-list / -;; "SEARCH" *(SP nz-number) / +;; "SEARCH" *(SP nz-number) / ;; "STATUS" SP mailbox SP "(" -;; [status-att SP number *(SP status-att SP number)] ")" / +;; [status-att SP number *(SP status-att SP number)] ")" / ;; number SP "EXISTS" / -;; number SP "RECENT" +;; number SP "RECENT" ;; ;; message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att)) ;; @@ -1881,11 +1911,11 @@ Return nil if no complete line has arrived." (FLAGS (imap-mailbox-put 'flags (imap-parse-flag-list))) (LIST (imap-parse-data-list 'list)) (LSUB (imap-parse-data-list 'lsub)) - (SEARCH (imap-mailbox-put - 'search + (SEARCH (imap-mailbox-put + 'search (read (concat "(" (buffer-substring (point) (point-max)) ")")))) (STATUS (imap-parse-status)) - (CAPABILITY (setq imap-capability + (CAPABILITY (setq imap-capability (read (concat "(" (upcase (buffer-substring (point) (point-max))) ")")))) @@ -1915,7 +1945,7 @@ Return nil if no complete line has arrived." (search-forward "]"))) (imap-forward)) (setq text (buffer-substring (point) (point-max))) - (push (list token status code text) + (push (list token status code text) imap-failed-tags)))) (BAD (progn (setq imap-reached-tag (max imap-reached-tag token)) @@ -1943,15 +1973,15 @@ Return nil if no complete line has arrived." ;; resp-text-code = "ALERT" / ;; "BADCHARSET [SP "(" astring *(SP astring) ")" ] / -;; "NEWNAME" SP string SP string / -;; "PARSE" / -;; "PERMANENTFLAGS" SP "(" +;; "NEWNAME" SP string SP string / +;; "PARSE" / +;; "PERMANENTFLAGS" SP "(" ;; [flag-perm *(SP flag-perm)] ")" / -;; "READ-ONLY" / -;; "READ-WRITE" / -;; "TRYCREATE" / -;; "UIDNEXT" SP nz-number / -;; "UIDVALIDITY" SP nz-number / +;; "READ-ONLY" / +;; "READ-WRITE" / +;; "TRYCREATE" / +;; "UIDNEXT" SP nz-number / +;; "UIDVALIDITY" SP nz-number / ;; "UNSEEN" SP nz-number / ;; resp-text-atom [SP 1*] ;; @@ -1969,7 +1999,7 @@ Return nil if no complete line has arrived." ;; ; delimits between two numbers inclusive. ;; ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13, ;; ; 14,15 for a mailbox with 15 messages. -;; +;; ;; sequence-num = nz-number / "*" ;; ; * is the largest number in use. For message ;; ; sequence numbers, it is the number of messages @@ -2070,18 +2100,18 @@ Return nil if no complete line has arrived." ;; "BODY" ["STRUCTURE"] SPACE body / ;; "BODY" section ["<" number ">"] SPACE nstring / ;; "UID" SPACE uniqueid) ")" -;; +;; ;; date_time ::= <"> date_day_fixed "-" date_month "-" date_year ;; SPACE time SPACE zone <"> -;; +;; ;; section ::= "[" [section_text / (nz_number *["." nz_number] ;; ["." (section_text / "MIME")])] "]" -;; +;; ;; section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"] ;; SPACE header_list / "TEXT" -;; +;; ;; header_fld_name ::= astring -;; +;; ;; header_list ::= "(" 1#header_fld_name ")" (defsubst imap-parse-header-list () @@ -2094,7 +2124,7 @@ Return nil if no complete line has arrived." (nreverse strlist)))) (defsubst imap-parse-fetch-body-section () - (let ((section + (let ((section (buffer-substring (point) (1- (re-search-forward "[] ]" nil t))))) (if (eq (char-before) ? ) (prog1 @@ -2104,7 +2134,7 @@ Return nil if no complete line has arrived." (defun imap-parse-fetch (response) (when (eq (char-after) ?\() - (let (uid flags envelope internaldate rfc822 rfc822header rfc822text + (let (uid flags envelope internaldate rfc822 rfc822header rfc822text rfc822size body bodydetail bodystructure) (while (not (eq (char-after) ?\))) (imap-forward) @@ -2156,7 +2186,7 @@ Return nil if no complete line has arrived." ;; mailbox-data = ... ;; "STATUS" SP mailbox SP "(" -;; [status-att SP number +;; [status-att SP number ;; *(SP status-att SP number)] ")" ;; ... ;; @@ -2181,7 +2211,7 @@ Return nil if no complete line has arrived." ((eq token 'UNSEEN) (imap-mailbox-put 'unseen (read (current-buffer)) mailbox)) (t - (message "Unknown status data %s in mailbox %s ignored" + (message "Unknown status data %s in mailbox %s ignored" token mailbox)))))))) ;; acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE @@ -2220,12 +2250,16 @@ Return nil if no complete line has arrived." (defun imap-parse-flag-list () (let (flag-list start) - (assert (eq (char-after) ?\()) + (assert (eq (char-after) ?\() t "In imap-parse-flag-list") (while (and (not (eq (char-after) ?\))) - (setq start (progn (imap-forward) (point))) + (setq start (progn + (imap-forward) + ;; next line for Courier IMAP bug. + (skip-chars-forward " ") + (point))) (> (skip-chars-forward "^ )" (imap-point-at-eol)) 0)) (push (buffer-substring start (point)) flag-list)) - (assert (eq (char-after) ?\))) + (assert (eq (char-after) ?\)) t "In imap-parse-flag-list") (imap-forward) (nreverse flag-list))) @@ -2310,7 +2344,7 @@ Return nil if no complete line has arrived." (while (eq (char-after) ?\ ) (imap-forward) (push (imap-parse-body-extension) b-e)) - (assert (eq (char-after) ?\))) + (assert (eq (char-after) ?\)) t "In imap-parse-body-extension") (imap-forward) (nreverse b-e)) (or (imap-parse-number) @@ -2338,7 +2372,7 @@ Return nil if no complete line has arrived." (imap-forward) (push (imap-parse-string-list) dsp) (imap-forward)) - (assert (imap-parse-nil))) + (assert (imap-parse-nil) t "In imap-parse-body-ext")) (push (nreverse dsp) ext)) (when (eq (char-after) ?\ );; body-fld-lang (imap-forward) @@ -2434,7 +2468,7 @@ Return nil if no complete line has arrived." (push (and (imap-parse-nil) nil) body)) (setq body (append (imap-parse-body-ext) body)));; body-ext-... - (assert (eq (char-after) ?\))) + (assert (eq (char-after) ?\)) t "In imap-parse-body") (imap-forward) (nreverse body)) @@ -2493,15 +2527,15 @@ Return nil if no complete line has arrived." (imap-forward) (push (imap-parse-nstring) body);; body-fld-md5 (setq body (append (imap-parse-body-ext) body)));; body-ext-1part.. - - (assert (eq (char-after) ?\))) + + (assert (eq (char-after) ?\)) t "In imap-parse-body 2") (imap-forward) (nreverse body))))) (when imap-debug ; (untrace-all) (require 'trace) (buffer-disable-undo (get-buffer-create imap-debug)) - (mapcar (lambda (f) (trace-function-background f imap-debug)) + (mapcar (lambda (f) (trace-function-background f imap-debug)) '( imap-read-passwd imap-utf7-encode @@ -2595,7 +2629,7 @@ Return nil if no complete line has arrived." imap-parse-body-extension imap-parse-body ))) - + (provide 'imap) ;;; imap.el ends here