# -*-perl-*-

require Net::FTP;

sub yesno($$) {
  my ($d, $msg) = @_;

  my ($res, $r);
  $r = -1;
  $r = 0 if $d eq "n";
  $r = 1 if $d eq "y";
  die "Incorrect usage of yesno, stopped" if $r == -1;
  while (1) {
    print $msg, " [$d]: ";
    $res = <STDIN>;
    $res =~ /^[Yy]/ and return 1;
    $res =~ /^[Nn]/ and return 0;
    $res =~ /^[ \t]*$/ and return $r;
    print "Please enter one of the letters `y' or `n'\n";
  }
}

##############################

$::pass = "?";

sub do_connect {
    my($ftpsite,$username,$_pass,$ftpdir,$passive,
       $useproxy,$proxyhost,$proxylogname,$proxypassword) = @_;

  TRY_CONNECT:
    while(1) {
	my $exit = 0;
	my ($remote);

	if ($useproxy) {
	    $remotehost = $proxyhost;
	    $remoteuser = $username . "@" . $ftpsite;
	} else {
	    $remotehost = $ftpsite;
	    $remoteuser = $username;
	}
	print "Connecting to $ftpsite...\n";
	$ftp = Net::FTP->new($remotehost, Passive => $passive);
	if(!$ftp || !$ftp->ok) { print "Failed to connect\n"; $exit=1; }
	if (!$exit) {
#    $ftp->debug(1);
	    if ($useproxy) {
		print "Login on $proxyhost...\n";
		$ftp->_USER($proxylogname);
		$ftp->_PASS($proxypassword);
	    }
	    print "Login as $username...\n";
	    if ($::pass eq "?") {
		if ($_pass eq "?") {
		    print "Enter password for ftp: ";
		    system("stty", "-echo");
		    $::pass = <STDIN>;
		    chomp $::pass;
		    print "\n";
		    system("stty", "echo");
		} else {
		    $::pass = $_pass;
		}
	    }
	    if(!$ftp->login($remoteuser, $::pass)) { print $ftp->message() . "\n"; $exit=1; }
	}
	if (!$exit) {
	    print "Setting transfer mode to binary...\n";
	    if(!$ftp->binary()) { print $ftp->message . "\n"; $exit=1; }
	}
	if (!$exit) {
	    print "Cd to `$ftpdir'...\n";
	    if(!$ftp->cwd($ftpdir)) { print $ftp->message . "\n"; $exit=1; }
	}

	if ($exit) {
	    if (yesno ("y", "Retry connection at once")) {
		next TRY_CONNECT;
	    } else {
		die "error";
	    }
	}

	last TRY_CONNECT;
    }

#    if(!$ftp->pasv()) { print $ftp->message . "\n"; die "error"; }

    return $ftp;
}

##############################

# assume server supports MDTM - will be adjusted if needed
my $has_mdtm = 1;

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

sub do_mdtm {
    my ($ftp, $file) = @_;
    my $time;

    if ($has_mdtm) {
	$time = $ftp->mdtm($file);
#	my $code=$ftp->code();	my $message=$ftp->message();
#	print " [ $code: $message ] ";
	if ($ftp->code() == 502		      # MDTM not implemented
	    || $ftp->code() == 500	      # command not understood (SUN firewall)
	    ) {
	    $has_mdtm = 0;
	} elsif (!$ftp->ok()) {
	    return undef;
	}
    }

    if (! $has_mdtm) {
	use Time::Local;

	my @files = $ftp->dir($file);
	if (($#files == -1) || ($ftp->code == 550)) { # No such file or directory
	    return undef;
	}

#	my $code=$ftp->code();	my $message=$ftp->message();
#	print " [ $code: $message ] ";

#	print "[$#files]";

	# get the date components from the output of "ls -l"
	if ($files[0] =~ 
	    /([^ ]+ *){5}[^ ]+ ([A-Z][a-z]{2}) ([ 0-9][0-9]) ([0-9 ][0-9][:0-9][0-9]{2})/) {

	    # what we can read
	    $month_name = $2;
	    $day = 0 + $3;
	    $yearOrTime = $4;

	    # translate the month name into number
	    $month = $months{$month_name};

	    # recognize time or year, and compute missing one
	    if ($yearOrTime =~ /([0-9]{2}):([0-9]{2})/) {
		$hours = 0 + $1; $minutes = 0 + $2;
		my @this_date = gmtime(time());
		my $this_month = $this_date[4];
		my $this_year = $this_date[5];
		if ($month > $this_month) {
		    $year = $this_year - 1;
		} else {
		    $year = $this_year;
		}
	    } elsif ($yearOrTime =~ / [0-9]{4}/) {
		$hours = 0; $minutes = 0;
		$year = $yearOrTime - 1900;
	    } else {
		die "Cannot parse year-or-time";
	    }

	    # build a system time
	    $time = timegm (0, $minutes, $hours, $day, $month, $year);
	} else {
	    die "Regexp match failed on LIST output";
	}
    }

    return $time;
}

1;

__END__
