* gnus-int.el (gnus-open-server): Catch errors in backend's
[gnus] / lisp / gnus-uu.el
index 48152f8..314700d 100644 (file)
@@ -1,7 +1,8 @@
 ;;; gnus-uu.el --- extract (uu)encoded files in Gnus
-;; Copyright (C) 1985,86,87,93,94,95,96 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
+;;        2001, 2002 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Created: 2 Oct 1993
 ;; Keyword: news
 
 
 ;;; Commentary:
 
-;;; Code: 
+;;; Code:
 
-(require 'gnus-load)
+(eval-when-compile (require 'cl))
+
+(require 'gnus)
 (require 'gnus-art)
 (require 'message)
 (require 'gnus-msg)
+(require 'mm-decode)
+
+(defgroup gnus-extract nil
+  "Extracting encoded files."
+  :prefix "gnus-uu-"
+  :group 'gnus)
+
+(defgroup gnus-extract-view nil
+  "Viewwing extracted files."
+  :group 'gnus-extract)
+
+(defgroup gnus-extract-archive nil
+  "Extracting encoded archives."
+  :group 'gnus-extract)
+
+(defgroup gnus-extract-post nil
+  "Extracting encoded archives."
+  :prefix "gnus-uu-post"
+  :group 'gnus-extract)
 
 ;; Default viewing action rules
 
-(defvar gnus-uu-default-view-rules 
-  '(("\\.te?xt$\\|\\.doc$\\|read.*me\\|\\.c?$\\|\\.h$\\|\\.bat$\\|\\.asm$\\|makefile" "cat %s | sed s/\r//g")
-    ("\\.pas$" "cat %s | sed s/\r//g")
+(defcustom gnus-uu-default-view-rules
+  '(("\\.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\\)$" "xv")
-    ("\\.tga$" "tgatoppm %s | xv -")
-    ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$" 
+    ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "display")
+    ("\\.tga$" "tgatoppm %s | ee -")
+    ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$"
      "sox -v .5 %s -t .au -u - > /dev/audio")
     ("\\.au$" "cat %s > /dev/audio")
     ("\\.midi?$" "playmidi -f")
@@ -49,9 +71,9 @@
     ("\\.html$" "xmosaic")
     ("\\.mpe?g$" "mpeg_play")
     ("\\.\\(flc\\|fli\\|rle\\|iff\\|pfx\\|avi\\|sme\\|rpza\\|dl\\|qt\\|rsrc\\|mov\\)$" "xanim")
-    ("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\|lha\\)$" 
+    ("\\.\\(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.  
+  "*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
 `gnus-uu-user-view-rules' to something useful.
 
@@ -62,38 +84,44 @@ following in your .emacs file:
 
   (setq gnus-uu-user-view-rules '((\"jpg$\\\\|gif$\" \"xli\")))
 
-Both these variables are lists of lists with two string elements. The
-first string is a regular expression. If the file name matches this
+Both these variables are lists of lists with two string elements.  The
+first string is a regular expression.  If the file name matches this
 regular expression, the command in the second string is executed with
 the file as an argument.
 
 If the command string contains \"%s\", the file name will be inserted
-at that point in the command string. If there's no \"%s\" in the
+at that point in the command string.  If there's no \"%s\" in the
 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
-your needs. First we have `gnus-uu-user-view-rules', which is the
+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
-default rule variable provided in this package. If gnus-uu finds no
+file.  If this variable contains no matches, gnus-uu examines the
+default rule variable provided in this package.  If gnus-uu finds no
 match here, it uses `gnus-uu-user-view-rules-end' to try to make a
-match.")
-
-(defvar gnus-uu-user-view-rules nil 
-  "*Variable detailing what actions are to be taken to view a file.
-See the documentation on the `gnus-uu-default-view-rules' variable for 
-details.")
-
-(defvar gnus-uu-user-view-rules-end 
+match."
+  :group 'gnus-extract-view
+  :type '(repeat (group regexp (string :tag "Command"))))
+
+(defcustom gnus-uu-user-view-rules nil
+  "What actions are to be taken to view a file.
+See the documentation on the `gnus-uu-default-view-rules' variable for
+details."
+  :group 'gnus-extract-view
+  :type '(repeat (group regexp (string :tag "Command"))))
+
+(defcustom gnus-uu-user-view-rules-end
   '(("" "file"))
-  "*Variable saying what actions are to be taken if no rule matched the file name.
-See the documentation on the `gnus-uu-default-view-rules' variable for 
-details.")
+  "*What actions are to be taken if no rule matched the file name.
+See the documentation on the `gnus-uu-default-view-rules' variable for
+details."
+  :group 'gnus-extract-view
+  :type '(repeat (group regexp (string :tag "Command"))))
 
 ;; Default unpacking commands
 
-(defvar gnus-uu-default-archive-rules 
+(defcustom gnus-uu-default-archive-rules
   '(("\\.tar$" "tar xf")
     ("\\.zip$" "unzip -o")
     ("\\.ar$" "ar x")
@@ -102,38 +130,49 @@ details.")
     ("\\.\\(lzh\\|lha\\)$" "lha x")
     ("\\.Z$" "uncompress")
     ("\\.gz$" "gunzip")
-    ("\\.arc$" "arc -x")))
+    ("\\.arc$" "arc -x"))
+  "*See `gnus-uu-user-archive-rules'."
+  :group 'gnus-extract-archive
+  :type '(repeat (group regexp (string :tag "Command"))))
 
-(defvar gnus-uu-destructive-archivers 
+(defvar gnus-uu-destructive-archivers
   (list "uncompress" "gunzip"))
 
-(defvar gnus-uu-user-archive-rules nil
-  "*A list that can be set to override the default archive unpacking commands.
+(defcustom gnus-uu-user-archive-rules nil
+  "A list that can be set to override the default archive unpacking commands.
 To use, for instance, 'untar' to unpack tar files and 'zip -x' to
 unpack zip files, say the following:
-  (setq gnus-uu-user-archive-rules 
+  (setq gnus-uu-user-archive-rules
     '((\"\\\\.tar$\" \"untar\")
-      (\"\\\\.zip$\" \"zip -x\")))")
+      (\"\\\\.zip$\" \"zip -x\")))"
+  :group 'gnus-extract-archive
+  :type '(repeat (group regexp (string :tag "Command"))))
 
-(defvar gnus-uu-ignore-files-by-name nil
+(defcustom gnus-uu-ignore-files-by-name nil
   "*A regular expression saying what files should not be viewed based on name.
-If, for instance, you want gnus-uu to ignore all .au and .wav files, 
+If, for instance, you want gnus-uu to ignore all .au and .wav files,
 you could say something like
 
   (setq gnus-uu-ignore-files-by-name \"\\\\.au$\\\\|\\\\.wav$\")
 
 Note that this variable can be used in conjunction with the
-`gnus-uu-ignore-files-by-type' variable.")
+`gnus-uu-ignore-files-by-type' variable."
+  :group 'gnus-extract
+  :type '(choice (const :tag "off" nil)
+                (regexp :format "%v")))
 
-(defvar gnus-uu-ignore-files-by-type nil
+(defcustom gnus-uu-ignore-files-by-type nil
   "*A regular expression saying what files that shouldn't be viewed, based on MIME file type.
-If, for instance, you want gnus-uu to ignore all audio files and all mpegs, 
+If, for instance, you want gnus-uu to ignore all audio files and all mpegs,
 you could say something like
 
   (setq gnus-uu-ignore-files-by-type \"audio/\\\\|video/mpeg\")
 
 Note that this variable can be used in conjunction with the
-`gnus-uu-ignore-files-by-name' variable.")
+`gnus-uu-ignore-files-by-name' variable."
+  :group 'gnus-extract
+  :type '(choice (const :tag "off" nil)
+                (regexp :format "%v")))
 
 ;; Pseudo-MIME support
 
@@ -176,72 +215,117 @@ Note that this variable can be used in conjunction with the
     ("\\.rsrc$" "video/rsrc")
     ("\\..*$" "unknown/unknown")))
 
-;; Various variables users may set 
+;; Various variables users may set
 
-(defvar gnus-uu-tmp-dir "/tmp/" 
+(defcustom gnus-uu-tmp-dir
+  (cond ((fboundp 'temp-directory) (temp-directory))
+       ((boundp 'temporary-file-directory) temporary-file-directory)
+       ("/tmp/"))
   "*Variable saying where gnus-uu is to do its work.
-Default is \"/tmp/\".")
+Default is \"/tmp/\"."
+  :group 'gnus-extract
+  :type 'directory)
 
-(defvar gnus-uu-do-not-unpack-archives nil 
-  "*Non-nil means that gnus-uu won't peek inside archives looking for files to display. 
-Default is nil.")
+(defcustom gnus-uu-do-not-unpack-archives nil
+  "*Non-nil means that gnus-uu won't peek inside archives looking for files to display.
+Default is nil."
+  :group 'gnus-extract-archive
+  :type 'boolean)
 
-(defvar gnus-uu-ignore-default-view-rules nil
+(defcustom gnus-uu-ignore-default-view-rules nil
   "*Non-nil means that gnus-uu will ignore the default viewing rules.
-Only the user viewing rules will be consulted. Default is nil.")
+Only the user viewing rules will be consulted.  Default is nil."
+  :group 'gnus-extract-view
+  :type 'boolean)
 
-(defvar gnus-uu-grabbed-file-functions nil
-  "*Functions run on each file after successful decoding.
+(defcustom gnus-uu-grabbed-file-functions nil
+  "Functions run on each file after successful decoding.
 They will be called with the name of the file as the argument.
-Likely functions you can use in this list are `gnus-uu-grab-view' 
-and `gnus-uu-grab-move'.")
-
-(defvar gnus-uu-ignore-default-archive-rules nil 
-  "*Non-nil means that gnus-uu will ignore the default archive unpacking commands.  
-Only the user unpacking commands will be consulted. Default is nil.")
-
-(defvar gnus-uu-kill-carriage-return t
+Likely functions you can use in this list are `gnus-uu-grab-view'
+and `gnus-uu-grab-move'."
+  :group 'gnus-extract
+  :options '(gnus-uu-grab-view gnus-uu-grab-move)
+  :type 'hook)
+
+(defcustom gnus-uu-ignore-default-archive-rules nil
+  "*Non-nil means that gnus-uu will ignore the default archive unpacking commands.
+Only the user unpacking commands will be consulted.  Default is nil."
+  :group 'gnus-extract-archive
+  :type 'boolean)
+
+(defcustom gnus-uu-kill-carriage-return t
   "*Non-nil means that gnus-uu will strip all carriage returns from articles.
-Default is t.")
+Default is t."
+  :group 'gnus-extract
+  :type 'boolean)
 
-(defvar gnus-uu-view-with-metamail nil
+(defcustom gnus-uu-view-with-metamail nil
   "*Non-nil means that files will be viewed with metamail.
 The gnus-uu viewing functions will be ignored and gnus-uu will try
-to guess at a content-type based on file name suffixes. Default
-it nil.")
-
-(defvar gnus-uu-unmark-articles-not-decoded nil
-  "*Non-nil means that gnus-uu will mark articles that were unsuccessfully decoded as unread. 
-Default is nil.")
-
-(defvar gnus-uu-correct-stripped-uucode nil
-  "*Non-nil means that gnus-uu will *try* to fix uuencoded files that have had trailing spaces deleted. 
-Default is nil.")
-
-(defvar gnus-uu-save-in-digest nil
+to guess at a content-type based on file name suffixes.  Default
+it nil."
+  :group 'gnus-extract
+  :type 'boolean)
+
+(defcustom gnus-uu-unmark-articles-not-decoded nil
+  "*Non-nil means that gnus-uu will mark articles that were unsuccessfully decoded as unread.
+Default is nil."
+  :group 'gnus-extract
+  :type 'boolean)
+
+(defcustom gnus-uu-correct-stripped-uucode nil
+  "*Non-nil means that gnus-uu will *try* to fix uuencoded files that have had trailing spaces deleted.
+Default is nil."
+  :group 'gnus-extract
+  :type 'boolean)
+
+(defcustom gnus-uu-save-in-digest nil
   "*Non-nil means that gnus-uu, when asked to save without decoding, will save in digests.
-If this variable is nil, gnus-uu will just save everything in a 
-file without any embellishments. The digesting almost conforms to RFC1153 -
-no easy way to specify any meaningful volume and issue numbers were found, 
-so I simply dropped them.")
-
-(defvar gnus-uu-digest-headers 
+If this variable is nil, gnus-uu will just save everything in a
+file without any embellishments.  The digesting almost conforms to RFC1153 -
+no easy way to specify any meaningful volume and issue numbers were found,
+so I simply dropped them."
+  :group 'gnus-extract
+  :type 'boolean)
+
+(defcustom gnus-uu-pre-uudecode-hook nil
+  "Hook run before sending a message to uudecode."
+  :group 'gnus-extract
+  :type 'hook)
+
+(defcustom gnus-uu-digest-headers
   '("^Date:" "^From:" "^To:" "^Cc:" "^Subject:" "^Message-ID:" "^Keywords:"
-    "^Summary:" "^References:")
+    "^Summary:" "^References:" "^Content-Type:" "^Content-Transfer-Encoding:"
+    "^MIME-Version:" "^Content-Disposition:" "^Content-Description:"
+    "^Content-ID:")
   "*List of regexps to match headers included in digested messages.
-The headers will be included in the sequence they are matched.")
-
-(defvar gnus-uu-save-separate-articles nil
-  "*Non-nil means that gnus-uu will save articles in separate files.")
+The headers will be included in the sequence they are matched.  If nil
+include all headers."
+  :group 'gnus-extract
+  :type '(repeat regexp))
+
+(defcustom gnus-uu-save-separate-articles nil
+  "*Non-nil means that gnus-uu will save articles in separate files."
+  :group 'gnus-extract
+  :type 'boolean)
+
+(defcustom gnus-uu-be-dangerous 'ask
+  "*Specifies what to do if unusual situations arise during decoding.
+If nil, be as conservative as possible.  If t, ignore things that
+didn't work, and overwrite existing files.  Otherwise, ask each time."
+  :group 'gnus-extract
+  :type '(choice (const :tag "conservative" nil)
+                (const :tag "ask" ask)
+                (const :tag "liberal" t)))
 
 ;; Internal variables
 
 (defvar gnus-uu-saved-article-name nil)
 
-(defconst