#! /bin/tcsh -f # # Realtime transfer of a directory system to a Windows share # # # set host = "" set share = "share" set smbuser = "Administrator" set smbpass = "" set host = "" set share = "" set smbuser = "Administrator" set smbpass = "" set directory = "." set tempfile = /tmp/${USER}/backup_firewire_temp set onlyfind = "default " set not = "default " if ($#argv == 0) then cat << EOF usage: backup_firewire.com //host/share:Username%password directory where: host - is the name of the Windows computer sharing the disk share - is the sharename you gave to the disk Username - is the Windows username on "host" password - is your Windows password directory - is the directory system to be sent example: #1 backup_firewire.com //192.168.10.3/share/Administrator%password sends everything under the current directory to the folder shared as "share" by the Administrator account on the computer with IP address 192.168.10.3. #2 backup_firewire.com //archive/ALS_831:Administrator stuff sends everything under "stuff" to the "ALS_831" share on the computer called "archive" using the Administrator account and and empty password. #3 backup_firewire.com ///%password /data/${USER} sends everything under /data/${USER} to the first DHCP-connected laptop on the network, using the first share found on that computer using the Administrator accound and password "password" EOF exit 9 endif set i = 0 while($i < $#argv) @ i = ( $i + 1 ) @ j = ( $i + 1 ) set arg = "$argv[$i]" set ARG = `echo $arg | awk '{print toupper($1)}'` if ("$arg" =~ //*) then set test = `echo $arg | awk -F "[/:%]" '$2!=""{print $2;exit} $3!=""{print $3}' | awk -F "[%:]" '{print $1}'` if ("$test" != "") set host = "$test" set test = `echo $arg | awk -F "[/]" '{print $4}' | awk -F "[%:]" '{print $1}'` if ("$test" != "") set share = "$test" set test = `echo $arg | awk -F "[:]" '{print $2}' | awk -F "[%]" '{print $1}'` if ("$test" != "") set smbuser = "$test" set test = `echo $arg | awk -F "[%]" '{print $2}'` if ("$test" != "") set smbpass = "$test" continue endif if(-d $arg) then set directory = "$arg" endif # only back up certain patterns if("$arg" == "-only" && $j <= $#argv) then set noglob if("$onlyfind" == "default ") set onlyfind = "" set onlyfind = ( $onlyfind $argv[$j] ) unset noglob # skip two this time @ i = ( $i + 1 ) continue endif if("$arg" == "-regardless" || "$arg" == "-allfiles") then set onlyfind = "" set not = "\a " continue endif if($?NO) then if("$not" == "default ") set not = "" set not = ( $not $arg ) endif if(("$ARG" =~ NO*) || ("$ARG" =~ "-NO"*)) then set NO continue endif unset NO end # default to exclude common undesirables if("$not" == "default ") set not = "\.imx_ \.dkx_ mtz2various_TMP \.adxv_beam_center tempfile sent_home _temp" # create exclusion definitions set not = `echo " $not " | awk 'BEGIN{RS=" "} NF==1{printf "%s|", $1}'` set not = `echo $not | awk '{print substr($1,1,length($1)-1)}'` if ("$not" == "") set not = "\a " # default to just images if("$onlyfind" == "default ") set onlyfind = "jpg jpeg img scan" set onlyfind = `echo " $onlyfind " | awk 'BEGIN{RS=" "} NF==1{printf "%s|", $1}'` set onlyfind = `echo "$onlyfind" | awk '{print substr($1,1,length($1)-1)}'` echo "host = $host" echo "share = $share" echo "user = $smbuser" echo "pass = $smbpass" echo "source = $directory" echo "onlyfind $onlyfind" echo "not: $not" # fix up so that no password = empty password if ("$smbpass" != "") set smbpass = "%$smbpass" # fix so that directory ends with a / set directory = `cd $directory ; pwd` # see if we are backing up files from a remote disk set besthost = `df $directory | awk -F "[:]" 'NF==2{print $1}'` if ($besthost != "") then echo "WARNING: file transfers will be faster if you: " echo "rsh $besthost" echo "backup_firewire.com $*" sleep 10 endif # try to discover the laptop sharing a folder foreach machine ( $host firewire `awk 'BEGIN{for(i=1;i<=255;++i) print "192.168.10."i}'` ) echo "checking $machine" ping -c 1 -w 1 $machine >& /dev/null if( ! $status) then set host = $machine if ( "$share" == "" ) then smbclient -U ${smbuser}$smbpass -L $host -N >&! ${tempfile}shares set test = `cat ${tempfile}shares | awk '/Sharename/,NF==0' | awk '$2=="Disk" && ! /[\$]/{print $1}' | tail -1` if("$test" != "") then set share = "$test" echo "found share: $share on $host" endif endif if("$host" != "" && "$share" != "" ) break endif end echo "host = $host" echo "share = $share" echo "user = $smbuser" echo "pass = $smbpass" # keep reconnecting while ( 1 ) # start from the beginning if this file is deleted if(! -e last_backup.stamp) then # this must be the first time, back up ALL existing files set lastbackup = 0 else # not first time, so don't back up anything created before the # stamp file set lastbackup = `find last_backup.stamp -printf "%T@"` endif # now create a stamp file that indicates when the last backup session started cat << EOF >! last_backup.stamp the date stamp on this file indicates the last time the processing directories were backeup up every file created AFTER this file will be backeup up on the next run. to change this file's date to a particular time: touch -t "199912250800.00" last_backup.stamp CCYYMMDDhhmm.ss to change this file's date to match another file: touch --reference another_file.txt last_backup.stamp to start over, delete this file. EOF try_again: # find everything in the filesystem, and filter by date find $directory -type f -printf "%T@ %s %t %p\n" |\ sort -n |\ egrep "$onlyfind" |\ egrep -v "$not" |\ awk -v lastbackup="$lastbackup" -v directory=$directory '\ $NF~"^"directory{$NF=substr($NF,length(directory)+2)}\ $1 >= lastbackup-30{++seen_first}\ seen_first{print $NF}' |\ tee ${tempfile}2bxfered |\ tar cCTf $directory - - |\ smbclient //${host}/$share -U "${smbuser}$smbpass" -N -Tx - if($status) then set test = `cat ${tempfile}2bxfered | wc -l` if("$test" == "0") then echo "nothing to do right now..." else # something went wrong with the transfer ... do it again echo "ERROR: from tar program..." echo "lets do that again." rm -f ${tempfile}2bxfered >& /dev/null goto try_again endif endif rm -f ${tempfile}2bxfered >& /dev/null # re-scan filesystem at most every ten minutes set now = `echo "puts [clock seconds]" | tclsh` set transfertime = `echo "$now - $lastbackup" | bc` set til_ten_minutes = `echo 600 - $transfertime | bc` if( $til_ten_minutes > 10 ) then # wait up to ten minute mark before doing this again echo "waiting for ten minutes..." sleep $til_ten_minutes endif end