March 2005


This scsh script logs into a specified list of hosts using OpenSSH and runs a command there. For example:

sshfe host1 host2 host3 % rm -rf /

The % character is used to seperate the list of host names and the command (and its arguments) to run. The code assumes that Sunterlib is installed because it uses the Scheme implementation of the Concurrent ML API.

#!/bin/sh
exec scsh -lel cml/load.scm -o srfi-1 -o threads \
          -o rendezvous -o rendezvous-channels -s "$0" "$@"
!#

(define-syntax run/strings-status
  (syntax-rules ()
     ((_ epf ...)
      (call-with-values
         (lambda ()
             (run/port+proc epf ...))
         (lambda (port proc)
            (let ((string-list (port->string-list port))
                   (status (wait proc)))
               (close-input-port port)
               (values string-list status)))))))

(define display*
  (lambda things
    (for-each display things)
    (newline)))

(define (run-processes hosts command)
  (map (lambda (host)
	 (let ((channel (make-channel)))
	   (spawn
	    (lambda ()
	      (send channel
		    (call-with-values
			(lambda ()
			  (run/strings-status
			   ("ssh" ,host ,@command) (= 2 1)))
		      (lambda (strings status)
			(list strings status host))))))
	   channel))
       hosts))

(define (handle-result lst)
  (call-with-values
      (lambda ()
	(apply values lst))
    (lambda (strings status host)
      (newline)
      (display* "result for " host " exited with "
		status ": ")
      (for-each display* strings))))

(define (collect-results channels)
  (let lp ((channels channels))
    (if (null? channels)
	(values)
	(apply
	 select
	 (map (lambda (channel)
		(wrap (receive-rv channel)
		      (lambda (lst)
			(handle-result lst)
			(lp (delete channel channels)))))
	      channels)))))

(define (parse-arguments args)
  (let lp ((args args) (hosts '()))
    (cond
     ((null? args)
      (values hosts '()))
     ((string=? (car args) "%")
      (values hosts (cdr args)))
     (else
      (lp (cdr args) (cons (car args) hosts))))))

(call-with-values
    (lambda ()
      (parse-arguments command-line-arguments))
  (lambda (hosts command/args)
    (collect-results
     (run-processes hosts command/args))))

;;; Local Variables:
;;; mode:scheme
;;; End:

Technorati Tags: ,

I have to use a ssh gateway to connect to my desk machine at the university. In fact there are six ssh gateway machines available which have a round-robin DNS entry. However, using the round-robin DNS entry seems to be a problem in the presence of Kerberos V and (or?) GSSAPI ticket forwarding: When connecting to the round-robin entry the client fails to send the ticket, it works fine when I connect to a certain machine. So, I do the round-robin myself using jot and it actually works. Amazing!

ForwardX11 yes
ForwardX11Trusted yes
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes

Host ssh1.uni-somewhere.de
ProxyCommand none

Host ssh2.uni-somewhere.de
ProxyCommand none

Host ssh3.uni-somewhere.de
ProxyCommand none

Host ssh4.uni-somewhere.de
ProxyCommand none

Host ssh5.uni-somewhere.de
ProxyCommand none

Host ssh-proxy.uni-somewhere.de
ProxyCommand none

Host *.uni-somewhere.de
ProxyCommand ssh ssh`jot -r 1 1 6`.uni-somewhere.de /home/ek/connect %h %p

(I’m using connect.c here)

Technorati Tags: ,

The new Carbon port by Andrew Choi of XEmacs is on an extra branch in the XEmacs CVS. Works fine. I wonder if there is yet a way to change the background color. XEmacs seems to ignore the stuff from my ~/.xemacs/custom.el.

Technorati Tags: , ,