aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2009-01-31 02:50:28 +0000
committerGlenn Morris2009-01-31 02:50:28 +0000
commit9f08b1415dcb5291bdbb036acab9bc22c076768b (patch)
tree71f3562ce3261f334e3f715cfcdaaa1b291e378f
parentb83b70b81220f03bf8db0f2c2a2024623171966e (diff)
downloademacs-9f08b1415dcb5291bdbb036acab9bc22c076768b.tar.gz
emacs-9f08b1415dcb5291bdbb036acab9bc22c076768b.zip
Tidy up commentary.
(rmail-current-message): Remove unneeded declaration. (uce-message-text, uce-default-headers): Fix custom type. (rmail-buffer, rmail-msg-is-pruned): Declare. (uce-reply-to-uce): Add autoload cookie. Doc fix. Update for mbox Rmail.
-rw-r--r--lisp/mail/uce.el263
1 files changed, 121 insertions, 142 deletions
diff --git a/lisp/mail/uce.el b/lisp/mail/uce.el
index 7faa6e9530d..2d7122775ff 100644
--- a/lisp/mail/uce.el
+++ b/lisp/mail/uce.el
@@ -1,11 +1,11 @@
1;;; uce.el --- facilitate reply to unsolicited commercial email 1;;; uce.el --- facilitate reply to unsolicited commercial email
2 2
3;; Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 3;; Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 4;; 2007, 2008, 2009 Free Software Foundation, Inc.
5 5
6;; Author: stanislav shalunov <shalunov@mccme.ru> 6;; Author: stanislav shalunov <shalunov@mccme.ru>
7;; Created: 10 Dec 1996 7;; Created: 10 Dec 1996
8;; Keywords: uce, unsolicited commercial email 8;; Keywords: mail, uce, unsolicited commercial email
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11 11
@@ -24,43 +24,68 @@
24 24
25;;; Commentary: 25;;; Commentary:
26 26
27;; Code in this file provides semi-automatic means of replying to 27;; The code in this file provides a semi-automatic means of replying
28;; UCE's you might get. It works currently only with Rmail and Gnus. 28;; to unsolicited commercial email (UCE) you might get. Currently, it
29;; If you would like to make it work with other mail readers, 29;; only works with Rmail and Gnus. If you would like to make it work
30;; Rmail-specific section is marked below. If you want to play with 30;; with other mail readers, see the mail-client dependent section of
31;; code, please let me know about your changes so I can incorporate 31;; uce-reply-to-uce. Please let me know about your changes so I can
32;; them. I'd appreciate it. 32;; incorporate them. I'd appreciate it.
33 33
34;; Function uce-reply-to-uce, if called when current message in RMAIL 34;; The command uce-reply-to-uce, if called when the current message
35;; buffer is a UCE, will setup *mail* buffer in the following way: it 35;; buffer is a UCE, will setup a reply *mail* buffer as follows. It
36;; scans full headers of message for 1) normal return address of 36;; scans the full headers of the message for: 1) the normal return
37;; sender (From, Reply-To lines); and puts these addresses into To: 37;; address of the sender (From, Reply-To lines), and puts these
38;; header, it also puts abuse@offenders.host address there 2) mailhub 38;; addresses into the To: header, along with abuse@offenders.host; 2)
39;; that first saw this message; and puts address of its postmaster 39;; the mailhub that first saw this message, and adds the address of
40;; into To: header 3) finally, it looks at Message-Id and adds 40;; its postmaster into the To: header; and 3), finally, it looks at
41;; posmaster of that host to the list of addresses. 41;; the Message-Id and adds the postmaster of that host to the list of
42 42;; addresses.
43;; Then, we add "Errors-To: nobody@localhost" header, so that if some 43
44;; of these addresses are not actually correct, we will never see 44;; Then, we add an "Errors-To: nobody@localhost" header, so that if
45;; some of these addresses are not actually correct, we will never see
45;; bounced mail. Also, mail-self-blind and mail-archive-file-name 46;; bounced mail. Also, mail-self-blind and mail-archive-file-name
46;; take no effect: the ideology is that we don't want to save junk or 47;; take no effect: the ideology is that we don't want to save junk or
47;; replies to junk. 48;; replies to junk.
48 49
49;; Then we put template into buffer (customizable message that 50;; Then we insert a template into the buffer (a customizable message
50;; explains what has happened), customizable signature, and the 51;; that explains what has happened), customizable signature, and the
51;; original message with full headers and envelope for postmasters. 52;; original message with full headers and envelope for postmasters.
52;; Then buffer is left for editing. 53;; Then the buffer is left for editing.
53 54
54;; The reason that function uce-reply-to-uce is Rmail dependant is 55;; The reason that the function uce-reply-to-uce is mail-client
55;; that we want full headers of the original message, nothing 56;; dependent is that we want the full headers of the original message,
56;; stripped. If we use normal means of inserting of the original 57;; nothing stripped. If we use the normal means of inserting the
57;; message into *mail* buffer headers like Received: (not really 58;; original message into the *mail* buffer, headers like Received:
58;; headers, but envelope lines) will be stripped while they bear 59;; (not really headers, but envelope lines) will be stripped, while
59;; valuable for us and postmasters information. I do wish that there 60;; they bear valuable information for us and postmasters. I do wish
60;; would be some way to write this function in some portable way, but 61;; that there would be some portable way to write this function, but I
61;; I am not aware of any. 62;; am not aware of any.
62 63
63;;; Change log: 64;; Usage:
65
66;; Place uce.el in your load-path (and optionally byte-compile it).
67;; Add the following line to your ~/.emacs:
68;; (autoload 'uce-reply-to-uce "uce" "Reply to UCEs" t nil)
69;; If you want to use it with Gnus rather than Rmail:
70;; (setq uce-mail-reader 'gnus)
71
72;; Options:
73
74;; uce-message-text is a template that will be inserted into buffer.
75;; It has a reasonable default. If you want to write some scarier
76;; one, please do so and send it to me. Please keep it polite.
77
78;; uce-signature behaves just like mail-signature. If nil, nothing is
79;; inserted, if t, file ~/.signature is used, if a string, its
80;; contents are inserted into buffer.
81
82;; uce-uce-separator is a line that separates your message from the
83;; UCE that you enclose.
84
85;; uce-subject-line will be used as the subject of the outgoing message.
86
87
88;;; Change Log:
64 89
65;; Dec 10, 1996 -- posted draft version to gnu.sources.emacs 90;; Dec 10, 1996 -- posted draft version to gnu.sources.emacs
66 91
@@ -83,39 +108,11 @@
83;; latest Gnus. Lars told him it should work for all versions of Gnus 108;; latest Gnus. Lars told him it should work for all versions of Gnus
84;; younger than three years. 109;; younger than three years.
85 110
86;; Setup:
87
88;; Add the following line to your ~/.emacs:
89
90;; (autoload 'uce-reply-to-uce "uce" "Reply to UCEs" t nil)
91
92;; If you want to use it with Gnus also use
93
94;; (setq uce-mail-reader 'gnus)
95
96;; store this file (uce.el) somewhere in load-path and byte-compile it.
97
98;;; Variables:
99
100;; uce-message-text is template that will be inserted into buffer. It
101;; has reasonable default. If you want to write some scarier one,
102;; please do so and send it to me. Please keep it polite.
103
104;; uce-signature behaves just like mail-signature. If nil, nothing is
105;; inserted, if t, file ~/.signature is used, if a string, its
106;; contents are inserted into buffer.
107
108;; uce-uce-separator is line that separates your message from the UCE
109;; that you enclose.
110
111;; uce-subject-line will be used as subject of outgoing message. If
112;; nil, left blank.
113 111
114;;; Code: 112;;; Code:
115 113
116(defvar gnus-original-article-buffer) 114(defvar gnus-original-article-buffer)
117(defvar mail-reply-buffer) 115(defvar mail-reply-buffer)
118(defvar rmail-current-message)
119 116
120(require 'sendmail) 117(require 'sendmail)
121;; Those sections of code which are dependent upon 118;; Those sections of code which are dependent upon
@@ -184,7 +181,7 @@ on beginning of some line from the spamming list. So, when you set it
184up, it might be a good idea to actually use this feature. 181up, it might be a good idea to actually use this feature.
185 182
186Value nil means insert no text by default, lets you type it in." 183Value nil means insert no text by default, lets you type it in."
187 :type 'string 184 :type '(choice (const nil) string)
188 :group 'uce) 185 :group 'uce)
189 186
190(defcustom uce-uce-separator 187(defcustom uce-uce-separator
@@ -206,7 +203,7 @@ as your signature."
206 "Errors-To: nobody@localhost\nPrecedence: bulk\n" 203 "Errors-To: nobody@localhost\nPrecedence: bulk\n"
207 "Additional headers to use when responding to a UCE with \\[uce-reply-to-uce]. 204 "Additional headers to use when responding to a UCE with \\[uce-reply-to-uce].
208These are mostly meant for headers that prevent delivery errors reporting." 205These are mostly meant for headers that prevent delivery errors reporting."
209 :type 'string 206 :type '(choice (const nil) string)
210 :group 'uce) 207 :group 'uce)
211 208
212(defcustom uce-subject-line 209(defcustom uce-subject-line
@@ -215,40 +212,47 @@ These are mostly meant for headers that prevent delivery errors reporting."
215 :type 'string 212 :type 'string
216 :group 'uce) 213 :group 'uce)
217 214
215;; End of user options.
216
217
218(defvar rmail-buffer)
219(declare-function rmail-msg-is-pruned "rmail" ())
218(declare-function mail-strip-quoted-names "mail-utils" (address)) 220(declare-function mail-strip-quoted-names "mail-utils" (address))
219(declare-function rmail-maybe-set-message-counters "rmail" ()) 221(declare-function rmail-maybe-set-message-counters "rmail" ())
220(declare-function rmail-msgbeg "rmail" (n)) 222(declare-function rmail-msgbeg "rmail" (n))
221(declare-function rmail-msgend "rmail" (n)) 223(declare-function rmail-msgend "rmail" (n))
222(declare-function rmail-toggle-header "rmail" (&optional arg)) 224(declare-function rmail-toggle-header "rmail" (&optional arg))
223 225
224 226;;;###autoload
225(defun uce-reply-to-uce (&optional ignored) 227(defun uce-reply-to-uce (&optional ignored)
226 "Send reply to UCE in Rmail. 228 "Compose a reply to unsolicited commercial email (UCE).
227UCE stands for unsolicited commercial email. Function will set up reply 229Sets up a reply buffer addressed to: the sender, his postmaster,
228buffer with default To: to the sender, his postmaster, his abuse@ 230his abuse@ address, and the postmaster of the mail relay used.
229address, and postmaster of the mail relay used." 231You might need to set `uce-mail-reader' before using this."
230 (interactive) 232 (interactive)
233 ;; Start of mail-client dependent section.
231 (let ((message-buffer 234 (let ((message-buffer
232 (cond ((eq uce-mail-reader 'gnus) gnus-original-article-buffer) 235 (cond ((eq uce-mail-reader 'gnus) gnus-original-article-buffer)
233 ((eq uce-mail-reader 'rmail) "RMAIL") 236 ((eq uce-mail-reader 'rmail) (bound-and-true-p rmail-buffer))
234 (t (error 237 (t (error
235 "Variable uce-mail-reader set to unrecognized value")))) 238 "Variable uce-mail-reader set to unrecognized value"))))
236 (full-header-p (and (eq uce-mail-reader 'rmail) 239 pruned)
237 (not (rmail-msg-is-pruned))))) 240 (or (and message-buffer (get-buffer message-buffer))
238 (or (get-buffer message-buffer) 241 (error "No mail buffer, cannot find UCE"))
239 (error "No buffer %s, cannot find UCE" message-buffer))
240 (switch-to-buffer message-buffer) 242 (switch-to-buffer message-buffer)
241 ;; We need the message with headers pruned. 243 ;; We need the message with headers pruned.
242 (if full-header-p 244 ;; Why? All we do is get the from and reply-to headers. ?
243 (rmail-toggle-header 1)) 245 (and (eq uce-mail-reader 'rmail)
246 (not (setq pruned (rmail-msg-is-pruned)))
247 (rmail-toggle-header 1))
244 (let ((to (mail-strip-quoted-names (mail-fetch-field "from" t))) 248 (let ((to (mail-strip-quoted-names (mail-fetch-field "from" t)))
245 (reply-to (mail-fetch-field "reply-to")) 249 (reply-to (mail-fetch-field "reply-to"))
246 temp) 250 temp)
247 ;; Initial setting of the list of recipients of our message; that's 251 ;; Initial setting of the list of recipients of our message; that's
248 ;; what they are pretending to be. 252 ;; what they are pretending to be.
249 (if to 253 (setq to (if to
250 (setq to (format "%s" (mail-strip-quoted-names to))) 254 (format "%s" (mail-strip-quoted-names to))
251 (setq to "")) 255 ""))
252 (if reply-to 256 (if reply-to
253 (setq to (format "%s, %s" to (mail-strip-quoted-names reply-to)))) 257 (setq to (format "%s, %s" to (mail-strip-quoted-names reply-to))))
254 (let (first-at-sign end-of-hostname sender-host) 258 (let (first-at-sign end-of-hostname sender-host)
@@ -260,31 +264,22 @@ address, and postmaster of the mail relay used."
260 to sender-host sender-host)))) 264 to sender-host sender-host))))
261 (setq mail-send-actions nil) 265 (setq mail-send-actions nil)
262 (setq mail-reply-buffer nil) 266 (setq mail-reply-buffer nil)
263 (cond ((eq uce-mail-reader 'gnus) 267 (when (eq uce-mail-reader 'rmail)
264 (copy-region-as-kill (point-min) (point-max))) 268 (rmail-toggle-header 0)
265 ((eq uce-mail-reader 'rmail) 269 (rmail-maybe-set-message-counters)) ; why?
266 (save-excursion 270 (copy-region-as-kill (point-min) (point-max))
267 (save-restriction 271 ;; Restore the initial header state we found.
268 (rmail-toggle-header 1) 272 (and pruned (rmail-toggle-header 1))
269 (widen)
270 (rmail-maybe-set-message-counters)
271 (copy-region-as-kill (rmail-msgbeg rmail-current-message)
272 (rmail-msgend rmail-current-message))))))
273 ;; Restore the pruned header state we found.
274 (if full-header-p
275 (rmail-toggle-header 0))
276 (switch-to-buffer "*mail*") 273 (switch-to-buffer "*mail*")
277 (erase-buffer) 274 (erase-buffer)
278 (setq temp (point))
279 (yank) 275 (yank)
280 (goto-char temp) 276 (goto-char (point-min))
281 (if (eq uce-mail-reader 'rmail) 277 ;; Delete any internal Rmail headers.
282 (progn 278 (when (eq uce-mail-reader 'rmail)
283 (forward-line 2) 279 (search-forward "\n\n")
284 (let ((case-fold-search t)) 280 (while (re-search-backward "^X-RMAIL" nil t)
285 (while (looking-at "Summary-Line:\\|Mail-From:") 281 (delete-region (point) (line-beginning-position 2)))
286 (forward-line 1))) 282 (goto-char (point-min)))
287 (delete-region temp (point))))
288 ;; Now find the mail hub that first accepted this message. 283 ;; Now find the mail hub that first accepted this message.
289 ;; This should try to find the last Received: header. 284 ;; This should try to find the last Received: header.
290 ;; Sometimes there may be other headers inbetween Received: headers. 285 ;; Sometimes there may be other headers inbetween Received: headers.
@@ -293,22 +288,15 @@ address, and postmaster of the mail relay used."
293 (re-search-forward "^Lines:") 288 (re-search-forward "^Lines:")
294 (beginning-of-line)) 289 (beginning-of-line))
295 ((eq uce-mail-reader 'rmail) 290 ((eq uce-mail-reader 'rmail)
296 (goto-char (point-min)) 291 (search-forward "\n\n")))
297 (search-forward "*** EOOH ***\n")
298 (beginning-of-line)
299 (forward-line -1)))
300 (re-search-backward "^Received:") 292 (re-search-backward "^Received:")
301 (beginning-of-line)
302 ;; Is this always good? It's the only thing I saw when I checked 293 ;; Is this always good? It's the only thing I saw when I checked
303 ;; a few messages. 294 ;; a few messages.
304 (let ((eol (save-excursion (end-of-line) (point)))) 295 ;;(if (not (re-search-forward ": \\(from\\|by\\) " eol t))
305 ;;(if (not (re-search-forward ": \\(from\\|by\\) " eol t)) 296 (unless (re-search-forward "\\(from\\|by\\) " (line-end-position) 'move)
306 (if (not (re-search-forward "\\(from\\|by\\) " eol t)) 297 (if (looking-at "[ \t\n]+\\(from\\|by\\) ")
307 (progn 298 (goto-char (match-end 0))
308 (goto-char eol) 299 (error "Failed to extract hub address")))
309 (if (looking-at "[ \t\n]+\\(from\\|by\\) ")
310 (goto-char (match-end 0))
311 (error "Failed to extract hub address")))))
312 (setq temp (point)) 300 (setq temp (point))
313 (search-forward " ") 301 (search-forward " ")
314 (forward-char -1) 302 (forward-char -1)
@@ -317,34 +305,25 @@ address, and postmaster of the mail relay used."
317 (setq to (format "%s, postmaster@%s" 305 (setq to (format "%s, postmaster@%s"
318 to (buffer-substring temp (point))))) 306 to (buffer-substring temp (point)))))
319 ;; Also look at the message-id, it helps *very* often. 307 ;; Also look at the message-id, it helps *very* often.
320 (if (and (search-forward "\nMessage-Id: " nil t) 308 (and (search-forward "\nMessage-Id: " nil t)
321 ;; Not all Message-Id:'s have an `@' sign. 309 ;; Not all Message-Id:'s have an `@' sign.
322 (let ((bol (point)) 310 (search-forward "@" (line-end-position) t)
323 eol) 311 (progn
324 (end-of-line) 312 (setq temp (point))
325 (setq eol (point)) 313 (search-forward ">")
326 (goto-char bol) 314 (forward-char -1)
327 (search-forward "@" eol t))) 315 (if (string-match "\\." (buffer-substring temp (point)))
328 (progn 316 (setq to (format "%s, postmaster@%s"
329 (setq temp (point)) 317 to (buffer-substring temp (point)))))))
330 (search-forward ">") 318 (when (eq uce-mail-reader 'gnus)
331 (forward-char -1) 319 ;; Does Gnus always have Lines: in the end?
332 (if (string-match "\\." (buffer-substring temp (point))) 320 (re-search-forward "^Lines:")
333 (setq to (format "%s, postmaster@%s" 321 (beginning-of-line)
334 to (buffer-substring temp (point))))))) 322 (setq temp (point))
335 (cond ((eq uce-mail-reader 'gnus) 323 (search-forward "\n\n" nil t)
336 ;; Does Gnus always have Lines: in the end? 324 (forward-line -1)
337 (re-search-forward "^Lines:") 325 (delete-region temp (point)))
338 (beginning-of-line)) 326 ;; End of mail-client dependent section.
339 ((eq uce-mail-reader 'rmail)
340 (search-forward "\n*** EOOH ***\n")
341 (forward-line -1)))
342 (setq temp (point))
343 (search-forward "\n\n" nil t)
344 (if (eq uce-mail-reader 'gnus)
345 (forward-line -1))
346 (delete-region temp (point))
347 ;; End of Rmail dependent section.
348 (auto-save-mode auto-save-default) 327 (auto-save-mode auto-save-default)
349 (mail-mode) 328 (mail-mode)
350 (goto-char (point-min)) 329 (goto-char (point-min))
@@ -387,7 +366,7 @@ address, and postmaster of the mail relay used."
387 (if to (goto-char to)) 366 (if to (goto-char to))
388 (or to (set-buffer-modified-p nil)) 367 (or to (set-buffer-modified-p nil))
389 ;; Run hooks before we leave buffer for editing. Reasonable usage 368 ;; Run hooks before we leave buffer for editing. Reasonable usage
390 ;; might be to set up special key bindings, replace standart 369 ;; might be to set up special key bindings, replace standard
391 ;; functions in mail-mode, etc. 370 ;; functions in mail-mode, etc.
392 (run-hooks 'mail-setup-hook 'uce-setup-hook)))) 371 (run-hooks 'mail-setup-hook 'uce-setup-hook))))
393 372