(defvar sends-file-name (concat "/usr/spool/sends/" (user-real-login-name)))
(defvar send-program "send")

(defvar send-summary-format "%f %d %c" nil)

(defun send-generate-recipient-list (string)
  (let (name-list)
    (while (string-match "[ \t,]+" string)
      (setq name-list (cons (substring string 0 (match-beginning 0)) name-list))
      (setq string (substring string (match-end 0))))
    ;; Get last part of string (which may not have any whitespace after it)
    (if (string-match "[^ \t,]+$" string)
        (setq name-list (cons (substring string 0 (match-end 0)) name-list)))
    (nreverse name-list)))

(defun send (recipients)
  (interactive "sSend to: ")
  ;; Convert single string to list
  (setq recipients (send-generate-recipient-list recipients))
  (pop-to-buffer (generate-new-buffer (concat "*Send message to " 
                                              (car recipients) 
                                              (if (< 1 (length recipients))
                                                  ", ..."
                                                "")
                                              "*")))
  (text-mode)
  (use-local-map (copy-keymap text-mode-map))
  (local-set-key "\C-c\C-c" 'send-do-send)
  (set (make-local-variable 'send-recipients) recipients)
  (message "Type \"C-c C-c\" to send message when finished."))

(defun send-reply ()
  (interactive)
  (send (send-get-last-sender)))

(defun send-get-last-sender ()
  "Return the name of the user who last sent a message via the \"send\" command"
  (interactive)
  ;; Only bother to do work if the sends file is readable and nonzero in size. 
  (and (> (nth 7 (file-attributes sends-file-name)) 0) (file-readable-p sends-file-name)
       (save-excursion
         (let ((send-buffer (get-buffer-create " *Sends data*"))
               (message-header "Message from ")
               last-sender
               start
               end)
           (set-buffer send-buffer)
           (erase-buffer)
           (insert-file-contents sends-file-name)
           (goto-char (point-max))
           (and (search-backward message-header (point-min) t)
                (progn
                  (setq start (+ (point) (length message-header)))
                  (or (search-forward "(" (point-max) t)
                      (error (concat sends-file-name ": corrupt ``Message from'' format.")))
                  (setq end (- (point) 2))
                  (setq last-sender (buffer-substring start end))
                  (kill-buffer send-buffer)
                  (if (interactive-p)
                      (message last-sender)
                    last-sender)))))))

(defun send-do-send ()
  (interactive)
  (let ((send-input-file (concat "/tmp/.send" (int-to-string (random))))
        (send-output-buffer (generate-new-buffer "*Send output*")))
    (write-region (point-min) (point-max) send-input-file nil 'no-messages)
    (apply 'call-process send-program send-input-file send-output-buffer 
           nil "+noverify" "+quiet" send-recipients)
    (delete-file send-input-file)
    (kill-buffer (current-buffer))
    (if (save-excursion
           (set-buffer send-output-buffer)
           (eq 0 (buffer-size)))
        (progn
          (or (one-window-p) (delete-window))
          (kill-buffer send-output-buffer))
      (switch-to-buffer send-output-buffer))))

(defun send-lastsend ()
  (interactive)
  (and (file-readable-p sends-file-name)
       (let ((lastsend-buffer (get-buffer-create "*Lastsend*")))
         (set-buffer lastsend-buffer)
         (erase-buffer)
         (insert-file-contents sends-file-name)
         (replace-regexp "\C-m\\|\C-c" "")
         (beginning-of-buffer)
         (text-mode))))

(defun send-generate-summary ()
  (interactive)
  (and (file-readable-p sends-file-name)
       (let ((send-buffer (get-buffer-create " *Sends*"))
             (send-summary-format-alist
              '(("%f" . sender)
                ("%d" . date)
                ("%c" . contents)))
             sender
             date
             contents)
         (set-buffer lastsend-buffer)

;; eof
