58 lines
1.7 KiB
Scheme
58 lines
1.7 KiB
Scheme
|
#!/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"))
|