#!/usr/local/bin/wermit + ; ; s y n c h r o n i z e ; ; Synchronizes parallel directory trees over a Telnet connection. ; ; Requires: C-Kermit 7.0 Beta.07 or later. ; Author: F. da Cruz, Columbia University Kermit Project ; ; Command-line parameters: ; 1. Root of source directory tree on local computer. ; 2. Root of destination directory tree on target computer. ; 3. Hostname or address of target computer. ; 4. Username on target host ; 5. Password on target host ; ; Parameters 2-5 are prompted for if not suplied. ; ; This script synchronizes parallel directory trees on two computers ; over a Telnet connection. The two computers need not be running the ; same operating system. For example, any pair from { Win32, UNIX, VMS } ; can be chosen, as long as they are running the required C-Kermit ; version. ; ; . For shell logins, the remote prompt is assumed to be "$ ". ; Change as needed (or use IKSD login). ; ; . The root directory on the target host must exist (easy to ; change). ; ; . The synchronization is in one direction only: the target ; is updated from the source. ; ; . Subdirectories are created as needed at the destination. ; ; . Files that exist in the destination tree that do not also ; exist in the source tree are deleted. ; ; . Files are transferred in update mode; only the source files ; that are newer than the corresponding destination files are ; sent. ; ; . Backup files (*.~*~) are not sent. All other files are sent. ; ; . The destination TCP port is hardwired (Telnet or IKSD). ; ; . A regular connection is made, rather than a secure one. ; The password is transmitted in the clear. This can be fixed ; by using a Kerberized or SRP-enabled C-Kermit build and then ; slightly modifying this script. ; ; Limitations: ; ; . Filenames containing spaces cause trouble. Avoid them. ; ; . Empty source directories are not replicated at the target. ; ; . Special characters in command line options might need to be ; quoted according to the rules of your shell. Also note the ; use \fcontents() around variables containing directory names; ; this is to prevent recursive evaluation when the directory ; name contains backslashes (e.g. C:\WINDOWS\SYSTEM). ; ; . C-Kermit 7.0 Beta.08 and earlier issue various gratuitous ; and/or misleading messages; this is a cosmetic problem only, ; fixed in Beta.09. ; ; Begin by checking C-Kermit version: ; define badversion echo Sorry - C-Kermit 7.0 or later required., exit if not equal "\v(program)" "C-Kermit" badversion if LLT \v(version) 70000 badversion ; Define usage and fatal error macros. define usage exit 1 { Usage: sourcedir [ targetdir [ targethost [ username [ password ] ] ] ] } define giveup { bye, hangup, close, exit 1 {FATAL: \%1 (Connection closed)} } ; Runtime parameters... .iksd = 0 ; Set to nonzero to use IKSD. .debug = 0 ; Set to nonzero for debug messages. ; Command-line parsing... if not def \%1 usage ; Give usage message if no arguments. cd \fcontents(\%1) ; Change to source directory if fail exit 1 Can't CD to "\fcontents(\%1)" ; Failure is fatal while not def \%3 { ; If hostname/address not supplied ask \%1 { Host: } ; prompt for one until we get it. if > \fsplit(\%3) 1 { ; Allow only one "word" here. echo Just the address please. ; E.g. no TCP port number. undef \%3 } } while not def \%2 { ; If target directory not supplied ask \%2 { Directory on \%3: } ; ask til we get it. } if not def \%4 { ; If username not supplied ask \%4 { User [\v(user)]: } ; Prompt for one, but default if not def \%4 assign \%4 \v(user) ; to local user ID. } while not defined \%5 { ; Ditto for password askq \%5 { Password for \%4 at \%3: } } set telnet environment user \%4 ; Make sure correct userid is sent set exit warning off ; No "OK to exit?" prompts please ; This script assumes that authenticated logins are not being performed ; via Kerberos, SRP, or any other supported method. It can easily be ; modified to use Kerberos or SRP. set telopt start-tls refuse ; Do not use START_TLS option set telopt authentication refuse ; Do not use AUTH option set telopt encrypt refuse refuse ; Do not use ENCRYPT option if \m(debug) { echo Source directory: \fcontents(\%1) echo Target directory: \fcontents(\%2) echo Target host: \fcontents(\%3) echo User at host: \fcontents(\%4) echo IKSD: \m(iksd) set input echo on } else { set input echo off set quiet on } if \m(iksd) { ; IKSD... echo Connecting to \%3:kermit... set host \%3 1649 /telnet if fail exit 1 Can't open connection to iksd@\%3. remote login \%4 \%5 if fail exit 1 Authentication failure } else { ; Regular shell login echo Connecting to \%3:telnet... set host \%3 23 /telnet if fail exit 1 Can't open Telnet connection to \%3. minput 20 login: Username: Password: {Password for \%3:} if fail exit 1 Timed out waiting for initial prompt: \v(inwait) sec. if ( = \v(minput) 1 || = \v(minput) 2 ) { lineout \%4 ; User ID required - send it. minput 10 Password: {Password for \%4:} if fail exit 1 Timed out waiting for Password prompt: \v(inwait) sec. } lineout \%5 ; Send password undef \%5 ; Erase password from memory input 60 {$ } ; *** Wait for shell prompt *** if fail echo WARNING: No shell prompt ; But ignore failure lineout kermit -x ; Start Kermit server input 30 READY TO SERVE... ; Courtesy but not necessary } ; Have a connection with Kermit server on the far end. ; The rest is easy... .m1 := Can't CD to remote directory "\fcontents(\%2)" .m2 := WARNING: Update mode not negotiated - performing full transfer... set transfer bell off ; Silence the bell set transfer display brief ; Skip the fullscreen display. rcd \fcontents(\%2) ; CD to remote target directory. if fail giveup {\m(m1)} ; Failure is fatal rset file collision update ; Use update mode (only send new files) rset server cd-message off ; We don't need orientation messages if fail echo {\m(m2)} ; Failure is not fatal echo send /recursive /nobackup * ; Send the source tree if fail giveup {SEND failed} ; Update failed ; Delete all files at the remote that do not exist locally... ;;; forward fin ; Uncomment to skip deletion phase echo echo DELETION PHASE: Searching \%3:\fcontents(\%2)... echo query kermit rfiles(*) ; Get recursive remote file list if fail giveup {QUERY failed} .\%n := \v(query) ; How many in list .\%m = 0 ; How many deleted if \m(debug) echo REMOTE FILES = \%n ; Debug message for \%i 1 \%n 1 { ; Loop through remote files query kermit nextfile() ; Next one if \m(debug) echo \%i. \v(query) if not exist \v(query) { ; If it doesn't exist on this end... rdelete \v(query) ; Delete the one on the far end if success increment \%m ; Count it if deletion successful } } if \%m echo echo DELETED: \%m ; Say how many were deleted :FIN bye ; Close the server exit 0 ; Update succeeded - done