#!/usr/athena/bin/perl

$source_dir = '/afs/sipb/project/www/root-stuff';
$dest_dir   = '/var/local/www/root';

$gcp_bin    = '/usr/local/bin/gcp';
$mail_cmd   = '/bin/mail';

$error_log_file = '/tmp/tmp.server-AFS-update-errors';

$discuss_mtg         = 'anxiety-maint-mtg@charon.mit.edu';
$contact_address     = 'anxiety-maintainers@mit.edu';
$normal_mail_address = 'anxiety-maint-mtg@charon.mit.edu';
$error_mail_address  = 'anxiety-maintainers@mit.edu';

@updated = ();

if ( ((getpwuid($<))[0]) ne "wwwmaint") {
    print "This script should only be run as user 'wwwmaint'. Aborting.\n";
    exit(-1);
}

if ($ARGV[0] eq "") {
    &main();
} else {

    # the argument to this script is the destination directory.
    $dest_dir = $ARGV[0];

    # strip off trailing slashes
    $dest_dir =~ s/\/*$//;

    if (! (-d $dest_dir)) {
	print "$0 aborting: $dest_dir is not a directory.\n";
	exit(-1);
    }

    &main();
}

sub main {
    local(@fresh_dirs);
    umask(022);
    
    unlink($error_log_file);

    open(GCP, ($gcp_bin . " -dfRruv " . $source_dir . " " . $dest_dir .
	       " 2>" . $error_log_file . " |"));

    # Grab the names of the files that gcp (tries to) update
    while (<GCP>) {
	/\-\> (.*)$/;
	push(@updated, $1);
    }

    close GCP;
    
    # Basically, this line chmod 02755's all elements of @updated
    # that are directories. This makes it easy for people to update
    # files incrementally as themselves, as long as they're in group www.

    @fresh_dirs = grep(&grepsub($_), @updated);
    chmod (02775, @fresh_dirs);
    chown ($>, (getgrnam("www"))[2], @fresh_dirs);

    # If anything was updated, log it.
    if ($#updated > -1) {
	&send_normal_mail(@updated);
    }

    # This tests the size of the file. If it's == 0, it will be false.
    # Otherwise, it will be true. If it's true, there were errors logged, and
    # they should be reported.
    if (-s $error_log_file) {

	open(ERRLOG, "<" . $error_log_file);
	while (<ERRLOG>) {
	    $errors .= $_;
	}
	close(ERRLOG);

	&send_error_mail($errors);
    }
    
    unlink($error_log_file);

}

sub send_normal_mail {
    local(@updated) = @_;

    $whole_mail_cmd = "|" . $mail_cmd . " " . $normal_mail_address .
	" " . $discuss_mtg ;

    open(MAIL, $whole_mail_cmd);
    print MAIL "To: " . $normal_mail_address . "\n";
    print MAIL "bcc: " . $discuss_mtg . "\n";
    print MAIL "From: $ENV{'USER'}\n";
    print MAIL "Reply-to: " . $contact_address . "\n";
    print MAIL "Subject: nightly server update from AFS\n\n";
    print MAIL "These files were updated on stuff.mit.edu:\n";

    print MAIL (join("\n", @updated));
    print MAIL "\n";

    close MAIL;
}

sub send_error_mail {
    local($errors) = @_;

    $whole_mail_cmd = "|" . $mail_cmd . " " . $error_mail_address .
	" " . $discuss_mtg ;

    open(MAIL, $whole_mail_cmd);
    print MAIL "To: " . $error_mail_address . "\n";
    print MAIL "bcc: " . $discuss_mtg . "\n";
    print MAIL "From: $ENV{'USER'}\n";
    print MAIL "Reply-to: " . $contact_address . "\n";
    print MAIL "Subject: ERROR in nightly server update from AFS\n\n";
    print MAIL "Errors reported by the nightly stuff.mit.edu update from AFS:\n";

    print MAIL "\n" . $errors . "\n" ;

    close MAIL;
}

sub grepsub {
    lstat($_);
    -d _;
}
