;;; Code:
+;; For Emacs <22.2 and XEmacs.
+(eval-and-compile
+ (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
(eval-and-compile
(require 'nnheader))
(* 5 60)))
(nnimap-send-command "NOOP")))))))
+(declare-function gnutls-negotiate "subr" (fn file &optional arglist fileonly))
+
(defun nnimap-open-connection (buffer)
(unless nnimap-keepalive-timer
(setq nnimap-keepalive-timer (run-at-time (* 60 15) (* 60 15)
(port nil)
(ports
(cond
- ((eq nnimap-stream 'network)
+ ((or (eq nnimap-stream 'network)
+ (and (eq nnimap-stream 'starttls)
+ (fboundp 'open-gnutls-stream)))
+ (nnheader-message 7 "Opening connection to %s..."
+ nnimap-address)
(open-network-stream
"*nnimap*" (current-buffer) nnimap-address
(setq port
"143"))))
'("143" "imap"))
((eq nnimap-stream 'shell)
+ (nnheader-message 7 "Opening connection to %s via shell..."
+ nnimap-address)
(nnimap-open-shell-stream
"*nnimap*" (current-buffer) nnimap-address
(setq port (or nnimap-server-port "imap")))
'("imap"))
((eq nnimap-stream 'starttls)
- (let ((tls-program (nnimap-extend-tls-programs)))
+ (nnheader-message 7 "Opening connection to %s via starttls..."
+ nnimap-address)
+ (let ((tls-program
+ '("openssl s_client -connect %h:%p -no_ssl2 -ign_eof -starttls imap")))
(open-tls-stream
"*nnimap*" (current-buffer) nnimap-address
- (setq port (or nnimap-server-port "imap"))
- 'starttls))
+ (setq port (or nnimap-server-port "imap"))))
'("imap"))
((memq nnimap-stream '(ssl tls))
+ (nnheader-message 7 "Opening connection to %s via tls..."
+ nnimap-address)
(funcall (if (fboundp 'open-gnutls-stream)
'open-gnutls-stream
'open-tls-stream)
(push (format "%s" nnimap-server-port) ports))
;; If this is a STARTTLS-capable server, then sever the
;; connection and start a STARTTLS connection instead.
- (when (and (eq nnimap-stream 'network)
- (member "STARTTLS" (nnimap-capabilities nnimap-object)))
+ (cond
+ ((and (or (and (eq nnimap-stream 'network)
+ (member "STARTTLS"
+ (nnimap-capabilities nnimap-object)))
+ (eq nnimap-stream 'starttls))
+ (fboundp 'open-gnutls-stream))
+ (nnimap-command "STARTTLS")
+ (gnutls-negotiate (nnimap-process nnimap-object) nil))
+ ((and (eq nnimap-stream 'network)
+ (member "STARTTLS" (nnimap-capabilities nnimap-object)))
(let ((nnimap-stream 'starttls))
(let ((tls-process
(nnimap-open-connection buffer)))
(when (memq (process-status tls-process) '(open run))
(delete-process (nnimap-process nnimap-object))
(kill-buffer (current-buffer))
- (return tls-process)))))
+ (return tls-process))))))
(unless (equal connection-result "PREAUTH")
(if (not (setq credentials
(if (eq nnimap-authenticator 'anonymous)
(nnimap-command "ENABLE QRESYNC"))
(nnimap-process nnimap-object))))))))
-(defun nnimap-extend-tls-programs ()
- (let ((programs tls-program)
- result)
- (unless (consp programs)
- (setq programs (list programs)))
- (dolist (program programs)
- (when (assoc (car (split-string program)) tls-starttls-switches)
- (push (if (not (string-match "%s" program))
- (concat program " " "%s")
- program)
- result)))
- (nreverse result)))
-
(defun nnimap-find-parameter (parameter elems)
(let (result)
(dolist (elem elems)
(when (nnoo-change-server 'nnimap server nil)
(ignore-errors
(delete-process (get-buffer-process (nnimap-buffer))))
+ (nnoo-close-server 'nnimap server)
t))
(deffoo nnimap-request-close ()
(deffoo nnimap-request-rename-group (group new-name &optional server)
(when (nnimap-possibly-change-group nil server)
(with-current-buffer (nnimap-buffer)
+ ;; Make sure we don't have this group open read/write by asking
+ ;; to examine a mailbox that doesn't exist. This seems to be
+ ;; the only way that allows us to reliably go back to unselected
+ ;; state on Courier.
+ (nnimap-command "EXAMINE DOES.NOT.EXIST")
+ (setf (nnimap-group nnimap-object) nil)
(car (nnimap-command "RENAME %S %S"
(utf7-encode group t) (utf7-encode new-name t))))))
((and force
(eq nnmail-expiry-target 'delete))
(unless (nnimap-delete-article (gnus-compress-sequence articles))
- (message "Article marked for deletion, but not expunged."))
+ (nnheader-message 7 "Article marked for deletion, but not expunged."))
nil)
(t
(let ((deletable-articles
(let ((target nnmail-expiry-target))
(with-temp-buffer
(when (nnimap-request-article article group server (current-buffer))
- (message "Expiring article %s:%d" group article)
+ (nnheader-message 7 "Expiring article %s:%d" group article)
(when (functionp target)
(setq target (funcall target group)))
(when (and target
(when (and (nnimap-possibly-change-group nil server)
nnimap-inbox
nnimap-split-methods)
- (message "nnimap %s splitting mail..." server)
+ (nnheader-message 7 "nnimap %s splitting mail..." server)
(nnimap-split-incoming-mail)))
(defun nnimap-marks-to-flags (marks)
(let ((result (nnimap-get-response sequence)))
(if (not (car result))
(progn
- (message "%s" (nnheader-get-report-string 'nnimap))
+ (nnheader-message 7 "%s" (nnheader-get-report-string 'nnimap))
nil)
(cons group
(nnimap-find-article-by-message-id group message-id))))))))
modseq)
(push
(list (nnimap-send-command "EXAMINE %S (QRESYNC (%s %s))"
- group uidvalidity modseq)
+ (utf7-encode group t)
+ uidvalidity modseq)
'qresync
nil group 'qresync)
sequences)
;; examine), but will tell us whether the group
;; is read-only or not.
"SELECT")))
- (push (list (nnimap-send-command "%s %S" command group)
+ (push (list (nnimap-send-command "%s %S" command
+ (utf7-encode group t))
(nnimap-send-command "UID FETCH %d:* FLAGS" start)
start group command)
sequences)))
(let* ((group (gnus-info-group info))
(completep (and start-article
(= start-article 1)))
- (active (or (cdr (assq 'active (gnus-info-params info)))
- (gnus-active group))))
+ (active (or (gnus-active group)
+ (cdr (assq 'active (gnus-info-params info))))))
(when uidnext
(setq high (1- uidnext)))
;; First set the active ranges based on high/low.
;; Add all the vanished articles to the list of read articles.
(gnus-info-set-read
info
- (gnus-range-add (gnus-info-read info)
- vanished))
+ (gnus-add-to-range
+ (gnus-add-to-range
+ (gnus-range-add (gnus-info-read info)
+ vanished)
+ (cdr (assq '%Flagged flags)))
+ (cdr (assq '%Seen flags))))
(let ((marks (gnus-info-marks info)))
(dolist (type (cdr nnimap-mark-alist))
(let ((ticks (assoc (car type) marks))
(setq start end))
(setq start (point))
(goto-char end))
- (while (search-forward " FETCH " start t)
+ (while (re-search-forward "^\\* [0-9]+ FETCH " start t)
(setq elems (read (current-buffer)))
(push (cons (cadr (memq 'UID elems))
(cadr (memq 'FLAGS elems)))
(setq nnimap-status-string "Read-only server")
nil)
+(deffoo nnimap-request-thread (id)
+ (let* ((refs (split-string
+ (or (mail-header-references (gnus-summary-article-header))
+ "")))
+ (cmd (let ((value
+ (format
+ "(OR HEADER REFERENCES %s HEADER Message-Id %s)"
+ id id)))
+ (dolist (refid refs value)
+ (setq value (format
+ "(OR (OR HEADER Message-Id %s HEADER REFERENCES %s) %s)"
+ refid refid value)))))
+ (result
+ (with-current-buffer (nnimap-buffer)
+ (nnimap-command "UID SEARCH %s" cmd))))
+ (gnus-fetch-headers (and (car result)
+ (delete 0 (mapcar #'string-to-number
+ (cdr (assoc "SEARCH" (cdr result)))))))))
+
(defun nnimap-possibly-change-group (group server)
(let ((open-result t))
(when (and server
(point-min))
t)))
(when messagep
- (message "nnimap read %dk" (/ (buffer-size) 1000)))
+ (nnheader-message 7 "nnimap read %dk" (/ (buffer-size) 1000)))
(nnheader-accept-process-output process)
(goto-char (point-max)))
openp)
(forward-char (1+ bytes))
(setq bytes (nnimap-get-length))
(delete-region (line-beginning-position) (line-end-position))
- (forward-char (1+ bytes))
- (delete-region (line-beginning-position) (line-end-position))))))
+ ;; There's a body; skip past that.
+ (when bytes
+ (forward-char (1+ bytes))
+ (delete-region (line-beginning-position) (line-end-position)))))))
(defun nnimap-dummy-active-number (group &optional server)
1)