#!/local/pkg/perl/=/bin/perl

#use strict;

use English;
use File::Basename;
use File::Find;
use Time::Local;

my($this_prog) = basename($PROGRAM_NAME);
my($usage) = "Usage:  $this_prog [-d] username\n        $this_prog [-d] -f filename";

my($mail_spool) = "/mail/spool/imap";

my($local_tz) = "-0600";
my($local_tz_sec) = -6 * 60 * 60;

my(%month_tab) = (
                  "Jan", 1,
                  "Feb", 2,
                  "Mar", 3,
                  "Apr", 4,
                  "May", 5,
                  "Jun", 6,
                  "Jul", 7,
                  "Aug", 8,
                  "Sep", 9,
                  "Oct", 10,
                  "Nov", 11,
                  "Dec", 12
                 );

my($debug) = 0;

my($batchfile) = "";
my($uname) = "";

my(@batch) = ();

my($initial) = "";
my($mail_dir) = "";

my(@found) = ();

my($filename) = "";
my($line) = "";

my(@pieces) = ();
my($last_line) = "";

my($dev) = "";
my($ino) = 0;
my($mode) = 0;
my($nlink) = 0;
my($uid) = 0;
my($gid) = 0;
my($rdev) = "";
my($size) = 0;
my($atime) = 0;
my($mtime) = 0;
my($ctime) = 0;
my($blksize) = 0;
my($blocks) = 0;

my($timezone) = "";
my($month_str) = "";
my($date_str) = "";
my($hhmmss) = "";
my($year) = 0;
my($month) = "";
my($date) = 0;
my($hours) = 0;
my($minutes) = 0;
my($seconds) = 0;
my($new_mtime) = 0;

sub wanted {
  if ((-f $File::Find::name) && (! ($_ =~ /^cyrus\.\w+$/))) {
    push(@found, $File::Find::name);
  }
}

sub date_to_seconds {
  my($year, $month, $day, $hour, $minutes, $seconds, $timezone) = @_;
  my(@timelist) = (0, 0, 0, 0, 0, 0, 0, 0, -1);
  my($tz_sign) = "";
  my($result, $tz_hour, $tz_min, $tz_sec) = 0;

  # timelocal chokes on anything earlier than 1970
  if ($year < 1970) {
    $month = 1;
    $day = 1;
    $year = 1970;
  }
  $year -= 1900;
  $month -= 1;
  if (   ($month < 0)
      || ($month > 11)
      || ($day < 0)
      || ($day > 31)
      || ($year < 0)
      || ($hour < 0)
      || ($hour > 23)
      || ($minutes < 0)
      || ($minutes > 59)
      || ($seconds < 0)
      || ($seconds > 61)) {
    return 0;
  }
  $timelist[3] = $day;
  $timelist[4] = $month;
  $timelist[5] = $year;
  $timelist[2] = $hour;
  $timelist[1] = $minutes;
  $timelist[0] = $seconds;
  $result = timelocal(@timelist);
  if ($timezone ne $local_tz) {
    ($tz_sign, $tz_hour, $tz_min) = ($timezone =~ /^(\+|-)(\d\d)(\d\d)$/);
    $tz_sec = (($tz_hour * 60) + $tz_min) * 60;
    if ($tz_sign eq "-") {
      $tz_sec = -1 * $tz_sec;
    }
    $tz_sec = $local_tz_sec - $tz_sec;
    $result += $tz_sec;
  }
  return $result;
}

while (@ARGV) {
  if ($ARGV[0] eq "-d") {
    if ($debug) {
      print "$usage\n";
      exit;
    }
    $debug = 1;
    shift(@ARGV);
  }
  elsif ($ARGV[0] eq "-f") {
    if ($batchfile) {
      print "$usage\n";
      exit;
    }
    $batchfile = $ARGV[1];
    shift(@ARGV);
    shift(@ARGV);
  }
  elsif (! $uname) {
    $uname = $ARGV[0];
    shift(@ARGV);
  }
  else {
    print "$usage\n";
    exit;
  }
}

if ($batchfile) {
  if ($uname) {
    print "$usage\n";
    exit;
  }
  open (DATA, $batchfile) || die "ERROR:  Cannot open $batchfile\n";
  foreach $uname (<DATA>) {
    chop($uname);
    if ($uname) {
      push(@batch, $uname);
    }
  }
  close(DATA);
}
elsif ($uname) {
  push(@batch, $uname);
}
else {
  print "$usage\n";
  exit;
}

foreach $uname (@batch) {
  if ($uname) {
    ($initial) = ($uname =~ /^(\S).*$/);
    $mail_dir = "$mail_spool/$initial/user/$uname";
    find(\&wanted, ("$mail_dir"));
  }
}

foreach $filename (@found) {
  if ($debug) {
    print "Opening $filename\n";
  }
  if (open(MSG, "$filename")) {
    if ($debug) {
      print "Finding timestamp\n";
    }
    $new_mtime = 0;
    $last_line = "";
    while (($line = <MSG>) && (! $new_mtime)) {
      chop($line);
      if ($debug) {
        print "  $line\n";
      }
      if ($line) {
        if ($line =~ /^From .*$/) {
          ($date_str) = ($line =~ /^From (.*)$/);
          @pieces = split(" ", $line);
          $timezone = $local_tz;
          $year = pop(@pieces);
          $hhmmss = pop(@pieces);
          ($hours, $minutes, $seconds) = split(/:/, $hhmmss);
          $date = pop(@pieces);
          $month_str = pop(@pieces);
          $month = $month_tab{$month_str};
          $new_mtime = date_to_seconds($year, $month, $date, $hours,
                                       $minutes, $seconds, $timezone);
        }
        elsif ($line =~ /^Received: .*$/) {
          $last_line = $line;
        }
        elsif ($line =~ /^Date: .*$/) {
          @pieces = split(" ", $line);
          $timezone = pop(@pieces);
          $hhmmss = pop(@pieces);
          ($hours, $minutes, $seconds) = split(/:/, $hhmmss);
          $year = pop(@pieces);
          $month_str = pop(@pieces);
          $month = $month_tab{$month_str};
          $date = pop(@pieces);
          $new_mtime = date_to_seconds($year, $month, $date, $hours,
                                       $minutes, $seconds, $timezone);
        }
        elsif ($last_line) {
          if ($line =~ /^\w+/) {
            @pieces = split(" ", $line);
            $timezone = pop(@pieces);
            $hhmmss = pop(@pieces);
            ($hours, $minutes, $seconds) = split(/:/, $hhmmss);
            $year = pop(@pieces);
            $month_str = pop(@pieces);
            $month = $month_tab{$month_str};
            $date = pop(@pieces);
            $new_mtime = date_to_seconds($year, $month, $date, $hours,
                                         $minutes, $seconds, $timezone);
  
            $last_line = "";
          }
          else {
            $last_line .= $line;
          }
        }
      }
    }
    close(MSG);
    if ($debug) {
      print "Timestamp is $new_mtime\n";
    }
    if ($new_mtime) {
      ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
       $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
      if ($debug) {
        print "utime($atime, $new_mtime, ($filename));\n";
      }
      utime($atime, $new_mtime, ($filename));
    }
  }
  else {
    print "WARNING:  Cannot open $filename\n";
  }
}

