#!/usr/local/bin/perl -w

# @(#)$Id: push,v 1.3 1999/10/17 21:36:48 twitham Exp twitham $

# upload newer files to an ftp server

# usage: push [config file] [-q]

# -*- perl -*- push.conf - push configuration file:

$serv = 'ftp.somewhere.com';	# ftp server to upload to
$user = 'username';		# username
$pass = 'password';		# password
$time = 5 * 60;			# allow server time to be ahead this many sec.
# $cache = "$conf.cache";	# only upload files changed since last push

# array of references to (local directory, remote directory, [files to upload])
# if no files are specified for the directory, all plain files are uploaded
@upload = (
	   # upload most current weather data:
	   [qw(/usr/local/etc/httpd/htdocs/wx200
	       /public_html/wx200
	       wx200.txt
	       day.html
	       dayall.html
	       intemp.gif
	       temp.gif
	       humid.gif
	       baro.gif
	       dir.gif
	       speed.gif
	       rain.gif
	       )],
	   # another example, everything in my homepage directory:
	   [qw(/home/myname/public_html
	       /public_html
	       )],
	   );

$verbose = 1 unless grep(/-q/, @ARGV);

1;				# return true

# any of the above can be overridden in a config file which is loaded here:
require $conf if -s ($conf = $ARGV[0] || "$0.conf");

use Net::FTP;			# your perl must have Net::FTP, from CPAN

sub update {
    my($loc, $rem, $ltime) = @_;
    my($rtime);

    unless ($ftp) {
	$ftp = Net::FTP->new($serv,
			     'Timeout' => 30,
			     'Passive' => 1,
			     ) || die $@;
#	$ftp->debug(1);
	$ftp->login($user, $pass) || die 'login';
	$ftp->type('I') || die 'type';
    }
    $rtime = $ftp->mdtm($rem) || 0;
    if ($ltime > $rtime - $time) {
	$ftp->put($loc, "$rem.in")
	    || die "put $loc $rem.in: ", $ftp->message;
	$ftp->rename("$rem.in", $rem)
	    || die "rename $rem.in $rem: ", $ftp->message;
	print "$loc ($ltime)\n\t-> $rem ($rtime - $time)\n"
	    if $verbose;
    } else {
	print "skip: $loc ($ltime)\n\t< $rem ($rtime - $time)\n"
	    if $verbose;
    }
}

if ($cache) {			# only upload new or modified files?
    open(FILE, $cache) || warn "$0: can't read $cache: $!\n";
    while (<FILE>) {
	($f, $t) = split;
	$cache{$f} = $t;
    }
    close FILE;
}
for $dir (@upload) {
    ($loc, $rem, @file) = @$dir;
    unless (@file) {		# all plain files in the dir if none specified
	opendir(DIR, $loc) || warn "$0: can't read $loc: $!\n";
	@file = grep(!/^\./ && -f "$loc/$_", readdir(DIR));
	closedir DIR;
    }
    for (@file) {
	$lfile = "$loc/$_";
	$rfile = "$rem/$_";
	$ltime = (stat($lfile))[9] || 0;
	&update($lfile, $rfile, $ltime) if $ltime > $cache{$lfile} || 0;
	push(@line, "$lfile $ltime\n") if $cache;
    }
}
if ($cache) {
    open(FILE, ">$cache") || warn "$0: can't write $cache: $!\n";
    map { print FILE $_ } @line;
    close FILE;
}
$ftp->quit || die 'quit' if $ftp;
