#! /usr/bin/env perl

#
#   Copyright (C) Heinz-Josef Claes (2000,2004)
#                 hjclaes@web.de
#   
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#   
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#   
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#


push @VERSION, '$Id: llt 335 2004-07-23 03:56:18Z hjc $ ';


use strict;

sub libPath
{
    my $file = shift;

    my $dir;

    # Falls Datei selbst ein symlink ist, solange folgen, bis aufgelst
    if (-f $file)
    {
	while (-l $file)
	{
	    my $link = readlink($file);

	    if (substr($link, 0, 1) ne "/")
	    {
		$file =~ s/[^\/]+$/$link/;
	    }
	    else
	    {
		$file = $link;
	    }
	}

	($dir, $file) = &splitFileDir($file);
	$file = "/$file";
    }
    else
    {
	print STDERR "<$file> does not exist!\n";
	exit 1;
    }

    $dir .= "/../lib";           # Pfad zu den Bibliotheken
    my $oldDir = `/bin/pwd`;
    chomp $oldDir;
    if (chdir $dir)
    {
	my $absDir = `/bin/pwd`;
	chop $absDir;
	chdir $oldDir;

	return (&splitFileDir("$absDir$file"));
    }
    else
    {
	print STDERR "<$dir> does not exist, exiting\n";
    }
}
sub splitFileDir
{
    my $name = shift;

    return ('.', $name) unless ($name =~/\//);    # nur einfacher Dateiname

    my ($dir, $file) = $name =~ /^(.*)\/(.*)$/s;
    $dir = '/' if ($dir eq '');                   # gilt, falls z.B. /filename
    return ($dir, $file);
}
my ($req, $prog) = &libPath($0);
push @INC, "$req";

require 'checkParam.pl';
require 'version.pl';

my $Help =<<EOH;
list files with create, access and modification times

usage:
	$0 [-r] [-i] [-a|-m|-c] [files] [dirs]

--help		-h show this help
--reverse	-r sort in reverse order
--insensitive   -i case-insensitively (not with -a, -m or -c)
--access	-a sort according to access time
--modification	-m sort according to access time
--creation	-c sort according to access time
--unixTime	-u show unix time (unsigned integer)

Sorting without [-a|-m|-c] is sorting according to file names.

		-V  print version(s)

Copyright (c) 2000,2004 by Heinz-Josef Claes
Published under the GNU General Public License
EOH

&printVersions(\@ARGV, '-V');

my $CheckPar =
    CheckParam->new(
		    '-allowLists' => 'yes',
		    '-list' => [
				Option->new('-option' => '-i',
					    '-alias' => '-insensitive',
					    '-only_if' =>
					    'not [-a] and not [-m] and not [-c]'
					    ),
				Option->new('-option' => '-a',
					    '-alias' => '--access',
					    '-only_if' =>
					    'not [-m] and not [-c]'
					    ),
				Option->new('-option' => '-m',
					    '-alias' => '--modification',
					    '-only_if' =>
					    'not [-a] and not [-c]'
					    ),
				Option->new('-option' => '-c',
					    '-alias' => '--creation',
					    '-only_if' =>
					    'not [-a] and not [-m]'
					    ),
				Option->new('-option' => '-r',
					    '-alias' => '--reverse'
					    ),
				Option->new('-option' => '-u',
					    '-alias' => '--unixTime'),
				Option->new('-option' => '-h',
					    '-alias' => '--help'
					    ),
				]
		    );

$CheckPar->check('-argv' => \@ARGV,
		 '-help' => $Help
		 );

if ($CheckPar->getOptWithoutPar('-h'))
{
    print "$Help";
    exit 0;
}

my $sort = 'name';      # Default: Alphabetisch sortieren
$sort = 'atime' if ($CheckPar->getOptWithoutPar('-a'));
$sort = 'mtime' if ($CheckPar->getOptWithoutPar('-m'));
$sort = 'ctime' if ($CheckPar->getOptWithoutPar('-c'));
my $reverse = 1 if ($CheckPar->getOptWithoutPar('-r'));
my $insensitive = 1 if ($CheckPar->getOptWithoutPar('-i'));
my $unixTime = $CheckPar->getOptWithoutPar('-u');

my (@all) = ($CheckPar->getListPar() == 0) ? ('.') : ($CheckPar->getListPar());

my (@files);
my $f;
foreach $f (@all)
{
    if (-d $f)    # wenn Directory
    {
	opendir(DIR, $f) or print STDERR "cannot open <$f>\n";
	my $f1;
	foreach $f1 (readdir(DIR))
	{
	    push @files, "$f/$f1";
	}
	closedir(DIR);
    }
    else          # Datei
    {
	if (-f $f)
	{
	    push @files, $f;
	}
	else
	{
	    print "Cannot open file <$f>\n";
	}
    }
}

# Ermitteln der Zeiten
my (@f);
foreach $f (@files)
{
    my ($atime, $mtime, $ctime) = (lstat($f))[8,9,10];
    my %h = ('name' => $f,
	     'atime' => $atime,
	     'mtime' => $mtime,
	     'ctime' => $ctime
	     );
    push @f, \%h;
}

# Sortieren
my (@sf);
if ($sort eq 'name')
{
    if ($insensitive)
    {
	@sf = $reverse ? sort { uc($b->{$sort}) cmp uc($a->{$sort}) } @f
	    : sort { uc($a->{$sort}) cmp uc($b->{$sort}) } @f;
    }
    else
    {
	@sf = $reverse ? sort { $b->{$sort} cmp $a->{$sort} } @f
	    : sort { $a->{$sort} cmp $b->{$sort} } @f;
    }
}
else
{
    @sf = $reverse ?
	sort { $b->{$sort} <=> $a->{$sort} } @f :
	sort { $a->{$sort} <=> $b->{$sort} } @f;
}

# Ausgabe
my $len = $unixTime ? 11 : 19;
printf "%-${len}s  %-${len}s  %-${len}s  [Time]\n", "access",
    "modification", "creation";
foreach $f (@sf)
{
    my $t;
    foreach $t ($f->{'atime'}, $f->{'mtime'}, $f->{'ctime'})
    {
	if ($unixTime)
	{
	    print "$t   ",
	}
	else
	{
	    print &getTime($t), "  ";
	}
    }
    print $f->{'name'}, "\n";
}

exit 0;


sub getTime
{
    my $t = shift;

    my ($sec,$min,$hour,$mday,$mon,$year) = localtime($t);
    return sprintf("%4d.%02d.%02d %02d:%02d:%02d",
		   $year+1900, $mon+1, $mday,
		   $hour, $min, $sec);
}

