view lisp/mail/uce.el @ 94414:d86cb59eea9f

2008-04-27 Carsten Dominik <dominik@science.uva.nl> * org/org.el (org-html-level-start): Always have id's in HTML (org-export-as-html): Use `org-link-protocols' to retrieve the export form of the link. (org-add-link-type): Final parameter renamed from PUBLISH. Better documentation of how it is to be used. Avoid double entries for the same link type. (org-add-link-props): New function. (org-modules-loaded): New variable. (org-load-modules-maybe, org-set-modules): New function. (org-modules): New option. (org-mode, org-cycle, orgstruct-mode, org-run-like-in-org-mode) (orgtbl-mode, org-store-link, org-insert-link-global) (org-open-at-point): Call `org-load-modules-maybe'. (org-search-view): Add more text properties. (org-agenda-schedule, org-agenda-deadline): Allow also in search-type agendas. (org-search-view): Order of arguments has been changed. Interpret prefix-arg as TODO-ONLY. (org-agenda, org-run-agenda-series, org-agenda-manipulate-query): Take new argument order of `org-search-view' into account. (org-todo-only): New variable. (org-search-syntax-table): New variable and function. (org-search-view): Do the search with the special syntax table. (define-obsolete-function-alias): Make work with XEmacs. (org-add-planning-info): Use old date as default when modifying an existing deadline or scheduled item. (org-agenda-compute-time-span): Make argument N optional. (org-agenda-format-date-aligned): Require `cal-iso'. (org-agenda-list): Include week into into agenda heading, don't list it at each date (only on Mondays). (org-read-date-analyze): Define local variable `iso-date'. (org-agenda-format-date-aligned): Remove dependency on `calendar-time-from-absolute'. (org-remember-apply-template, org-go-to-remember-target): Interpret filenames relative to `org-directory'. (org-complete): Silently fail when trying to complete keywords that don't have a default value. (org-get-current-options): Added a #+DATE: option. (org-additional-option-like-keywords): Removed "DATE:" from the list of additional keywords. (org-export-as-html): Removed (current-time) as unnecessary second argument of `format-time-string'. (org-clock-find-position): Handle special case at end of buffer. (org-agenda-day-view): New argument DAY-OF-YEAR, pass it on to `org-agenda-change-time-span'. (org-agenda-week-view): New argument ISO-WEEK, pass it on to `org-agenda-change-time-span'. (org-agenda-month-view): New argument MONTH, pass it on to `org-agenda-change-time-span'. (org-agenda-year-view): New argument YEAR, pass it on to `org-agenda-change-time-span'. (org-agenda-change-time-span): New optional argument N, pass it on to `org-agenda-compute-time-span'. (org-agenda-compute-time-span): New argument N, interpret it by changing the starting day. (org-small-year-to-year): New function. (org-scheduled-past-days): Respect `org-scheduled-past-days'. (org-auto-repeat-maybe): Make sure that repeating dates are pushed into the future, and that the shift is at least one interval, never 0. (org-update-checkbox-count): Fix bug with checkbox counting. (org-add-note): New command. (org-add-log-setup): Renamed from `org-add-log-maybe'. (org-log-note-headings): New entry for plain notes (i.e. notes not related to state changes or clocking). (org-get-org-file): Check for availability of `remember-data-file'. (org-cached-entry-get): Allow a regexp value for `org-use-property-inheritance'. (org-use-property-inheritance): Allow regexp value. Fix bug in customization type. (org-use-tag-inheritance): Allow a list and a regexp value for this variable. (org-scan-tags, org-get-tags-at): Implement selective tag inheritance. (org-entry-get): Respect value `selective' for the INHERIT argument. (org-tag-inherit-p, org-property-inherit-p): New functions. (org-agenda-format-date-aligned): Allow 10 characters for weekday, to acomodate German locale. (org-add-archive-files): New function. (org-agenda-files): New argument `ext', to get archive files as well. (org-tbl-menu): Protect the use of variables that are only available when org-table.el gets loaded. (org-read-agenda-file-list): Error if `org-agenda-files' is a single directory. (org-open-file): Allow a batch process to trigger waiting after executing a system command. (org-store-link): Link to headline when there is not target and no region in an org-mode buffer when creating a link. (org-link-types-re): New variable. (org-make-link-regexps): Compute `org-link-types-re'. (org-make-link-description-function): New option. (org-agenda-date, org-agenda-date-weekend): New faces. (org-archive-sibling-heading): New option. (org-archive-to-archive-sibling): New function. (org-iswitchb): New command. (org-buffer-list): New function. (org-agenda-columns): Also try the #+COLUMNS line in the buffer associated with the entry at point (or with the first entry in the agenda view). (org-modules): Add entry for org-bibtex.el. (org-completion-fallback-command): Moved into `org-completion' group. (org-clock-heading-function): Moved to `org-progress' group. (org-auto-repeat-maybe): Make sure that a note can be enforces if `org-log-repeat' is `note'. (org-modules): Allow additional symbols for external packages. (org-ctrl-c-ctrl-c): Allow for `org-clock-overlays' to be undefined. (org-clock-goto): Hide drawers after showing an entry with `org-clock-goto.' (org-shiftup, org-shiftdown, org-shiftright, org-shiftleft): Try also a clocktable block shift. (org-clocktable-try-shift): New function. (org-columns-hscoll-title): New function. (org-columns-previous-hscroll): New variable. (org-columns-full-header-line-format): New variable. (org-columns-display-here-title, org-columns-remove-overlays): Install `org-columns-hscoll-title' in post-command-hook. * org/org.el: Split into many small files. * org/org-agenda.el: New file, split off from org.el. * org/org-archive.el: New file, split off from org.el. * org/org-bbdb.el: New file. * org/org-bibtex.el: New file, split off from org.el. * org/org-clock.el: New file, split off from org.el. * org/org-colview.el: New file, split off from org.el. * org/org-compat.el: New file, split off from org.el. * org/org-exp.el: New file, split off from org.el. * org/org-faces.el: New file, split off from org.el. * org/org-gnus.el: New file, split off from org.el. * org/org-info.el: New file, split off from org.el. * org/org-infojs.el: New file. * org/org-irc.el: New file. * org/org-macs.el: New file, split off from org.el. * org/org-mew.el: New file. * org/org-mhe.el: New file, split off from org.el. * org/org-publish.el: New file, split off from org.el. * org/org-remember.el: New file, split off from org.el. * org/org-rmail.el: New file, split off from org.el. * org/org-table.el: New file, split off from org.el. * org/org-vm.el: New file, split off from org.el. * org/org-wl.el: New file, split off from org.el. 2008-04-27 Jason Riedy <jason@acm.org> * lisp/org-table.el (orgtbl-to-generic): Add a :remove-nil-lines parameter that supresses lines that evaluate to NIL. (orgtbl-get-fmt): New inline function for picking apart formats that may be lists. (orgtbl-apply-fmt): New inline function for applying formats that may be functions. (orgtbl-eval-str): New inline function for strings that may be functions. (orgtbl-format-line, orgtbl-to-generic): Use and document. (orgtbl-to-latex, orgtbl-to-texinfo): Document. (*orgtbl-llfmt*, *orgtbl-llstart*) (*orgtbl-llend*): Dynamic variables for last-line formatting. (orgtbl-format-section): Shift formatting to support detecting the last line and formatting it specially. (orgtbl-to-generic): Document :ll* formats. Set to the non-ll formats unless overridden. (orgtbl-to-latex): Suggest using :llend to suppress the final \\. (*orgtbl-table*, *orgtbl-rtn*): Dynamically bound variables to hold the input collection of lines and output formatted text. (*orgtbl-hline*, *orgtbl-sep*, *orgtbl-fmt*, *orgtbl-efmt*, (*orgtbl-lfmt*, *orgtbl-lstart*, *orgtbl-lend*): Dynamically bound format parameters. (orgtbl-format-line): New function encapsulating formatting for a single line. (orgtbl-format-section): Similar for each section. Rebinding the dynamic vars customizes the formatting for each section. (orgtbl-to-generic): Use orgtbl-format-line and orgtbl-format-section. (org-get-param): Now unused, so delete. (orgtbl-gather-send-defs): New function to gather all the SEND definitions before a table. (orgtbl-send-replace-tbl): New function to find the RECEIVE corresponding to the current name. (orgtbl-send-table): Use the previous two functions and implement multiple destinations for each table. * doc/org.texi (A LaTeX example): Note that fmt may be a one-argument function, and efmt may be a two-argument function. (Radio tables): Document multiple destinations. 2008-04-27 Carsten Dominik <dominik@science.uva.nl> * org/org-agenda.el (org-add-to-diary-list): New function. (org-prefix-has-effort): New variable. (org-sort-agenda-noeffort-is-high): New option. (org-agenda-columns-show-summaries) (org-agenda-columns-compute-summary-properties): New options. (org-format-agenda-item): Compute the duration of the item. (org-agenda-weekend-days): New variable. (org-agenda-list, org-timeline): Use the proper faces for dates in the agenda and timeline buffers. (org-agenda-archive-to-archive-sibling): New command. (org-agenda-start-with-clockreport-mode): New option. (org-agenda-clockreport-parameter-plist): New option. (org-agenda-clocktable-mode): New variable. (org-agenda-deadline-leaders): Allow a function value for the deadline leader. (org-agenda-get-deadlines): Deal with new function value. * lisp/org-clock.el (org-clock): New customization group. (org-clock-into-drawer, org-clock-out-when-done) (org-clock-in-switch-to-state, org-clock-heading-function): Moved into the new group. (org-clock-out-remove-zero-time-clocks): New option. (org-clock-out): Use `org-clock-out-remove-zero-time-clocks'. (org-dblock-write:clocktable): Allow a Lisp form for the scope parameter. (org-dblock-write:clocktable): Fixed bug with total time calculation. (org-dblock-write:clocktable): Request the unrestricted list of files. (org-get-clocktable): New function. (org-dblock-write:clocktable): Make sure :tstart and :tend can not only be strings but also integers (an absolute day number) and lists (m d y). * org/org-colview.el (org-columns-next-allowed-value) (org-columns-edit-value): Limit the effort for updatig in the agenda to recomputing a single file. (org-columns-compute): Only write property value if it has changed. This avoids raising the buffer-change-flag unnecessarily. (org-agenda-colview-summarize) (org-agenda-colview-compute): New functions. (org-agenda-columns): Call `org-agenda-colview-summarize'. * org/org-exp.el (org-export-run-in-background): New option. (org-export-icalendar): Allow a batch process to trigger waiting after executing a system command. (org-export-preprocess-string): Renamed-from `org-cleaned-string-for-export'. (org-export-html-style): Made target class look like normal text. (org-export-as-html): Make use of the better proprocessing in `org-cleaned-string-for-export'. (org-cleaned-string-for-export): Better treatment of heuristic targets, many more internal links will now work in HTML export. (org-get-current-options): Incorporate LINK_UP, LINK_HOME, and INFOJS. (org-export-inbuffer-options-extra): New variable. (org-export-options-filters): New hook. (org-infile-export-plist): Find also the settings keywords in `org-export-inbuffer-options-extra'. (org-infile-export-plist): Allow multiple #+OPTIONS lines and multiple #+INFOJS_OPT lines. (org-export-html-handle-js-options): New function. (org-export-html-infojs-setup): New option. (org-export-as-html): Call `org-export-html-handle-js-options'. Add autoload to all entry points. (org-skip-comments): Function removed. * org/org-table.el (org-table-make-reference): Extra parenthesis around single fields, to make sure that algebraic formulas get correctly interpreted by calc. (org-table-current-column): No longer interactive. * org/org-export-latex.el (org-export-latex-preprocess): Renamed from `org-export-latex-cleaned-string'. 2008-04-27 Bastien Guerry <bzg@altern.org> * org/org-publish.el (org-publish-get-base-files-1): New function. (org-publish-get-base-files): Use it. (org-publish-temp-files): New variable. Don't require 'dired-aux anymore. (org-publish-initial-buffer): New variable. (org-publish-org-to, org-publish): Use it. (org-publish-get-base-files-1): Bug fix: get the proper list of files when recursing thru a directory. (org-publish-get-base-files): Use the :exclude property to skip both files and directories.
author Carsten Dominik <dominik@science.uva.nl>
date Sun, 27 Apr 2008 18:33:39 +0000
parents 1e3a407766b9
children ef65fa4dca3b
line wrap: on
line source

;;; uce.el --- facilitate reply to unsolicited commercial email

;; Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004,
;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.

;; Author: stanislav shalunov <shalunov@mccme.ru>
;; Created: 10 Dec 1996
;; Keywords: uce, unsolicited commercial email

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;; Code in this file provides semi-automatic means of replying to
;; UCE's you might get.  It works currently only with Rmail and Gnus.
;; If you would like to make it work with other mail readers,
;; Rmail-specific section is marked below.  If you want to play with
;; code, please let me know about your changes so I can incorporate
;; them.  I'd appreciate it.

;; Function uce-reply-to-uce, if called when current message in RMAIL
;; buffer is a UCE, will setup *mail* buffer in the following way: it
;; scans full headers of message for 1) normal return address of
;; sender (From, Reply-To lines); and puts these addresses into To:
;; header, it also puts abuse@offenders.host address there 2) mailhub
;; that first saw this message; and puts address of its postmaster
;; into To: header 3) finally, it looks at Message-Id and adds
;; posmaster of that host to the list of addresses.

;; Then, we add "Errors-To: nobody@localhost" header, so that if some
;; of these addresses are not actually correct, we will never see
;; bounced mail.  Also, mail-self-blind and mail-archive-file-name
;; take no effect: the ideology is that we don't want to save junk or
;; replies to junk.

;; Then we put template into buffer (customizable message that
;; explains what has happened), customizable signature, and the
;; original message with full headers and envelope for postmasters.
;; Then buffer is left for editing.

;; The reason that function uce-reply-to-uce is Rmail dependant is
;; that we want full headers of the original message, nothing
;; stripped.  If we use normal means of inserting of the original
;; message into *mail* buffer headers like Received: (not really
;; headers, but envelope lines) will be stripped while they bear
;; valuable for us and postmasters information.  I do wish that there
;; would be some way to write this function in some portable way, but
;; I am not aware of any.

;;; Change log:

;; Dec 10, 1996 -- posted draft version to gnu.sources.emacs

;; Dec 11, 1996 -- fixed some typos, and Francesco Potorti`
;; <F.Potorti@cnuce.cnr.it> pointed out that my use of defvar was
;; weird, suggested fix, and added let form.

;; Dec 17, 1996 -- made scanning for host names little bit more clever
;; (obviously bogus stuff like localhost is now ignored).

;; Nov 11, 1997 -- incorporated changes from Mikael Djurfeldt
;; <mdj@nada.kth.se> to make uce.el work with Gnus.  Changed the text
;; of message that is sent.

;; Dec 3, 1997 -- changes from Gareth Jones <gdj1@gdjones.demon.co.uk>
;; handling Received headers following some line like `From:'.

;; Aug 16, 2000 -- changes from Detlev Zundel
;; <detlev.zundel@stud.uni-karlsruhe.de> to make uce.el work with the
;; latest Gnus.  Lars told him it should work for all versions of Gnus
;; younger than three years.

;; Setup:

;; Add the following line to your ~/.emacs:

;; (autoload 'uce-reply-to-uce "uce" "Reply to UCEs" t nil)

;; If you want to use it with Gnus also use

;; (setq uce-mail-reader 'gnus)

;; store this file (uce.el) somewhere in load-path and byte-compile it.

;;; Variables:

;; uce-message-text is template that will be inserted into buffer.  It
;; has reasonable default.  If you want to write some scarier one,
;; please do so and send it to me.  Please keep it polite.

;; uce-signature behaves just like mail-signature.  If nil, nothing is
;; inserted, if t, file ~/.signature is used, if a string, its
;; contents are inserted into buffer.

;; uce-uce-separator is line that separates your message from the UCE
;; that you enclose.

;; uce-subject-line will be used as subject of outgoing message.  If
;; nil, left blank.

;;; Code:

(defvar gnus-original-article-buffer)
(defvar mail-reply-buffer)
(defvar rmail-current-message)

(require 'sendmail)
;; Those sections of code which are dependent upon
;; RMAIL are only evaluated if we have received a message with RMAIL...
;;(require 'rmail)

(defgroup uce nil
  "Facilitate reply to unsolicited commercial email."
  :prefix "uce-"
  :group 'mail)

(defcustom uce-mail-reader 'rmail
  "A symbol indicating which mail reader you are using.
Choose from: `gnus', `rmail'."
  :type '(choice (const gnus) (const rmail))
  :version "20.3"
  :group 'uce)

(defcustom uce-setup-hook nil
  "Hook to run after UCE rant message is composed.
This hook is run after `mail-setup-hook', which is run as well."
  :type 'hook
  :group 'uce)

(defcustom uce-message-text
  "Recently, I have received an Unsolicited Commercial E-mail from you.
I do not like UCE's and I would like to inform you that sending
unsolicited messages to someone while he or she may have to pay for
reading your message may be illegal.  Anyway, it is highly annoying
and not welcome by anyone.  It is rude, after all.

If you think that this is a good way to advertise your products or
services you are mistaken.  Spamming will only make people hate you, not
buy from you.

If you have any list of people you send unsolicited commercial emails to,
REMOVE me from such list immediately.  I suggest that you make this list
just empty.

	----------------------------------------------------

If you are not an administrator of any site and still have received
this message then your email address is being abused by some spammer.
They fake your address in From: or Reply-To: header.  In this case,
you might want to show this message to your system administrator, and
ask him/her to investigate this matter.

Note to the postmaster(s): I append the text of UCE in question to
this message; I would like to hear from you about action(s) taken.
This message has been sent to postmasters at the host that is
mentioned as original sender's host (I do realize that it may be
faked, but I think that if your domain name is being abused this way
you might want to learn about it, and take actions) and to the
postmaster whose host was used as mail relay for this message.  If
message was sent not by your user, could you please compare time when
this message was sent (use time in Received: field of the envelope
rather than Date: field) with your sendmail logs and see what host was
using your sendmail at this moment of time.

Thank you."

  "This is the text that `uce-reply-to-uce' command will put in reply buffer.
Some of spamming programs in use will be set up to read all incoming
to spam address email, and will remove people who put the word `remove'
on beginning of some line from the spamming list.  So, when you set it
up, it might be a good idea to actually use this feature.

Value nil means insert no text by default, lets you type it in."
  :type 'string
  :group 'uce)

(defcustom uce-uce-separator
  "----- original unsolicited commercial email follows -----"
  "Line that will begin quoting of the UCE.
Value nil means use no separator."
  :type '(choice (const nil) string)
  :group 'uce)

(defcustom uce-signature mail-signature
"Text to put as your signature after the note to UCE sender.
Value nil means none, t means insert `~/.signature' file (if it happens
to exist), if this variable is a string this string will be inserted
as your signature."
  :type '(choice (const nil) (const t) string)
  :group 'uce)

(defcustom uce-default-headers
  "Errors-To: nobody@localhost\nPrecedence: bulk\n"
  "Additional headers to use when responding to a UCE with \\[uce-reply-to-uce].
These are mostly meant for headers that prevent delivery errors reporting."
  :type 'string
  :group 'uce)

(defcustom uce-subject-line
  "Spam alert: unsolicited commercial e-mail"
  "Subject of the message that will be sent in response to a UCE."
  :type 'string
  :group 'uce)

(declare-function mail-strip-quoted-names "mail-utils" (address))
(declare-function rmail-msg-is-pruned "rmail" ())
(declare-function rmail-maybe-set-message-counters "rmail" ())
(declare-function rmail-msgbeg "rmail" (n))
(declare-function rmail-msgend "rmail" (n))
(declare-function rmail-toggle-header "rmail" (&optional arg))


(defun uce-reply-to-uce (&optional ignored)
  "Send reply to UCE in Rmail.
UCE stands for unsolicited commercial email.  Function will set up reply
buffer with default To: to the sender, his postmaster, his abuse@
address, and postmaster of the mail relay used."
  (interactive)
  (let ((message-buffer
	 (cond ((eq uce-mail-reader 'gnus) gnus-original-article-buffer)
	       ((eq uce-mail-reader 'rmail) "RMAIL")
	       (t (error
		   "Variable uce-mail-reader set to unrecognized value"))))
	(full-header-p (and (eq uce-mail-reader 'rmail)
			    (not (rmail-msg-is-pruned)))))
    (or (get-buffer message-buffer)
	(error "No buffer %s, cannot find UCE" message-buffer))
    (switch-to-buffer message-buffer)
    ;; We need the message with headers pruned.
    (if full-header-p
	(rmail-toggle-header 1))
    (let ((to (mail-strip-quoted-names (mail-fetch-field "from" t)))
	  (reply-to (mail-fetch-field "reply-to"))
	  temp)
      ;; Initial setting of the list of recipients of our message; that's
      ;; what they are pretending to be.
      (if to
	  (setq to (format "%s" (mail-strip-quoted-names to)))
	(setq to ""))
      (if reply-to
	  (setq to (format "%s, %s" to (mail-strip-quoted-names reply-to))))
      (let (first-at-sign end-of-hostname sender-host)
	(setq first-at-sign (string-match "@" to)
	      end-of-hostname (string-match "[ ,>]" to first-at-sign)
	      sender-host (substring to first-at-sign end-of-hostname))
	(if (string-match "\\." sender-host)
	    (setq to (format "%s, postmaster%s, abuse%s"
			     to sender-host sender-host))))
      (setq mail-send-actions nil)
      (setq mail-reply-buffer nil)
      (cond ((eq uce-mail-reader 'gnus)
	     (copy-region-as-kill (point-min) (point-max)))
	    ((eq uce-mail-reader 'rmail)
	     (save-excursion
	       (save-restriction
		 (rmail-toggle-header 1)
		 (widen)
		 (rmail-maybe-set-message-counters)
		 (copy-region-as-kill (rmail-msgbeg rmail-current-message)
				      (rmail-msgend rmail-current-message))))))
      ;; Restore the pruned header state we found.
      (if full-header-p
	  (rmail-toggle-header 0))
      (switch-to-buffer "*mail*")
      (erase-buffer)
      (setq temp (point))
      (yank)
      (goto-char temp)
      (if (eq uce-mail-reader 'rmail)
	  (progn
	    (forward-line 2)
	    (let ((case-fold-search t))
	      (while (looking-at "Summary-Line:\\|Mail-From:")
		(forward-line 1)))
	    (delete-region temp (point))))
      ;; Now find the mail hub that first accepted this message.
      ;; This should try to find the last Received: header.
      ;; Sometimes there may be other headers inbetween Received: headers.
      (cond ((eq uce-mail-reader 'gnus)
	     ;; Does Gnus always have Lines: in the end?
	     (re-search-forward "^Lines:")
	     (beginning-of-line))
	    ((eq uce-mail-reader 'rmail)
	     (goto-char (point-min))
	     (search-forward "*** EOOH ***\n")
	     (beginning-of-line)
	     (forward-line -1)))
      (re-search-backward "^Received:")
      (beginning-of-line)
      ;; Is this always good?  It's the only thing I saw when I checked
      ;; a few messages.
      (let ((eol (save-excursion (end-of-line) (point))))
	;;(if (not (re-search-forward ": \\(from\\|by\\) " eol t))
	(if (not (re-search-forward "\\(from\\|by\\) " eol t))
	    (progn
	      (goto-char eol)
	      (if (looking-at "[ \t\n]+\\(from\\|by\\) ")
		  (goto-char (match-end 0))
		(error "Failed to extract hub address")))))
      (setq temp (point))
      (search-forward " ")
      (forward-char -1)
      ;; And add its postmaster to the list of addresses.
      (if (string-match "\\." (buffer-substring temp (point)))
	  (setq to (format "%s, postmaster@%s"
			   to (buffer-substring temp (point)))))
      ;; Also look at the message-id, it helps *very* often.
      (if (and (search-forward "\nMessage-Id: " nil t)
	       ;; Not all Message-Id:'s have an `@' sign.
	       (let ((bol (point))
		     eol)
		 (end-of-line)
		 (setq eol (point))
		 (goto-char bol)
		 (search-forward "@" eol t)))
	  (progn
	    (setq temp (point))
	    (search-forward ">")
	    (forward-char -1)
	    (if (string-match "\\." (buffer-substring temp (point)))
		(setq to (format "%s, postmaster@%s"
				 to (buffer-substring temp (point)))))))
      (cond ((eq uce-mail-reader 'gnus)
	     ;; Does Gnus always have Lines: in the end?
	     (re-search-forward "^Lines:")
	     (beginning-of-line))
	    ((eq uce-mail-reader 'rmail)
	     (search-forward "\n*** EOOH ***\n")
	     (forward-line -1)))
      (setq temp (point))
      (search-forward "\n\n" nil t)
      (if (eq uce-mail-reader 'gnus)
	  (forward-line -1))
      (delete-region temp (point))
      ;; End of Rmail dependent section.
      (auto-save-mode auto-save-default)
      (mail-mode)
      (goto-char (point-min))
      (insert "To: ")
      (save-excursion
	(if to
	    (let ((fill-prefix "\t")
		  (address-start (point)))
	      (insert to "\n")
	      (fill-region-as-paragraph address-start (point)))
	  (newline))
	(insert "Subject: " uce-subject-line "\n")
	(if uce-default-headers
	    (insert uce-default-headers))
	(if mail-default-headers
	    (insert mail-default-headers))
	(if mail-default-reply-to
	    (insert "Reply-to: " mail-default-reply-to "\n"))
	(insert mail-header-separator "\n")
	;; Insert all our text.  Then go back to the place where we started.
	(if to (setq to (point)))
	;; Text of ranting.
	(if uce-message-text
	    (insert uce-message-text))
	;; Signature.
	(cond ((eq uce-signature t)
	       (if (file-exists-p "~/.signature")
		   (progn
		     (insert "\n\n-- \n")
		     (forward-char (cadr (insert-file-contents "~/.signature"))))))
	      (uce-signature
	       (insert "\n\n-- \n" uce-signature)))
	;; And text of the original message.
	(if uce-uce-separator
	    (insert "\n\n" uce-uce-separator "\n"))
	;; If message doesn't end with a newline, insert it.
	(goto-char (point-max))
	(or (bolp) (newline)))
      ;; And go back to the beginning of text.
      (if to (goto-char to))
      (or to (set-buffer-modified-p nil))
      ;; Run hooks before we leave buffer for editing.  Reasonable usage
      ;; might be to set up special key bindings, replace standart
      ;; functions in mail-mode, etc.
      (run-hooks 'mail-setup-hook 'uce-setup-hook))))

(defun uce-insert-ranting (&optional ignored)
  "Insert text of the usual reply to UCE into current buffer."
  (interactive "P")
  (insert uce-message-text))

(provide 'uce)

;; arch-tag: 44b68c87-9b29-47bd-822c-3feee3883221
;;; uce.el ends here