;;; gnus-uu.el --- extract (uu)encoded files in Gnus
-;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998,
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Created: 2 Oct 1993
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
(require 'message)
(require 'gnus-msg)
(require 'mm-decode)
+(require 'yenc)
(defgroup gnus-extract nil
"Extracting encoded files."
("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\|lha\\)$"
"gnus-uu-archive"))
"*Default actions to be taken when the user asks to view a file.
-To change the behaviour, you can either edit this variable or set
+To change the behavior, you can either edit this variable or set
`gnus-uu-user-view-rules' to something useful.
For example:
command string, the file name will be appended to the command string
before executing.
-There are several user variables to tailor the behaviour of gnus-uu to
+There are several user variables to tailor the behavior of gnus-uu to
your needs. First we have `gnus-uu-user-view-rules', which is the
variable gnus-uu first consults when trying to decide how to view a
file. If this variable contains no matches, gnus-uu examines the
(defvar gnus-uu-file-name nil)
(defvar gnus-uu-uudecode-process nil)
(defvar gnus-uu-binhex-article-name nil)
+(defvar gnus-uu-yenc-article-name nil)
(defvar gnus-uu-work-dir nil)
(list current-prefix-arg
(read-file-name
(if gnus-uu-save-separate-articles
- "Save articles is dir: "
+ "Save articles in dir: "
"Save articles in file: ")
gnus-uu-default-dir
gnus-uu-default-dir)))
(mm-make-temp-file (expand-file-name "binhex" gnus-uu-work-dir)))
(gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir))
+(defun gnus-uu-decode-yenc (n dir)
+ "Decode the yEnc-encoded current article."
+ (interactive
+ (list current-prefix-arg
+ (file-name-as-directory
+ (read-file-name "yEnc decode and save in dir: "
+ gnus-uu-default-dir
+ gnus-uu-default-dir))))
+ (setq gnus-uu-yenc-article-name nil)
+ (gnus-uu-decode-with-method 'gnus-uu-yenc-article n dir nil t))
+
(defun gnus-uu-decode-uu-view (&optional n)
"Uudecodes and views the current article."
(interactive "P")
(if (and n (not (numberp n)))
(setq message-forward-as-mime (not message-forward-as-mime)
n nil))
- (let ((gnus-article-reply (gnus-summary-work-articles n))
- gnus-newsgroup-processable)
+ (let ((gnus-article-reply (gnus-summary-work-articles n)))
(when (and (not n)
(= (length gnus-article-reply) 1))
;; The case where neither a number of articles nor a region is
;; specified.
(gnus-summary-top-thread)
- (setq gnus-article-reply (gnus-uu-get-list-of-articles nil)))
- ;; Specify articles to be forwarded.
- (setq gnus-newsgroup-processable (copy-sequence gnus-article-reply))
+ (setq gnus-article-reply (nreverse (gnus-uu-find-articles-matching))))
(gnus-setup-message 'forward
(setq gnus-uu-digest-from-subject nil)
(setq gnus-uu-digest-buffer
(gnus-get-buffer-create " *gnus-uu-forward*"))
- (gnus-uu-decode-save n file)
+ ;; Specify articles to be forwarded. Note that they should be
+ ;; reversed; see `gnus-uu-get-list-of-articles'.
+ (let ((gnus-newsgroup-processable (reverse gnus-article-reply)))
+ (gnus-uu-decode-save n file)
+ (setq gnus-article-reply gnus-newsgroup-processable))
+ ;; Restore the value of `gnus-newsgroup-processable' to which
+ ;; it should be set when it is not `let'-bound.
+ (setq gnus-newsgroup-processable (reverse gnus-article-reply))
(switch-to-buffer gnus-uu-digest-buffer)
(let ((fs gnus-uu-digest-from-subject))
(when fs
(defun gnus-message-process-mark (unmarkp new-marked)
(let ((old (- (length gnus-newsgroup-processable) (length new-marked))))
- (message "%d mark%s %s%s"
- (length new-marked)
- (if (= (length new-marked) 1) "" "s")
- (if unmarkp "removed" "added")
- (cond
- ((and (zerop old)
- (not unmarkp))
- "")
- (unmarkp
- (format ", %d remain marked"
- (length gnus-newsgroup-processable)))
- (t
- (format ", %d already marked" old))))))
+ (gnus-message 6 "%d mark%s %s%s"
+ (length new-marked)
+ (if (= (length new-marked) 1) "" "s")
+ (if unmarkp "removed" "added")
+ (cond
+ ((and (zerop old)
+ (not unmarkp))
+ "")
+ (unmarkp
+ (format ", %d remain marked"
+ (length gnus-newsgroup-processable)))
+ (t
+ (format ", %d already marked" old))))))
(defun gnus-new-processable (unmarkp articles)
(if unmarkp
(interactive "sUnmark (regexp): ")
(gnus-uu-mark-by-regexp regexp t))
-(defun gnus-uu-mark-series ()
+(defun gnus-uu-mark-series (&optional silent)
"Mark the current series with the process mark."
(interactive)
(let* ((articles (gnus-uu-find-articles-matching))
- (l (length articles)))
+ (l (length articles)))
(while articles
(gnus-summary-set-process-mark (car articles))
(setq articles (cdr articles)))
- (message "Marked %d articles" l))
- (gnus-summary-position-point))
+ (unless silent
+ (gnus-message 6 "Marked %d articles" l))
+ (gnus-summary-position-point)
+ l))
(defun gnus-uu-mark-region (beg end &optional unmark)
"Set the process mark on all articles between point and mark."
(setq gnus-newsgroup-processable nil)
(save-excursion
(let ((data gnus-newsgroup-data)
+ (count 0)
number)
(while data
(when (and (not (memq (setq number (gnus-data-number (car data)))
gnus-newsgroup-processable))
(vectorp (gnus-data-header (car data))))
(gnus-summary-goto-subject number)
- (gnus-uu-mark-series))
- (setq data (cdr data)))))
+ (setq count (+ count (gnus-uu-mark-series t))))
+ (setq data (cdr data)))
+ (gnus-message 6 "Marked %d articles" count)))
(gnus-summary-position-point))
;; All PostScript functions written by Erik Selberg <speed@cs.washington.edu>.
"Date: %s\nFrom: %s\nSubject: %s Digest\n\n"
(message-make-date) name name))
(when (and message-forward-as-mime gnus-uu-digest-buffer)
- (insert "<#part type=message/rfc822>\nSubject: Topics\n\n"))
+ (insert
+ "<#mml type=message/rfc822>\nSubject: Topics\n\n<#/mml>\n")
+ (forward-line -1))
(insert "Topics:\n")))
(when (not (eq in-state 'end))
(setq state (list 'middle))))
(cons gnus-uu-binhex-article-name state)
state)))
+;; yEnc
+
+(defun gnus-uu-yenc-article (buffer in-state)
+ (save-excursion
+ (set-buffer gnus-original-article-buffer)
+ (widen)
+ (let ((file-name (yenc-extract-filename))
+ state start-char)
+ (when (not file-name)
+ (setq state (list 'wrong-type)))
+
+ (if (memq 'wrong-type state)
+ ()
+ (when (yenc-first-part-p)
+ (setq gnus-uu-yenc-article-name
+ (expand-file-name file-name gnus-uu-work-dir))
+ (push 'begin state))
+ (when (yenc-last-part-p)
+ (push 'end state))
+ (unless state
+ (push 'middle state))
+ (mm-with-unibyte-buffer
+ (insert-buffer-substring gnus-original-article-buffer)
+ (yenc-decode-region (point-min) (point-max))
+ (when (and (member 'begin state)
+ (file-exists-p gnus-uu-yenc-article-name))
+ (delete-file gnus-uu-yenc-article-name))
+ (mm-append-to-file (point-min) (point-max)
+ gnus-uu-yenc-article-name)))
+ (if (memq 'begin state)
+ (cons file-name state)
+ state))))
+
;; PostScript
(defun gnus-uu-decode-postscript-article (process-buffer in-state)
nil t)
(replace-match "\\1[0-9]+\\2[0-9]+" t nil nil nil))))
- (goto-char 1)
+ (goto-char (point-min))
(while (re-search-forward "[ \t]+" nil t)
(replace-match "[ \t]+" t t))
(format "%06d"
(string-to-number (buffer-substring
(match-beginning 0) (match-end 0)))))))
- (setq string (buffer-substring 1 (point-max)))
+ (setq string (buffer-substring (point-min) (point-max)))
(setcar (car string-list) string)
(setq string-list (cdr string-list))))
out-list))
(not gnus-uu-be-dangerous)
(or (eq gnus-uu-be-dangerous t)
(gnus-y-or-n-p
- (format "Delete unsuccessfully decoded file %s"
+ (format "Delete unsuccessfully decoded file %s? "
result-file))))
(delete-file result-file)))
(when (memq 'begin process-state)
(gnus-message 2 "No begin part at the beginning")
(sleep-for 2))
(setq state 'middle))))
-
+
;; When there are no result-files, then something must be wrong.
(if result-files
(message "")
;; We replace certain characters that could make things messy.
(setq gnus-uu-file-name
(gnus-map-function
- mm-file-name-rewrite-functions
+ mm-file-name-rewrite-functions
(file-name-nondirectory (match-string 1))))
(replace-match (concat "begin 644 " gnus-uu-file-name) t t)
(provide 'gnus-uu)
-;;; arch-tag: 05312384-0a83-4720-9a58-b3160b888853
+;; arch-tag: 05312384-0a83-4720-9a58-b3160b888853
;;; gnus-uu.el ends here