#!/usr/bin/perl -w
# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl>
# Web: http://www.xs4all.nl/~itsme/
#      http://wiki.xda-developers.com/
#
# $Id$
#

use strict;

# list all timestampts assosiated with a file.


use Time::Local;
use Getopt::Long;
use POSIX;

# time - 86400 * -A $fn  == atime  == dir /ta
# time - 86400 * -M $fn  == mtime  == dir /tw  ** default
# time - 86400 * -C $fn  == ctime  == dir /tc

my $g_rate;
my $g_mtime;
my $g_atime;
my $g_ctime;

sub usage {
	return <<__EOF__;
Usage: lstm [options] [files]
   -mt  show inode modification time
   -at  show last access time
   -ct  show creation time
   -t0  specify starttime
   -r[mac0n][mac0n]   show growth rate, ( with respect to m/a/c/t0/now time )
__EOF__
}
my $t0;
GetOptions(
	"mt"=>\$g_mtime,
	"at"=>\$g_atime,
	"ct"=>\$g_ctime,
    "t0=s"=>sub { $t0=parsetime($_[1]); },
    "tnow"=>sub { $t0=time(); },
	"r:s"=>\$g_rate,
) or die usage();

if (!defined $g_rate && !defined $g_mtime && !defined $g_atime && !defined $g_ctime) {
	$g_mtime= $g_atime= $g_ctime = 1;
}
elsif (defined $g_rate && !defined $g_mtime && !defined $g_atime && !defined $g_ctime) {
	$g_mtime= 1;
	$g_atime= $g_ctime = 0;
}

# todo: fix '-r' option defaults, it often picks the wrong timestamps.
# ... probably because xp behaves different from *ix
if (defined $g_rate && length($g_rate)==0) {
    $g_rate= $t0 ? "n0" : "nc";
}
elsif (defined $g_rate && length($g_rate)==1) {
    $g_rate.= $t0 ? "0" : "c";
}
printheader();


for my $filename (@ARGV) {
	$filename .= "/" if ( -d $filename  && $filename !~ m{/$});

    if (my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
      $atime,$mtime,$ctime,$blksize,$blocks)= stat $filename)
    {
        my %time= (a=>$atime, m=>$mtime, c=>$ctime, 0=>$t0, n=>time());
		my @items;
		push @items, timestr($atime) if ($g_atime);
		push @items, timestr($mtime) if ($g_mtime);
		push @items, timestr($ctime) if ($g_ctime);
		push @items, sprintf("%12s", $size);

                if ($g_rate) {
                    my $tt0= $time{substr($g_rate,1,1)};
                    my $ttu= $time{substr($g_rate,0,1)};
                    push @items, sprintf("%8d", $ttu==$tt0?0:$size/($ttu-$tt0));
                }
		push @items, $filename;

		print join(", ", @items), "\n";
    }
    else {
         warn "$filename: $!\n";
    }
}

sub timestr {
    return POSIX::strftime("%Y-%m-%d %H:%M:%S", localtime shift);
}

sub printheader {
	my @list;
	push @list, ".atime" if ($g_atime);
	push @list, ".mtime" if ($g_mtime);
	push @list, ".ctime" if ($g_ctime);
	push @list, ".size";
	push @list, ".rate" if ($g_rate);
	push @list, ".filename";

	print join(", ", @list), "\n";
}
sub parsetime {
    my @t= reverse split m{[-/ :]+}, $_[0];
    $t[4]-=1;
    $t[5]-=1900;
    return POSIX::mktime @t;
}
