#!/usr/bin/perl # file: # create_batch.pl # author: # marcus fritzsch # date: # 20040617 # purpose: # generate a sftp batch file with all updates files # it uses a file modification tracker named $TRACKER in # each directory to know whether a file was modified # or not # $Id: create_batch.pl,v 1.4 2005/04/08 18:46:48 m Exp $ use warnings; use strict; use Fcntl ':mode'; our $directory=""; my $BASEDIR=qx(pwd); chomp $BASEDIR; my $BATCHFILE="$BASEDIR/.sftp.batch"; my $TRACKER=".remote_files.txt"; my @EXCLUDES=( "Makefile", "menu.txt", "misc_gfx", "redo_menu.sh", "sftp.batch", "$TRACKER", "$BATCHFILE.prev", "$BATCHFILE", "menu_programming.txt", "create_batch.pl", "create_batch.sh", "LOCK", "CVS" ); sub do_dir_tree ($); sub notice; sub errexit; sub error; sub to_batch ($$); sub notice { print "[+] " . shift () . "\n"; return 1; } sub errexit { print STDERR "[!] " . shift () . "\n"; exit 1; } sub error { print "[-] " . shift () . "\n"; return 1; } #### # prints a line to $BATCHFILE # param1 is the indentation depth # param2 the sftp cmd sub to_batch ($) { print BATCH " " x shift () . shift () . "\n"; } sub pad ($$) { return " " x shift () . shift (); } sub do_dir_tree ($) { my $ind = shift; my @tracker; $ind = 0 unless defined $ind; my $dd = qx(pwd); chomp $dd; $dd =~ s#^$BASEDIR##g; $dd =~ s#^/##g; $dd .= "/" if $dd ne ""; if (open TRACK, "<$TRACKER") { @tracker = ; chomp @tracker; close TRACK; } else { error "$dd$TRACKER\: $!"; } push @tracker, "x 1"; #just in case there's no file to read... opendir DIR, "." or die $!; my @entries = grep { !/^\./ && !/^\.\./ } readdir(DIR); foreach my $e (@EXCLUDES) { notice ("excluding $e") if grep (/^$e$/, @entries); @entries = grep { !/^$e$/ } @entries; } closedir DIR; foreach my $e (@entries) { my @buf; if (S_ISDIR((stat ($e))[2])) { #push @buf, pad $ind, "-mkdir $e"; #push @buf, pad $ind, "chmod 755"; #push @buf, pad $ind, "cd $e"; to_batch $ind, "-mkdir $e"; to_batch $ind, "chmod 755 $e"; to_batch $ind, "cd $e"; chdir $e or errexit $!; do_dir_tree ($ind+2); chdir ".." or errexit $!; #push @buf, pad $ind, "cd .."; to_batch $ind, "cd .."; } elsif (S_ISREG((stat ($e))[2])) { my $t = (grep (/^$e \d+/, @tracker))[0]; $t = "" unless defined $t; my ($track2,$track) = split / /, $t; my $ntrack = (stat $e)[9]; $track = 0 unless defined $track; $track2 = "" unless defined $track2; if ($ntrack gt $track) { notice "adding new entry for $dd$e"; #push @buf, pad $ind, "put $dd$e"; #push @buf, pad $ind, "chmod 644 $e"; to_batch $ind, "put $dd$e"; to_batch $ind, "chmod 644 $e"; } else { notice "skipping $dd$e - no change since last upload!"; } @tracker = grep { !/$track2/ } @tracker; push @tracker, "$e $ntrack"; } else { error "skipping non regular file $dd$e"; } if (grep (/put/, @buf)) { map { to_batch $_ } @buf; } undef @buf; } @tracker = grep { !/x 1/ } @tracker; open TRACK, ">$TRACKER" or errexit "$dd$TRACKER\: $!"; foreach my $l (@tracker) { print TRACK "$l\n"; } close TRACK; } # eventually get more excludes from cmnd-line for (my $x = 0; defined $ARGV[$x]; $x++) { push @EXCLUDES, $ARGV[$x]; } open BATCH, ">$BATCHFILE" or die $!; print BATCH "cd fritschy.de/\n"; print BATCH "progress\n"; do_dir_tree 0; close BATCH; # if there are _no_ puts in $BATCHFILE, empty the batch open BATCH, "<$BATCHFILE" or die $!; my @TB = ; close BATCH; unless (grep (/put/, @TB)) { notice "XXX: no put in $BATCHFILE, removing all lines..."; open BATCH, ">$BATCHFILE" or die $!; truncate BATCH, 0; #print BATCH "cd fritschy.de/\n"; close BATCH; }