comparison lisp/gnus/gnus-uu.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents e04119814345
children 0d2f883870bc
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
1 ;;; gnus-uu.el --- extract (uu)encoded files in Gnus 1 ;;; gnus-uu.el --- extract (uu)encoded files in Gnus
2 ;; Copyright (C) 1985,86,87,93,94,95,96,97 Free Software Foundation, Inc. 2 ;; Copyright (C) 1985,86,87,93,94,95,96 Free Software Foundation, Inc.
3 3
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no> 4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
5 ;; Created: 2 Oct 1993 5 ;; Created: 2 Oct 1993
6 ;; Keyword: news 6 ;; Keyword: news
7 7
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. 23 ;; Boston, MA 02111-1307, USA.
24 24
25 ;;; Commentary: 25 ;;; Commentary:
26 26
27 ;;; Code: 27 ;;; Code:
28 28
29 (require 'gnus) 29 (require 'gnus)
30 (require 'gnus-art)
31 (require 'message)
32 (require 'gnus-msg) 30 (require 'gnus-msg)
33 31 (eval-when-compile (require 'cl))
34 (defgroup gnus-extract nil
35 "Extracting encoded files."
36 :prefix "gnus-uu-"
37 :group 'gnus)
38
39 (defgroup gnus-extract-view nil
40 "Viewwing extracted files."
41 :group 'gnus-extract)
42
43 (defgroup gnus-extract-archive nil
44 "Extracting encoded archives."
45 :group 'gnus-extract)
46
47 (defgroup gnus-extract-post nil
48 "Extracting encoded archives."
49 :prefix "gnus-uu-post"
50 :group 'gnus-extract)
51 32
52 ;; Default viewing action rules 33 ;; Default viewing action rules
53 34
54 (defcustom gnus-uu-default-view-rules 35 (defvar gnus-uu-default-view-rules
55 '(("\\.te?xt$\\|\\.doc$\\|read.*me\\|\\.c?$\\|\\.h$\\|\\.bat$\\|\\.asm$\\|makefile" "cat %s | sed s/\r//g") 36 '(("\\.te?xt$\\|\\.doc$\\|read.*me\\|\\.c?$\\|\\.h$\\|\\.bat$\\|\\.asm$\\|makefile" "cat %s | sed s/\r//g")
56 ("\\.pas$" "cat %s | sed s/\r//g") 37 ("\\.pas$" "cat %s | sed s/\r//g")
57 ("\\.[1-9]$" "groff -mandoc -Tascii %s | sed s/\b.//g") 38 ("\\.[1-9]$" "groff -mandoc -Tascii %s | sed s/\b.//g")
58 ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "xv") 39 ("\\.\\(jpe?g\\|gif\\|tiff?\\|p[pgb]m\\|xwd\\|xbm\\|pcx\\)$" "xv")
59 ("\\.tga$" "tgatoppm %s | xv -") 40 ("\\.tga$" "tgatoppm %s | xv -")
60 ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$" 41 ("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$"
61 "sox -v .5 %s -t .au -u - > /dev/audio") 42 "sox -v .5 %s -t .au -u - > /dev/audio")
62 ("\\.au$" "cat %s > /dev/audio") 43 ("\\.au$" "cat %s > /dev/audio")
63 ("\\.midi?$" "playmidi -f") 44 ("\\.midi?$" "playmidi -f")
64 ("\\.mod$" "str32") 45 ("\\.mod$" "str32")
65 ("\\.ps$" "ghostview") 46 ("\\.ps$" "ghostview")
66 ("\\.dvi$" "xdvi") 47 ("\\.dvi$" "xdvi")
67 ("\\.html$" "xmosaic") 48 ("\\.html$" "xmosaic")
68 ("\\.mpe?g$" "mpeg_play") 49 ("\\.mpe?g$" "mpeg_play")
69 ("\\.\\(flc\\|fli\\|rle\\|iff\\|pfx\\|avi\\|sme\\|rpza\\|dl\\|qt\\|rsrc\\|mov\\)$" "xanim") 50 ("\\.\\(flc\\|fli\\|rle\\|iff\\|pfx\\|avi\\|sme\\|rpza\\|dl\\|qt\\|rsrc\\|mov\\)$" "xanim")
70 ("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\|lha\\)$" 51 ("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\|lha\\)$"
71 "gnus-uu-archive")) 52 "gnus-uu-archive"))
72 "Default actions to be taken when the user asks to view a file. 53 "*Default actions to be taken when the user asks to view a file.
73 To change the behaviour, you can either edit this variable or set 54 To change the behaviour, you can either edit this variable or set
74 `gnus-uu-user-view-rules' to something useful. 55 `gnus-uu-user-view-rules' to something useful.
75 56
76 For example: 57 For example:
77 58
78 To make gnus-uu use 'xli' to display JPEG and GIF files, put the 59 To make gnus-uu use 'xli' to display JPEG and GIF files, put the
79 following in your .emacs file: 60 following in your .emacs file:
80 61
81 (setq gnus-uu-user-view-rules '((\"jpg$\\\\|gif$\" \"xli\"))) 62 (setq gnus-uu-user-view-rules '((\"jpg$\\\\|gif$\" \"xli\")))
82 63
83 Both these variables are lists of lists with two string elements. The 64 Both these variables are lists of lists with two string elements. The
84 first string is a regular expression. If the file name matches this 65 first string is a regular expression. If the file name matches this
85 regular expression, the command in the second string is executed with 66 regular expression, the command in the second string is executed with
86 the file as an argument. 67 the file as an argument.
87 68
88 If the command string contains \"%s\", the file name will be inserted 69 If the command string contains \"%s\", the file name will be inserted
89 at that point in the command string. If there's no \"%s\" in the 70 at that point in the command string. If there's no \"%s\" in the
90 command string, the file name will be appended to the command string 71 command string, the file name will be appended to the command string
91 before executing. 72 before executing.
92 73
93 There are several user variables to tailor the behaviour of gnus-uu to 74 There are several user variables to tailor the behaviour of gnus-uu to
94 your needs. First we have `gnus-uu-user-view-rules', which is the 75 your needs. First we have `gnus-uu-user-view-rules', which is the
95 variable gnus-uu first consults when trying to decide how to view a 76 variable gnus-uu first consults when trying to decide how to view a
96 file. If this variable contains no matches, gnus-uu examines the 77 file. If this variable contains no matches, gnus-uu examines the
97 default rule variable provided in this package. If gnus-uu finds no 78 default rule variable provided in this package. If gnus-uu finds no
98 match here, it uses `gnus-uu-user-view-rules-end' to try to make a 79 match here, it uses `gnus-uu-user-view-rules-end' to try to make a
99 match." 80 match.")
100 :group 'gnus-extract-view 81
101 :type '(repeat (group regexp (string :tag "Command")))) 82 (defvar gnus-uu-user-view-rules nil
102 83 "*Variable detailing what actions are to be taken to view a file.
103 (defcustom gnus-uu-user-view-rules nil 84 See the documentation on the `gnus-uu-default-view-rules' variable for
104 "What actions are to be taken to view a file. 85 details.")
105 See the documentation on the `gnus-uu-default-view-rules' variable for 86
106 details." 87 (defvar gnus-uu-user-view-rules-end
107 :group 'gnus-extract-view
108 :type '(repeat (group regexp (string :tag "Command"))))
109
110 (defcustom gnus-uu-user-view-rules-end
111 '(("" "file")) 88 '(("" "file"))
112 "What actions are to be taken if no rule matched the file name. 89 "*Variable saying what actions are to be taken if no rule matched the file name.
113 See the documentation on the `gnus-uu-default-view-rules' variable for 90 See the documentation on the `gnus-uu-default-view-rules' variable for
114 details." 91 details.")
115 :group 'gnus-extract-view
116 :type '(repeat (group regexp (string :tag "Command"))))
117 92
118 ;; Default unpacking commands 93 ;; Default unpacking commands
119 94
120 (defcustom gnus-uu-default-archive-rules 95 (defvar gnus-uu-default-archive-rules
121 '(("\\.tar$" "tar xf") 96 '(("\\.tar$" "tar xf")
122 ("\\.zip$" "unzip -o") 97 ("\\.zip$" "unzip -o")
123 ("\\.ar$" "ar x") 98 ("\\.ar$" "ar x")
124 ("\\.arj$" "unarj x") 99 ("\\.arj$" "unarj x")
125 ("\\.zoo$" "zoo -e") 100 ("\\.zoo$" "zoo -e")
126 ("\\.\\(lzh\\|lha\\)$" "lha x") 101 ("\\.\\(lzh\\|lha\\)$" "lha x")
127 ("\\.Z$" "uncompress") 102 ("\\.Z$" "uncompress")
128 ("\\.gz$" "gunzip") 103 ("\\.gz$" "gunzip")
129 ("\\.arc$" "arc -x")) 104 ("\\.arc$" "arc -x")))
130 "See `gnus-uu-user-archive-rules'." 105
131 :group 'gnus-extract-archive 106 (defvar gnus-uu-destructive-archivers
132 :type '(repeat (group regexp (string :tag "Command"))))
133
134 (defvar gnus-uu-destructive-archivers
135 (list "uncompress" "gunzip")) 107 (list "uncompress" "gunzip"))
136 108
137 (defcustom gnus-uu-user-archive-rules nil 109 (defvar gnus-uu-user-archive-rules nil
138 "A list that can be set to override the default archive unpacking commands. 110 "*A list that can be set to override the default archive unpacking commands.
139 To use, for instance, 'untar' to unpack tar files and 'zip -x' to 111 To use, for instance, 'untar' to unpack tar files and 'zip -x' to
140 unpack zip files, say the following: 112 unpack zip files, say the following:
141 (setq gnus-uu-user-archive-rules 113 (setq gnus-uu-user-archive-rules
142 '((\"\\\\.tar$\" \"untar\") 114 '((\"\\\\.tar$\" \"untar\")
143 (\"\\\\.zip$\" \"zip -x\")))" 115 (\"\\\\.zip$\" \"zip -x\")))")
144 :group 'gnus-extract-archive 116
145 :type '(repeat (group regexp (string :tag "Command")))) 117 (defvar gnus-uu-ignore-files-by-name nil
146
147 (defcustom gnus-uu-ignore-files-by-name nil
148 "*A regular expression saying what files should not be viewed based on name. 118 "*A regular expression saying what files should not be viewed based on name.
149 If, for instance, you want gnus-uu to ignore all .au and .wav files, 119 If, for instance, you want gnus-uu to ignore all .au and .wav files,
150 you could say something like 120 you could say something like
151 121
152 (setq gnus-uu-ignore-files-by-name \"\\\\.au$\\\\|\\\\.wav$\") 122 (setq gnus-uu-ignore-files-by-name \"\\\\.au$\\\\|\\\\.wav$\")
153 123
154 Note that this variable can be used in conjunction with the 124 Note that this variable can be used in conjunction with the
155 `gnus-uu-ignore-files-by-type' variable." 125 `gnus-uu-ignore-files-by-type' variable.")
156 :group 'gnus-extract 126
157 :type '(choice (const :tag "off" nil) 127 (defvar gnus-uu-ignore-files-by-type nil
158 (regexp :format "%v")))
159
160 (defcustom gnus-uu-ignore-files-by-type nil
161 "*A regular expression saying what files that shouldn't be viewed, based on MIME file type. 128 "*A regular expression saying what files that shouldn't be viewed, based on MIME file type.
162 If, for instance, you want gnus-uu to ignore all audio files and all mpegs, 129 If, for instance, you want gnus-uu to ignore all audio files and all mpegs,
163 you could say something like 130 you could say something like
164 131
165 (setq gnus-uu-ignore-files-by-type \"audio/\\\\|video/mpeg\") 132 (setq gnus-uu-ignore-files-by-type \"audio/\\\\|video/mpeg\")
166 133
167 Note that this variable can be used in conjunction with the 134 Note that this variable can be used in conjunction with the
168 `gnus-uu-ignore-files-by-name' variable." 135 `gnus-uu-ignore-files-by-name' variable.")
169 :group 'gnus-extract
170 :type '(choice (const :tag "off" nil)
171 (regexp :format "%v")))
172 136
173 ;; Pseudo-MIME support 137 ;; Pseudo-MIME support
174 138
175 (defconst gnus-uu-ext-to-mime-list 139 (defconst gnus-uu-ext-to-mime-list
176 '(("\\.gif$" "image/gif") 140 '(("\\.gif$" "image/gif")
209 ("\\.dl$" "video/dl") 173 ("\\.dl$" "video/dl")
210 ("\\.qt$" "video/qt") 174 ("\\.qt$" "video/qt")
211 ("\\.rsrc$" "video/rsrc") 175 ("\\.rsrc$" "video/rsrc")
212 ("\\..*$" "unknown/unknown"))) 176 ("\\..*$" "unknown/unknown")))
213 177
214 ;; Various variables users may set 178 ;; Various variables users may set
215 179
216 (defcustom gnus-uu-tmp-dir "/tmp/" 180 (defvar gnus-uu-tmp-dir "/tmp/"
217 "*Variable saying where gnus-uu is to do its work. 181 "*Variable saying where gnus-uu is to do its work.
218 Default is \"/tmp/\"." 182 Default is \"/tmp/\".")
219 :group 'gnus-extract 183
220 :type 'directory) 184 (defvar gnus-uu-do-not-unpack-archives nil
221 185 "*Non-nil means that gnus-uu won't peek inside archives looking for files to display.
222 (defcustom gnus-uu-do-not-unpack-archives nil 186 Default is nil.")
223 "*Non-nil means that gnus-uu won't peek inside archives looking for files to display. 187
224 Default is nil." 188 (defvar gnus-uu-ignore-default-view-rules nil
225 :group 'gnus-extract-archive
226 :type 'boolean)
227
228 (defcustom gnus-uu-ignore-default-view-rules nil
229 "*Non-nil means that gnus-uu will ignore the default viewing rules. 189 "*Non-nil means that gnus-uu will ignore the default viewing rules.
230 Only the user viewing rules will be consulted. Default is nil." 190 Only the user viewing rules will be consulted. Default is nil.")
231 :group 'gnus-extract-view 191
232 :type 'boolean) 192 (defvar gnus-uu-grabbed-file-functions nil
233 193 "*Functions run on each file after successful decoding.
234 (defcustom gnus-uu-grabbed-file-functions nil
235 "Functions run on each file after successful decoding.
236 They will be called with the name of the file as the argument. 194 They will be called with the name of the file as the argument.
237 Likely functions you can use in this list are `gnus-uu-grab-view' 195 Likely functions you can use in this list are `gnus-uu-grab-view'
238 and `gnus-uu-grab-move'." 196 and `gnus-uu-grab-move'.")
239 :group 'gnus-extract 197
240 :options '(gnus-uu-grab-view gnus-uu-grab-move) 198 (defvar gnus-uu-ignore-default-archive-rules nil
241 :type 'hook) 199 "*Non-nil means that gnus-uu will ignore the default archive unpacking commands.
242 200 Only the user unpacking commands will be consulted. Default is nil.")
243 (defcustom gnus-uu-ignore-default-archive-rules nil 201
244 "*Non-nil means that gnus-uu will ignore the default archive unpacking commands. 202 (defvar gnus-uu-kill-carriage-return t
245 Only the user unpacking commands will be consulted. Default is nil."
246 :group 'gnus-extract-archive
247 :type 'boolean)
248
249 (defcustom gnus-uu-kill-carriage-return t
250 "*Non-nil means that gnus-uu will strip all carriage returns from articles. 203 "*Non-nil means that gnus-uu will strip all carriage returns from articles.
251 Default is t." 204 Default is t.")
252 :group 'gnus-extract 205
253 :type 'boolean) 206 (defvar gnus-uu-view-with-metamail nil
254
255 (defcustom gnus-uu-view-with-metamail nil
256 "*Non-nil means that files will be viewed with metamail. 207 "*Non-nil means that files will be viewed with metamail.
257 The gnus-uu viewing functions will be ignored and gnus-uu will try 208 The gnus-uu viewing functions will be ignored and gnus-uu will try
258 to guess at a content-type based on file name suffixes. Default 209 to guess at a content-type based on file name suffixes. Default
259 it nil." 210 it nil.")
260 :group 'gnus-extract 211
261 :type 'boolean) 212 (defvar gnus-uu-unmark-articles-not-decoded nil
262 213 "*Non-nil means that gnus-uu will mark articles that were unsuccessfully decoded as unread.
263 (defcustom gnus-uu-unmark-articles-not-decoded nil 214 Default is nil.")
264 "*Non-nil means that gnus-uu will mark articles that were unsuccessfully decoded as unread. 215
265 Default is nil." 216 (defvar gnus-uu-correct-stripped-uucode nil
266 :group 'gnus-extract 217 "*Non-nil means that gnus-uu will *try* to fix uuencoded files that have had trailing spaces deleted.
267 :type 'boolean) 218 Default is nil.")
268 219
269 (defcustom gnus-uu-correct-stripped-uucode nil 220 (defvar gnus-uu-save-in-digest nil
270 "*Non-nil means that gnus-uu will *try* to fix uuencoded files that have had trailing spaces deleted.
271 Default is nil."
272 :group 'gnus-extract
273 :type 'boolean)
274
275 (defcustom gnus-uu-save-in-digest nil
276 "*Non-nil means that gnus-uu, when asked to save without decoding, will save in digests. 221 "*Non-nil means that gnus-uu, when asked to save without decoding, will save in digests.
277 If this variable is nil, gnus-uu will just save everything in a 222 If this variable is nil, gnus-uu will just save everything in a
278 file without any embellishments. The digesting almost conforms to RFC1153 - 223 file without any embellishments. The digesting almost conforms to RFC1153 -
279 no easy way to specify any meaningful volume and issue numbers were found, 224 no easy way to specify any meaningful volume and issue numbers were found,
280 so I simply dropped them." 225 so I simply dropped them.")
281 :group 'gnus-extract 226
282 :type 'boolean) 227 (defvar gnus-uu-digest-headers
283
284 (defcustom gnus-uu-digest-headers
285 '("^Date:" "^From:" "^To:" "^Cc:" "^Subject:" "^Message-ID:" "^Keywords:" 228 '("^Date:" "^From:" "^To:" "^Cc:" "^Subject:" "^Message-ID:" "^Keywords:"
286 "^Summary:" "^References:") 229 "^Summary:" "^References:")
287 "List of regexps to match headers included in digested messages. 230 "*List of regexps to match headers included in digested messages.
288 The headers will be included in the sequence they are matched." 231 The headers will be included in the sequence they are matched.")
289 :group 'gnus-extract 232
290 :type '(repeat regexp)) 233 (defvar gnus-uu-save-separate-articles nil
291 234 "*Non-nil means that gnus-uu will save articles in separate files.")
292 (defcustom gnus-uu-save-separate-articles nil
293 "*Non-nil means that gnus-uu will save articles in separate files."
294 :group 'gnus-extract
295 :type 'boolean)
296
297 (defcustom gnus-uu-be-dangerous 'ask
298 "*Specifies what to do if unusual situations arise during decoding.
299 If nil, be as conservative as possible. If t, ignore things that
300 didn't work, and overwrite existing files. Otherwise, ask each time."
301 :group 'gnus-extract
302 :type '(choice (const :tag "conservative" nil)
303 (const :tag "ask" ask)
304 (const :tag "liberal" t)))
305 235
306 ;; Internal variables 236 ;; Internal variables
307 237
308 (defvar gnus-uu-saved-article-name nil) 238 (defvar gnus-uu-saved-article-name nil)
309 239
337 (defvar gnus-uu-default-dir gnus-article-save-directory) 267 (defvar gnus-uu-default-dir gnus-article-save-directory)
338 (defvar gnus-uu-digest-from-subject nil) 268 (defvar gnus-uu-digest-from-subject nil)
339 269
340 ;; Keymaps 270 ;; Keymaps
341 271
342 (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map) 272 (gnus-define-keys
343 "p" gnus-summary-mark-as-processable 273 (gnus-uu-mark-map "P" gnus-summary-mark-map)
344 "u" gnus-summary-unmark-as-processable 274 "p" gnus-summary-mark-as-processable
345 "U" gnus-summary-unmark-all-processable 275 "u" gnus-summary-unmark-as-processable
346 "v" gnus-uu-mark-over 276 "U" gnus-summary-unmark-all-processable
347 "s" gnus-uu-mark-series 277 "v" gnus-uu-mark-over
348 "r" gnus-uu-mark-region 278 "s" gnus-uu-mark-series
349 "R" gnus-uu-mark-by-regexp 279 "r" gnus-uu-mark-region
350 "t" gnus-uu-mark-thread 280 "R" gnus-uu-mark-by-regexp
351 "T" gnus-uu-unmark-thread 281 "t" gnus-uu-mark-thread
352 "a" gnus-uu-mark-all 282 "T" gnus-uu-unmark-thread
353 "b" gnus-uu-mark-buffer 283 "a" gnus-uu-mark-all
354 "S" gnus-uu-mark-sparse 284 "b" gnus-uu-mark-buffer
355 "k" gnus-summary-kill-process-mark 285 "S" gnus-uu-mark-sparse)
356 "y" gnus-summary-yank-process-mark 286
357 "w" gnus-summary-save-process-mark 287 (gnus-define-keys
358 "i" gnus-uu-invert-processable) 288 (gnus-uu-extract-map "X" gnus-summary-mode-map)
359 289 ;;"x" gnus-uu-extract-any
360 (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map) 290 ;;"m" gnus-uu-extract-mime
361 ;;"x" gnus-uu-extract-any 291 "u" gnus-uu-decode-uu
362 ;;"m" gnus-uu-extract-mime 292 "U" gnus-uu-decode-uu-and-save
363 "u" gnus-uu-decode-uu 293 "s" gnus-uu-decode-unshar
364 "U" gnus-uu-decode-uu-and-save 294 "S" gnus-uu-decode-unshar-and-save
365 "s" gnus-uu-decode-unshar 295 "o" gnus-uu-decode-save
366 "S" gnus-uu-decode-unshar-and-save 296 "O" gnus-uu-decode-save
367 "o" gnus-uu-decode-save 297 "b" gnus-uu-decode-binhex
368 "O" gnus-uu-decode-save 298 "B" gnus-uu-decode-binhex
369 "b" gnus-uu-decode-binhex 299 "p" gnus-uu-decode-postscript
370 "B" gnus-uu-decode-binhex 300 "P" gnus-uu-decode-postscript-and-save)
371 "p" gnus-uu-decode-postscript 301
372 "P" gnus-uu-decode-postscript-and-save) 302 (gnus-define-keys
373
374 (gnus-define-keys
375 (gnus-uu-extract-view-map "v" gnus-uu-extract-map) 303 (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
376 "u" gnus-uu-decode-uu-view 304 "u" gnus-uu-decode-uu-view
377 "U" gnus-uu-decode-uu-and-save-view 305 "U" gnus-uu-decode-uu-and-save-view
378 "s" gnus-uu-decode-unshar-view 306 "s" gnus-uu-decode-unshar-view
379 "S" gnus-uu-decode-unshar-and-save-view 307 "S" gnus-uu-decode-unshar-and-save-view
387 315
388 ;; Commands. 316 ;; Commands.
389 317
390 (defun gnus-uu-decode-uu (&optional n) 318 (defun gnus-uu-decode-uu (&optional n)
391 "Uudecodes the current article." 319 "Uudecodes the current article."
392 (interactive "P") 320 (interactive "P")
393 (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n)) 321 (gnus-uu-decode-with-method 'gnus-uu-uustrip-article n))
394 322
395 (defun gnus-uu-decode-uu-and-save (n dir) 323 (defun gnus-uu-decode-uu-and-save (n dir)
396 "Decodes and saves the resulting file." 324 "Decodes and saves the resulting file."
397 (interactive 325 (interactive
419 347
420 (defun gnus-uu-decode-save (n file) 348 (defun gnus-uu-decode-save (n file)
421 "Saves the current article." 349 "Saves the current article."
422 (interactive 350 (interactive
423 (list current-prefix-arg 351 (list current-prefix-arg
424 (read-file-name 352 (read-file-name
425 (if gnus-uu-save-separate-articles 353 (if gnus-uu-save-separate-articles
426 "Save articles is dir: " 354 "Save articles is dir: "
427 "Save articles in file: ") 355 "Save articles in file: ")
428 gnus-uu-default-dir 356 gnus-uu-default-dir
429 gnus-uu-default-dir))) 357 gnus-uu-default-dir)))
436 (list current-prefix-arg 364 (list current-prefix-arg
437 (file-name-as-directory 365 (file-name-as-directory
438 (read-file-name "Unbinhex and save in dir: " 366 (read-file-name "Unbinhex and save in dir: "
439 gnus-uu-default-dir 367 gnus-uu-default-dir
440 gnus-uu-default-dir)))) 368 gnus-uu-default-dir))))
441 (setq gnus-uu-binhex-article-name 369 (setq gnus-uu-binhex-article-name
442 (make-temp-name (concat gnus-uu-work-dir "binhex"))) 370 (make-temp-name (concat gnus-uu-work-dir "binhex")))
443 (gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir)) 371 (gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir))
444 372
445 (defun gnus-uu-decode-uu-view (&optional n) 373 (defun gnus-uu-decode-uu-view (&optional n)
446 "Uudecodes and views the current article." 374 "Uudecodes and views the current article."
447 (interactive "P") 375 (interactive "P")
448 (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) 376 (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
449 (gnus-uu-decode-uu n))) 377 (gnus-uu-decode-uu n)))
450 378
451 (defun gnus-uu-decode-uu-and-save-view (n dir) 379 (defun gnus-uu-decode-uu-and-save-view (n dir)
489 "Unbinhexes and views the current article." 417 "Unbinhexes and views the current article."
490 (interactive 418 (interactive
491 (list current-prefix-arg 419 (list current-prefix-arg
492 (read-file-name "Unbinhex, view and save in dir: " 420 (read-file-name "Unbinhex, view and save in dir: "
493 gnus-uu-default-dir gnus-uu-default-dir))) 421 gnus-uu-default-dir gnus-uu-default-dir)))
494 (setq gnus-uu-binhex-article-name 422 (setq gnus-uu-binhex-article-name
495 (make-temp-name (concat gnus-uu-work-dir "binhex"))) 423 (make-temp-name (concat gnus-uu-work-dir "binhex")))
496 (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) 424 (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic)))
497 (gnus-uu-decode-binhex n file))) 425 (gnus-uu-decode-binhex n file)))
498 426
499 427
501 429
502 (defun gnus-uu-digest-mail-forward (&optional n post) 430 (defun gnus-uu-digest-mail-forward (&optional n post)
503 "Digests and forwards all articles in this series." 431 "Digests and forwards all articles in this series."
504 (interactive "P") 432 (interactive "P")
505 (let ((gnus-uu-save-in-digest t) 433 (let ((gnus-uu-save-in-digest t)
506 (file (make-temp-name (nnheader-concat gnus-uu-tmp-dir "forward"))) 434 (file (make-temp-name (concat gnus-uu-tmp-dir "forward")))
507 buf subject from newsgroups) 435 buf subject from)
508 (gnus-setup-message 'forward 436 (setq gnus-uu-digest-from-subject nil)
509 (setq gnus-uu-digest-from-subject nil) 437 (gnus-uu-decode-save n file)
510 (gnus-uu-decode-save n file) 438 (setq buf (switch-to-buffer (get-buffer-create " *gnus-uu-forward*")))
511 (setq buf (switch-to-buffer (get-buffer-create " *gnus-uu-forward*"))) 439 (gnus-add-current-to-buffer-list)
512 (gnus-add-current-to-buffer-list) 440 (erase-buffer)
513 (erase-buffer) 441 (delete-other-windows)
514 (insert-file file) 442 (insert-file file)
515 (let ((fs gnus-uu-digest-from-subject)) 443 (let ((fs gnus-uu-digest-from-subject))
516 (when fs 444 (if (not fs)
517 (setq from (caar fs) 445 ()
518 subject (gnus-simplify-subject-fuzzy (cdar fs)) 446 (setq from (caar fs)
519 fs (cdr fs)) 447 subject (gnus-simplify-subject-fuzzy (cdar fs))
520 (while (and fs (or from subject)) 448 fs (cdr fs))
521 (when from 449 (while (and fs (or from subject))
522 (unless (string= from (caar fs)) 450 (and from
523 (setq from nil))) 451 (or (string= from (caar fs))
524 (when subject 452 (setq from nil)))
525 (unless (string= (gnus-simplify-subject-fuzzy (cdar fs)) 453 (and subject
526 subject) 454 (or (string= (gnus-simplify-subject-fuzzy (cdar fs))
527 (setq subject nil))) 455 subject)
528 (setq fs (cdr fs)))) 456 (setq subject nil)))
529 (unless subject 457 (setq fs (cdr fs))))
530 (setq subject "Digested Articles")) 458 (or subject (setq subject "Digested Articles"))
531 (unless from 459 (or from (setq from "Various")))
532 (setq from 460 (goto-char (point-min))
533 (if (gnus-news-group-p gnus-newsgroup-name) 461 (and (re-search-forward "^Subject: ")
534 gnus-newsgroup-name 462 (progn
535 "Various")))) 463 (delete-region (point) (gnus-point-at-eol))
536 (goto-char (point-min)) 464 (insert subject)))
537 (when (re-search-forward "^Subject: ") 465 (goto-char (point-min))
538 (delete-region (point) (gnus-point-at-eol)) 466 (and (re-search-forward "^From: ")
539 (insert subject)) 467 (progn
540 (goto-char (point-min)) 468 (delete-region (point) (gnus-point-at-eol))
541 (when (re-search-forward "^From: ") 469 (insert from)))
542 (delete-region (point) (gnus-point-at-eol)) 470 (message-forward post)
543 (insert from))
544 (message-forward post))
545 (delete-file file) 471 (delete-file file)
546 (kill-buffer buf) 472 (kill-buffer buf)
547 (setq gnus-uu-digest-from-subject nil))) 473 (setq gnus-uu-digest-from-subject nil)))
548 474
549 (defun gnus-uu-digest-post-forward (&optional n) 475 (defun gnus-uu-digest-post-forward (&optional n)
601 527
602 (defun gnus-uu-mark-buffer () 528 (defun gnus-uu-mark-buffer ()
603 "Set the process mark on all articles in the buffer." 529 "Set the process mark on all articles in the buffer."
604 (interactive) 530 (interactive)
605 (gnus-uu-mark-region (point-min) (point-max))) 531 (gnus-uu-mark-region (point-min) (point-max)))
606 532
607 (defun gnus-uu-unmark-buffer () 533 (defun gnus-uu-unmark-buffer ()
608 "Remove the process mark on all articles in the buffer." 534 "Remove the process mark on all articles in the buffer."
609 (interactive) 535 (interactive)
610 (gnus-uu-mark-region (point-min) (point-max) t)) 536 (gnus-uu-mark-region (point-min) (point-max) t))
611 537
612 (defun gnus-uu-mark-thread () 538 (defun gnus-uu-mark-thread ()
613 "Marks all articles downwards in this thread." 539 "Marks all articles downwards in this thread."
614 (interactive) 540 (interactive)
615 (gnus-set-global-variables) 541 (gnus-set-global-variables)
616 (let ((level (gnus-summary-thread-level))) 542 (let ((level (gnus-summary-thread-level)))
626 (let ((level (gnus-summary-thread-level))) 552 (let ((level (gnus-summary-thread-level)))
627 (while (and (gnus-summary-remove-process-mark 553 (while (and (gnus-summary-remove-process-mark
628 (gnus-summary-article-number)) 554 (gnus-summary-article-number))
629 (zerop (gnus-summary-next-subject 1)) 555 (zerop (gnus-summary-next-subject 1))
630 (> (gnus-summary-thread-level) level)))) 556 (> (gnus-summary-thread-level) level))))
631 (gnus-summary-position-point))
632
633 (defun gnus-uu-invert-processable ()
634 "Invert the list of process-marked articles."
635 (let ((data gnus-newsgroup-data)
636 d number)
637 (save-excursion
638 (while data
639 (if (memq (setq number (gnus-data-number (pop data)))
640 gnus-newsgroup-processable)
641 (gnus-summary-remove-process-mark number)
642 (gnus-summary-set-process-mark number)))))
643 (gnus-summary-position-point)) 557 (gnus-summary-position-point))
644 558
645 (defun gnus-uu-mark-over (&optional score) 559 (defun gnus-uu-mark-over (&optional score)
646 "Mark all articles with a score over SCORE (the prefix.)" 560 "Mark all articles with a score over SCORE (the prefix.)"
647 (interactive "P") 561 (interactive "P")
661 "Mark all series that have some articles marked." 575 "Mark all series that have some articles marked."
662 (interactive) 576 (interactive)
663 (gnus-set-global-variables) 577 (gnus-set-global-variables)
664 (let ((marked (nreverse gnus-newsgroup-processable)) 578 (let ((marked (nreverse gnus-newsgroup-processable))
665 subject articles total headers) 579 subject articles total headers)
666 (unless marked 580 (or marked (error "No articles marked with the process mark"))
667 (error "No articles marked with the process mark"))
668 (setq gnus-newsgroup-processable nil) 581 (setq gnus-newsgroup-processable nil)
669 (save-excursion 582 (save-excursion
670 (while marked 583 (while marked
671 (and (vectorp (setq headers 584 (and (vectorp (setq headers
672 (gnus-summary-article-header (car marked)))) 585 (gnus-summary-article-header (car marked))))
673 (setq subject (mail-header-subject headers) 586 (setq subject (mail-header-subject headers)
674 articles (gnus-uu-find-articles-matching 587 articles (gnus-uu-find-articles-matching
675 (gnus-uu-reginize-string subject)) 588 (gnus-uu-reginize-string subject))
676 total (nconc total articles))) 589 total (nconc total articles)))
677 (while articles 590 (while articles
678 (gnus-summary-set-process-mark (car articles)) 591 (gnus-summary-set-process-mark (car articles))
679 (setcdr marked (delq (car articles) (cdr marked))) 592 (setcdr marked (delq (car articles) (cdr marked)))
697 (gnus-summary-goto-subject number) 610 (gnus-summary-goto-subject number)
698 (gnus-uu-mark-series)) 611 (gnus-uu-mark-series))
699 (setq data (cdr data))))) 612 (setq data (cdr data)))))
700 (gnus-summary-position-point)) 613 (gnus-summary-position-point))
701 614
702 ;; All PostScript functions written by Erik Selberg <speed@cs.washington.edu>. 615 ;; All PostScript functions written by Erik Selberg <speed@cs.washington.edu>.
703 616
704 (defun gnus-uu-decode-postscript (&optional n) 617 (defun gnus-uu-decode-postscript (&optional n)
705 "Gets postscript of the current article." 618 "Gets postscript of the current article."
706 (interactive "P") 619 (interactive "P")
707 (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article n)) 620 (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article n))
718 (list current-prefix-arg 631 (list current-prefix-arg
719 (file-name-as-directory 632 (file-name-as-directory
720 (read-file-name "Save in dir: " 633 (read-file-name "Save in dir: "
721 gnus-uu-default-dir 634 gnus-uu-default-dir
722 gnus-uu-default-dir t)))) 635 gnus-uu-default-dir t))))
723 (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article 636 (gnus-uu-decode-with-method 'gnus-uu-decode-postscript-article
724 n dir nil nil t)) 637 n dir nil nil t))
725 638
726 (defun gnus-uu-decode-postscript-and-save-view (n dir) 639 (defun gnus-uu-decode-postscript-and-save-view (n dir)
727 "Decodes, views and saves the resulting file." 640 "Decodes, views and saves the resulting file."
728 (interactive 641 (interactive
734 (gnus-uu-decode-postscript-and-save n dir))) 647 (gnus-uu-decode-postscript-and-save n dir)))
735 648
736 649
737 ;; Internal functions. 650 ;; Internal functions.
738 651
739 (defun gnus-uu-decode-with-method (method n &optional save not-insert 652 (defun gnus-uu-decode-with-method (method n &optional save not-insert
740 scan cdir) 653 scan cdir)
741 (gnus-uu-initialize scan) 654 (gnus-uu-initialize scan)
742 (when save 655 (if save (setq gnus-uu-default-dir save))
743 (setq gnus-uu-default-dir save))
744 ;; Create the directory we save to. 656 ;; Create the directory we save to.
745 (when (and scan cdir save 657 (when (and scan cdir save
746 (not (file-exists-p save))) 658 (not (file-exists-p save)))
747 (make-directory save t)) 659 (make-directory save t))
748 (let ((articles (gnus-uu-get-list-of-articles n)) 660 (let ((articles (gnus-uu-get-list-of-articles n))
749 files) 661 files)
750 (setq files (gnus-uu-grab-articles articles method t)) 662 (setq files (gnus-uu-grab-articles articles method t))
751 (let ((gnus-current-article (car articles))) 663 (let ((gnus-current-article (car articles)))
752 (when scan 664 (and scan (setq files (gnus-uu-scan-directory gnus-uu-work-dir))))
753 (setq files (gnus-uu-scan-directory gnus-uu-work-dir)))) 665 (and save (gnus-uu-save-files files save))
754 (when save 666 (if (eq gnus-uu-do-not-unpack-archives nil)
755 (gnus-uu-save-files files save))
756 (when (eq gnus-uu-do-not-unpack-archives nil)
757 (setq files (gnus-uu-unpack-files files))) 667 (setq files (gnus-uu-unpack-files files)))
758 (setq files (nreverse (gnus-uu-get-actions files))) 668 (setq files (nreverse (gnus-uu-get-actions files)))
759 (or not-insert (not gnus-insert-pseudo-articles) 669 (or not-insert (not gnus-insert-pseudo-articles)
760 (gnus-summary-insert-pseudos files save)))) 670 (gnus-summary-insert-pseudos files save))))
761 671
768 (push (list (cons 'name file) 678 (push (list (cons 'name file)
769 (cons 'article gnus-current-article)) 679 (cons 'article gnus-current-article))
770 out) 680 out)
771 (when (file-directory-p file) 681 (when (file-directory-p file)
772 (setq out (nconc (gnus-uu-scan-directory file t) out))))) 682 (setq out (nconc (gnus-uu-scan-directory file t) out)))))
773 (if rec 683 (if rec
774 out 684 out
775 (nreverse out)))) 685 (nreverse out))))
776 686
777 (defun gnus-uu-save-files (files dir) 687 (defun gnus-uu-save-files (files dir)
778 "Save FILES in DIR." 688 "Save FILES in DIR."
782 (while (setq file (cdr (assq 'name (pop files)))) 692 (while (setq file (cdr (assq 'name (pop files))))
783 (when (file-exists-p file) 693 (when (file-exists-p file)
784 (string-match reg file) 694 (string-match reg file)
785 (setq fromdir (substring file (match-end 0))) 695 (setq fromdir (substring file (match-end 0)))
786 (if (file-directory-p file) 696 (if (file-directory-p file)
787 (gnus-make-directory (concat dir fromdir)) 697 (unless (file-exists-p (concat dir fromdir))
698 (make-directory (concat dir fromdir) t))
788 (setq to-file (concat dir fromdir)) 699 (setq to-file (concat dir fromdir))
789 (when (or (not (file-exists-p to-file)) 700 (when (or (not (file-exists-p to-file))
790 (eq gnus-uu-be-dangerous t) 701 (gnus-y-or-n-p (format "%s exists; overwrite? " to-file)))
791 (and gnus-uu-be-dangerous
792 (gnus-y-or-n-p (format "%s exists; overwrite? "
793 to-file))))
794 (copy-file file to-file t t))))) 702 (copy-file file to-file t t)))))
795 (gnus-message 5 "Saved %d file%s" len (if (= len 1) "" "s")))) 703 (gnus-message 5 "Saved %d file%s" len (if (= len 1) "" "s"))))
796 704
797 ;; Functions for saving and possibly digesting articles without 705 ;; Functions for saving and possibly digesting articles without
798 ;; any decoding. 706 ;; any decoding.
799 707
800 ;; Function called by gnus-uu-grab-articles to treat each article. 708 ;; Function called by gnus-uu-grab-articles to treat each article.
801 (defun gnus-uu-save-article (buffer in-state) 709 (defun gnus-uu-save-article (buffer in-state)
802 (cond 710 (cond
803 (gnus-uu-save-separate-articles 711 (gnus-uu-save-separate-articles
804 (save-excursion 712 (save-excursion
805 (set-buffer buffer) 713 (set-buffer buffer)
806 (gnus-write-buffer 714 (write-region 1 (point-max) (concat gnus-uu-saved-article-name
807 (concat gnus-uu-saved-article-name gnus-current-article)) 715 gnus-current-article))
808 (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) 716 (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin))
809 ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name 717 ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name
810 'begin 'end)) 718 'begin 'end))
811 ((eq in-state 'last) (list 'end)) 719 ((eq in-state 'last) (list 'end))
812 (t (list 'middle))))) 720 (t (list 'middle)))))
813 ((not gnus-uu-save-in-digest) 721 ((not gnus-uu-save-in-digest)
814 (save-excursion 722 (save-excursion
815 (set-buffer buffer) 723 (set-buffer buffer)
816 (write-region (point-min) (point-max) gnus-uu-saved-article-name t) 724 (write-region 1 (point-max) gnus-uu-saved-article-name t)
817 (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) 725 (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin))
818 ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name 726 ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name
819 'begin 'end)) 727 'begin 'end))
820 ((eq in-state 'last) (list 'end)) 728 ((eq in-state 'last) (list 'end))
821 (t (list 'middle))))) 729 (t (list 'middle)))))
822 (t 730 (t
823 (let ((header (gnus-summary-article-header))) 731 (let ((header (gnus-summary-article-header)))
824 (push (cons (mail-header-from header) 732 (setq gnus-uu-digest-from-subject
825 (mail-header-subject header)) 733 (cons (cons (mail-header-from header)
826 gnus-uu-digest-from-subject)) 734 (mail-header-subject header))
735 gnus-uu-digest-from-subject)))
827 (let ((name (file-name-nondirectory gnus-uu-saved-article-name)) 736 (let ((name (file-name-nondirectory gnus-uu-saved-article-name))
828 (delim (concat "^" (make-string 30 ?-) "$")) 737 (delim (concat "^" (make-string 30 ?-) "$"))
829 beg subj headers headline sorthead body end-string state) 738 beg subj headers headline sorthead body end-string state)
830 (if (or (eq in-state 'first) 739 (if (or (eq in-state 'first)
831 (eq in-state 'first-and-last)) 740 (eq in-state 'first-and-last))
832 (progn 741 (progn
833 (setq state (list 'begin)) 742 (setq state (list 'begin))
834 (save-excursion (set-buffer (get-buffer-create "*gnus-uu-body*")) 743 (save-excursion (set-buffer (get-buffer-create "*gnus-uu-body*"))
835 (erase-buffer)) 744 (erase-buffer))
836 (save-excursion 745 (save-excursion
837 (set-buffer (get-buffer-create "*gnus-uu-pre*")) 746 (set-buffer (get-buffer-create "*gnus-uu-pre*"))
838 (erase-buffer) 747 (erase-buffer)
839 (insert (format 748 (insert (format
840 "Date: %s\nFrom: %s\nSubject: %s Digest\n\nTopics:\n" 749 "Date: %s\nFrom: %s\nSubject: %s Digest\n\nTopics:\n"
841 (current-time-string) name name)))) 750 (current-time-string) name name))))
842 (when (not (eq in-state 'end)) 751 (if (not (eq in-state 'end))
843 (setq state (list 'middle)))) 752 (setq state (list 'middle))))
844 (save-excursion 753 (save-excursion
845 (set-buffer (get-buffer "*gnus-uu-body*")) 754 (set-buffer (get-buffer "*gnus-uu-body*"))
846 (goto-char (setq beg (point-max))) 755 (goto-char (setq beg (point-max)))
847 (save-excursion 756 (save-excursion
848 (save-restriction 757 (save-restriction
867 (while headers 776 (while headers
868 (setq headline (car headers)) 777 (setq headline (car headers))
869 (setq headers (cdr headers)) 778 (setq headers (cdr headers))
870 (goto-char (point-min)) 779 (goto-char (point-min))
871 (while (re-search-forward headline nil t) 780 (while (re-search-forward headline nil t)
872 (setq sorthead 781 (setq sorthead
873 (concat sorthead 782 (concat sorthead
874 (buffer-substring 783 (buffer-substring
875 (match-beginning 0) 784 (match-beginning 0)
876 (or (and (re-search-forward "^[^ \t]" nil t) 785 (or (and (re-search-forward "^[^ \t]" nil t)
877 (1- (point))) 786 (1- (point)))
878 (progn (forward-line 1) (point))))))))) 787 (progn (forward-line 1) (point)))))))))
879 (widen))) 788 (widen)))
880 (insert sorthead) (goto-char (point-max)) 789 (insert sorthead) (goto-char (point-max))
881 (insert body) (goto-char (point-max)) 790 (insert body) (goto-char (point-max))
882 (insert (concat "\n" (make-string 30 ?-) "\n\n")) 791 (insert (concat "\n" (make-string 30 ?-) "\n\n"))
883 (goto-char beg) 792 (goto-char beg)
884 (when (re-search-forward "^Subject: \\(.*\\)$" nil t) 793 (if (re-search-forward "^Subject: \\(.*\\)$" nil t)
885 (setq subj (buffer-substring (match-beginning 1) (match-end 1))) 794 (progn
886 (save-excursion 795 (setq subj (buffer-substring (match-beginning 1) (match-end 1)))
887 (set-buffer (get-buffer "*gnus-uu-pre*")) 796 (save-excursion
888 (insert (format " %s\n" subj))))) 797 (set-buffer (get-buffer "*gnus-uu-pre*"))
889 (when (or (eq in-state 'last) 798 (insert (format " %s\n" subj))))))
890 (eq in-state 'first-and-last)) 799 (if (or (eq in-state 'last)
891 (save-excursion 800 (eq in-state 'first-and-last))
892 (set-buffer (get-buffer "*gnus-uu-pre*")) 801 (progn
893 (insert (format "\n\n%s\n\n" (make-string 70 ?-))) 802 (save-excursion
894 (gnus-write-buffer gnus-uu-saved-article-name)) 803 (set-buffer (get-buffer "*gnus-uu-pre*"))
895 (save-excursion 804 (insert (format "\n\n%s\n\n" (make-string 70 ?-)))
896 (set-buffer (get-buffer "*gnus-uu-body*")) 805 (write-region 1 (point-max) gnus-uu-saved-article-name))
897 (goto-char (point-max)) 806 (save-excursion
898 (insert 807 (set-buffer (get-buffer "*gnus-uu-body*"))
899 (concat (setq end-string (format "End of %s Digest" name)) 808 (goto-char (point-max))
900 "\n")) 809 (insert
901 (insert (concat (make-string (length end-string) ?*) "\n")) 810 (concat (setq end-string (format "End of %s Digest" name))
902 (write-region 811 "\n"))
903 (point-min) (point-max) gnus-uu-saved-article-name t)) 812 (insert (concat (make-string (length end-string) ?*) "\n"))
904 (kill-buffer (get-buffer "*gnus-uu-pre*")) 813 (write-region 1 (point-max) gnus-uu-saved-article-name t))
905 (kill-buffer (get-buffer "*gnus-uu-body*")) 814 (kill-buffer (get-buffer "*gnus-uu-pre*"))
906 (push 'end state)) 815 (kill-buffer (get-buffer "*gnus-uu-body*"))
816 (setq state (cons 'end state))))
907 (if (memq 'begin state) 817 (if (memq 'begin state)
908 (cons gnus-uu-saved-article-name state) 818 (cons gnus-uu-saved-article-name state)
909 state))))) 819 state)))))
910 820
911 ;; Binhex treatment - not very advanced. 821 ;; Binhex treatment - not very advanced.
912 822
913 (defconst gnus-uu-binhex-body-line 823 (defconst gnus-uu-binhex-body-line
914 "^[^:]...............................................................$") 824 "^[^:]...............................................................$")
915 (defconst gnus-uu-binhex-begin-line 825 (defconst gnus-uu-binhex-begin-line
916 "^:...............................................................$") 826 "^:...............................................................$")
917 (defconst gnus-uu-binhex-end-line 827 (defconst gnus-uu-binhex-end-line
918 ":$") 828 ":$")
919 829
920 (defun gnus-uu-binhex-article (buffer in-state) 830 (defun gnus-uu-binhex-article (buffer in-state)
921 (let (state start-char) 831 (let (state start-char)
922 (save-excursion 832 (save-excursion
923 (set-buffer buffer) 833 (set-buffer buffer)
924 (widen) 834 (widen)
925 (goto-char (point-min)) 835 (goto-char (point-min))
926 (when (not (re-search-forward gnus-uu-binhex-begin-line nil t)) 836 (if (not (re-search-forward gnus-uu-binhex-begin-line nil t))
927 (when (not (re-search-forward gnus-uu-binhex-body-line nil t)) 837 (if (not (re-search-forward gnus-uu-binhex-body-line nil t))
928 (setq state (list 'wrong-type)))) 838 (setq state (list 'wrong-type))))
929 839
930 (if (memq 'wrong-type state) 840 (if (memq 'wrong-type state)
931 () 841 ()
932 (beginning-of-line) 842 (beginning-of-line)
933 (setq start-char (point)) 843 (setq start-char (point))
935 (progn 845 (progn
936 (setq state (list 'begin)) 846 (setq state (list 'begin))
937 (write-region 1 1 gnus-uu-binhex-article-name)) 847 (write-region 1 1 gnus-uu-binhex-article-name))
938 (setq state (list 'middle))) 848 (setq state (list 'middle)))
939 (goto-char (point-max)) 849 (goto-char (point-max))
940 (re-search-backward (concat gnus-uu-binhex-body-line "\\|" 850 (re-search-backward (concat gnus-uu-binhex-body-line "\\|"
941 gnus-uu-binhex-end-line) 851 gnus-uu-binhex-end-line) nil t)
942 nil t) 852 (if (looking-at gnus-uu-binhex-end-line)
943 (when (looking-at gnus-uu-binhex-end-line) 853 (setq state (if (memq 'begin state)
944 (setq state (if (memq 'begin state) 854 (cons 'end state)
945 (cons 'end state) 855 (list 'end))))
946 (list 'end))))
947 (beginning-of-line) 856 (beginning-of-line)
948 (forward-line 1) 857 (forward-line 1)
949 (when (file-exists-p gnus-uu-binhex-article-name) 858 (if (file-exists-p gnus-uu-binhex-article-name)
950 (append-to-file start-char (point) gnus-uu-binhex-article-name)))) 859 (append-to-file start-char (point) gnus-uu-binhex-article-name))))
951 (if (memq 'begin state) 860 (if (memq 'begin state)
952 (cons gnus-uu-binhex-article-name state) 861 (cons gnus-uu-binhex-article-name state)
953 state))) 862 state)))
954 863
955 ;; PostScript 864 ;; PostScript
972 (setq file-name (concat gnus-uu-work-dir 881 (setq file-name (concat gnus-uu-work-dir
973 (cdr gnus-article-current) ".ps")) 882 (cdr gnus-article-current) ".ps"))
974 (write-region (point-min) (point-max) file-name) 883 (write-region (point-min) (point-max) file-name)
975 (setq state (list file-name 'begin 'end))))) 884 (setq state (list file-name 'begin 'end)))))
976 state)) 885 state))
977 886
978 887
979 ;; Find actions. 888 ;; Find actions.
980 889
981 (defun gnus-uu-get-actions (files) 890 (defun gnus-uu-get-actions (files)
982 (let ((ofiles files) 891 (let ((ofiles files)
983 action name) 892 action name)
984 (while files 893 (while files
985 (setq name (cdr (assq 'name (car files)))) 894 (setq name (cdr (assq 'name (car files))))
986 (and 895 (and
987 (setq action (gnus-uu-get-action name)) 896 (setq action (gnus-uu-get-action name))
988 (setcar files (nconc (list (if (string= action "gnus-uu-archive") 897 (setcar files (nconc (list (if (string= action "gnus-uu-archive")
989 (cons 'action "file") 898 (cons 'action "file")
990 (cons 'action action)) 899 (cons 'action action))
991 (cons 'execute (gnus-uu-command 900 (cons 'execute (gnus-uu-command
994 (setq files (cdr files))) 903 (setq files (cdr files)))
995 ofiles)) 904 ofiles))
996 905
997 (defun gnus-uu-get-action (file-name) 906 (defun gnus-uu-get-action (file-name)
998 (let (action) 907 (let (action)
999 (setq action 908 (setq action
1000 (gnus-uu-choose-action 909 (gnus-uu-choose-action
1001 file-name 910 file-name
1002 (append 911 (append
1003 gnus-uu-user-view-rules 912 gnus-uu-user-view-rules
1004 (if gnus-uu-ignore-default-view-rules 913 (if gnus-uu-ignore-default-view-rules
1005 nil 914 nil
1006 gnus-uu-default-view-rules) 915 gnus-uu-default-view-rules)
1007 gnus-uu-user-view-rules-end))) 916 gnus-uu-user-view-rules-end)))
1008 (when (and (not (string= (or action "") "gnus-uu-archive")) 917 (if (and (not (string= (or action "") "gnus-uu-archive"))
1009 gnus-uu-view-with-metamail) 918 gnus-uu-view-with-metamail)
1010 (when (setq action 919 (if (setq action
1011 (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list)) 920 (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list))
1012 (setq action (format "metamail -d -b -c \"%s\"" action)))) 921 (setq action (format "metamail -d -b -c \"%s\"" action))))
1013 action)) 922 action))
1014 923
1015 924
1016 ;; Functions for treating subjects and collecting series. 925 ;; Functions for treating subjects and collecting series.
1017 926
1018 (defun gnus-uu-reginize-string (string) 927 (defun gnus-uu-reginize-string (string)
1019 ;; Takes a string and puts a \ in front of every special character; 928 ;; Takes a string and puts a \ in front of every special character;
1020 ;; ignores any leading "version numbers" thingies that they use in 929 ;; ignores any leading "version numbers" thingies that they use in
1021 ;; the comp.binaries groups, and either replaces anything that looks 930 ;; the comp.binaries groups, and either replaces anything that looks
1022 ;; like "2/3" with "[0-9]+/[0-9]+" or, if it can't find something 931 ;; like "2/3" with "[0-9]+/[0-9]+" or, if it can't find something
1023 ;; like that, replaces the last two numbers with "[0-9]+". This, in 932 ;; like that, replaces the last two numbers with "[0-9]+". This, in
1024 ;; my experience, should get most postings of a series. 933 ;; my experience, should get most postings of a series.
1025 (let ((count 2) 934 (let ((count 2)
1026 (vernum "v[0-9]+[a-z][0-9]+:") 935 (vernum "v[0-9]+[a-z][0-9]+:")
1027 beg) 936 beg)
1028 (save-excursion 937 (save-excursion
1032 (insert (regexp-quote string)) 941 (insert (regexp-quote string))
1033 (setq beg 1) 942 (setq beg 1)
1034 943
1035 (setq case-fold-search nil) 944 (setq case-fold-search nil)
1036 (goto-char (point-min)) 945 (goto-char (point-min))
1037 (when (looking-at vernum) 946 (if (looking-at vernum)
1038 (replace-match vernum t t) 947 (progn
1039 (setq beg (length vernum))) 948 (replace-match vernum t t)
949 (setq beg (length vernum))))
1040 950
1041 (goto-char beg) 951 (goto-char beg)
1042 (if (re-search-forward "[ \t]*[0-9]+/[0-9]+" nil t) 952 (if (re-search-forward "[ \t]*[0-9]+/[0-9]+" nil t)
1043 (replace-match " [0-9]+/[0-9]+") 953 (replace-match " [0-9]+/[0-9]+")
1044 954
1045 (goto-char beg) 955 (goto-char beg)
1046 (if (re-search-forward "[0-9]+[ \t]*of[ \t]*[0-9]+" nil t) 956 (if (re-search-forward "[0-9]+[ \t]*of[ \t]*[0-9]+" nil t)
1047 (replace-match "[0-9]+ of [0-9]+") 957 (replace-match "[0-9]+ of [0-9]+")
1048 958
1049 (end-of-line) 959 (end-of-line)
1050 (if (re-search-backward "\\([^0-9]\\)[0-9]+\\([^0-9]+\\)[0-9]+" 960 (while (and (re-search-backward "[0-9]" nil t) (> count 0))
1051 nil t) 961 (while (and
1052 (replace-match "\\1[0-9]+\\2[0-9]+" t nil nil nil)))) 962 (looking-at "[0-9]")
963 (< 1 (goto-char (1- (point))))))
964 (re-search-forward "[0-9]+" nil t)
965 (replace-match "[0-9]+")
966 (backward-char 5)
967 (setq count (1- count)))))
1053 968
1054 (goto-char beg) 969 (goto-char beg)
1055 (while (re-search-forward "[ \t]+" nil t) 970 (while (re-search-forward "[ \t]+" nil t)
1056 (replace-match "[ \t]*" t t)) 971 (replace-match "[ \t]*" t t))
1057 972
1059 974
1060 (defun gnus-uu-get-list-of-articles (n) 975 (defun gnus-uu-get-list-of-articles (n)
1061 ;; If N is non-nil, the article numbers of the N next articles 976 ;; If N is non-nil, the article numbers of the N next articles
1062 ;; will be returned. 977 ;; will be returned.
1063 ;; If any articles have been marked as processable, they will be 978 ;; If any articles have been marked as processable, they will be
1064 ;; returned. 979 ;; returned.
1065 ;; Failing that, articles that have subjects that are part of the 980 ;; Failing that, articles that have subjects that are part of the
1066 ;; same "series" as the current will be returned. 981 ;; same "series" as the current will be returned.
1067 (let (articles) 982 (let (articles)
1068 (cond 983 (cond
1069 (n 984 (n
1070 (setq n (prefix-numeric-value n))
1071 (let ((backward (< n 0)) 985 (let ((backward (< n 0))
1072 (n (abs n))) 986 (n (abs n)))
1073 (save-excursion 987 (save-excursion
1074 (while (and (> n 0) 988 (while (and (> n 0)
1075 (push (gnus-summary-article-number) 989 (setq articles (cons (gnus-summary-article-number)
1076 articles) 990 articles))
1077 (gnus-summary-search-forward nil nil backward)) 991 (gnus-summary-search-forward nil nil backward))
1078 (setq n (1- n)))) 992 (setq n (1- n))))
1079 (nreverse articles))) 993 (nreverse articles)))
1080 (gnus-newsgroup-processable 994 (gnus-newsgroup-processable
1081 (reverse gnus-newsgroup-processable)) 995 (reverse gnus-newsgroup-processable))
1083 (gnus-uu-find-articles-matching))))) 997 (gnus-uu-find-articles-matching)))))
1084 998
1085 (defun gnus-uu-string< (l1 l2) 999 (defun gnus-uu-string< (l1 l2)
1086 (string< (car l1) (car l2))) 1000 (string< (car l1) (car l2)))
1087 1001
1088 (defun gnus-uu-find-articles-matching 1002 (defun gnus-uu-find-articles-matching
1089 (&optional subject only-unread do-not-translate) 1003 (&optional subject only-unread do-not-translate)
1090 ;; Finds all articles that matches the regexp SUBJECT. If it is 1004 ;; Finds all articles that matches the regexp SUBJECT. If it is
1091 ;; nil, the current article name will be used. If ONLY-UNREAD is 1005 ;; nil, the current article name will be used. If ONLY-UNREAD is
1092 ;; non-nil, only unread articles are chosen. If DO-NOT-TRANSLATE is 1006 ;; non-nil, only unread articles are chosen. If DO-NOT-TRANSLATE is
1093 ;; non-nil, article names are not equalized before sorting. 1007 ;; non-nil, article names are not equalized before sorting.
1094 (let ((subject (or subject 1008 (let ((subject (or subject
1095 (gnus-uu-reginize-string (gnus-summary-article-subject)))) 1009 (gnus-uu-reginize-string (gnus-summary-article-subject))))
1096 list-of-subjects) 1010 list-of-subjects)
1097 (save-excursion 1011 (save-excursion
1098 (if (not subject) 1012 (if (not subject)
1099 () 1013 ()
1109 gnus-unread-mark) 1023 gnus-unread-mark)
1110 (= mark gnus-ticked-mark) 1024 (= mark gnus-ticked-mark)
1111 (= mark gnus-dormant-mark)) 1025 (= mark gnus-dormant-mark))
1112 (setq subj (mail-header-subject (gnus-data-header d))) 1026 (setq subj (mail-header-subject (gnus-data-header d)))
1113 (string-match subject subj) 1027 (string-match subject subj)
1114 (push (cons subj (gnus-data-number d)) 1028 (setq list-of-subjects
1115 list-of-subjects)))) 1029 (cons (cons subj (gnus-data-number d))
1030 list-of-subjects)))))
1116 1031
1117 ;; Expand numbers, sort, and return the list of article 1032 ;; Expand numbers, sort, and return the list of article
1118 ;; numbers. 1033 ;; numbers.
1119 (mapcar (lambda (sub) (cdr sub)) 1034 (mapcar (lambda (sub) (cdr sub))
1120 (sort (gnus-uu-expand-numbers 1035 (sort (gnus-uu-expand-numbers
1121 list-of-subjects 1036 list-of-subjects
1122 (not do-not-translate)) 1037 (not do-not-translate))
1123 'gnus-uu-string<)))))) 1038 'gnus-uu-string<))))))
1124 1039
1125 (defun gnus-uu-expand-numbers (string-list &optional translate) 1040 (defun gnus-uu-expand-numbers (string-list &optional translate)
1126 ;; Takes a list of strings and "expands" all numbers in all the 1041 ;; Takes a list of strings and "expands" all numbers in all the
1127 ;; strings. That is, this function makes all numbers equal length by 1042 ;; strings. That is, this function makes all numbers equal length by
1128 ;; prepending lots of zeroes before each number. This is to ease later 1043 ;; prepending lots of zeroes before each number. This is to ease later
1129 ;; sorting to find out what sequence the articles are supposed to be 1044 ;; sorting to find out what sequence the articles are supposed to be
1130 ;; decoded in. Returns the list of expanded strings. 1045 ;; decoded in. Returns the list of expanded strings.
1131 (let ((out-list string-list) 1046 (let ((out-list string-list)
1132 string) 1047 string)
1133 (save-excursion 1048 (save-excursion
1134 (set-buffer (get-buffer-create gnus-uu-output-buffer-name)) 1049 (set-buffer (get-buffer-create gnus-uu-output-buffer-name))
1135 (buffer-disable-undo (current-buffer)) 1050 (buffer-disable-undo (current-buffer))
1140 (goto-char (point-min)) 1055 (goto-char (point-min))
1141 (while (re-search-forward "[ \t]+" nil t) 1056 (while (re-search-forward "[ \t]+" nil t)
1142 (replace-match " ")) 1057 (replace-match " "))
1143 ;; Translate all characters to "a". 1058 ;; Translate all characters to "a".
1144 (goto-char (point-min)) 1059 (goto-char (point-min))
1145 (when translate 1060 (if translate
1146 (while (re-search-forward "[A-Za-z]" nil t) 1061 (while (re-search-forward "[A-Za-z]" nil t)
1147 (replace-match "a" t t))) 1062 (replace-match "a" t t)))
1148 ;; Expand numbers. 1063 ;; Expand numbers.
1149 (goto-char (point-min)) 1064 (goto-char (point-min))
1150 (while (re-search-forward "[0-9]+" nil t) 1065 (while (re-search-forward "[0-9]+" nil t)
1151 (replace-match 1066 (replace-match
1152 (format "%06d" 1067 (format "%06d"
1153 (string-to-int (buffer-substring 1068 (string-to-int (buffer-substring
1154 (match-beginning 0) (match-end 0)))))) 1069 (match-beginning 0) (match-end 0))))))
1155 (setq string (buffer-substring 1 (point-max))) 1070 (setq string (buffer-substring 1 (point-max)))
1156 (setcar (car string-list) string) 1071 (setcar (car string-list) string)
1157 (setq string-list (cdr string-list)))) 1072 (setq string-list (cdr string-list))))
1158 out-list)) 1073 out-list))
1161 ;; `gnus-uu-grab-articles' is the general multi-article treatment 1076 ;; `gnus-uu-grab-articles' is the general multi-article treatment
1162 ;; function. It takes a list of articles to be grabbed and a function 1077 ;; function. It takes a list of articles to be grabbed and a function
1163 ;; to apply to each article. 1078 ;; to apply to each article.
1164 ;; 1079 ;;
1165 ;; The function to be called should take two parameters. The first 1080 ;; The function to be called should take two parameters. The first
1166 ;; parameter is the article buffer. The function should leave the 1081 ;; parameter is the article buffer. The function should leave the
1167 ;; result, if any, in this buffer. Most treatment functions will just 1082 ;; result, if any, in this buffer. Most treatment functions will just
1168 ;; generate files... 1083 ;; generate files...
1169 ;; 1084 ;;
1170 ;; The second parameter is the state of the list of articles, and can 1085 ;; The second parameter is the state of the list of articles, and can
1171 ;; have four values: `first', `middle', `last' and `first-and-last'. 1086 ;; have four values: `first', `middle', `last' and `first-and-last'.
1172 ;; 1087 ;;
1173 ;; The function should return a list. The list may contain the 1088 ;; The function should return a list. The list may contain the
1174 ;; following symbols: 1089 ;; following symbols:
1175 ;; `error' if an error occurred 1090 ;; `error' if an error occurred
1176 ;; `begin' if the beginning of an encoded file has been received 1091 ;; `begin' if the beginning of an encoded file has been received
1177 ;; If the list returned contains a `begin', the first element of 1092 ;; If the list returned contains a `begin', the first element of
1178 ;; the list *must* be a string with the file name of the decoded 1093 ;; the list *must* be a string with the file name of the decoded
1187 (defun gnus-uu-unmark-list-of-grabbed (&optional dont-unmark-last-article) 1102 (defun gnus-uu-unmark-list-of-grabbed (&optional dont-unmark-last-article)
1188 (let (art) 1103 (let (art)
1189 (if (not (and gnus-uu-has-been-grabbed 1104 (if (not (and gnus-uu-has-been-grabbed
1190 gnus-uu-unmark-articles-not-decoded)) 1105 gnus-uu-unmark-articles-not-decoded))
1191 () 1106 ()
1192 (when dont-unmark-last-article 1107 (if dont-unmark-last-article
1193 (setq art (car gnus-uu-has-been-grabbed)) 1108 (progn
1194 (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))) 1109 (setq art (car gnus-uu-has-been-grabbed))
1110 (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))))
1195 (while gnus-uu-has-been-grabbed 1111 (while gnus-uu-has-been-grabbed
1196 (gnus-summary-tick-article (car gnus-uu-has-been-grabbed) t) 1112 (gnus-summary-tick-article (car gnus-uu-has-been-grabbed) t)
1197 (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))) 1113 (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed)))
1198 (when dont-unmark-last-article 1114 (if dont-unmark-last-article
1199 (setq gnus-uu-has-been-grabbed (list art)))))) 1115 (setq gnus-uu-has-been-grabbed (list art))))))
1200 1116
1201 ;; This function takes a list of articles and a function to apply to 1117 ;; This function takes a list of articles and a function to apply to
1202 ;; each article grabbed. 1118 ;; each article grabbed.
1203 ;; 1119 ;;
1204 ;; This function returns a list of files decoded if the grabbing and 1120 ;; This function returns a list of files decoded if the grabbing and
1205 ;; the process-function has been successful and nil otherwise. 1121 ;; the process-function has been successful and nil otherwise.
1206 (defun gnus-uu-grab-articles (articles process-function 1122 (defun gnus-uu-grab-articles (articles process-function
1207 &optional sloppy limit no-errors) 1123 &optional sloppy limit no-errors)
1208 (let ((state 'first) 1124 (let ((state 'first)
1209 has-been-begin article result-file result-files process-state 1125 has-been-begin article result-file result-files process-state
1210 gnus-summary-display-article-function 1126 gnus-summary-display-article-function
1211 gnus-article-display-hook gnus-article-prepare-hook 1127 gnus-article-display-hook gnus-article-prepare-hook
1212 article-series files) 1128 article-series files)
1213 1129
1214 (while (and articles 1130 (while (and articles
1215 (not (memq 'error process-state)) 1131 (not (memq 'error process-state))
1216 (or sloppy 1132 (or sloppy
1217 (not (memq 'end process-state)))) 1133 (not (memq 'end process-state))))
1218 1134
1219 (setq article (pop articles)) 1135 (setq article (pop articles))
1220 (push article article-series) 1136 (push article article-series)
1221 1137
1222 (unless articles 1138 (unless articles
1223 (if (eq state 'first) 1139 (if (eq state 'first)
1224 (setq state 'first-and-last) 1140 (setq state 'first-and-last)
1225 (setq state 'last))) 1141 (setq state 'last)))
1226 1142
1227 (let ((part (gnus-uu-part-number article))) 1143 (let ((part (gnus-uu-part-number article)))
1228 (gnus-message 6 "Getting article %d%s..." 1144 (gnus-message 6 "Getting article %d%s..."
1229 article (if (string= part "") "" (concat ", " part)))) 1145 article (if (string= part "") "" (concat ", " part))))
1230 (gnus-summary-display-article article) 1146 (gnus-summary-display-article article)
1231 1147
1232 ;; Push the article to the processing function. 1148 ;; Push the article to the processing function.
1233 (save-excursion 1149 (save-excursion
1234 (set-buffer gnus-original-article-buffer) 1150 (set-buffer gnus-original-article-buffer)
1235 (let ((buffer-read-only nil)) 1151 (let ((buffer-read-only nil))
1236 (save-excursion 1152 (save-excursion
1237 (set-buffer gnus-summary-buffer) 1153 (set-buffer gnus-summary-buffer)
1238 (setq process-state 1154 (setq process-state
1239 (funcall process-function 1155 (funcall process-function
1240 gnus-original-article-buffer state))))) 1156 gnus-original-article-buffer state)))))
1241 1157
1242 (gnus-summary-remove-process-mark article) 1158 (gnus-summary-remove-process-mark article)
1243 1159
1244 ;; If this is the beginning of a decoded file, we push it 1160 ;; If this is the beginning of a decoded file, we push it
1245 ;; on to a list. 1161 ;; on to a list.
1246 (when (or (memq 'begin process-state) 1162 (when (or (memq 'begin process-state)
1247 (and (or (eq state 'first) 1163 (and (or (eq state 'first)
1248 (eq state 'first-and-last)) 1164 (eq state 'first-and-last))
1249 (memq 'ok process-state))) 1165 (memq 'ok process-state)))
1250 (when has-been-begin 1166 (if has-been-begin
1251 ;; If there is a `result-file' here, that means that the 1167 ;; If there is a `result-file' here, that means that the
1252 ;; file was unsuccessfully decoded, so we delete it. 1168 ;; file was unsuccessfully decoded, so we delete it.
1253 (when (and result-file 1169 (when (and result-file
1254 (file-exists-p result-file) 1170 (file-exists-p result-file))
1255 (not gnus-uu-be-dangerous) 1171 (delete-file result-file)))
1256 (or (eq gnus-uu-be-dangerous t)
1257 (gnus-y-or-n-p
1258 (format "Delete unsuccessfully decoded file %s"
1259 result-file))))
1260 (delete-file result-file)))
1261 (when (memq 'begin process-state) 1172 (when (memq 'begin process-state)
1262 (setq result-file (car process-state))) 1173 (setq result-file (car process-state)))
1263 (setq has-been-begin t)) 1174 (setq has-been-begin t))
1264 1175
1265 ;; Check whether we have decoded one complete file. 1176 ;; Check whether we have decoded one complete file.
1279 (let ((funcs gnus-uu-grabbed-file-functions)) 1190 (let ((funcs gnus-uu-grabbed-file-functions))
1280 (unless (listp funcs) 1191 (unless (listp funcs)
1281 (setq funcs (list funcs))) 1192 (setq funcs (list funcs)))
1282 (while funcs 1193 (while funcs
1283 (funcall (pop funcs) result-file)))) 1194 (funcall (pop funcs) result-file))))
1284 (setq result-file nil)
1285 ;; Check whether we have decoded enough articles. 1195 ;; Check whether we have decoded enough articles.
1286 (and limit (= (length result-files) limit) 1196 (and limit (= (length result-files) limit)
1287 (setq articles nil))) 1197 (setq articles nil)))
1288 1198
1289 ;; If this is the last article to be decoded, and 1199 ;; If this is the last article to be decoded, and
1290 ;; we still haven't reached the end, then we delete 1200 ;; we still haven't reached the end, then we delete
1291 ;; the partially decoded file. 1201 ;; the partially decoded file.
1292 (and (or (eq state 'last) (eq state 'first-and-last)) 1202 (and (or (eq state 'last) (eq state 'first-and-last))
1293 (not (memq 'end process-state)) 1203 (not (memq 'end process-state))
1294 result-file 1204 result-file
1295 (file-exists-p result-file) 1205 (file-exists-p result-file)
1296 (not gnus-uu-be-dangerous)
1297 (or (eq gnus-uu-be-dangerous t)
1298 (gnus-y-or-n-p (format "Delete incomplete file %s? " result-file)))
1299 (delete-file result-file)) 1206 (delete-file result-file))
1300 1207
1301 ;; If this was a file of the wrong sort, then 1208 ;; If this was a file of the wrong sort, then
1302 (when (and (or (memq 'wrong-type process-state) 1209 (when (and (or (memq 'wrong-type process-state)
1303 (memq 'error process-state)) 1210 (memq 'error process-state))
1304 gnus-uu-unmark-articles-not-decoded) 1211 gnus-uu-unmark-articles-not-decoded)
1305 (gnus-summary-tick-article article t)) 1212 (gnus-summary-tick-article article t))
1306 1213
1321 (cond 1228 (cond
1322 ((not has-been-begin) 1229 ((not has-been-begin)
1323 (gnus-message 2 "Wrong type file")) 1230 (gnus-message 2 "Wrong type file"))
1324 ((memq 'error process-state) 1231 ((memq 'error process-state)
1325 (gnus-message 2 "An error occurred during decoding")) 1232 (gnus-message 2 "An error occurred during decoding"))
1326 ((not (or (memq 'ok process-state) 1233 ((not (or (memq 'ok process-state)
1327 (memq 'end process-state))) 1234 (memq 'end process-state)))
1328 (gnus-message 2 "End of articles reached before end of file"))) 1235 (gnus-message 2 "End of articles reached before end of file")))
1329 ;; Make unsuccessfully decoded articles unread. 1236 ;; Make unsuccessfully decoded articles unread.
1330 (when gnus-uu-unmark-articles-not-decoded 1237 (when gnus-uu-unmark-articles-not-decoded
1331 (while article-series 1238 (while article-series
1352 (make-symbolic-link to-file file))))) 1259 (make-symbolic-link to-file file)))))
1353 1260
1354 (defun gnus-uu-part-number (article) 1261 (defun gnus-uu-part-number (article)
1355 (let* ((header (gnus-summary-article-header article)) 1262 (let* ((header (gnus-summary-article-header article))
1356 (subject (and header (mail-header-subject header)))) 1263 (subject (and header (mail-header-subject header))))
1357 (if (and subject 1264 (if (and subject
1358 (string-match "[0-9]+ */[0-9]+\\|[0-9]+ * of *[0-9]+" subject)) 1265 (string-match "[0-9]+ */[0-9]+\\|[0-9]+ * of *[0-9]+" subject))
1359 (match-string 0 subject) 1266 (match-string 0 subject)
1360 ""))) 1267 "")))
1361 1268
1362 (defun gnus-uu-uudecode-sentinel (process event) 1269 (defun gnus-uu-uudecode-sentinel (process event)
1365 (defun gnus-uu-uustrip-article (process-buffer in-state) 1272 (defun gnus-uu-uustrip-article (process-buffer in-state)
1366 ;; Uudecodes a file asynchronously. 1273 ;; Uudecodes a file asynchronously.
1367 (save-excursion 1274 (save-excursion
1368 (set-buffer process-buffer) 1275 (set-buffer process-buffer)
1369 (let ((state (list 'wrong-type)) 1276 (let ((state (list 'wrong-type))
1370 process-connection-type case-fold-search buffer-read-only 1277 process-connection-type case-fold-search buffer-read-only
1371 files start-char) 1278 files start-char)
1372 (goto-char (point-min)) 1279 (goto-char (point-min))
1373 1280
1374 ;; Deal with ^M at the end of the lines. 1281 ;; Deal with ^M at the end of the lines.
1375 (when gnus-uu-kill-carriage-return 1282 (when gnus-uu-kill-carriage-return
1386 1293
1387 (if (not (looking-at gnus-uu-begin-string)) 1294 (if (not (looking-at gnus-uu-begin-string))
1388 (setq state (list 'middle)) 1295 (setq state (list 'middle))
1389 ;; This is the beginning of an uuencoded article. 1296 ;; This is the beginning of an uuencoded article.
1390 ;; We replace certain characters that could make things messy. 1297 ;; We replace certain characters that could make things messy.
1391 (setq gnus-uu-file-name 1298 (setq gnus-uu-file-name
1392 (let ((nnheader-file-name-translation-alist 1299 (let ((nnheader-file-name-translation-alist
1393 '((?/ . ?,) (? . ?_) (?* . ?_) (?$ . ?_)))) 1300 '((?/ . ?,) (? . ?_) (?* . ?_) (?$ . ?_))))
1394 (nnheader-translate-file-chars (match-string 1)))) 1301 (nnheader-translate-file-chars (match-string 1))))
1395 (replace-match (concat "begin 644 " gnus-uu-file-name) t t)
1396 1302
1397 ;; Remove any non gnus-uu-body-line right after start. 1303 ;; Remove any non gnus-uu-body-line right after start.
1398 (forward-line 1) 1304 (forward-line 1)
1399 (while (and (not (eobp)) 1305 (while (and (not (eobp))
1400 (not (looking-at gnus-uu-body-line))) 1306 (not (looking-at gnus-uu-body-line)))
1401 (gnus-delete-line)) 1307 (gnus-delete-line))
1402 1308
1403 ;; If a process is running, we kill it. 1309 ;; If a process is running, we kill it.
1404 (when (and gnus-uu-uudecode-process 1310 (when (and gnus-uu-uudecode-process
1405 (memq (process-status gnus-uu-uudecode-process) 1311 (memq (process-status gnus-uu-uudecode-process)
1406 '(run stop))) 1312 '(run stop)))
1407 (delete-process gnus-uu-uudecode-process) 1313 (delete-process gnus-uu-uudecode-process)
1408 (gnus-uu-unmark-list-of-grabbed t)) 1314 (gnus-uu-unmark-list-of-grabbed t))
1409 1315
1410 ;; Start a new uudecoding process. 1316 ;; Start a new uudecoding process.
1411 (let ((cdir default-directory)) 1317 (let ((cdir default-directory))
1412 (unwind-protect 1318 (unwind-protect
1413 (progn 1319 (progn
1414 (cd gnus-uu-work-dir) 1320 (cd gnus-uu-work-dir)
1415 (setq gnus-uu-uudecode-process 1321 (setq gnus-uu-uudecode-process
1416 (start-process 1322 (start-process
1417 "*uudecode*" 1323 "*uudecode*"
1418 (get-buffer-create gnus-uu-output-buffer-name) 1324 (get-buffer-create gnus-uu-output-buffer-name)
1419 shell-file-name shell-command-switch 1325 shell-file-name shell-command-switch
1420 (format "cd %s %s uudecode" gnus-uu-work-dir 1326 (format "cd %s %s uudecode" gnus-uu-work-dir
1421 gnus-shell-command-separator)))) 1327 gnus-shell-command-separator))))
1422 (cd cdir))) 1328 (cd cdir)))
1423 (set-process-sentinel 1329 (set-process-sentinel
1424 gnus-uu-uudecode-process 'gnus-uu-uudecode-sentinel) 1330 gnus-uu-uudecode-process 'gnus-uu-uudecode-sentinel)
1425 (setq state (list 'begin)) 1331 (setq state (list 'begin))
1426 (push (concat gnus-uu-work-dir gnus-uu-file-name) files)) 1332 (push (concat gnus-uu-work-dir gnus-uu-file-name) files))
1427 1333
1428 ;; We look for the end of the thing to be decoded. 1334 ;; We look for the end of the thing to be decoded.
1429 (if (re-search-forward gnus-uu-end-string nil t) 1335 (if (re-search-forward gnus-uu-end-string nil t)
1430 (push 'end state) 1336 (setq state (cons 'end state))
1431 (goto-char (point-max)) 1337 (goto-char (point-max))
1432 (re-search-backward gnus-uu-body-line nil t)) 1338 (re-search-backward gnus-uu-body-line nil t))
1433 1339
1434 (forward-line 1) 1340 (forward-line 1)
1435 1341
1436 (when gnus-uu-uudecode-process 1342 (when gnus-uu-uudecode-process
1437 (when (memq (process-status gnus-uu-uudecode-process) '(run stop)) 1343 (when (memq (process-status gnus-uu-uudecode-process) '(run stop))
1438 ;; Try to correct mishandled uucode. 1344 ;; Try to correct mishandled uucode.
1441 1347
1442 ;; Send the text to the process. 1348 ;; Send the text to the process.
1443 (condition-case nil 1349 (condition-case nil
1444 (process-send-region 1350 (process-send-region
1445 gnus-uu-uudecode-process start-char (point)) 1351 gnus-uu-uudecode-process start-char (point))
1446 (error 1352 (error
1447 (progn 1353 (progn
1448 (delete-process gnus-uu-uudecode-process) 1354 (delete-process gnus-uu-uudecode-process)
1449 (gnus-message 2 "gnus-uu: Couldn't uudecode") 1355 (gnus-message 2 "gnus-uu: Couldn't uudecode")
1450 (setq state (list 'wrong-type))))) 1356 (setq state (list 'wrong-type)))))
1451 1357
1452 (if (memq 'end state) 1358 (if (memq 'end state)
1453 (progn 1359 (progn
1454 ;; Send an EOF, just in case. 1360 ;; Send an EOF, just in case.
1455 (ignore-errors 1361 (condition-case ()
1456 (process-send-eof gnus-uu-uudecode-process)) 1362 (process-send-eof gnus-uu-uudecode-process)
1363 (error nil))
1457 (while (memq (process-status gnus-uu-uudecode-process) 1364 (while (memq (process-status gnus-uu-uudecode-process)
1458 '(open run)) 1365 '(open run))
1459 (accept-process-output gnus-uu-uudecode-process 1))) 1366 (accept-process-output gnus-uu-uudecode-process 1)))
1460 (when (or (not gnus-uu-uudecode-process) 1367 (when (or (not gnus-uu-uudecode-process)
1461 (not (memq (process-status gnus-uu-uudecode-process) 1368 (not (memq (process-status gnus-uu-uudecode-process)
1476 (goto-char (point-min)) 1383 (goto-char (point-min))
1477 (if (not (re-search-forward gnus-uu-shar-begin-string nil t)) 1384 (if (not (re-search-forward gnus-uu-shar-begin-string nil t))
1478 (setq state (list 'wrong-type)) 1385 (setq state (list 'wrong-type))
1479 (beginning-of-line) 1386 (beginning-of-line)
1480 (setq start-char (point)) 1387 (setq start-char (point))
1481 (call-process-region 1388 (call-process-region
1482 start-char (point-max) shell-file-name nil 1389 start-char (point-max) shell-file-name nil
1483 (get-buffer-create gnus-uu-output-buffer-name) nil 1390 (get-buffer-create gnus-uu-output-buffer-name) nil
1484 shell-command-switch 1391 shell-command-switch (concat "cd " gnus-uu-work-dir " ; sh"))))
1485 (concat "cd " gnus-uu-work-dir " "
1486 gnus-shell-command-separator " sh"))))
1487 state)) 1392 state))
1488 1393
1489 ;; Returns the name of what the shar file is going to unpack. 1394 ;; Returns the name of what the shar file is going to unpack.
1490 (defun gnus-uu-find-name-in-shar () 1395 (defun gnus-uu-find-name-in-shar ()
1491 (let ((oldpoint (point)) 1396 (let ((oldpoint (point))
1492 res) 1397 res)
1493 (goto-char (point-min)) 1398 (goto-char (point-min))
1494 (when (re-search-forward gnus-uu-shar-name-marker nil t) 1399 (if (re-search-forward gnus-uu-shar-name-marker nil t)
1495 (setq res (buffer-substring (match-beginning 1) (match-end 1)))) 1400 (setq res (buffer-substring (match-beginning 1) (match-end 1))))
1496 (goto-char oldpoint) 1401 (goto-char oldpoint)
1497 res)) 1402 res))
1498 1403
1499 ;; `gnus-uu-choose-action' chooses what action to perform given the name 1404 ;; `gnus-uu-choose-action' chooses what action to perform given the name
1500 ;; and `gnus-uu-file-action-list'. Returns either nil if no action is 1405 ;; and `gnus-uu-file-action-list'. Returns either nil if no action is
1501 ;; found, or the name of the command to run if such a rule is found. 1406 ;; found, or the name of the command to run if such a rule is found.
1502 (defun gnus-uu-choose-action (file-name file-action-list &optional no-ignore) 1407 (defun gnus-uu-choose-action (file-name file-action-list &optional no-ignore)
1503 (let ((action-list (copy-sequence file-action-list)) 1408 (let ((action-list (copy-sequence file-action-list))
1504 (case-fold-search t) 1409 (case-fold-search t)
1505 rule action) 1410 rule action)
1506 (and 1411 (and
1507 (unless no-ignore 1412 (or no-ignore
1508 (and (not 1413 (and (not
1509 (and gnus-uu-ignore-files-by-name 1414 (and gnus-uu-ignore-files-by-name
1510 (string-match gnus-uu-ignore-files-by-name file-name))) 1415 (string-match gnus-uu-ignore-files-by-name file-name)))
1511 (not 1416 (not
1512 (and gnus-uu-ignore-files-by-type 1417 (and gnus-uu-ignore-files-by-type
1513 (string-match gnus-uu-ignore-files-by-type 1418 (string-match gnus-uu-ignore-files-by-type
1514 (or (gnus-uu-choose-action 1419 (or (gnus-uu-choose-action
1515 file-name gnus-uu-ext-to-mime-list t) 1420 file-name gnus-uu-ext-to-mime-list t)
1516 "")))))) 1421 ""))))))
1517 (while (not (or (eq action-list ()) action)) 1422 (while (not (or (eq action-list ()) action))
1518 (setq rule (car action-list)) 1423 (setq rule (car action-list))
1519 (setq action-list (cdr action-list)) 1424 (setq action-list (cdr action-list))
1520 (when (string-match (car rule) file-name) 1425 (if (string-match (car rule) file-name)
1521 (setq action (cadr rule))))) 1426 (setq action (cadr rule)))))
1522 action)) 1427 action))
1523 1428
1524 (defun gnus-uu-treat-archive (file-path) 1429 (defun gnus-uu-treat-archive (file-path)
1525 ;; Unpacks an archive. Returns t if unpacking is successful. 1430 ;; Unpacks an archive. Returns t if unpacking is successful.
1526 (let ((did-unpack t) 1431 (let ((did-unpack t)
1527 action command dir) 1432 action command dir)
1528 (setq action (gnus-uu-choose-action 1433 (setq action (gnus-uu-choose-action
1529 file-path (append gnus-uu-user-archive-rules 1434 file-path (append gnus-uu-user-archive-rules
1530 (if gnus-uu-ignore-default-archive-rules 1435 (if gnus-uu-ignore-default-archive-rules
1531 nil 1436 nil
1532 gnus-uu-default-archive-rules)))) 1437 gnus-uu-default-archive-rules))))
1533 1438
1534 (when (not action) 1439 (if (not action) (error "No unpackers for the file %s" file-path))
1535 (error "No unpackers for the file %s" file-path))
1536 1440
1537 (string-match "/[^/]*$" file-path) 1441 (string-match "/[^/]*$" file-path)
1538 (setq dir (substring file-path 0 (match-beginning 0))) 1442 (setq dir (substring file-path 0 (match-beginning 0)))
1539 1443
1540 (when (member action gnus-uu-destructive-archivers) 1444 (if (member action gnus-uu-destructive-archivers)
1541 (copy-file file-path (concat file-path "~") t)) 1445 (copy-file file-path (concat file-path "~") t))
1542 1446
1543 (setq command (format "cd %s ; %s" dir (gnus-uu-command action file-path))) 1447 (setq command (format "cd %s ; %s" dir (gnus-uu-command action file-path)))
1544 1448
1545 (save-excursion 1449 (save-excursion
1546 (set-buffer (get-buffer-create gnus-uu-output-buffer-name)) 1450 (set-buffer (get-buffer-create gnus-uu-output-buffer-name))
1547 (erase-buffer)) 1451 (erase-buffer))
1548 1452
1549 (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path)) 1453 (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path))
1550 1454
1551 (if (= 0 (call-process shell-file-name nil 1455 (if (= 0 (call-process shell-file-name nil
1552 (get-buffer-create gnus-uu-output-buffer-name) 1456 (get-buffer-create gnus-uu-output-buffer-name)
1553 nil shell-command-switch command)) 1457 nil shell-command-switch command))
1554 (message "") 1458 (message "")
1555 (gnus-message 2 "Error during unpacking of archive") 1459 (gnus-message 2 "Error during unpacking of archive")
1556 (setq did-unpack nil)) 1460 (setq did-unpack nil))
1557 1461
1558 (when (member action gnus-uu-destructive-archivers) 1462 (if (member action gnus-uu-destructive-archivers)
1559 (rename-file (concat file-path "~") file-path t)) 1463 (rename-file (concat file-path "~") file-path t))
1560 1464
1561 did-unpack)) 1465 did-unpack))
1562 1466
1563 (defun gnus-uu-dir-files (dir) 1467 (defun gnus-uu-dir-files (dir)
1564 (let ((dirs (directory-files dir t "[^/][^\\.][^\\.]?$")) 1468 (let ((dirs (directory-files dir t "[^/][^\\.][^\\.]?$"))
1565 files file) 1469 files file)
1566 (while dirs 1470 (while dirs
1567 (if (file-directory-p (setq file (car dirs))) 1471 (if (file-directory-p (setq file (car dirs)))
1568 (setq files (append files (gnus-uu-dir-files file))) 1472 (setq files (append files (gnus-uu-dir-files file)))
1569 (push file files)) 1473 (setq files (cons file files)))
1570 (setq dirs (cdr dirs))) 1474 (setq dirs (cdr dirs)))
1571 files)) 1475 files))
1572 1476
1573 (defun gnus-uu-unpack-files (files &optional ignore) 1477 (defun gnus-uu-unpack-files (files &optional ignore)
1574 ;; Go through FILES and look for files to unpack. 1478 ;; Go through FILES and look for files to unpack.
1575 (let* ((totfiles (gnus-uu-ls-r gnus-uu-work-dir)) 1479 (let* ((totfiles (gnus-uu-ls-r gnus-uu-work-dir))
1576 (ofiles files) 1480 (ofiles files)
1577 file did-unpack) 1481 file did-unpack)
1578 (while files 1482 (while files
1579 (setq file (cdr (assq 'name (car files)))) 1483 (setq file (cdr (assq 'name (car files))))
1580 (when (and (not (member file ignore)) 1484 (if (and (not (member file ignore))
1581 (equal (gnus-uu-get-action (file-name-nondirectory file)) 1485 (equal (gnus-uu-get-action (file-name-nondirectory file))
1582 "gnus-uu-archive")) 1486 "gnus-uu-archive"))
1583 (push file did-unpack) 1487 (progn
1584 (unless (gnus-uu-treat-archive file) 1488 (setq did-unpack (cons file did-unpack))
1585 (gnus-message 2 "Error during unpacking of %s" file)) 1489 (or (gnus-uu-treat-archive file)
1586 (let* ((newfiles (gnus-uu-ls-r gnus-uu-work-dir)) 1490 (gnus-message 2 "Error during unpacking of %s" file))
1587 (nfiles newfiles)) 1491 (let* ((newfiles (gnus-uu-ls-r gnus-uu-work-dir))
1588 (while nfiles 1492 (nfiles newfiles))
1589 (unless (member (car nfiles) totfiles) 1493 (while nfiles
1590 (push (list (cons 'name (car nfiles)) 1494 (or (member (car nfiles) totfiles)
1591 (cons 'original file)) 1495 (setq ofiles (cons (list (cons 'name (car nfiles))
1592 ofiles)) 1496 (cons 'original file))
1593 (setq nfiles (cdr nfiles))) 1497 ofiles)))
1594 (setq totfiles newfiles))) 1498 (setq nfiles (cdr nfiles)))
1499 (setq totfiles newfiles))))
1595 (setq files (cdr files))) 1500 (setq files (cdr files)))
1596 (if did-unpack 1501 (if did-unpack
1597 (gnus-uu-unpack-files ofiles (append did-unpack ignore)) 1502 (gnus-uu-unpack-files ofiles (append did-unpack ignore))
1598 ofiles))) 1503 ofiles)))
1599 1504
1600 (defun gnus-uu-ls-r (dir) 1505 (defun gnus-uu-ls-r (dir)
1601 (let* ((files (gnus-uu-directory-files dir t)) 1506 (let* ((files (gnus-uu-directory-files dir t))
1602 (ofiles files)) 1507 (ofiles files))
1603 (while files 1508 (while files
1604 (when (file-directory-p (car files)) 1509 (if (file-directory-p (car files))
1605 (setq ofiles (delete (car files) ofiles)) 1510 (progn
1606 (setq ofiles (append ofiles (gnus-uu-ls-r (car files))))) 1511 (setq ofiles (delete (car files) ofiles))
1512 (setq ofiles (append ofiles (gnus-uu-ls-r (car files))))))
1607 (setq files (cdr files))) 1513 (setq files (cdr files)))
1608 ofiles)) 1514 ofiles))
1609 1515
1610 ;; Various stuff 1516 ;; Various stuff
1611 1517
1613 (let (files out file) 1519 (let (files out file)
1614 (setq files (directory-files dir full)) 1520 (setq files (directory-files dir full))
1615 (while files 1521 (while files
1616 (setq file (car files)) 1522 (setq file (car files))
1617 (setq files (cdr files)) 1523 (setq files (cdr files))
1618 (unless (member (file-name-nondirectory file) '("." "..")) 1524 (or (member (file-name-nondirectory file) '("." ".."))
1619 (push file out))) 1525 (setq out (cons file out))))
1620 (setq out (nreverse out)) 1526 (setq out (nreverse out))
1621 out)) 1527 out))
1622 1528
1623 (defun gnus-uu-check-correct-stripped-uucode (start end) 1529 (defun gnus-uu-check-correct-stripped-uucode (start end)
1624 (save-excursion 1530 (save-excursion
1630 (if (re-search-forward " \\|`" end t) 1536 (if (re-search-forward " \\|`" end t)
1631 (progn 1537 (progn
1632 (goto-char start) 1538 (goto-char start)
1633 (while (not (eobp)) 1539 (while (not (eobp))
1634 (progn 1540 (progn
1635 (when (looking-at "\n") 1541 (if (looking-at "\n") (replace-match ""))
1636 (replace-match ""))
1637 (forward-line 1)))) 1542 (forward-line 1))))
1638 1543
1639 (while (not (eobp)) 1544 (while (not (eobp))
1640 (if (looking-at (concat gnus-uu-begin-string "\\|" 1545 (if (looking-at (concat gnus-uu-begin-string "\\|"
1641 gnus-uu-end-string)) 1546 gnus-uu-end-string))
1642 () 1547 ()
1643 (when (not found) 1548 (if (not found)
1644 (beginning-of-line) 1549 (progn
1645 (setq beg (point)) 1550 (beginning-of-line)
1646 (end-of-line) 1551 (setq beg (point))
1647 (setq length (- (point) beg))) 1552 (end-of-line)
1553 (setq length (- (point) beg))))
1648 (setq found t) 1554 (setq found t)
1649 (beginning-of-line) 1555 (beginning-of-line)
1650 (setq beg (point)) 1556 (setq beg (point))
1651 (end-of-line) 1557 (end-of-line)
1652 (when (not (= length (- (point) beg))) 1558 (if (not (= length (- (point) beg)))
1653 (insert (make-string (- length (- (point) beg)) ? )))) 1559 (insert (make-string (- length (- (point) beg)) ? ))))
1654 (forward-line 1))))))) 1560 (forward-line 1)))))))
1655 1561
1656 (defvar gnus-uu-tmp-alist nil) 1562 (defvar gnus-uu-tmp-alist nil)
1657 1563
1658 (defun gnus-uu-initialize (&optional scan) 1564 (defun gnus-uu-initialize (&optional scan)
1659 (let (entry) 1565 (let (entry)
1660 (if (and (not scan) 1566 (if (and (not scan)
1661 (when (setq entry (assoc gnus-newsgroup-name gnus-uu-tmp-alist)) 1567 (if (setq entry (assoc gnus-newsgroup-name gnus-uu-tmp-alist))
1662 (if (file-exists-p (cdr entry)) 1568 (if (file-exists-p (cdr entry))
1663 (setq gnus-uu-work-dir (cdr entry)) 1569 (setq gnus-uu-work-dir (cdr entry))
1664 (setq gnus-uu-tmp-alist (delq entry gnus-uu-tmp-alist)) 1570 (setq gnus-uu-tmp-alist (delq entry gnus-uu-tmp-alist))
1665 nil))) 1571 nil)))
1666 t 1572 t
1667 (setq gnus-uu-tmp-dir (file-name-as-directory 1573 (setq gnus-uu-tmp-dir (file-name-as-directory
1668 (expand-file-name gnus-uu-tmp-dir))) 1574 (expand-file-name gnus-uu-tmp-dir)))
1669 (if (not (file-directory-p gnus-uu-tmp-dir)) 1575 (if (not (file-directory-p gnus-uu-tmp-dir))
1670 (error "Temp directory %s doesn't exist" gnus-uu-tmp-dir) 1576 (error "Temp directory %s doesn't exist" gnus-uu-tmp-dir)
1671 (when (not (file-writable-p gnus-uu-tmp-dir)) 1577 (if (not (file-writable-p gnus-uu-tmp-dir))
1672 (error "Temp directory %s can't be written to" 1578 (error "Temp directory %s can't be written to"
1673 gnus-uu-tmp-dir))) 1579 gnus-uu-tmp-dir)))
1674 1580
1675 (setq gnus-uu-work-dir 1581 (setq gnus-uu-work-dir
1676 (make-temp-name (concat gnus-uu-tmp-dir "gnus"))) 1582 (make-temp-name (concat gnus-uu-tmp-dir "gnus")))
1677 (gnus-make-directory gnus-uu-work-dir) 1583 (if (not (file-directory-p gnus-uu-work-dir))
1584 (gnus-make-directory gnus-uu-work-dir))
1678 (set-file-modes gnus-uu-work-dir 448) 1585 (set-file-modes gnus-uu-work-dir 448)
1679 (setq gnus-uu-work-dir (file-name-as-directory gnus-uu-work-dir)) 1586 (setq gnus-uu-work-dir (file-name-as-directory gnus-uu-work-dir))
1680 (push (cons gnus-newsgroup-name gnus-uu-work-dir) 1587 (setq gnus-uu-tmp-alist (cons (cons gnus-newsgroup-name gnus-uu-work-dir)
1681 gnus-uu-tmp-alist)))) 1588 gnus-uu-tmp-alist)))))
1682 1589
1683 1590
1684 ;; Kills the temporary uu buffers, kills any processes, etc. 1591 ;; Kills the temporary uu buffers, kills any processes, etc.
1685 (defun gnus-uu-clean-up () 1592 (defun gnus-uu-clean-up ()
1686 (let (buf) 1593 (let (buf)
1687 (and gnus-uu-uudecode-process 1594 (and gnus-uu-uudecode-process
1688 (memq (process-status (or gnus-uu-uudecode-process "nevair")) 1595 (memq (process-status (or gnus-uu-uudecode-process "nevair"))
1689 '(stop run)) 1596 '(stop run))
1690 (delete-process gnus-uu-uudecode-process)) 1597 (delete-process gnus-uu-uudecode-process))
1691 (when (setq buf (get-buffer gnus-uu-output-buffer-name)) 1598 (and (setq buf (get-buffer gnus-uu-output-buffer-name))
1692 (kill-buffer buf)))) 1599 (kill-buffer buf))))
1693 1600
1694 (defun gnus-quote-arg-for-sh-or-csh (arg) 1601 ;; Inputs an action and a file and returns a full command, putting
1695 (let ((pos 0) new-pos accum) 1602 ;; quotes round the file name and escaping any quotes in the file name.
1696 ;; *** bug: we don't handle newline characters properly
1697 (while (setq new-pos (string-match "[!`\"$\\& \t{}]" arg pos))
1698 (push (substring arg pos new-pos) accum)
1699 (push "\\" accum)
1700 (push (list (aref arg new-pos)) accum)
1701 (setq pos (1+ new-pos)))
1702 (if (= pos 0)
1703 arg
1704 (apply 'concat (nconc (nreverse accum) (list (substring arg pos)))))))
1705
1706 ;; Inputs an action and a filename and returns a full command, making sure
1707 ;; that the filename will be treated as a single argument when the shell
1708 ;; executes the command.
1709 (defun gnus-uu-command (action file) 1603 (defun gnus-uu-command (action file)
1710 (let ((quoted-file (gnus-quote-arg-for-sh-or-csh file))) 1604 (let ((ofile ""))
1605 (while (string-match "!\\|`\\|\"\\|\\$\\|\\\\\\|&" file)
1606 (progn
1607 (setq ofile
1608 (concat ofile (substring file 0 (match-beginning 0)) "\\"
1609 (substring file (match-beginning 0) (match-end 0))))
1610 (setq file (substring file (1+ (match-beginning 0))))))
1611 (setq ofile (concat "\"" ofile file "\""))
1711 (if (string-match "%s" action) 1612 (if (string-match "%s" action)
1712 (format action quoted-file) 1613 (format action ofile)
1713 (concat action " " quoted-file)))) 1614 (concat action " " ofile))))
1714 1615
1715 (defun gnus-uu-delete-work-dir (&optional dir) 1616 (defun gnus-uu-delete-work-dir (&optional dir)
1716 "Delete recursively all files and directories under `gnus-uu-work-dir'." 1617 "Delete recursively all files and directories under `gnus-uu-work-dir'."
1717 (if dir 1618 (if dir
1718 (gnus-message 7 "Deleting directory %s..." dir) 1619 (gnus-message 7 "Deleting directory %s..." dir)
1740 ;;; 1641 ;;;
1741 ;;; uuencoded posting 1642 ;;; uuencoded posting
1742 ;;; 1643 ;;;
1743 1644
1744 ;; Any function that is to be used as and encoding method will take two 1645 ;; Any function that is to be used as and encoding method will take two
1745 ;; parameters: PATH-NAME and FILE-NAME. (E.g. "/home/gaga/spiral.jpg" 1646 ;; parameters: PATH-NAME and FILE-NAME. (E.g. "/home/gaga/spiral.jpg"
1746 ;; and "spiral.jpg", respectively.) The function should return nil if 1647 ;; and "spiral.jpg", respectively.) The function should return nil if
1747 ;; the encoding wasn't successful. 1648 ;; the encoding wasn't successful.
1748 (defcustom gnus-uu-post-encode-method 'gnus-uu-post-encode-uuencode 1649 (defvar gnus-uu-post-encode-method 'gnus-uu-post-encode-uuencode
1749 "Function used for encoding binary files. 1650 "Function used for encoding binary files.
1750 There are three functions supplied with gnus-uu for encoding files: 1651 There are three functions supplied with gnus-uu for encoding files:
1751 `gnus-uu-post-encode-uuencode', which does straight uuencoding; 1652 `gnus-uu-post-encode-uuencode', which does straight uuencoding;
1752 `gnus-uu-post-encode-mime', which encodes with base64 and adds MIME 1653 `gnus-uu-post-encode-mime', which encodes with base64 and adds MIME
1753 headers; and `gnus-uu-post-encode-mime-uuencode', which encodes with 1654 headers; and `gnus-uu-post-encode-mime-uuencode', which encodes with
1754 uuencode and adds MIME headers." 1655 uuencode and adds MIME headers.")
1755 :group 'gnus-extract-post 1656
1756 :type '(radio (function-item gnus-uu-post-encode-uuencode) 1657 (defvar gnus-uu-post-include-before-composing nil
1757 (function-item gnus-uu-post-encode-mime)
1758 (function-item gnus-uu-post-encode-mime-uuencode)
1759 (function :tag "Other")))
1760
1761 (defcustom gnus-uu-post-include-before-composing nil
1762 "Non-nil means that gnus-uu will ask for a file to encode before you compose the article. 1658 "Non-nil means that gnus-uu will ask for a file to encode before you compose the article.
1763 If this variable is t, you can either include an encoded file with 1659 If this variable is t, you can either include an encoded file with
1764 \\[gnus-uu-post-insert-binary-in-article] or have one included for you when you post the article." 1660 \\[gnus-uu-post-insert-binary-in-article] or have one included for you when you post the article.")
1765 :group 'gnus-extract-post 1661
1766 :type 'boolean) 1662 (defvar gnus-uu-post-length 990
1767
1768 (defcustom gnus-uu-post-length 990
1769 "Maximum length of an article. 1663 "Maximum length of an article.
1770 The encoded file will be split into how many articles it takes to 1664 The encoded file will be split into how many articles it takes to
1771 post the entire file." 1665 post the entire file.")
1772 :group 'gnus-extract-post 1666
1773 :type 'integer) 1667 (defvar gnus-uu-post-threaded nil
1774
1775 (defcustom gnus-uu-post-threaded nil
1776 "Non-nil means that gnus-uu will post the encoded file in a thread. 1668 "Non-nil means that gnus-uu will post the encoded file in a thread.
1777 This may not be smart, as no other decoder I have seen are able to 1669 This may not be smart, as no other decoder I have seen are able to
1778 follow threads when collecting uuencoded articles. (Well, I have seen 1670 follow threads when collecting uuencoded articles. (Well, I have seen
1779 one package that does that - gnus-uu, but somehow, I don't think that 1671 one package that does that - gnus-uu, but somehow, I don't think that
1780 counts...) Default is nil." 1672 counts...) Default is nil.")
1781 :group 'gnus-extract-post 1673
1782 :type 'boolean) 1674 (defvar gnus-uu-post-separate-description t
1783
1784 (defcustom gnus-uu-post-separate-description t
1785 "Non-nil means that the description will be posted in a separate article. 1675 "Non-nil means that the description will be posted in a separate article.
1786 The first article will typically be numbered (0/x). If this variable 1676 The first article will typically be numbered (0/x). If this variable
1787 is nil, the description the user enters will be included at the 1677 is nil, the description the user enters will be included at the
1788 beginning of the first article, which will be numbered (1/x). Default 1678 beginning of the first article, which will be numbered (1/x). Default
1789 is t." 1679 is t.")
1790 :group 'gnus-extract-post
1791 :type 'boolean)
1792 1680
1793 (defvar gnus-uu-post-binary-separator "--binary follows this line--") 1681 (defvar gnus-uu-post-binary-separator "--binary follows this line--")
1794 (defvar gnus-uu-post-message-id nil) 1682 (defvar gnus-uu-post-message-id nil)
1795 (defvar gnus-uu-post-inserted-file-name nil) 1683 (defvar gnus-uu-post-inserted-file-name nil)
1796 (defvar gnus-uu-winconf-post-news nil) 1684 (defvar gnus-uu-winconf-post-news nil)
1806 (use-local-map (copy-keymap (current-local-map))) 1694 (use-local-map (copy-keymap (current-local-map)))
1807 (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done) 1695 (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
1808 (local-set-key "\C-c\C-c" 'gnus-uu-post-news-inews) 1696 (local-set-key "\C-c\C-c" 'gnus-uu-post-news-inews)
1809 (local-set-key "\C-c\C-s" 'gnus-uu-post-news-inews) 1697 (local-set-key "\C-c\C-s" 'gnus-uu-post-news-inews)
1810 (local-set-key "\C-c\C-i" 'gnus-uu-post-insert-binary-in-article) 1698 (local-set-key "\C-c\C-i" 'gnus-uu-post-insert-binary-in-article)
1811 1699
1812 (when gnus-uu-post-include-before-composing 1700 (if gnus-uu-post-include-before-composing
1813 (save-excursion (setq gnus-uu-post-inserted-file-name 1701 (save-excursion (setq gnus-uu-post-inserted-file-name
1814 (gnus-uu-post-insert-binary))))) 1702 (gnus-uu-post-insert-binary)))))
1815 1703
1816 (defun gnus-uu-post-insert-binary-in-article () 1704 (defun gnus-uu-post-insert-binary-in-article ()
1817 "Inserts an encoded file in the buffer. 1705 "Inserts an encoded file in the buffer.
1818 The user will be asked for a file name." 1706 The user will be asked for a file name."
1819 (interactive) 1707 (interactive)
1820 (save-excursion 1708 (save-excursion
1821 (setq gnus-uu-post-inserted-file-name (gnus-uu-post-insert-binary)))) 1709 (setq gnus-uu-post-inserted-file-name (gnus-uu-post-insert-binary))))
1822 1710
1823 ;; Encodes with uuencode and substitutes all spaces with backticks. 1711 ;; Encodes with uuencode and substitutes all spaces with backticks.
1824 (defun gnus-uu-post-encode-uuencode (path file-name) 1712 (defun gnus-uu-post-encode-uuencode (path file-name)
1825 (when (gnus-uu-post-encode-file "uuencode" path file-name) 1713 (if (gnus-uu-post-encode-file "uuencode" path file-name)
1826 (goto-char (point-min)) 1714 (progn
1827 (forward-line 1) 1715 (goto-char (point-min))
1828 (while (re-search-forward " " nil t) 1716 (forward-line 1)
1829 (replace-match "`")) 1717 (while (re-search-forward " " nil t)
1830 t)) 1718 (replace-match "`"))
1719 t)))
1831 1720
1832 ;; Encodes with uuencode and adds MIME headers. 1721 ;; Encodes with uuencode and adds MIME headers.
1833 (defun gnus-uu-post-encode-mime-uuencode (path file-name) 1722 (defun gnus-uu-post-encode-mime-uuencode (path file-name)
1834 (when (gnus-uu-post-encode-uuencode path file-name) 1723 (if (gnus-uu-post-encode-uuencode path file-name)
1835 (gnus-uu-post-make-mime file-name "x-uue") 1724 (progn
1836 t)) 1725 (gnus-uu-post-make-mime file-name "x-uue")
1726 t)))
1837 1727
1838 ;; Encodes with base64 and adds MIME headers 1728 ;; Encodes with base64 and adds MIME headers
1839 (defun gnus-uu-post-encode-mime (path file-name) 1729 (defun gnus-uu-post-encode-mime (path file-name)
1840 (when (gnus-uu-post-encode-file "mmencode" path file-name) 1730 (if (gnus-uu-post-encode-file "mmencode" path file-name)
1841 (gnus-uu-post-make-mime file-name "base64") 1731 (progn
1842 t)) 1732 (gnus-uu-post-make-mime file-name "base64")
1733 t)))
1843 1734
1844 ;; Adds MIME headers. 1735 ;; Adds MIME headers.
1845 (defun gnus-uu-post-make-mime (file-name encoding) 1736 (defun gnus-uu-post-make-mime (file-name encoding)
1846 (goto-char (point-min)) 1737 (goto-char (point-min))
1847 (insert (format "Content-Type: %s; name=\"%s\"\n" 1738 (insert (format "Content-Type: %s; name=\"%s\"\n"
1848 (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list) 1739 (gnus-uu-choose-action file-name gnus-uu-ext-to-mime-list)
1849 file-name)) 1740 file-name))
1850 (insert (format "Content-Transfer-Encoding: %s\n\n" encoding)) 1741 (insert (format "Content-Transfer-Encoding: %s\n\n" encoding))
1851 (save-restriction 1742 (save-restriction
1852 (set-buffer gnus-message-buffer) 1743 (set-buffer gnus-message-buffer)
1853 (goto-char (point-min)) 1744 (goto-char (point-min))
1854 (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) 1745 (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$"))
1855 (forward-line -1) 1746 (forward-line -1)
1856 (narrow-to-region 1 (point)) 1747 (narrow-to-region 1 (point))
1857 (unless (mail-fetch-field "mime-version") 1748 (or (mail-fetch-field "mime-version")
1858 (widen) 1749 (progn
1859 (insert "MIME-Version: 1.0\n")) 1750 (widen)
1751 (insert "MIME-Version: 1.0\n")))
1860 (widen))) 1752 (widen)))
1861 1753
1862 ;; Encodes a file PATH with COMMAND, leaving the result in the 1754 ;; Encodes a file PATH with COMMAND, leaving the result in the
1863 ;; current buffer. 1755 ;; current buffer.
1864 (defun gnus-uu-post-encode-file (command path file-name) 1756 (defun gnus-uu-post-encode-file (command path file-name)
1865 (= 0 (call-process shell-file-name nil t nil shell-command-switch 1757 (= 0 (call-process shell-file-name nil t nil shell-command-switch
1866 (format "%s %s %s" command path file-name)))) 1758 (format "%s %s %s" command path file-name))))
1867 1759
1868 (defun gnus-uu-post-news-inews () 1760 (defun gnus-uu-post-news-inews ()
1869 "Posts the composed news article and encoded file. 1761 "Posts the composed news article and encoded file.
1870 If no file has been included, the user will be asked for a file." 1762 If no file has been included, the user will be asked for a file."
1873 (let (file-name) 1765 (let (file-name)
1874 1766
1875 (if gnus-uu-post-inserted-file-name 1767 (if gnus-uu-post-inserted-file-name
1876 (setq file-name gnus-uu-post-inserted-file-name) 1768 (setq file-name gnus-uu-post-inserted-file-name)
1877 (setq file-name (gnus-uu-post-insert-binary))) 1769 (setq file-name (gnus-uu-post-insert-binary)))
1878 1770
1879 (if gnus-uu-post-threaded 1771 (if gnus-uu-post-threaded
1880 (let ((message-required-news-headers 1772 (let ((message-required-news-headers
1881 (if (memq 'Message-ID message-required-news-headers) 1773 (if (memq 'Message-ID message-required-news-headers)
1882 message-required-news-headers 1774 message-required-news-headers
1883 (cons 'Message-ID message-required-news-headers))) 1775 (cons 'Message-ID message-required-news-headers)))
1884 gnus-inews-article-hook) 1776 gnus-inews-article-hook)
1885 1777
1886 (setq gnus-inews-article-hook (if (listp gnus-inews-article-hook) 1778 (setq gnus-inews-article-hook (if (listp gnus-inews-article-hook)
1887 gnus-inews-article-hook 1779 gnus-inews-article-hook
1888 (list gnus-inews-article-hook))) 1780 (list gnus-inews-article-hook)))
1889 (push 1781 (setq gnus-inews-article-hook
1890 '(lambda () 1782 (cons
1891 (save-excursion 1783 '(lambda ()
1892 (goto-char (point-min)) 1784 (save-excursion
1893 (if (re-search-forward "^Message-ID: \\(.*\\)$" nil t) 1785 (goto-char (point-min))
1894 (setq gnus-uu-post-message-id 1786 (if (re-search-forward "^Message-ID: \\(.*\\)$" nil t)
1895 (buffer-substring 1787 (setq gnus-uu-post-message-id
1896 (match-beginning 1) (match-end 1))) 1788 (buffer-substring
1897 (setq gnus-uu-post-message-id nil)))) 1789 (match-beginning 1) (match-end 1)))
1898 gnus-inews-article-hook) 1790 (setq gnus-uu-post-message-id nil))))
1791 gnus-inews-article-hook))
1899 (gnus-uu-post-encoded file-name t)) 1792 (gnus-uu-post-encoded file-name t))
1900 (gnus-uu-post-encoded file-name nil))) 1793 (gnus-uu-post-encoded file-name nil)))
1901 (setq gnus-uu-post-inserted-file-name nil) 1794 (setq gnus-uu-post-inserted-file-name nil)
1902 (when gnus-uu-winconf-post-news 1795 (and gnus-uu-winconf-post-news
1903 (set-window-configuration gnus-uu-winconf-post-news))) 1796 (set-window-configuration gnus-uu-winconf-post-news)))
1904 1797
1905 ;; Asks for a file to encode, encodes it and inserts the result in 1798 ;; Asks for a file to encode, encodes it and inserts the result in
1906 ;; the current buffer. Returns the file name the user gave. 1799 ;; the current buffer. Returns the file name the user gave.
1907 (defun gnus-uu-post-insert-binary () 1800 (defun gnus-uu-post-insert-binary ()
1908 (let ((uuencode-buffer-name "*uuencode buffer*") 1801 (let ((uuencode-buffer-name "*uuencode buffer*")
1909 file-path uubuf file-name) 1802 file-path uubuf file-name)
1910 1803
1911 (setq file-path (read-file-name 1804 (setq file-path (read-file-name
1912 "What file do you want to encode? ")) 1805 "What file do you want to encode? "))
1913 (when (not (file-exists-p file-path)) 1806 (if (not (file-exists-p file-path))
1914 (error "%s: No such file" file-path)) 1807 (error "%s: No such file" file-path))
1915 1808
1916 (goto-char (point-max)) 1809 (goto-char (point-max))
1917 (insert (format "\n%s\n" gnus-uu-post-binary-separator)) 1810 (insert (format "\n%s\n" gnus-uu-post-binary-separator))
1918 1811
1919 (when (string-match "^~/" file-path) 1812 (if (string-match "^~/" file-path)
1920 (setq file-path (concat "$HOME" (substring file-path 1)))) 1813 (setq file-path (concat "$HOME" (substring file-path 1))))
1921 (if (string-match "/[^/]*$" file-path) 1814 (if (string-match "/[^/]*$" file-path)
1922 (setq file-name (substring file-path (1+ (match-beginning 0)))) 1815 (setq file-name (substring file-path (1+ (match-beginning 0))))
1923 (setq file-name file-path)) 1816 (setq file-name file-path))
1924 1817
1925 (unwind-protect 1818 (unwind-protect
1926 (if (save-excursion 1819 (if (save-excursion
1927 (set-buffer (setq uubuf 1820 (set-buffer (setq uubuf
1928 (get-buffer-create uuencode-buffer-name))) 1821 (get-buffer-create uuencode-buffer-name)))
1929 (erase-buffer) 1822 (erase-buffer)
1930 (funcall gnus-uu-post-encode-method file-path file-name)) 1823 (funcall gnus-uu-post-encode-method file-path file-name))
1931 (insert-buffer-substring uubuf) 1824 (insert-buffer-substring uubuf)
1932 (error "Encoding unsuccessful")) 1825 (error "Encoding unsuccessful"))
1943 beg-line minlen buf post-buf whole-len beg-binary end-binary) 1836 beg-line minlen buf post-buf whole-len beg-binary end-binary)
1944 1837
1945 (setq post-buf (current-buffer)) 1838 (setq post-buf (current-buffer))
1946 1839
1947 (goto-char (point-min)) 1840 (goto-char (point-min))
1948 (when (not (re-search-forward 1841 (if (not (re-search-forward
1949 (if gnus-uu-post-separate-description 1842 (if gnus-uu-post-separate-description
1950 (concat "^" (regexp-quote gnus-uu-post-binary-separator) 1843 (concat "^" (regexp-quote gnus-uu-post-binary-separator)
1951 "$") 1844 "$")
1952 (concat "^" (regexp-quote mail-header-separator) "$")) 1845 (concat "^" (regexp-quote mail-header-separator) "$")) nil t))
1953 nil t)) 1846 (error "Internal error: No binary/header separator"))
1954 (error "Internal error: No binary/header separator"))
1955 (beginning-of-line) 1847 (beginning-of-line)
1956 (forward-line 1) 1848 (forward-line 1)
1957 (setq beg-binary (point)) 1849 (setq beg-binary (point))
1958 (setq end-binary (point-max)) 1850 (setq end-binary (point-max))
1959 1851
1960 (save-excursion 1852 (save-excursion
1961 (set-buffer (setq uubuf (get-buffer-create encoded-buffer-name))) 1853 (set-buffer (setq uubuf (get-buffer-create encoded-buffer-name)))
1962 (erase-buffer) 1854 (erase-buffer)
1963 (insert-buffer-substring post-buf beg-binary end-binary) 1855 (insert-buffer-substring post-buf beg-binary end-binary)
1964 (goto-char (point-min)) 1856 (goto-char (point-min))
1965 (setq length (count-lines 1 (point-max))) 1857 (setq length (count-lines 1 (point-max)))
1966 (setq parts (/ length gnus-uu-post-length)) 1858 (setq parts (/ length gnus-uu-post-length))
1967 (when (not (< (% length gnus-uu-post-length) 4)) 1859 (if (not (< (% length gnus-uu-post-length) 4))
1968 (setq parts (1+ parts)))) 1860 (setq parts (1+ parts))))
1969 1861
1970 (when gnus-uu-post-separate-description 1862 (if gnus-uu-post-separate-description
1971 (forward-line -1)) 1863 (forward-line -1))
1972 (kill-region (point) (point-max)) 1864 (kill-region (point) (point-max))
1973 1865
1974 (goto-char (point-min)) 1866 (goto-char (point-min))
1975 (re-search-forward 1867 (re-search-forward
1976 (concat "^" (regexp-quote mail-header-separator) "$") nil t) 1868 (concat "^" (regexp-quote mail-header-separator) "$") nil t)
1977 (beginning-of-line) 1869 (beginning-of-line)
1978 (setq header (buffer-substring 1 (point))) 1870 (setq header (buffer-substring 1 (point)))
1979 1871
1980 (goto-char (point-min)) 1872 (goto-char (point-min))
1981 (if (not gnus-uu-post-separate-description) 1873 (if (not gnus-uu-post-separate-description)
1982 () 1874 ()
1983 (when (and (not threaded) (re-search-forward "^Subject: " nil t)) 1875 (if (and (not threaded) (re-search-forward "^Subject: " nil t))
1984 (end-of-line) 1876 (progn
1985 (insert (format " (0/%d)" parts))) 1877 (end-of-line)
1878 (insert (format " (0/%d)" parts))))
1986 (message-send)) 1879 (message-send))
1987 1880
1988 (save-excursion 1881 (save-excursion
1989 (setq i 1) 1882 (setq i 1)
1990 (setq beg 1) 1883 (setq beg 1)
1991 (while (not (> i parts)) 1884 (while (not (> i parts))
1992 (set-buffer (get-buffer-create send-buffer-name)) 1885 (set-buffer (get-buffer-create send-buffer-name))
1993 (erase-buffer) 1886 (erase-buffer)
1994 (insert header) 1887 (insert header)
1995 (when (and threaded gnus-uu-post-message-id) 1888 (if (and threaded gnus-uu-post-message-id)
1996 (insert (format "References: %s\n" gnus-uu-post-message-id))) 1889 (insert (format "References: %s\n" gnus-uu-post-message-id)))
1997 (insert separator) 1890 (insert separator)
1998 (setq whole-len 1891 (setq whole-len
1999 (- 62 (length (format top-string "" file-name i parts "")))) 1892 (- 62 (length (format top-string "" file-name i parts ""))))
2000 (when (> 1 (setq minlen (/ whole-len 2))) 1893 (if (> 1 (setq minlen (/ whole-len 2)))
2001 (setq minlen 1)) 1894 (setq minlen 1))
2002 (setq 1895 (setq
2003 beg-line 1896 beg-line
2004 (format top-string 1897 (format top-string
2005 (make-string minlen ?-) 1898 (make-string minlen ?-)
2006 file-name i parts 1899 file-name i parts
2007 (make-string 1900 (make-string
2008 (if (= 0 (% whole-len 2)) (1- minlen) minlen) ?-))) 1901 (if (= 0 (% whole-len 2)) (1- minlen) minlen) ?-)))
2009 1902
2010 (goto-char (point-min)) 1903 (goto-char (point-min))
2011 (if (not (re-search-forward "^Subject: " nil t)) 1904 (if (not (re-search-forward "^Subject: " nil t))
2012 () 1905 ()
2013 (if (not threaded) 1906 (if (not threaded)
2014 (progn 1907 (progn
2015 (end-of-line) 1908 (end-of-line)
2016 (insert (format " (%d/%d)" i parts))) 1909 (insert (format " (%d/%d)" i parts)))
2017 (when (or (and (= i 2) gnus-uu-post-separate-description) 1910 (if (or (and (= i 2) gnus-uu-post-separate-description)
2018 (and (= i 1) (not gnus-uu-post-separate-description))) 1911 (and (= i 1) (not gnus-uu-post-separate-description)))
2019 (replace-match "Subject: Re: ")))) 1912 (replace-match "Subject: Re: "))))
2020 1913
2021 (goto-char (point-max)) 1914 (goto-char (point-max))
2022 (save-excursion 1915 (save-excursion
2023 (set-buffer uubuf) 1916 (set-buffer uubuf)
2024 (goto-char beg) 1917 (goto-char beg)
2025 (if (= i parts) 1918 (if (= i parts)
2026 (goto-char (point-max)) 1919 (goto-char (point-max))
2027 (forward-line gnus-uu-post-length)) 1920 (forward-line gnus-uu-post-length))
2028 (when (and (= (1+ i) parts) (< (count-lines (point) (point-max)) 4)) 1921 (if (and (= (1+ i) parts) (< (count-lines (point) (point-max)) 4))
2029 (forward-line -4)) 1922 (forward-line -4))
2030 (setq end (point))) 1923 (setq end (point)))
2031 (insert-buffer-substring uubuf beg end) 1924 (insert-buffer-substring uubuf beg end)
2032 (insert beg-line) 1925 (insert beg-line)
2033 (insert "\n") 1926 (insert "\n")
2034 (setq beg end) 1927 (setq beg end)
2036 (goto-char (point-min)) 1929 (goto-char (point-min))
2037 (re-search-forward 1930 (re-search-forward
2038 (concat "^" (regexp-quote mail-header-separator) "$") nil t) 1931 (concat "^" (regexp-quote mail-header-separator) "$") nil t)
2039 (beginning-of-line) 1932 (beginning-of-line)
2040 (forward-line 2) 1933 (forward-line 2)
2041 (when (re-search-forward 1934 (if (re-search-forward
2042 (concat "^" (regexp-quote gnus-uu-post-binary-separator) "$") 1935 (concat "^" (regexp-quote gnus-uu-post-binary-separator) "$")
2043 nil t) 1936 nil t)
2044 (replace-match "") 1937 (progn
2045 (forward-line 1)) 1938 (replace-match "")
1939 (forward-line 1)))
2046 (insert beg-line) 1940 (insert beg-line)
2047 (insert "\n") 1941 (insert "\n")
2048 (let (message-sent-message-via) 1942 (let (message-sent-message-via)
2049 (message-send)))) 1943 (message-send))))
2050 1944
2051 (when (setq buf (get-buffer send-buffer-name)) 1945 (and (setq buf (get-buffer send-buffer-name))
2052 (kill-buffer buf)) 1946 (kill-buffer buf))
2053 (when (setq buf (get-buffer encoded-buffer-name)) 1947 (and (setq buf (get-buffer encoded-buffer-name))
2054 (kill-buffer buf)) 1948 (kill-buffer buf))
2055 1949
2056 (when (not gnus-uu-post-separate-description) 1950 (if (not gnus-uu-post-separate-description)
2057 (set-buffer-modified-p nil) 1951 (progn
2058 (when (fboundp 'bury-buffer) 1952 (set-buffer-modified-p nil)
2059 (bury-buffer))))) 1953 (and (fboundp 'bury-buffer) (bury-buffer))))))
2060 1954
2061 (provide 'gnus-uu) 1955 (provide 'gnus-uu)
2062 1956
2063 ;; gnus-uu.el ends here 1957 ;; gnus-uu.el ends here