diff --git a/examples/ping-and-mail.scm b/examples/ping-and-mail.scm new file mode 100755 index 0000000..54192e5 --- /dev/null +++ b/examples/ping-and-mail.scm @@ -0,0 +1,57 @@ +#!/bin/sh +exec scsh -lel expect/load.scm -o threads -o expect -o let-opt -e main -s "$0" "$@" +!# + +(define *respond-time* 2) +(define *sendmail* "/usr/sbin/sendmail") +(define verbose? #t) + +(define (display-mail address dead-hosts) + (display "From: ping-and-mail\n") + (display (format #f "To: ~a\n" address)) + (display "Subject: Dead hosts detected\n\n") + (display "The following hosts did not react to a ping within a ") + (display (format #f "period of ~a seconds:" (number->string *respond-time*))) + (display "\n") + (for-each (lambda (s) (display (format #f "~a\n" s))) dead-hosts) + (display ".\n")) + +(define (send-mail address dead-hosts) + (wait (fork (lambda () + (fork/pipe (lambda () + ;; child (stdout) + (display-mail address dead-hosts))) + ;; parent (stdin) + (exec-epf (,*sendmail* ,address)))))) + +(define (dead? host) + (let ((task (spawn (ping -c 1 ,host)))) + (let ((res (chat task + (chat-timeout *respond-time*) + (look-for (rx "1 " (* (- any #\,)) "received") #f) + 'alive))) + (close-task task) + (not (eq? res 'alive))))) + +(define (main args) + (if (or (< (length args) 2) (string=? (cadr args) "--help")) + (display-usage) + (let* ((hosts (cddr args)) + (address (cadr args)) + (dead (filter (lambda (h) + (let ((d (dead? h))) + (if verbose? + (display (format #f "~a: ~a\n" + h (if d "dead" "alive")))) + d)) + hosts))) + (if (not (null? dead)) + (begin + (send-mail address dead) + (if verbose? + (display (format #f "Mail sent to ~a\n" address)))) + (if verbose? + (display "No hosts dead\n")))))) + +(define (display-usage) + (display "Usage: ping-and-mail.scm emailaddress host ...\n"))