(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 screwtape@sdf.org \" 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 'screwtape@sdf.org \"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)))