+Sat Mar 23 00:01:56 1996 Lars Magne Ingebrigtsen <larsi@aegir.ifi.uio.no>
+
+ * gnus.el (gnus-group-add-score): Would bug out on dead groups.
+
+Fri Mar 22 22:30:32 1996 Lars Magne Ingebrigtsen <larsi@aegir.ifi.uio.no>
+
+ * gnus.el (gnus-get-newsgroup-headers): Would ignore In-Reply-To
+ headers.
+
+ * gnus-uu.el (gnus-uu-uustrip-article): Handle multiple uuencoded
+ files in each article.
+
+ * gnus-msg.el (gnus-inews-article): Switch to buffer where
+ `gnus-inews-article-hook' is run to make ispelling possible.
+
+ * gnus.el (gnus-summary-last-article-p): New function.
+ (gnus-summary-next-page): Wouldn't go past last article in
+ narrowed buffers.
+ (gnus-group-make-help-group): Would create under false name.
+
+Fri Mar 22 22:23:20 1996 Greg Stark <gsstark@mit.edu>
+
+ * nneething.el (nneething-make-head): Create better heads.
+
+Fri Mar 22 18:58:17 1996 Lars Magne Ingebrigtsen <lars@eyesore.no>
+
+ * gnus-score.el (gnus-score-body): Would bug out.
+
+ * nnfolder.el (nnfolder-retrieve-headers): Make sure the buffer
+ exists before setting it.
+
+ * gnus.el (gnus-summary-exit): Don't run prepare-exit-hook when
+ exiting temporarliy.
+
Fri Mar 22 00:38:28 1996 Lars Magne Ingebrigtsen <larsi@ylfing.ifi.uio.no>
+ * gnus.el: September Gnus v0.55 is released.
+
* gnus.el (gnus-summary-update-article): Would make things bug out.
(gnus-summary-insert-subject): Remove articles that have changed
number.
;; Run final inews hooks. This hook may do FCC.
;; The article must be saved before being posted because
;; `gnus-request-post' modifies the buffer.
- (run-hooks 'gnus-inews-article-hook)
+ (save-window-excursion
+ (switch-to-buffer (current-buffer))
+ (run-hooks 'gnus-inews-article-hook))
;; Copy the article over to some group, possibly.
(and gcc (gnus-inews-do-gcc gcc))
;; Post the article.
entries alist ofunc article last)
(while (cdr articles)
(setq articles (cdr articles)))
- (setq last (mail-header-number (car articles)))
+ (setq last (mail-header-number (caar articles)))
(setq articles gnus-scores-articles)
;; Not all backends support partial fetching. In that case,
;; we just fetch the entire article.
(when (or (not (file-exists-p to-file))
(gnus-y-or-n-p (format "%s exists; overwrite? " to-file)))
(copy-file file to-file t t)))))
- (message "Saved %d file%s" len (if (> len 1) "s" ""))))
+ (message "Saved %d file%s" len (if (= len 1) "" "s"))))
;; Functions for saving and possibly digesting articles without
;; any decoding.
(articles process-function &optional sloppy limit no-errors)
(let ((state 'first)
has-been-begin article result-file result-files process-state
- article-series)
+ article-series files)
(while (and articles
(not (memq 'error process-state))
(when (memq 'end process-state)
(setq article-series nil)
(setq has-been-begin nil)
- (push (list (cons 'name result-file)
- (cons 'article article))
- result-files)
+ (if (stringp result-file)
+ (setq files (list result-file))
+ (setq files result-file))
+ (setq result-file (car files))
+ (while files
+ (push (list (cons 'name (pop files))
+ (cons 'article article))
+ result-files))
;; Allow user-defined functions to be run on this file.
(when gnus-uu-grabbed-file-functions
(let ((funcs gnus-uu-grabbed-file-functions))
(defun gnus-uu-uustrip-article (process-buffer in-state)
;; Uudecodes a file asynchronously.
- (let ((state (list 'ok))
- (process-connection-type nil)
- start-char pst name-beg name-end)
- (save-excursion
- (set-buffer process-buffer)
- (let ((case-fold-search nil)
- (buffer-read-only nil))
+ (save-excursion
+ (set-buffer process-buffer)
+ (let ((state (list 'wrong-type))
+ process-connection-type case-fold-search buffer-read-only
+ files start-char)
+ (goto-char (point-min))
- (goto-char (point-min))
+ ;; Deal with ^M at the end of the lines.
+ (when gnus-uu-kill-carriage-return
+ (save-excursion
+ (while (search-forward "\r" nil t)
+ (delete-backward-char 1))))
- (if gnus-uu-kill-carriage-return
- (progn
- (while (search-forward "\r" nil t)
- (delete-backward-char 1))
- (goto-char (point-min))))
-
- (if (not (re-search-forward gnus-uu-begin-string nil t))
- (if (not (re-search-forward gnus-uu-body-line nil t))
- (setq state (list 'wrong-type))))
-
- (if (memq 'wrong-type state)
- ()
- (beginning-of-line)
- (setq start-char (point))
-
- (if (looking-at gnus-uu-begin-string)
- (progn
- (setq name-end (match-end 1)
- name-beg (match-beginning 1))
- ;; Remove any non gnus-uu-body-line right after start.
- (forward-line 1)
- (or (looking-at gnus-uu-body-line)
- (gnus-delete-line))
-
- ;; Replace any slashes and spaces in file names before decoding
- (goto-char name-beg)
- (while (re-search-forward "/" name-end t)
- (replace-match ","))
- (goto-char name-beg)
- (while (re-search-forward " " name-end t)
- (replace-match "_"))
- (goto-char name-beg)
- (if (re-search-forward "_*$" name-end t)
- (replace-match ""))
-
- (setq gnus-uu-file-name (buffer-substring name-beg name-end))
- (and gnus-uu-uudecode-process
- (setq pst (process-status
- (or gnus-uu-uudecode-process "nevair")))
- (if (or (eq pst 'stop) (eq pst 'run))
- (progn
- (delete-process gnus-uu-uudecode-process)
- (gnus-uu-unmark-list-of-grabbed t))))
- (if (get-process "*uudecode*")
- (delete-process "*uudecode*"))
- (setq gnus-uu-uudecode-process
- (start-process
- "*uudecode*"
- (get-buffer-create gnus-uu-output-buffer-name)
- "sh" "-c"
- (format "cd %s ; uudecode" gnus-uu-work-dir)))
- (set-process-sentinel
- gnus-uu-uudecode-process 'gnus-uu-uudecode-sentinel)
- (setq state (list 'begin))
- (gnus-uu-add-file (concat gnus-uu-work-dir gnus-uu-file-name)))
- (setq state (list 'middle)))
-
- (goto-char (point-max))
+ (while (or (re-search-forward gnus-uu-begin-string nil t)
+ (re-search-forward gnus-uu-body-line nil t))
+ (setq state (list 'ok))
+ ;; Ok, we are at the first uucoded line.
+ (beginning-of-line)
+ (setq start-char (point))
- (re-search-backward
- (concat gnus-uu-body-line "\\|" gnus-uu-end-string) nil t)
- (beginning-of-line)
+ (if (not (looking-at gnus-uu-begin-string))
+ (setq state (list 'middle))
+ ;; This is the beginning of an uuencoded article.
+ ;; We replace certain characters that could make things messy.
+ (setq gnus-uu-file-name
+ (let ((nnheader-file-name-translation-alist
+ '((?/ . ?,) (? . ?_) (?* . ?_) (?$ . ?_))))
+ (nnheader-translate-file-chars (match-string 1))))
- (if (looking-at gnus-uu-end-string)
- (setq state (cons 'end state)))
+ ;; Remove any non gnus-uu-body-line right after start.
(forward-line 1)
+ (while (and (not (eobp))
+ (not (looking-at gnus-uu-body-line)))
+ (gnus-delete-line))
+
+ ;; If a process is running, we kill it.
+ (when (and gnus-uu-uudecode-process
+ (memq (process-status gnus-uu-uudecode-process)
+ '(run stop)))
+ (delete-process gnus-uu-uudecode-process)
+ (gnus-uu-unmark-list-of-grabbed t))
+
+ ;; Start a new uudecoding process.
+ (setq gnus-uu-uudecode-process
+ (start-process
+ "*uudecode*"
+ (get-buffer-create gnus-uu-output-buffer-name)
+ "sh" "-c"
+ (format "cd %s ; uudecode" gnus-uu-work-dir)))
+ (set-process-sentinel
+ gnus-uu-uudecode-process 'gnus-uu-uudecode-sentinel)
+ (setq state (list 'begin))
+ (push (concat gnus-uu-work-dir gnus-uu-file-name) files)
+ (gnus-uu-add-file (car files)))
+
+ ;; We look for the end of the thing to be decoded.
+ (if (re-search-forward gnus-uu-end-string nil t)
+ (setq state (cons 'end state))
+ (goto-char (point-max))
+ (re-search-backward gnus-uu-body-line nil t))
+
+ (forward-line 1)
- (and gnus-uu-uudecode-process
- (setq pst (process-status
- (or gnus-uu-uudecode-process "nevair")))
- (if (or (eq pst 'run) (eq pst 'stop))
- (progn
- (if gnus-uu-correct-stripped-uucode
- (progn
- (gnus-uu-check-correct-stripped-uucode
- start-char (point))
- (goto-char (point-max))
- (re-search-backward
- (concat gnus-uu-body-line "\\|"
- gnus-uu-end-string)
- nil t)
- (forward-line 1)))
-
- (condition-case nil
- (process-send-region gnus-uu-uudecode-process
- start-char (point))
- (error
- (progn
- (delete-process gnus-uu-uudecode-process)
- (message "gnus-uu: Couldn't uudecode")
- ; (sleep-for 2)
- (setq state (list 'wrong-type)))))
-
- (when (memq 'end state)
- (while (memq (process-status gnus-uu-uudecode-process)
- '(open run))
- (accept-process-output gnus-uu-uudecode-process 1))))
- (setq state (list 'wrong-type))))
- (if (not gnus-uu-uudecode-process)
- (setq state (list 'wrong-type)))))
+ (when gnus-uu-uudecode-process
+ (when (memq (process-status gnus-uu-uudecode-process) '(run stop))
+ ;; Try to correct mishandled uucode.
+ (when gnus-uu-correct-stripped-uucode
+ (gnus-uu-check-correct-stripped-uucode start-char (point)))
+
+ ;; Send the text to the process.
+ (condition-case nil
+ (process-send-region
+ gnus-uu-uudecode-process start-char (point))
+ (error
+ (progn
+ (delete-process gnus-uu-uudecode-process)
+ (message "gnus-uu: Couldn't uudecode")
+ (setq state (list 'wrong-type)))))
+
+ (if (memq 'end state)
+ (progn
+ ;; Send an EOF, just in case.
+ (condition-case ()
+ (process-send-eof gnus-uu-uudecode-process)
+ (error nil))
+ (while (memq (process-status gnus-uu-uudecode-process)
+ '(open run))
+ (accept-process-output gnus-uu-uudecode-process 1)))
+ (when (or (not gnus-uu-uudecode-process)
+ (not (memq (process-status gnus-uu-uudecode-process)
+ '(run stop))))
+ (setq state (list 'wrong-type)))))))
(if (memq 'begin state)
- (cons (concat gnus-uu-work-dir gnus-uu-file-name) state)
+ (cons (if (= (length files) 1) (car files) files) state)
state))))
;; This function is used by `gnus-uu-grab-articles' to treat
out))
(defun gnus-uu-check-correct-stripped-uucode (start end)
- (let (found beg length)
- (if (not gnus-uu-correct-stripped-uucode)
- ()
- (goto-char start)
+ (save-excursion
+ (let (found beg length)
+ (if (not gnus-uu-correct-stripped-uucode)
+ ()
+ (goto-char start)
- (if (re-search-forward " \\|`" end t)
- (progn
- (goto-char start)
- (while (not (eobp))
- (progn
- (if (looking-at "\n") (replace-match ""))
- (forward-line 1))))
-
- (while (not (eobp))
- (if (looking-at (concat gnus-uu-begin-string "\\|"
- gnus-uu-end-string))
- ()
- (if (not found)
+ (if (re-search-forward " \\|`" end t)
+ (progn
+ (goto-char start)
+ (while (not (eobp))
(progn
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (setq length (- (point) beg))))
- (setq found t)
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (if (not (= length (- (point) beg)))
- (insert (make-string (- length (- (point) beg)) ? ))))
- (forward-line 1))))))
+ (if (looking-at "\n") (replace-match ""))
+ (forward-line 1))))
+
+ (while (not (eobp))
+ (if (looking-at (concat gnus-uu-begin-string "\\|"
+ gnus-uu-end-string))
+ ()
+ (if (not found)
+ (progn
+ (beginning-of-line)
+ (setq beg (point))
+ (end-of-line)
+ (setq length (- (point) beg))))
+ (setq found t)
+ (beginning-of-line)
+ (setq beg (point))
+ (end-of-line)
+ (if (not (= length (- (point) beg)))
+ (insert (make-string (- length (- (point) beg)) ? ))))
+ (forward-line 1)))))))
(defvar gnus-uu-tmp-alist nil)
"gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
"The mail address of the Gnus maintainers.")
-(defconst gnus-version "September Gnus v0.55"
+(defconst gnus-version "September Gnus v0.56"
"Version number for this version of Gnus.")
(defvar gnus-info-nodes
"Add SCORE to the GROUP score.
If SCORE is nil, add 1 to the score of GROUP."
(let ((info (gnus-get-info group)))
- (gnus-info-set-score info (+ (gnus-info-score info) (or score 1)))))
+ (when info
+ (gnus-info-set-score info (+ (gnus-info-score info) (or score 1))))))
(defun gnus-summary-bubble-group ()
"Increase the score of the current group.
(message "Couldn't find doc group")
(gnus-group-make-group
(gnus-group-real-name name)
- (list 'nndoc name
+ (list 'nndoc "gnus-help"
(list 'nndoc-address file)
(list 'nndoc-article-type 'mbox)))))
(gnus-group-position-point))
(file-name-nondirectory file) '(nndoc "")))))
(gnus-group-make-group
(gnus-group-real-name name)
- (list 'nndoc name
+ (list 'nndoc (file-name-nondirectory file)
(list 'nndoc-address file)
(list 'nndoc-article-type (or type 'guess))))
(forward-line -1)
(if (and (search-forward "\nin-reply-to: " nil t)
(setq in-reply-to (gnus-header-value))
(string-match "<[^>]+>" in-reply-to))
- (prog1
- (setq ref (substring in-reply-to (match-beginning 0)
- (match-end 0)))
- (setq ref ref)))
- (setq ref "")))
+ (setq ref (substring in-reply-to (match-beginning 0)
+ (match-end 0)))
+ (setq ref ""))))
;; Chars.
0
;; Lines.
(quit-config (gnus-group-quit-config gnus-newsgroup-name))
(mode major-mode)
(buf (current-buffer)))
- (run-hooks 'gnus-summary-prepare-exit-hook)
+ (unless temporary
+ (run-hooks 'gnus-summary-prepare-exit-hook))
;; If we have several article buffers, we kill them at exit.
(unless gnus-single-article-buffer
(gnus-kill-buffer gnus-article-buffer)
(gnus-message 3 "End of message"))
((null lines)
(if (and (eq gnus-summary-goto-unread 'never)
- (not (eq article gnus-newsgroup-end)))
+ (not (gnus-summary-last-article-p article)))
(gnus-summary-next-article)
(gnus-summary-next-unread-article))))))
(gnus-summary-recenter)
(or (nnheader-article-p) ; Either it's a real article...
(progn
(goto-char (point-min))
- (nneething-make-head file) ; ... or we fake some headers.
+ (nneething-make-head file (current-buffer)) ; ... or we fake some headers.
(insert "\n")))
t))))
(when (nneething-get-head file)
(insert-buffer-substring nneething-work-buffer)))
-(defun nneething-make-head (file)
+(defun nneething-make-head (file &optional buffer)
"Create a head by looking at the file attributes of FILE."
(let ((atts (file-attributes file)))
(insert
"Message-ID: <nneething-"
(int-to-string (incf nneething-message-id-number))
"@" (system-name) ">\n"
- "Date: " (current-time-string (nth 5 atts)) "\n"
- (nneething-from-line (nth 2 atts))
- "Chars: " (int-to-string (nth 7 atts)) "\n")))
+ (if (equal '(0 0) (nth 5 atts)) ""
+ (concat "Date: " (current-time-string (nth 5 atts)) "\n"))
+ (or (if buffer
+ (save-excursion
+ (set-buffer buffer)
+ (if (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t)
+ (concat "From: " (match-string 0) "\n"))))
+ (nneething-from-line (nth 2 atts) file))
+ (if (> (string-to-int (int-to-string (nth 7 atts))) 0)
+ (concat "Chars: " (int-to-string (nth 7 atts)) "\n")
+ "")
+ (if buffer
+ (save-excursion
+ (set-buffer buffer)
+ (concat "Lines: " (int-to-string
+ (count-lines (point-min) (point-max))) "\n"))
+ "")
+ )))
-(defun nneething-from-line (uid)
+(defun nneething-from-line (uid &optional file)
"Return a From header based of UID."
- (let ((login (condition-case nil
- (user-login-name uid)
+ (let* ((login (condition-case nil
+ (user-login-name uid)
+ (error
+ (cond ((= uid (user-uid)) (user-login-name))
+ ((zerop uid) "root")
+ (t (int-to-string uid))))))
+ (name (condition-case nil
+ (user-full-name uid)
(error
- (cond ((= uid (user-uid)) (user-login-name))
- ((zerop uid) "root")
- (t (int-to-string uid))))))
- (name (condition-case nil
- (user-full-name uid)
- (error
- (cond ((= uid (user-uid)) (user-full-name))
- ((zerop uid) "Ms. Root"))))))
- (concat "From: " login "@" (system-name)
+ (cond ((= uid (user-uid)) (user-full-name))
+ ((zerop uid) "Ms. Root")))))
+ (host (if (string-match "\\`/[^/@]*@\\([^:/]+\\):" file)
+ (prog1
+ (substring file
+ (match-beginning 1)
+ (match-end 1))
+ (if (string-match "/\\(users\\|home\\)/\\([^/]+\\)/" file)
+ (setq login (substring file
+ (match-beginning 2)
+ (match-end 2))
+ name nil)))
+ (system-name))))
+ (concat "From: " login "@" host
(if name (concat " (" name ")") "") "\n")))
(defun nneething-get-head (file)
(1- (point)))
(point-max)))
(point-max))
- (erase-buffer)
- (nneething-make-head file))
- t))))
+ (goto-char (point-min))
+ (nneething-make-head file (current-buffer))
+ (delete-region (point) (point-max))
+ t)))))
(defun nneething-file-name (article)
"Return the file name of ARTICLE."
(erase-buffer)
(let ((delim-string (concat "^" rmail-unix-mail-delimiter))
article art-string start stop)
- (nnfolder-possibly-change-group newsgroup server)
- (set-buffer nnfolder-current-buffer)
- (goto-char (point-min))
- (if (stringp (car sequence))
- 'headers
- (while sequence
- (setq article (car sequence))
- (setq art-string (nnfolder-article-string article))
- (set-buffer nnfolder-current-buffer)
- (if (or (search-forward art-string nil t)
- ;; Don't search the whole file twice! Also, articles
- ;; probably have some locality by number, so searching
- ;; backwards will be faster. Especially if we're at the
- ;; beginning of the buffer :-). -SLB
- (search-backward art-string nil t))
- (progn
- (setq start (or (re-search-backward delim-string nil t)
- (point)))
- (search-forward "\n\n" nil t)
- (setq stop (1- (point)))
- (set-buffer nntp-server-buffer)
- (insert (format "221 %d Article retrieved.\n" article))
- (insert-buffer-substring nnfolder-current-buffer start stop)
- (goto-char (point-max))
- (insert ".\n")))
- (setq sequence (cdr sequence)))
-
- (set-buffer nntp-server-buffer)
- (nnheader-fold-continuation-lines)
- 'headers))))
+ (when nnfolder-current-buffer
+ (nnfolder-possibly-change-group newsgroup server)
+ (set-buffer nnfolder-current-buffer)
+ (goto-char (point-min))
+ (if (stringp (car sequence))
+ 'headers
+ (while sequence
+ (setq article (car sequence))
+ (setq art-string (nnfolder-article-string article))
+ (set-buffer nnfolder-current-buffer)
+ (if (or (search-forward art-string nil t)
+ ;; Don't search the whole file twice! Also, articles
+ ;; probably have some locality by number, so searching
+ ;; backwards will be faster. Especially if we're at the
+ ;; beginning of the buffer :-). -SLB
+ (search-backward art-string nil t))
+ (progn
+ (setq start (or (re-search-backward delim-string nil t)
+ (point)))
+ (search-forward "\n\n" nil t)
+ (setq stop (1- (point)))
+ (set-buffer nntp-server-buffer)
+ (insert (format "221 %d Article retrieved.\n" article))
+ (insert-buffer-substring nnfolder-current-buffer start stop)
+ (goto-char (point-max))
+ (insert ".\n")))
+ (setq sequence (cdr sequence)))
+
+ (set-buffer nntp-server-buffer)
+ (nnheader-fold-continuation-lines)
+ 'headers)))))
(defun nnfolder-open-server (server &optional defs)
(nnheader-change-server 'nnfolder server defs)