(defpackage mail-demon (:use cl cl-user))
(in-package mail-demon)
;;;Assumes mail over ssh with public key access.
(defvar *ssh-user* "screwtape")
(defvar *ssh-address* "tty.sdf.org")
(defvar *ssh-port* 22)
(defun ssh-args ()
(list (format nil "-p~a" *ssh-port*)
(format nil "~a@~a" *ssh-user* *ssh-address*)))
(defun get-my-mail () "
Fetch one screen of BSD mail's output as a list of lists. like
(({>}N 1
[email protected] \" date size \\\"subject\\\"\"))
Assumes this is the only way mail is being accessed.
"
(let ((bsd-mail-string
(with-output-to-string (*standard-output*)
(with-input-from-string (in (format nil "x~%"))
(ext:run-program "ssh"
`(,@(ssh-args) "mail" "-I")
:output t :input in)))))
(with-input-from-string (in bsd-mail-string)
(loop for line = (read-line in nil nil) while line
collect (with-input-from-string (lin line)
(list (read lin) (read lin) (read lin)
(read-line lin)))
initially
(let ((initial-line (read-line in nil nil)))
(when initial-line
(print initial-line)
(print (read-line in nil nil))
(terpri)))))))
(defun send-mail (recipient topic file.txt) "
(send-mail '
[email protected] \"a topic\" #p\"my.file.txt\")
Uses system() kludge. Tfw. Backtick ist verbotten.
Avoid things your parent shell is going to misunderstand.
"
(let ((content (substitute #\' #\`
(with-open-file (in file.txt :direction :input)
(format nil "~{~a~%~}"
(loop for line = (read-line in nil nil) while line
collect line)))))) ;;kludge also
(ext:system
(format nil
"ssh -p~a ~a@~a mail -s '~s' ~a <<EOG
~a
EOG
" *ssh-port* *ssh-user* *ssh-address* topic recipient content))))
(defun dq-mail (&rest to-delete) "
(dq-mail 1 2 3)
runs
mail -I <<EOG
d 1 2 3
q
EOG
"
(with-input-from-string (in (format nil "~{d ~a~%}q~%" to-delete))
(ext:run-program "ssh"
`(,@(ssh-args) "mail" "-I")
:input in :output t :error t)))
(defun get-message (n) "
(get-message 1)
Uses one ssh like:
mail
w 1 .tmp.txt
x
And another:
cat .tmp.txt && rm .tmp.txt
"
(with-input-from-string (in (format nil "write ~d .tmp.txt~%x~%" n))
(ext:run-program "ssh"
`(,@(ssh-args) "mail" "-I")
:input in :output t :error t))
(with-output-to-string (*standard-output*)
(ext:run-program "ssh"
`(,@(ssh-args) "cat" ".tmp.txt" "&&" "rm" ".tmp.txt")
:output t)))