From jbowyer@cis.vutbr.cs Thu Apr 8 09:24:08 1993 X-VM-Attributes: [nil nil nil nil nil] Status: RO Return-Path: Received: from cme.nist.gov (durer.cme.nist.gov) by muffin.cme.nist.gov (4.1/SMI-3.2-del.7) id AA01871; Thu, 8 Apr 93 09:24:06 EDT Received: from rhino.cis.vutbr.cs by cme.nist.gov (4.1/SMI-3.2-del.8) id AA25063; Thu, 8 Apr 93 09:15:16 EDT Received: by rhino.cis.vutbr.cs (5.67/1.05 VUT Brno) id AA28819; Thu, 8 Apr 93 15:14:04 +0200 Message-Id: <9304081314.AA28819@rhino.cis.vutbr.cs> Reply-To: jbowyer@cis.vutbr.cs X-Mailer: ELM [version 2.4 PL20] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 7160 From: Bowyer Jeff To: libes@cme.nist.gov (Don Libes) Subject: expect Program #1 Date: Thu, 8 Apr 1993 15:14:03 +0200 (MET DST) I store several Internet-related documents on our anonymous ftp server for members of the university community to access. I want these documents to always represent the most recent edition, but I'm too lazy to regularly check their original sites. Therefore, I wrote the following expect program to check for me and get the document if a new version exists. Jeff *========================================================================* Jeff Bowyer EMail: Computing Center jbowyer@cis.vutbr.cs Technical University of Brno Udolni 19, 602 00 BRNO Czech Republic *========================================================================* THE MAIN SHELL PROGRAM /usr/bin/ksh MDIR=/users/jbowyer/maint/anondocs echo 'updatedocs is executing' | mail jbowyer $MDIR/update.internet.library $MDIR/update.mailing.lists $MDIR/update.ftp.sites $MDIR/update.whois.servers $MDIR/update.rfc.index $MDIR/update.inet.services $MDIR/update.serials $MDIR/update.active1 $MDIR/update.active2 $MDIR/update.alt1 $MDIR/update.alt2 $MDIR/update.moderator.list at 3am sa $MDIR/updatedocs exit A SAMPLE DOCUMENT-SPECIFIC SHELL PROGRAM (update.internet.library) MDIR=/users/jbowyer/maint/anondocs NDIR=/users/jbowyer/newdocs ADIR=/users/ftp/pub/doc/internet expect $MDIR/ftpdoc ariel.unm.edu library internet.library $ADIR book.libraries case $? in 0) cd $NDIR mv internet.library $ADIR/book.libraries chgrp ftp $ADIR/book.libraries chmod 644 $ADIR/book.libraries echo 'New book.libraries' | mail jbowyer ;; 1) if test 5 -ne `date +%w` then at 3am $MDIR/update.internet.library fi ;; 2) echo 'internet.library not found' | mail jbowyer ;; esac THE EXPECT PROGRAM match_max -d 100000 ;# max size of a directory listing set destdir "/users/jbowyer/newdocs" set currmonth 0 set curryear 0 set rmonth 0 set rday 0 set ryear 0 set lmonth 0 set lday 0 set lyear 0 proc getname {line} { # if it's a symbolic link, return local name set i [lsearch line "->"] if {-1==$i} { # not a sym link # return last token of line as name, and strip off newline at end return [string trimright [lindex $line [expr [llength $line]-1]]] } else { # sym link, return "a" of "a -> b" return [lindex $line [expr $i-1]] } } proc getmonth {line} { set fmonth [lindex $line [expr [llength $line]-4]] return [expr [lsearch {Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec} $fmonth]+1] } proc getday {line} { return [lindex $line [expr [llength $line]-3]] } proc getyear {line fmonth} { global currmonth curryear set fyear [lindex $line [expr [llength $line]-2]] if [regexp ".*:.*" $fyear] { if {$fmonth>$currmonth} { return [expr $curryear-1] } else { return $curryear } } else { return $fyear } } proc getrdate {} { global argv rmonth rday ryear send "dir\r" expect { "ftp>*" } set buf $expect_out(buffer) for {} 1 {} { set split_buf [split $buf ""] set i [string first "\n" $buf] set line [join [lrange $split_buf 0 $i] ""] set buf [join [lrange $split_buf [expr 1+$i] end] ""] set token [lindex $line 0] case $token in { dir\r { # original command } 200 { # command successful } 150 { # opening data connection } total { # directory header } 226 { # transfer complete, succeeded! # # Unfortunately, it indicates # that the desired filename on # the remote host was not found # return -1 } ftp> { # next prompt, failed! return 0 } . { # unreadable } default { # either file or directory set fname [getname $line] if 0==[string compare $fname [lindex $argv 3]] { set rmonth [getmonth $line] set rday [getday $line] set ryear [getyear $line $rmonth] return 1 } } } } return 0 } proc getldate {} { global argv lmonth lday lyear send "!ll\r" expect { "ftp>*" } set buf $expect_out(buffer) for {} 1 {} { set split_buf [split $buf ""] set i [string first "\n" $buf] set line [join [lrange $split_buf 0 $i] ""] set buf [join [lrange $split_buf [expr 1+$i] end] ""] set token [lindex $line 0] case $token in { !ll\r { # original command } total { # directory header } ftp> { # next prompt, failed! return 0 } . { # unreadable } default { # either file or directory set fname [getname $line] if 0==[string compare $fname [lindex $argv 5]] { set lmonth [getmonth $line] set lday [getday $line] set lyear [getyear $line $lmonth] return 1 } } } } return 0 } proc getrfile {} { global destdir argv rmonth rday ryear send "lcd $destdir\r" expect { "ftp>*" } send "binary\r" expect { "ftp>*" } send "hash\r" expect { "ftp>*" } send "get [lindex $argv 3]\r" expect { "ftp>*" } set touchstr [format "%02d%02d0000%s" $rmonth $rday [string range $ryear 2 end]] exec touch $touchstr $destdir/[lindex $argv 3] send "quit\r" return 1 } log_file /users/jbowyer/maint/logs/[exec date +%y%m%d] set currmonth [exec date +%m] set curryear [exec date +%Y] set timeout 900 spawn ftp [lindex $argv 1] expect_before { -re "closed connection*" { exit 1 } -re "Connection timed out*" { send "quit\r" exit 1 } timeout { send "quit\r" exit 1 } eof { exit 1 } } expect { -re "unknown host" { exit 1 } -re "unreachable*" { exit 1 } -re "Name*" } send "anonymous\r" expect { -re "Password:*" } send "jbowyer@cis.vutbr.cs\r" expect { "ok*ftp>*" } send "cd [lindex $argv 2]\r" expect { -re "CWD*success*" { continue -expect } "ftp>*" } case [expr [getrdate]] { -1 { # # Desired filename not found on remote anonymous ftp server # exit 2 } 0 { # # Error on remote anonymous ftp server # exit 1 } default { # # Desired filename found on remote anonymous ftp server # send "lcd [lindex $argv 4]\r" expect { -re "Local directory now*" { continue -expect } "ftp>*" } if [getldate] { if $ryear>$lyear { if [getrfile] { exit 0 } } else { if $ryear==$lyear { if $rmonth>$lmonth { if [getrfile] { exit 0 } } else { if $rmonth==$lmonth { if $rday>$lday { if [getrfile] { exit 0 } } } } } } } } } exit 4