;;; imap.el --- imap library
-;; Copyright (C) 1998, 1999, 2000
+;; Copyright (C) 1998, 1999, 2000, 2001
;; Free Software Foundation, Inc.
;; Author: Simon Josefsson <jas@pdc.kth.se>
;;
;; 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
;; 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
;; => "X-Sieve: cmu-sieve 1.3^M\nX-Username: <jas@pdc.kth.se>^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
:group 'imap
:type 'boolean)
-(defvar imap-shell-host "gateway"
- "Hostname of rlogin proxy.")
+(defcustom imap-use-utf7 t
+ "If non-nil, do utf7 encoding/decoding of mailbox names.
+Since the UTF7 decoding currently only decodes into ISO-8859-1
+characters, you may disable this decoding if you need to access UTF7
+encoded mailboxes which doesn't translate into ISO-8859-1."
+ :group 'imap
+ :type 'boolean)
-(defvar imap-default-user (user-login-name)
- "Default username to use.")
+(defcustom imap-log nil
+ "If non-nil, a imap session trace is placed in *imap-log* buffer."
+ :group 'imap
+ :type 'boolean)
-(defvar imap-error nil
- "Error codes from the last command.")
+(defcustom imap-debug nil
+ "If non-nil, random debug spews are placed in *imap-debug* buffer."
+ :group 'imap
+ :type 'boolean)
+
+(defcustom imap-shell-host "gateway"
+ "Hostname of rlogin proxy."
+ :group 'imap
+ :type 'string)
+
+(defcustom imap-default-user (user-login-name)
+ "Default username to use."
+ :group 'imap
+ :type 'string)
;; Various variables.
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
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)
the server support the authenticator and AUTHENTICATE is a function
for doing the actuall authentification.")
-(defvar imap-use-utf7 t
- "If non-nil, do utf7 encoding/decoding of mailbox names.
-Since the UTF7 decoding currently only decodes into ISO-8859-1
-characters, you may disable this decoding if you need to access UTF7
-encoded mailboxes which doesn't translate into ISO-8859-1.")
+(defvar imap-error nil
+ "Error codes from the last command.")
;; Internal constants. Change theese and die.
imap-process
imap-calculate-literal-size-first
imap-mailbox-data))
+(defconst imap-log-buffer "*imap-log*")
+(defconst imap-debug-buffer "*imap-debug*")
;; Internal variables.
(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'.")
(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
"Non-nil indicates that the server emitted a continuation request.
The actually value is really the text on the continuation line.")
-(defvar imap-log nil
- "Name of buffer for imap session trace.
-For example: (setq imap-log \"*imap-log*\")")
-
-(defvar imap-debug nil ;"*imap-debug*"
- "Name of buffer for random debug spew.
-For example: (setq imap-debug \"*imap-debug*\")")
-
\f
;; Utility functions:
(and string
(condition-case ()
(utf7-encode string t)
- (error (message
+ (error (message
"imap: Could not UTF7 encode `%s', using it unencoded..."
string)
string)))
(coding-system-for-read imap-coding-system-for-read)
(coding-system-for-write imap-coding-system-for-write)
(process-connection-type imap-process-connection-type)
- (process (start-process
+ (process (start-process
name buffer shell-file-name shell-command-switch
(format-spec
cmd
(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
+ ;; 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
+ ;; cyrus 1.6 imtest print "S: " before server greeting
(or (not (looking-at "S: "))
(forward-char 3)
t)
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(delete-process process)
nil)))))
done))
-
+
(defun imap-gssapi-stream-p (buffer)
(imap-capability 'AUTH=GSSAPI buffer))
(coding-system-for-read imap-coding-system-for-read)
(coding-system-for-write imap-coding-system-for-write)
(process-connection-type imap-process-connection-type)
- (process (start-process
+ (process (start-process
name buffer shell-file-name shell-command-switch
(format-spec
cmd
(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
+ ;; 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
+ ;; cyrus 1.6 imtest print "S: " before server greeting
(or (not (looking-at "S: "))
(forward-char 3)
t)
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(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)
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(let* ((port (or port imap-default-port))
(coding-system-for-read imap-coding-system-for-read)
(coding-system-for-write imap-coding-system-for-write)
- (process (start-process
+ (process (start-process
name buffer shell-file-name shell-command-switch
(format-spec
cmd
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(progn
(message "imap: Opening IMAP connection with `%s'...done" cmd)
done)
- (message "imap: Opening IMAP connection with `%s'...failed" cmd)
+ (message "imap: Opening IMAP connection with `%s'...failed" cmd)
nil)))
(defun imap-starttls-p (buffer)
(accept-process-output process 1)
(sit-for 1))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(buffer-disable-undo)
(goto-char (point-max))
(insert-buffer-substring buffer)))
done)
(message "imap: Connecting with STARTTLS...failed")
nil)))
-
+
;; Server functions; authenticator stuff:
(defun imap-interactive-login (buffer loginfunc)
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)
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"
(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"
(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)
(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)
(imap-interactive-login
buffer
(lambda (user passwd)
- (let ((tag
+ (let ((tag
(imap-send-command
(list
"AUTHENTICATE DIGEST-MD5"
(digest-md5-parse-digest-challenge
(base64-decode-string challenge))
(let* ((digest-uri
- (digest-md5-digest-uri
+ (digest-md5-digest-uri
"imap" (digest-md5-challenge 'realm)))
(response
- (digest-md5-digest-response
+ (digest-md5-digest-response
user passwd digest-uri)))
(base64-encode-string response 'no-line-break))))
)))
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)))
(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)
(imap-disable-multibyte)
(buffer-disable-undo)
(setq imap-server (or server imap-server))
(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
(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)
(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)))
(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)
(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))
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)
;; 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."
(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
"\"")))
(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
(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))
"%\"")))
(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))
"%\"")))
"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)
"\"")))))
"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)
"\"")))))
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)
(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))
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)
(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
(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)
(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)
(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)
(and from
(concat (aref from 0)
(if (aref from 0) " <")
- (aref from 2)
- "@"
+ (aref from 2)
+ "@"
(aref from 3)
(if (aref from 0) ">"))))
(defun imap-send-command-1 (cmdstr)
(setq cmdstr (concat cmdstr imap-client-eol))
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(replace-match eol)))
(if (not calcfirst)
(setq size (buffer-size))))
- (setq cmdstr
+ (setq cmdstr
(concat cmdstr (format "{%d}" size))))
(unwind-protect
(progn
(imap-send-command-1 cmdstr)
(setq cmdstr nil)
(if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE))
- (setq command nil);; abort command if no cont-req
+ (setq command nil) ;; abort command if no cont-req
(let ((process imap-process)
(stream imap-stream)
(eol imap-client-eol))
(with-current-buffer cmd
(and imap-log
(with-current-buffer (get-buffer-create
- imap-log)
+ imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(setq cmdstr nil)
(unwind-protect
(if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE))
- (setq command nil);; abort command if no cont-req
+ (setq command nil) ;; abort command if no cont-req
(setq command (cons (funcall cmd imap-continuation)
command)))
(setq imap-continuation nil)))
(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))
(goto-char (point-max))
(insert string)
(and imap-log
- (with-current-buffer (get-buffer-create imap-log)
+ (with-current-buffer (get-buffer-create imap-log-buffer)
(imap-disable-multibyte)
(buffer-disable-undo)
(goto-char (point-max))
(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))))))))
(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)
(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
(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)))
")"))))
(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))
;; resp-text-code = "ALERT" /
;; "BADCHARSET [SP "(" astring *(SP astring) ")" ] /
-;; "NEWNAME" SP string SP string /
+;; "NEWNAME" SP string SP string /
;; "PARSE" /
-;; "PERMANENTFLAGS" SP "("
+;; "PERMANENTFLAGS" SP "("
;; [flag-perm *(SP flag-perm)] ")" /
-;; "READ-ONLY" /
-;; "READ-WRITE" /
+;; "READ-ONLY" /
+;; "READ-WRITE" /
;; "TRYCREATE" /
-;; "UIDNEXT" SP nz-number /
+;; "UIDNEXT" SP nz-number /
;; "UIDVALIDITY" SP nz-number /
;; "UNSEEN" SP nz-number /
;; resp-text-atom [SP 1*<any TEXT-CHAR except "]">]
;; ; 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
;; "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 ()
(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
(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)
;; mailbox-data = ...
;; "STATUS" SP mailbox SP "("
-;; [status-att SP number
+;; [status-att SP number
;; *(SP status-att SP number)] ")"
;; ...
;;
((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
(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)))
(> (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)))
(defun imap-parse-envelope ()
(when (eq (char-after) ?\()
(imap-forward)
- (vector (prog1 (imap-parse-nstring);; date
+ (vector (prog1 (imap-parse-nstring) ;; date
(imap-forward))
- (prog1 (imap-parse-nstring);; subject
+ (prog1 (imap-parse-nstring) ;; subject
(imap-forward))
- (prog1 (imap-parse-address-list);; from
+ (prog1 (imap-parse-address-list) ;; from
(imap-forward))
- (prog1 (imap-parse-address-list);; sender
+ (prog1 (imap-parse-address-list) ;; sender
(imap-forward))
- (prog1 (imap-parse-address-list);; reply-to
+ (prog1 (imap-parse-address-list) ;; reply-to
(imap-forward))
- (prog1 (imap-parse-address-list);; to
+ (prog1 (imap-parse-address-list) ;; to
(imap-forward))
- (prog1 (imap-parse-address-list);; cc
+ (prog1 (imap-parse-address-list) ;; cc
(imap-forward))
- (prog1 (imap-parse-address-list);; bcc
+ (prog1 (imap-parse-address-list) ;; bcc
(imap-forward))
- (prog1 (imap-parse-nstring);; in-reply-to
+ (prog1 (imap-parse-nstring) ;; in-reply-to
(imap-forward))
- (prog1 (imap-parse-nstring);; message-id
+ (prog1 (imap-parse-nstring) ;; message-id
(imap-forward)))))
;; body-fld-param = "(" string SP string *(SP string SP string) ")" / nil
(defsubst imap-parse-string-list ()
- (cond ((eq (char-after) ?\();; body-fld-param
+ (cond ((eq (char-after) ?\() ;; body-fld-param
(let (strlist str)
(imap-forward)
(while (setq str (imap-parse-string))
(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)
(defsubst imap-parse-body-ext ()
(let (ext)
- (when (eq (char-after) ?\ );; body-fld-dsp
+ (when (eq (char-after) ?\ ) ;; body-fld-dsp
(imap-forward)
(let (dsp)
(if (eq (char-after) ?\()
(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
+ (when (eq (char-after) ?\ ) ;; body-fld-lang
(imap-forward)
(if (eq (char-after) ?\()
(push (imap-parse-string-list) ext)
(push (imap-parse-nstring) ext))
- (while (eq (char-after) ?\ );; body-extension
+ (while (eq (char-after) ?\ ) ;; body-extension
(imap-forward)
(setq ext (append (imap-parse-body-extension) ext)))))
ext))
(let (subbody)
(while (and (eq (char-after) ?\()
(setq subbody (imap-parse-body)))
- ;; buggy stalker communigate pro 3.0 insert a SPC between
+ ;; buggy stalker communigate pro 3.0 insert a SPC between
;; parts in multiparts
(when (and (eq (char-after) ?\ )
(eq (char-after (1+ (point))) ?\())
(imap-forward))
(push subbody body))
(imap-forward)
- (push (imap-parse-string) body);; media-subtype
- (when (eq (char-after) ?\ );; body-ext-mpart:
+ (push (imap-parse-string) body) ;; media-subtype
+ (when (eq (char-after) ?\ ) ;; body-ext-mpart:
(imap-forward)
- (if (eq (char-after) ?\();; body-fld-param
+ (if (eq (char-after) ?\() ;; body-fld-param
(push (imap-parse-string-list) body)
(push (and (imap-parse-nil) nil) body))
(setq body
- (append (imap-parse-body-ext) body)));; body-ext-...
- (assert (eq (char-after) ?\)))
+ (append (imap-parse-body-ext) body))) ;; body-ext-...
+ (assert (eq (char-after) ?\)) t "In imap-parse-body")
(imap-forward)
(nreverse body))
- (push (imap-parse-string) body);; media-type
+ (push (imap-parse-string) body) ;; media-type
(imap-forward)
- (push (imap-parse-string) body);; media-subtype
+ (push (imap-parse-string) body) ;; media-subtype
(imap-forward)
;; next line for Sun SIMS bug
(and (eq (char-after) ? ) (imap-forward))
- (if (eq (char-after) ?\();; body-fld-param
+ (if (eq (char-after) ?\() ;; body-fld-param
(push (imap-parse-string-list) body)
(push (and (imap-parse-nil) nil) body))
(imap-forward)
- (push (imap-parse-nstring) body);; body-fld-id
+ (push (imap-parse-nstring) body) ;; body-fld-id
(imap-forward)
- (push (imap-parse-nstring) body);; body-fld-desc
+ (push (imap-parse-nstring) body) ;; body-fld-desc
(imap-forward)
;; next `or' for Sun SIMS bug, it regard body-fld-enc as a
;; nstring and return NIL instead of defaulting back to 7BIT
;; as the standard says.
- (push (or (imap-parse-nstring) "7BIT") body);; body-fld-enc
+ (push (or (imap-parse-nstring) "7BIT") body) ;; body-fld-enc
(imap-forward)
- (push (imap-parse-number) body);; body-fld-octets
+ (push (imap-parse-number) body) ;; body-fld-octets
- ;; ok, we're done parsing the required parts, what comes now is one
+ ;; ok, we're done parsing the required parts, what comes now is one
;; of three things:
;;
;; envelope (then we're parsing body-type-msg)
;; body-fld-lines (then we're parsing body-type-text)
;; body-ext-1part (then we're parsing body-type-basic)
;;
- ;; the problem is that the two first are in turn optionally followed
- ;; by the third. So we parse the first two here (if there are any)...
+ ;; the problem is that the two first are in turn optionally followed
+;; by the third. So we parse the first two here (if there are any)...
(when (eq (char-after) ?\ )
(imap-forward)
(let (lines)
- (cond ((eq (char-after) ?\();; body-type-msg:
- (push (imap-parse-envelope) body);; envelope
+ (cond ((eq (char-after) ?\() ;; body-type-msg:
+ (push (imap-parse-envelope) body) ;; envelope
(imap-forward)
- (push (imap-parse-body) body);; body
+ (push (imap-parse-body) body) ;; body
;; buggy stalker communigate pro 3.0 doesn't print
;; number of lines in message/rfc822 attachment
(if (eq (char-after) ?\))
(push 0 body)
(imap-forward)
(push (imap-parse-number) body))) ;; body-fld-lines
- ((setq lines (imap-parse-number)) ;; body-type-text:
- (push lines body)) ;; body-fld-lines
+ ((setq lines (imap-parse-number)) ;; body-type-text:
+ (push lines body)) ;; body-fld-lines
(t
- (backward-char))))) ;; no match...
+ (backward-char))))) ;; no match...
;; ...and then parse the third one here...
- (when (eq (char-after) ?\ );; body-ext-1part:
+ (when (eq (char-after) ?\ ) ;; body-ext-1part:
(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) ?\)))
+ (push (imap-parse-nstring) body) ;; body-fld-md5
+ (setq body (append (imap-parse-body-ext) body))) ;; body-ext-1part..
+
+ (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))
+ (buffer-disable-undo (get-buffer-create imap-debug-buffer))
+ (mapcar (lambda (f) (trace-function-background f imap-debug-buffer))
'(
imap-read-passwd
imap-utf7-encode
imap-parse-body-extension
imap-parse-body
)))
-
+
(provide 'imap)
;;; imap.el ends here