# Revision history: # v1.0.0 -- 02-09-2000 -- initial # v1.0.1 -- 02-09-2000 -- added revision history ;-), added more ASCII types # v1.0.2 -- 02-11-2000 -- changing version number scheme and fixing local var # definitions (no perceived problems though) # v1.1.0 -- 02-13-2000 -- Allowing optional update file parameter print "Cool FPUpdate v1.1.0\n"; (5 == @ARGV) or (6 == @ARGV) or die "Args: RemoteHost LoginID LoginPW PathRoot RemotePathRoot [UpdateFile]"; ($remoteHost, $loginID, $loginPW, $pathRoot, $remotePathRoot, $update_file) = @ARGV; use POSIX; # for mktime use Time::ParseDate; use Net::FTP; if (!$update_file) { # use default $update_file = "cool_fpupdate_cfg.txt"; } $current_time = time; # Set the last updated time, which by default is "the beginning of time" $lastupdate_time = 0; # by default: never been updated if (open(UPDATEFILE, "+<$update_file")) { $szLastUpdateTime = ; # convert from string to raw time number that can be compared with stat $lastupdate_time = parsedate($szLastUpdateTime, NO_RELATIVE => 1); # check that this time checks out print "Last update: " . POSIX::ctime($lastupdate_time) . "\n"; close UPDATEFILE; } print "Logging into $remoteHost as $loginID (PW=$loginPW).\n" . "\tRoot path = $pathRoot, Remote root path = $remotePathRoot .\n"; $ftp = Net::FTP->new($remoteHost, Debug => 0) or die "Couldn't connect to server"; $ftp->login($loginID, $loginPW) or die "Couldn't login"; $ftp->cwd($remotePathRoot) or die "Couldn't change dir"; updateRootDir(); $ftp->quit; # save update info to update file # Note that the date and time are the time of invocation -- # this ensures that if you edit during the upload, your files # will end up on the server eventually (though they may get uploaded twice). open (UPDATEFILE, ">$update_file") or die "can't open update file"; print "Updating update file to " . POSIX::ctime($current_time) . "\n"; print UPDATEFILE POSIX::ctime($current_time); close(UPDATEFILE); exit; sub updateRootDir { # This is only a separate function in case we want to add a # special case later updateDir($pathRoot, $remotePathRoot); } sub updateDir { # get dir contents my ($szDir, $szRemoteDir) = @_; my ($fullpath, $pathlen, $pathlenRoot, $relativepath); my @statresults; my @dircontents; opendir(DIR, $szDir) or die "can't opendir : $!"; #print $_ . "\n"; @dircontents = readdir(DIR); closedir DIR; $nLastDirEntry = $#dircontents; $nSizeDir = @dircontents; # iterate through dir foreach (@dircontents) { if ( /^[a-zA-Z0-9]+/ ) { $szFileOrDir = $_; $fullpath = "$szDir\\$szFileOrDir"; #print "match: $fullpath\n"; @statresults = stat($fullpath); # dir or file? if (-d $fullpath) { # TODO: also want to make sure this dir exists on remote machine $mtime = @statresults[9]; if ($mtime > $lastupdate_time) { $pathlen = length $fullpath; $pathlenRoot = length $pathRoot; $relativepath = substr $fullpath, $pathlenRoot + 1, $pathlen - $pathlenRoot; #print "want to upload dir $fullpath to\n\t$remotePathRoot + $relativepath\n"; uploadDir($szRemoteDir, $szFileOrDir); } local $szRemoteSubDir = "$szRemoteDir/$szFileOrDir"; #print "Recursing with: $fullpath, $szRemoteSubDir\n"; updateDir($fullpath, $szRemoteSubDir); } else { $mtime = @statresults[9]; if ($mtime > $lastupdate_time) { $pathlen = length $fullpath; $pathlenRoot = length $pathRoot; $relativepath = substr $fullpath, $pathlenRoot + 1, $pathlen - $pathlenRoot; #print "want to upload file $fullpath (" . POSIX::ctime($mtime) . ") to\n" . # "\t$remotePathRoot + $relativepath\n"; #print "file time: " . POSIX::ctime($mtime) . " > " . POSIX::ctime($lastupdate_time) . "\n"; uploadFile($fullpath, $szRemoteDir, $szFileOrDir); } else { #print "don't want to upload file $fullpath because $mtime !> $lastupdate_time\n"; } } } } } sub uploadFile { local ($fullpath, $szRemoteDir, $szFile) = @_; print "uploadFile: Uploading:\n" . "\t$fullpath ->\n" . "\t$szRemoteDir /" . " $szFile (" . (($szFile =~ /(html?|txt|pl|bat|c|cpp)$/) ? "ascii" : "binary" ) . ")\n"; ($szFile =~ /(html?|txt|pl|bat|c|cpp)$/) ? $ftp->ascii() : $ftp->binary(); $ftp->cwd($szRemoteDir) or die "couldn't cd to $szRemoteDir"; $ftp->put($fullpath, $szFile) or die "couldn't upload $szFile"; } sub uploadDir { # this really just makes a dir, it doesn't upload anything local ($szRemoteDir, $szDir) = @_; $ftp->cwd($szRemoteDir) or die "couldn't cwd $szRemoteDir"; if (not $ftp->cwd($szDir)) { # only create it if it doesn't exist print "uploadDir: Creating DIR $szRemoteDir / $szDir\n"; $ftp->mkdir($szDir) or die "couldn't mkdir $szDir"; } }