aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1998-06-09 23:40:56 +0000
committerRichard M. Stallman1998-06-09 23:40:56 +0000
commitdc99d85edbd83301f6c1a14310287ec753bdac3d (patch)
tree36bdc8135148240533bedc9737ca4903cd489b61
parentf2ad0664957310ca41e4fef61eafa14982502f77 (diff)
downloademacs-dc99d85edbd83301f6c1a14310287ec753bdac3d.tar.gz
emacs-dc99d85edbd83301f6c1a14310287ec753bdac3d.zip
(uce-message-text): Change the text of message that is sent.
(uce-reply-to-uce): Do not assume all Received lines are on top of message without headers like `From' or `To'. (uce-reply-to-uce): Parse Received lines better. (uce-mail-reader): New user option. (uce-reply-to uce): Add support for Gnus. User is supposed to set uce-mail-reader to `gnus' if using Gnus to read mail. The default is to assume Rmail. There's no magic to determine what mail reader is currently active, so it is not possible to mix using uce.el with Rmail and Gnus.
-rw-r--r--lisp/mail/uce.el338
1 files changed, 200 insertions, 138 deletions
diff --git a/lisp/mail/uce.el b/lisp/mail/uce.el
index 1cec136da38..3b0956159dd 100644
--- a/lisp/mail/uce.el
+++ b/lisp/mail/uce.el
@@ -1,10 +1,9 @@
1;;; uce.el --- facilitate reply to unsolicited commercial email 1;;; uce.el --- facilitate reply to unsolicited commercial email
2 2
3;; Copyright (C) 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1996, 1998 Free Software Foundation, Inc.
4 4
5;; Author: stanislav shalunov <shalunov@math.wisc.edu> 5;; Author: stanislav shalunov <shalunov@mccme.ru>
6;; Created: 10 Dec 1996 6;; Created: 10 Dec 1996
7;; Version: 1.0
8;; Keywords: uce, unsolicited commercial email 7;; Keywords: uce, unsolicited commercial email
9 8
10;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
@@ -27,13 +26,11 @@
27;;; Commentary: 26;;; Commentary:
28 27
29;; Code in this file provides semi-automatic means of replying to 28;; Code in this file provides semi-automatic means of replying to
30;; UCE's you might get. It works currently only with Rmail. If you 29;; UCE's you might get. It works currently only with Rmail and Gnus.
31;; would like to make it work with other mail readers, Rmail-specific 30;; If you would like to make it work with other mail readers,
32;; section is marked below. If you want to play with code, would you 31;; Rmail-specific section is marked below. If you want to play with
33;; please grab the newest version from 32;; code, please let me know about your changes so I can incorporate
34;; http://math.wisc.edu/~shalunov/uce.el and let me know, if you would 33;; them. I'd appreciate it.
35;; like, about your changes so I can incorporate them. I'd appreciate
36;; it.
37 34
38;; Function uce-reply-to-uce, if called when current message in RMAIL 35;; Function uce-reply-to-uce, if called when current message in RMAIL
39;; buffer is a UCE, will setup *mail* buffer in the following way: it 36;; buffer is a UCE, will setup *mail* buffer in the following way: it
@@ -75,12 +72,23 @@
75;; Dec 17, 1996 -- made scanning for host names little bit more clever 72;; Dec 17, 1996 -- made scanning for host names little bit more clever
76;; (obviously bogus stuff like localhost is now ignored). 73;; (obviously bogus stuff like localhost is now ignored).
77 74
75;; Nov 11, 1997 -- incorporated changes from Mikael Djurfeldt
76;; <mdj@nada.kth.se> to make uce.el work with Gnus. Changed the text
77;; of message that is sent.
78
79;; Dec 3, 1997 -- changes from Gareth Jones <gdj1@gdjones.demon.co.uk>
80;; handling Received headers following some line like `From:'.
81
78;;; Setup: 82;;; Setup:
79 83
80;; put in your ~./emacs the following line: 84;; put in your ~./emacs the following line:
81 85
82;; (autoload 'uce-reply-to-uce "uce" "Reply to UCEs" t nil) 86;; (autoload 'uce-reply-to-uce "uce" "Reply to UCEs" t nil)
83 87
88;; If you want to use it with Gnus also use
89
90;; (setq uce-mail-reader 'gnus)
91
84;; store this file (uce.el) somewhere in load-path and byte-compile it. 92;; store this file (uce.el) somewhere in load-path and byte-compile it.
85 93
86;;; Variables: 94;;; Variables:
@@ -102,7 +110,13 @@
102;;; Code: 110;;; Code:
103 111
104(require 'sendmail) 112(require 'sendmail)
105(require 'rmail) 113;; Those sections of code which are dependent upon
114;; RMAIL are only evaluated if we have received a message with RMAIL...
115;;(require 'rmail)
116
117(defvar uce-mail-reader 'rmail
118 "A symbol indicating which mail reader you are using.
119Choose from: gnus, rmail.")
106 120
107(defgroup uce nil 121(defgroup uce nil
108 "Facilitate reply to unsolicited commercial email." 122 "Facilitate reply to unsolicited commercial email."
@@ -130,15 +144,25 @@ If you have any list of people you send unsolicited commercial emails to,
130REMOVE me from such list immediately. I suggest that you make this list 144REMOVE me from such list immediately. I suggest that you make this list
131just empty. 145just empty.
132 146
147 ----------------------------------------------------
148
149If you are not an administrator of any site and still have received
150this message then your email address is being abused by some spammer.
151They fake your address in From: or Reply-To: header. In this case,
152you might want to show this message to your system administrator, and
153ask him/her to investigate this matter.
154
133Note to the postmaster(s): I append the text of UCE in question to 155Note to the postmaster(s): I append the text of UCE in question to
134this message, I would like to hear from you about action(s) taken. 156this message; I would like to hear from you about action(s) taken.
135This message has been sent to postmasters at the host that is 157This message has been sent to postmasters at the host that is
136mentioned as original sender's host and to the postmaster whose host 158mentioned as original sender's host (I do realize that it may be
137was used as mail relay for this message. If message was sent not by 159faked, but I think that if your domain name is being abused this way
138your user, could you please compare time when this message was sent 160you might want to learn about it, and take actions) and to the
139(use time in Received: field of the envelope rather than Date: field) 161postmaster whose host was used as mail relay for this message. If
140with your sendmail logs and see what host was using your sendmail at 162message was sent not by your user, could you please compare time when
141this moment of time. 163this message was sent (use time in Received: field of the envelope
164rather than Date: field) with your sendmail logs and see what host was
165using your sendmail at this moment of time.
142 166
143Thank you." 167Thank you."
144 168
@@ -185,127 +209,165 @@ These are mostly meant for headers that prevent delivery errors reporting."
185UCE stands for unsolicited commercial email. Function will set up reply 209UCE stands for unsolicited commercial email. Function will set up reply
186buffer with default To: to the sender, his postmaster, his abuse@ 210buffer with default To: to the sender, his postmaster, his abuse@
187address, and postmaster of the mail relay used." 211address, and postmaster of the mail relay used."
188 (interactive "P") 212 (interactive)
189 (let ((to (mail-strip-quoted-names (mail-fetch-field "from" t))) 213 (let ((message-buffer
190 (reply-to (mail-fetch-field "reply-to")) 214 (cond ((eq uce-mail-reader 'gnus) "*Article*")
191 temp) 215 ((eq uce-mail-reader 'rmail) "RMAIL")
192 ;; Initial setting of the list of recipients of our message; that's 216 (t (error
193 ;; what they are pretending to be (and in many cases, really are). 217 "Variable uce-mail-reader set to unrecognized value")))))
194 (if to 218 (or (get-buffer message-buffer)
195 (setq to (format "%s" (mail-strip-quoted-names to))) 219 (error (concat "No buffer " message-buffer ", cannot find UCE")))
196 (setq to "")) 220 (switch-to-buffer message-buffer)
197 (if reply-to 221 (let ((to (mail-strip-quoted-names (mail-fetch-field "from" t)))
198 (setq to (format "%s, %s" to (mail-strip-quoted-names reply-to)))) 222 (reply-to (mail-fetch-field "reply-to"))
199 (let (first-at-sign end-of-hostname sender-host) 223 temp)
200 (setq first-at-sign (string-match "@" to) 224 ;; Initial setting of the list of recipients of our message; that's
201 end-of-hostname (string-match "[ ,>]" to first-at-sign) 225 ;; what they are pretending to be.
202 sender-host (substring to first-at-sign end-of-hostname))
203 (if (string-match "\\." sender-host)
204 (setq to (format "%s, postmaster%s, abuse%s"
205 to sender-host sender-host))))
206 (setq mail-send-actions nil)
207 (setq mail-reply-buffer nil)
208 ;; Begin of Rmail dependant section.
209 (or (get-buffer "RMAIL")
210 (error "No buffer RMAIL, cannot find UCE"))
211 (switch-to-buffer "RMAIL")
212 (save-excursion
213 (save-restriction
214 (widen)
215 (rmail-maybe-set-message-counters)
216 (copy-region-as-kill (rmail-msgbeg rmail-current-message)
217 (rmail-msgend rmail-current-message))))
218 (switch-to-buffer "*mail*")
219 (erase-buffer)
220 (setq temp (point))
221 (yank)
222 (goto-char temp)
223 (forward-line 2)
224 (while (looking-at "Summary-Line:\\|Mail-From:")
225 (forward-line 1))
226 (delete-region temp (point))
227 ;; Now find the mail hub that first accepted this message.
228 (while (or (looking-at "Received:")
229 (looking-at " ")
230 (looking-at "\t"))
231 (forward-line 1))
232 (while (or (looking-at " ")
233 (looking-at "\t"))
234 (forward-line -1))
235 ;; Is this always good? It's the only thing I saw when I checked
236 ;; a few messages.
237 (search-forward ": from ")
238 (setq temp (point))
239 (search-forward " ")
240 (forward-char -1)
241 ;; And add its postmaster to the list of addresses.
242 (if (string-match "\\." (buffer-substring temp (point)))
243 (setq to (format "%s, postmaster@%s"
244 to (buffer-substring temp (point)))))
245 ;; Also look at the message-id, it helps *very* often.
246 (search-forward "\nMessage-Id: ")
247 (search-forward "@")
248 (setq temp (point))
249 (search-forward ">")
250 (forward-char -1)
251 (if (string-match "\\." (buffer-substring temp (point)))
252 (setq to (format "%s, postmaster@%s"
253 to (buffer-substring temp (point)))))
254 (search-forward "\n*** EOOH ***\n")
255 (forward-line -1)
256 (setq temp (point))
257 (search-forward "\n\n" nil t)
258 (delete-region temp (point))
259 ;; End of Rmail dependent section.
260 (auto-save-mode auto-save-default)
261 (mail-mode)
262 (goto-char (point-min))
263 (insert "To: ")
264 (save-excursion
265 (if to 226 (if to
266 (let ((fill-prefix "\t") 227 (setq to (format "%s" (mail-strip-quoted-names to)))
267 (address-start (point))) 228 (setq to ""))
268 (insert to "\n") 229 (if reply-to
269 (fill-region-as-paragraph address-start (point))) 230 (setq to (format "%s, %s" to (mail-strip-quoted-names reply-to))))
270 (newline)) 231 (let (first-at-sign end-of-hostname sender-host)
271 (insert "Subject: " uce-subject-line "\n") 232 (setq first-at-sign (string-match "@" to)
272 (if uce-default-headers 233 end-of-hostname (string-match "[ ,>]" to first-at-sign)
273 (insert uce-default-headers)) 234 sender-host (substring to first-at-sign end-of-hostname))
274 (if mail-default-headers 235 (if (string-match "\\." sender-host)
275 (insert mail-default-headers)) 236 (setq to (format "%s, postmaster%s, abuse%s"
276 (if mail-default-reply-to 237 to sender-host sender-host))))
277 (insert "Reply-to: " mail-default-reply-to "\n\n")) 238 (setq mail-send-actions nil)
278 (mail-sendmail-delimit-header) 239 (setq mail-reply-buffer nil)
279 ;; Insert all our text. Then go back to the place where we started. 240 (cond ((eq uce-mail-reader 'gnus)
280 (if to (setq to (point))) 241 (article-hide-headers -1)
281 ;; Text of ranting. 242 (copy-region-as-kill (point-min) (point-max))
282 (if uce-message-text 243 (article-hide-headers))
283 (insert uce-message-text)) 244 ((eq uce-mail-reader 'rmail)
284 ;; Signature. 245 (save-excursion
285 (cond ((eq uce-signature t) 246 (save-restriction
286 (if (file-exists-p "~/.signature") 247 (widen)
287 (progn 248 (rmail-maybe-set-message-counters)
288 (insert "\n\n-- \n") 249 (copy-region-as-kill (rmail-msgbeg rmail-current-message)
289 (insert-file "~/.signature") 250 (rmail-msgend rmail-current-message))))))
290 ;; Function insert-file leaves point where it was, 251 (switch-to-buffer "*mail*")
291 ;; while we want to place signature in the ``middle'' 252 (erase-buffer)
292 ;; of the message. 253 (setq temp (point))
293 (exchange-point-and-mark)))) 254 (yank)
294 (uce-signature 255 (goto-char temp)
295 (insert "\n\n-- \n" uce-signature))) 256 (if (eq uce-mail-reader 'rmail)
296 ;; And text of the original message. 257 (progn
297 (if uce-uce-separator 258 (forward-line 2)
298 (insert "\n\n" uce-uce-separator "\n")) 259 (while (looking-at "Summary-Line:\\|Mail-From:")
299 ;; If message doesn't end with a newline, insert it. 260 (forward-line 1))
300 (goto-char (point-max)) 261 (delete-region temp (point))))
301 (or (bolp) (newline))) 262 ;; Now find the mail hub that first accepted this message.
302 ;; And go back to the beginning of text. 263 ;; This should try to find the last Received: header.
303 (if to (goto-char to)) 264 ;; Sometimes there may be other headers inbetween Received: headers.
304 (or to (set-buffer-modified-p nil)) 265 (cond ((eq uce-mail-reader 'gnus)
305 ;; Run hooks before we leave buffer for editing. Reasonable usage 266 ;; Does Gnus always have Lines: in the end?
306 ;; might be to set up special key bindings, replace standart 267 (re-search-forward "^Lines:")
307 ;; functions in mail-mode, etc. 268 (beginning-of-line))
308 (run-hooks 'mail-setup-hook 'uce-setup-hook))) 269 ((eq uce-mail-reader 'rmail)
270 (beginning-of-buffer)
271 (search-forward "*** EOOH ***\n")
272 (beginning-of-line)
273 (forward-line -1)))
274 (re-search-backward "^Received:")
275 (beginning-of-line)
276 ;; Is this always good? It's the only thing I saw when I checked
277 ;; a few messages.
278 (let ((eol (save-excursion (end-of-line) (point))))
279 ;;(if (not (re-search-forward ": \\(from\\|by\\) " eol t))
280 (if (not (re-search-forward "\\(from\\|by\\) " eol t))
281 (progn
282 (goto-char eol)
283 (if (looking-at "[ \t\n]+\\(from\\|by\\) ")
284 (goto-char (match-end 0))
285 (error "Failed to extract hub address")))))
286 (setq temp (point))
287 (search-forward " ")
288 (forward-char -1)
289 ;; And add its postmaster to the list of addresses.
290 (if (string-match "\\." (buffer-substring temp (point)))
291 (setq to (format "%s, postmaster@%s"
292 to (buffer-substring temp (point)))))
293 ;; Also look at the message-id, it helps *very* often.
294 (if (and (search-forward "\nMessage-Id: " nil t)
295 ;; Not all Message-Id:'s have an `@' sign.
296 (let ((bol (point))
297 eol)
298 (end-of-line)
299 (setq eol (point))
300 (goto-char bol)
301 (search-forward "@" eol t)))
302 (progn
303 (setq temp (point))
304 (search-forward ">")
305 (forward-char -1)
306 (if (string-match "\\." (buffer-substring temp (point)))
307 (setq to (format "%s, postmaster@%s"
308 to (buffer-substring temp (point)))))))
309 (cond ((eq uce-mail-reader 'gnus)
310 ;; Does Gnus always have Lines: in the end?
311 (re-search-forward "^Lines:")
312 (beginning-of-line))
313 ((eq uce-mail-reader 'rmail)
314 (search-forward "\n*** EOOH ***\n")
315 (forward-line -1)))
316 (setq temp (point))
317 (search-forward "\n\n" nil t)
318 (if (eq uce-mail-reader 'gnus)
319 (forward-line -1))
320 (delete-region temp (point))
321 ;; End of Rmail dependent section.
322 (auto-save-mode auto-save-default)
323 (mail-mode)
324 (goto-char (point-min))
325 (insert "To: ")
326 (save-excursion
327 (if to
328 (let ((fill-prefix "\t")
329 (address-start (point)))
330 (insert to "\n")
331 (fill-region-as-paragraph address-start (point)))
332 (newline))
333 (insert "Subject: " uce-subject-line "\n")
334 (if uce-default-headers
335 (insert uce-default-headers))
336 (if mail-default-headers
337 (insert mail-default-headers))
338 (if mail-default-reply-to
339 (insert "Reply-to: " mail-default-reply-to "\n"))
340 (insert mail-header-separator "\n")
341 ;; Insert all our text. Then go back to the place where we started.
342 (if to (setq to (point)))
343 ;; Text of ranting.
344 (if uce-message-text
345 (insert uce-message-text))
346 ;; Signature.
347 (cond ((eq uce-signature t)
348 (if (file-exists-p "~/.signature")
349 (progn
350 (insert "\n\n-- \n")
351 (insert-file "~/.signature")
352 ;; Function insert-file leaves point where it was,
353 ;; while we want to place signature in the ``middle''
354 ;; of the message.
355 (exchange-point-and-mark))))
356 (uce-signature
357 (insert "\n\n-- \n" uce-signature)))
358 ;; And text of the original message.
359 (if uce-uce-separator
360 (insert "\n\n" uce-uce-separator "\n"))
361 ;; If message doesn't end with a newline, insert it.
362 (goto-char (point-max))
363 (or (bolp) (newline)))
364 ;; And go back to the beginning of text.
365 (if to (goto-char to))
366 (or to (set-buffer-modified-p nil))
367 ;; Run hooks before we leave buffer for editing. Reasonable usage
368 ;; might be to set up special key bindings, replace standart
369 ;; functions in mail-mode, etc.
370 (run-hooks 'mail-setup-hook 'uce-setup-hook))))
309 371
310(defun uce-insert-ranting (&optional ignored) 372(defun uce-insert-ranting (&optional ignored)
311 "Insert text of the usual reply to UCE into current buffer." 373 "Insert text of the usual reply to UCE into current buffer."