This commit was generated by cvs2svn to compensate for changes in r5830,
[elisp/gnus.git-] / lisp / gnus-uu.el
index c9b9f0e..19929f3 100644 (file)
@@ -1,6 +1,5 @@
 ;;; gnus-uu.el --- extract (uu)encoded files in Gnus
-;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-;;        2001 Free Software Foundation, Inc.
+;; Copyright (C) 1985,86,87,93,94,95,96,97,98 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Created: 2 Oct 1993
@@ -33,7 +32,6 @@
 (require 'gnus-art)
 (require 'message)
 (require 'gnus-msg)
-(require 'mm-decode)
 
 (defgroup gnus-extract nil
   "Extracting encoded files."
@@ -59,8 +57,8 @@
   '(("\\.te?xt$\\|\\.doc$\\|read.*me\\|\\.c?$\\|\\.h$\\|\\.bat$\\|\\.asm$\\|makefile" "cat %s | sed 's/\r$//'")
     ("\\.pas$" "cat %s | sed 's/\r$//'")
     ("\\.[1-9]$" "groff -mandoc -Tascii %s | sed s/\b.//g")
-    ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "display")
-    ("\\.tga$" "tgatoppm %s | ee -")
+    ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "xv")
+    ("\\.tga$" "tgatoppm %s | xv -")
     ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$"
      "sox -v .5 %s -t .au -u - > /dev/audio")
     ("\\.au$" "cat %s > /dev/audio")
@@ -217,10 +215,7 @@ Note that this variable can be used in conjunction with the
 
 ;; Various variables users may set
 
-(defcustom gnus-uu-tmp-dir
-  (cond ((fboundp 'temp-directory) (temp-directory))
-       ((boundp 'temporary-file-directory) temporary-file-directory)
-       ("/tmp/"))
+(defcustom gnus-uu-tmp-dir "/tmp/"
   "*Variable saying where gnus-uu is to do its work.
 Default is \"/tmp/\"."
   :group 'gnus-extract
@@ -295,9 +290,7 @@ so I simply dropped them."
 
 (defcustom gnus-uu-digest-headers
   '("^Date:" "^From:" "^To:" "^Cc:" "^Subject:" "^Message-ID:" "^Keywords:"
-    "^Summary:" "^References:" "^Content-Type:" "^Content-Transfer-Encoding:"
-    "^MIME-Version:" "^Content-Disposition:" "^Content-Description:"
-    "^Content-ID:")
+    "^Summary:" "^References:" "^Content-Type:" "^Content-Transfer-Encoding:")
   "*List of regexps to match headers included in digested messages.
 The headers will be included in the sequence they are matched."
   :group 'gnus-extract
@@ -335,8 +328,7 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
 (defvar gnus-uu-shar-begin-string "^#! */bin/sh")
 
 (defvar gnus-uu-shar-file-name nil)
-(defvar gnus-uu-shar-name-marker
-  "begin [0-7][0-7][0-7][ \t]+\\(\\(\\w\\|\\.\\)*\\b\\)")
+(defvar gnus-uu-shar-name-marker "begin [0-7][0-7][0-7][ \t]+\\(\\(\\w\\|\\.\\)*\\b\\)")
 
 (defvar gnus-uu-postscript-begin-string "^%!PS-")
 (defvar gnus-uu-postscript-end-string "^%%EOF$")
@@ -351,7 +343,6 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
 
 (defvar gnus-uu-default-dir gnus-article-save-directory)
 (defvar gnus-uu-digest-from-subject nil)
-(defvar gnus-uu-digest-buffer nil)
 
 ;; Keymaps
 
@@ -377,7 +368,7 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
 
 (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
   ;;"x" gnus-uu-extract-any
-  "m" gnus-summary-save-parts
+  ;;"m" gnus-uu-extract-mime
   "u" gnus-uu-decode-uu
   "U" gnus-uu-decode-uu-and-save
   "s" gnus-uu-decode-unshar
@@ -390,17 +381,17 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
   "P" gnus-uu-decode-postscript-and-save)
 
 (gnus-define-keys
-    (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
-  "u" gnus-uu-decode-uu-view
-  "U" gnus-uu-decode-uu-and-save-view
-  "s" gnus-uu-decode-unshar-view
-  "S" gnus-uu-decode-unshar-and-save-view
-  "o" gnus-uu-decode-save-view
-  "O" gnus-uu-decode-save-view
-  "b" gnus-uu-decode-binhex-view
-  "B" gnus-uu-decode-binhex-view
-  "p" gnus-uu-decode-postscript-view
-  "P" gnus-uu-decode-postscript-and-save-view)
+ (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
+ "u" gnus-uu-decode-uu-view
+ "U" gnus-uu-decode-uu-and-save-view
+ "s" gnus-uu-decode-unshar-view
+ "S" gnus-uu-decode-unshar-and-save-view
+ "o" gnus-uu-decode-save-view
+ "O" gnus-uu-decode-save-view
+ "b" gnus-uu-decode-binhex-view
+ "B" gnus-uu-decode-binhex-view
+ "p" gnus-uu-decode-postscript-view
+ "P" gnus-uu-decode-postscript-and-save-view)
 
 
 ;; Commands.
@@ -522,51 +513,46 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
   (interactive "P")
   (let ((gnus-uu-save-in-digest t)
        (file (make-temp-name (nnheader-concat gnus-uu-tmp-dir "forward")))
-       (message-forward-as-mime message-forward-as-mime)
-       (mail-parse-charset gnus-newsgroup-charset)
-       (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets)
-       gnus-uu-digest-buffer subject from)
-    (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-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)
-       (switch-to-buffer gnus-uu-digest-buffer)
-       (let ((fs gnus-uu-digest-from-subject))
-         (when fs
-           (setq from (caar fs)
-                 subject (gnus-simplify-subject-fuzzy (cdar fs))
-                 fs (cdr fs))
-           (while (and fs (or from subject))
-             (when from
-               (unless (string= from (caar fs))
-                 (setq from nil)))
-             (when subject
-               (unless (string= (gnus-simplify-subject-fuzzy (cdar fs))
-                                subject)
-                 (setq subject nil)))
-             (setq fs (cdr fs))))
-         (unless subject
-           (setq subject "Digested Articles"))
-         (unless from
-           (setq from
-                 (if (gnus-news-group-p gnus-newsgroup-name)
-                     gnus-newsgroup-name
-                   "Various"))))
-       (goto-char (point-min))
-       (when (re-search-forward "^Subject: ")
-         (delete-region (point) (gnus-point-at-eol))
-         (insert subject))
-       (goto-char (point-min))
-       (when (re-search-forward "^From:")
-         (delete-region (point) (gnus-point-at-eol))
-         (insert " " from))
-       (let ((message-forward-decoded-p t))
-         (message-forward post t))))
+       buf subject from)
+    (gnus-setup-message 'forward
+      (setq gnus-uu-digest-from-subject nil)
+      (gnus-uu-decode-save n file)
+      (setq buf (switch-to-buffer
+                (gnus-get-buffer-create " *gnus-uu-forward*")))
+      (erase-buffer)
+      (insert-file file)
+      (let ((fs gnus-uu-digest-from-subject))
+       (when fs
+         (setq from (caar fs)
+               subject (gnus-simplify-subject-fuzzy (cdar fs))
+               fs (cdr fs))
+         (while (and fs (or from subject))
+           (when from
+             (unless (string= from (caar fs))
+               (setq from nil)))
+           (when subject
+             (unless (string= (gnus-simplify-subject-fuzzy (cdar fs))
+                              subject)
+               (setq subject nil)))
+           (setq fs (cdr fs))))
+       (unless subject
+         (setq subject "Digested Articles"))
+       (unless from
+         (setq from
+               (if (gnus-news-group-p gnus-newsgroup-name)
+                   gnus-newsgroup-name
+                 "Various"))))
+      (goto-char (point-min))
+      (when (re-search-forward "^Subject: ")
+       (delete-region (point) (gnus-point-at-eol))
+       (insert subject))
+      (goto-char (point-min))
+      (when (re-search-forward "^From: ")
+       (delete-region (point) (gnus-point-at-eol))
+       (insert from))
+      (message-forward post))
+    (delete-file file)
+    (kill-buffer buf)
     (setq gnus-uu-digest-from-subject nil)))
 
 (defun gnus-uu-digest-post-forward (&optional n)
@@ -576,46 +562,20 @@ didn't work, and overwrite existing files.  Otherwise, ask each time."
 
 ;; Process marking.
 
-(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))))))
-
-(defun gnus-new-processable (unmarkp articles)
-  (if unmarkp
-      (gnus-intersection gnus-newsgroup-processable articles)
-    (gnus-set-difference articles gnus-newsgroup-processable)))
-
 (defun gnus-uu-mark-by-regexp (regexp &optional unmark)
-  "Set the process mark on articles whose subjects match REGEXP.
-When called interactively, prompt for REGEXP.
-Optional UNMARK non-nil means unmark instead of mark."
-  (interactive "sMark (regexp): \nP")
-  (save-excursion
-    (let* ((articles (gnus-uu-find-articles-matching regexp))
-          (new-marked (gnus-new-processable unmark articles)))
-      (while articles
-       (if unmark
-           (gnus-summary-remove-process-mark (pop articles))
-         (gnus-summary-set-process-mark (pop articles))))
-      (gnus-message-process-mark unmark new-marked)))
+  "Ask for a regular expression and set the process mark on all articles that match."
+  (interactive (list (read-from-minibuffer "Mark (regexp): ")))
+  (let ((articles (gnus-uu-find-articles-matching regexp)))
+    (while articles
+      (if unmark
+         (gnus-summary-remove-process-mark (pop articles))
+       (gnus-summary-set-process-mark (pop articles))))
+    (message ""))
   (gnus-summary-position-point))
 
-(defun gnus-uu-unmark-by-regexp (regexp)
-  "Remove the process mark from articles whose subjects match REGEXP.
-When called interactively, prompt for REGEXP."
-  (interactive "sUnmark (regexp): ")
+(defun gnus-uu-unmark-by-regexp (regexp &optional unmark)
+  "Ask for a regular expression and remove the process mark on all articles that match."
+  (interactive (list (read-from-minibuffer "Mark (regexp): ")))
   (gnus-uu-mark-by-regexp regexp t))
 
 (defun gnus-uu-mark-series ()
@@ -658,12 +618,10 @@ When called interactively, prompt for REGEXP."
 (defun gnus-uu-mark-thread ()
   "Marks all articles downwards in this thread."
   (interactive)
-  (gnus-save-hidden-threads
-    (let ((level (gnus-summary-thread-level)))
-      (while (and (gnus-summary-set-process-mark
-                  (gnus-summary-article-number))
-                 (zerop (gnus-summary-next-subject 1 nil t))
-                 (> (gnus-summary-thread-level) level)))))
+  (let ((level (gnus-summary-thread-level)))
+    (while (and (gnus-summary-set-process-mark (gnus-summary-article-number))
+               (zerop (gnus-summary-next-subject 1))
+               (> (gnus-summary-thread-level) level))))
   (gnus-summary-position-point))
 
 (defun gnus-uu-unmark-thread ()
@@ -692,7 +650,7 @@ When called interactively, prompt for REGEXP."
 (defun gnus-uu-mark-over (&optional score)
   "Mark all articles with a score over SCORE (the prefix)."
   (interactive "P")
-  (let ((score (or score gnus-summary-default-score 0))
+  (let ((score (gnus-score-default score))
        (data gnus-newsgroup-data))
     (save-excursion
       (while data
@@ -848,9 +806,8 @@ When called interactively, prompt for REGEXP."
    (gnus-uu-save-separate-articles
     (save-excursion
       (set-buffer buffer)
-      (let ((coding-system-for-write mm-text-coding-system))
-       (gnus-write-buffer
-        (concat gnus-uu-saved-article-name gnus-current-article)))
+      (gnus-write-buffer
+       (concat gnus-uu-saved-article-name gnus-current-article))
       (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin))
            ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name
                                                 'begin 'end))
@@ -876,20 +833,14 @@ When called interactively, prompt for REGEXP."
              (eq in-state 'first-and-last))
          (progn
            (setq state (list 'begin))
-           (save-excursion
-             (set-buffer (gnus-get-buffer-create "*gnus-uu-body*"))
-             (erase-buffer))
+           (save-excursion (set-buffer (gnus-get-buffer-create "*gnus-uu-body*"))
+                           (erase-buffer))
            (save-excursion
              (set-buffer (gnus-get-buffer-create "*gnus-uu-pre*"))
              (erase-buffer)
              (insert (format
-                      "Date: %s\nFrom: %s\nSubject: %s Digest\n\n"
-                      (current-time-string) name name))
-             (when (and message-forward-as-mime gnus-uu-digest-buffer)
-               ;; The default part in multipart/digest is message/rfc822.
-               ;; Subject is a fake head.
-               (insert "<#part type=message/rfc822>\nSubject: Topics\n\n"))
-             (insert "Topics:\n")))
+                      "Date: %s\nFrom: %s\nSubject: %s Digest\n\nTopics:\n"
+                      (current-time-string) name name))))
        (when (not (eq in-state 'end))
          (setq state (list 'middle))))
       (save-excursion
@@ -903,20 +854,14 @@ When called interactively, prompt for REGEXP."
              ;; These two are necessary for XEmacs 19.12 fascism.
              (put-text-property (point-min) (point-max) 'invisible nil)
              (put-text-property (point-min) (point-max) 'intangible nil))
-           (when (and message-forward-as-mime
-                      message-forward-show-mml
-                      gnus-uu-digest-buffer)
-             (mm-enable-multibyte)
-             (mime-to-mml))
            (goto-char (point-min))
            (re-search-forward "\n\n")
-           (unless (and message-forward-as-mime gnus-uu-digest-buffer)
-             ;; Quote all 30-dash lines.
-             (save-excursion
-               (while (re-search-forward "^-" nil t)
-                 (beginning-of-line)
-                 (delete-char 1)
-                 (insert "- "))))
+           ;; Quote all 30-dash lines.
+           (save-excursion
+             (while (re-search-forward "^-" nil t)
+               (beginning-of-line)
+               (delete-char 1)
+               (insert "- ")))
            (setq body (buffer-substring (1- (point)) (point-max)))
            (narrow-to-region (point-min) (point))
            (if (not (setq headers gnus-uu-digest-headers))
@@ -934,66 +879,30 @@ When called interactively, prompt for REGEXP."
                                          (1- (point)))
                                     (progn (forward-line 1) (point)))))))))
            (widen)))
-       (if (and message-forward-as-mime gnus-uu-digest-buffer)
-         (if message-forward-show-mml
-             (progn
-               (insert "\n<#mml type=message/rfc822>\n")
-               (insert sorthead) (goto-char (point-max))
-               (insert body) (goto-char (point-max))
-               (insert "\n<#/mml>\n"))
-           (let ((buf (mml-generate-new-buffer " *mml*")))
-             (with-current-buffer buf
-               (insert sorthead)
-               (goto-char (point-min))
-               (when (re-search-forward "^Subject: \\(.*\\)$" nil t)
-                 (setq subj (buffer-substring (match-beginning 1)
-                                              (match-end 1))))
-               (goto-char (point-max))
-               (insert body))
-             (insert "\n<#part type=message/rfc822"
-                     " buffer=\"" (buffer-name buf) "\">\n")))
-         (insert sorthead) (goto-char (point-max))
-         (insert body) (goto-char (point-max))
-         (insert (concat "\n" (make-string 30 ?-) "\n\n")))
+       (insert sorthead) (goto-char (point-max))
+       (insert body) (goto-char (point-max))
+       (insert (concat "\n" (make-string 30 ?-) "\n\n"))
        (goto-char beg)
        (when (re-search-forward "^Subject: \\(.*\\)$" nil t)
-         (setq subj (buffer-substring (match-beginning 1) (match-end 1))))
-       (when subj
+         (setq subj (buffer-substring (match-beginning 1) (match-end 1)))
          (save-excursion
            (set-buffer "*gnus-uu-pre*")
            (insert (format "   %s\n" subj)))))
       (when (or (eq in-state 'last)
                (eq in-state 'first-and-last))
-       (if (and message-forward-as-mime gnus-uu-digest-buffer)
-           (with-current-buffer gnus-uu-digest-buffer
-             (erase-buffer)
-             (insert-buffer "*gnus-uu-pre*")
-             (goto-char (point-max))
-             (insert-buffer "*gnus-uu-body*"))
-         (save-excursion
-           (set-buffer "*gnus-uu-pre*")
-           (insert (format "\n\n%s\n\n" (make-string 70 ?-)))
-           (if gnus-uu-digest-buffer
-               (with-current-buffer gnus-uu-digest-buffer
-                 (erase-buffer)
-                 (insert-buffer "*gnus-uu-pre*"))
-             (let ((coding-system-for-write mm-text-coding-system))
-               (gnus-write-buffer gnus-uu-saved-article-name))))
-         (save-excursion
-           (set-buffer "*gnus-uu-body*")
-           (goto-char (point-max))
-           (insert
-            (concat (setq end-string (format "End of %s Digest" name))
-                    "\n"))
-           (insert (concat (make-string (length end-string) ?*) "\n"))
-           (if gnus-uu-digest-buffer
-               (with-current-buffer gnus-uu-digest-buffer
-                 (goto-char (point-max))
-                 (insert-buffer "*gnus-uu-body*"))
-             (let ((coding-system-for-write mm-text-coding-system)
-                   (file-name-coding-system nnmail-pathname-coding-system))
-               (write-region
-                (point-min) (point-max) gnus-uu-saved-article-name t)))))
+       (save-excursion
+         (set-buffer "*gnus-uu-pre*")
+         (insert (format "\n\n%s\n\n" (make-string 70 ?-)))
+         (gnus-write-buffer gnus-uu-saved-article-name))
+       (save-excursion
+         (set-buffer "*gnus-uu-body*")
+         (goto-char (point-max))
+         (insert
+          (concat (setq end-string (format "End of %s Digest" name))
+                  "\n"))
+         (insert (concat (make-string (length end-string) ?*) "\n"))
+         (write-region
+          (point-min) (point-max) gnus-uu-saved-article-name t))
        (gnus-kill-buffer "*gnus-uu-pre*")
        (gnus-kill-buffer "*gnus-uu-body*")
        (push 'end state))
@@ -1040,7 +949,7 @@ When called interactively, prompt for REGEXP."
        (beginning-of-line)
        (forward-line 1)
        (when (file-exists-p gnus-uu-binhex-article-name)
-         (mm-append-to-file start-char (point) gnus-uu-binhex-article-name))))
+         (append-to-file start-char (point) gnus-uu-binhex-article-name))))
     (if (memq 'begin state)
        (cons gnus-uu-binhex-article-name state)
       state)))
@@ -1115,7 +1024,7 @@ When called interactively, prompt for REGEXP."
   ;; finally just replaces the next to last number with "[0-9]+".
   (save-excursion
     (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name))
-    (buffer-disable-undo)
+    (buffer-disable-undo (current-buffer))
     (erase-buffer)
     (insert (regexp-quote string))
 
@@ -1215,7 +1124,7 @@ When called interactively, prompt for REGEXP."
        string)
     (save-excursion
       (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name))
-      (buffer-disable-undo)
+      (buffer-disable-undo (current-buffer))
       (while string-list
        (erase-buffer)
        (insert (caar string-list))
@@ -1290,10 +1199,9 @@ When called interactively, prompt for REGEXP."
                                       &optional sloppy limit no-errors)
   (let ((state 'first)
        (gnus-asynchronous nil)
-       (gnus-inhibit-treatment t)
        has-been-begin article result-file result-files process-state
        gnus-summary-display-article-function
-       gnus-article-prepare-hook gnus-display-mime-function
+       gnus-article-display-hook gnus-article-prepare-hook
        article-series files)
 
     (while (and articles
@@ -1418,9 +1326,6 @@ When called interactively, prompt for REGEXP."
          (while article-series
            (gnus-summary-tick-article (pop article-series) t)))))
 
-    ;; The original article buffer is hosed, shoot it down.
-    (gnus-kill-buffer gnus-original-article-buffer)
-
     result-files))
 
 (defun gnus-uu-grab-view (file)
@@ -1487,7 +1392,7 @@ When called interactively, prompt for REGEXP."
          ;; 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))))
           (replace-match (concat "begin 644 " gnus-uu-file-name) t t)
 
@@ -1564,21 +1469,6 @@ When called interactively, prompt for REGEXP."
          (cons (if (= (length files) 1) (car files) files) state)
        state))))
 
-(defvar gnus-uu-unshar-warning
-  "*** WARNING ***
-
-Shell archives are an archaic method of bundling files for distribution
-across computer networks.  During the unpacking process, arbitrary commands
-are executed on your system, and all kinds of nasty things can happen.
-Please examine the archive very carefully before you instruct Emacs to
-unpack it.  You can browse the archive buffer using \\[scroll-other-window].
-
-If you are unsure what to do, please answer \"no\"."
-  "Text of warning message displayed by `gnus-uu-unshar-article'.
-Make sure that this text consists only of few text lines.  Otherwise,
-Gnus might fail to display all of it.")
-
-
 ;; This function is used by `gnus-uu-grab-articles' to treat
 ;; a shared article.
 (defun gnus-uu-unshar-article (process-buffer in-state)
@@ -1589,31 +1479,14 @@ Gnus might fail to display all of it.")
       (goto-char (point-min))
       (if (not (re-search-forward gnus-uu-shar-begin-string nil t))
          (setq state (list 'wrong-type))
-       (save-window-excursion
-         (save-excursion
-           (switch-to-buffer (current-buffer))
-           (delete-other-windows)
-           (let ((buffer (get-buffer-create (generate-new-buffer-name
-                                             "*Warning*"))))
-             (unless
-                 (unwind-protect
-                     (with-current-buffer buffer
-                       (insert (substitute-command-keys
-                                gnus-uu-unshar-warning))
-                       (goto-char (point-min))
-                       (display-buffer buffer)
-                       (yes-or-no-p "This is a shell archive, unshar it? "))
-                   (kill-buffer buffer))
-               (setq state (list 'error))))))
-       (unless (memq 'error state)
-         (beginning-of-line)
-         (setq start-char (point))
-         (call-process-region
-          start-char (point-max) shell-file-name nil
-          (gnus-get-buffer-create gnus-uu-output-buffer-name) nil
-          shell-command-switch
-          (concat "cd " gnus-uu-work-dir " "
-                  gnus-shell-command-separator  " sh")))))
+       (beginning-of-line)
+       (setq start-char (point))
+       (call-process-region
+        start-char (point-max) shell-file-name nil
+        (gnus-get-buffer-create gnus-uu-output-buffer-name) nil
+        shell-command-switch
+        (concat "cd " gnus-uu-work-dir " "
+                gnus-shell-command-separator  " sh"))))
     state))
 
 ;; Returns the name of what the shar file is going to unpack.
@@ -1821,11 +1694,23 @@ Gnus might fail to display all of it.")
     (when (setq buf (get-buffer gnus-uu-output-buffer-name))
       (kill-buffer buf))))
 
+(defun gnus-quote-arg-for-sh-or-csh (arg)
+  (let ((pos 0) new-pos accum)
+    ;; *** bug: we don't handle newline characters properly
+    (while (setq new-pos (string-match "[!`\"$\\& \t{}]" arg pos))
+      (push (substring arg pos new-pos) accum)
+      (push "\\" accum)
+      (push (list (aref arg new-pos)) accum)
+      (setq pos (1+ new-pos)))
+    (if (= pos 0)
+        arg
+      (apply 'concat (nconc (nreverse accum) (list (substring arg pos)))))))
+
 ;; Inputs an action and a filename and returns a full command, making sure
 ;; that the filename will be treated as a single argument when the shell
 ;; executes the command.
 (defun gnus-uu-command (action file)
-  (let ((quoted-file (mm-quote-arg file)))
+  (let ((quoted-file (gnus-quote-arg-for-sh-or-csh file)))
     (if (string-match "%s" action)
        (format action quoted-file)
       (concat action " " quoted-file))))
@@ -1921,10 +1806,8 @@ is t."
 
   (gnus-summary-post-news)
 
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map (current-local-map))
-    (use-local-map map))
-  ;;(local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
+  (use-local-map (copy-keymap (current-local-map)))
+  (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
   (local-set-key "\C-c\C-c" 'gnus-uu-post-news-inews)
   (local-set-key "\C-c\C-s" 'gnus-uu-post-news-inews)
   (local-set-key "\C-c\C-i" 'gnus-uu-post-insert-binary-in-article)