#!/usr/bin/perl -w
# vim: set sw=8 ts=8 si et:
my $directory;
my $file;
my $lslong=-1;  # -1:not set 0:normal ls -lR  1: ls -lR --full-time
my $lscmd;
my $printed=1;
my @line;my $i=0;my $ii;

$lscmd="/bin/ls -alR";
# un-comment the following line if you have gnu ls:
$lscmd="/bin/ls -alR --full-time";

use strict;
use vars qw($opt_h $opt_f $opt_s);
use Getopt::Std;

&getopts("f:hs")||exit 1;
&help if ($opt_h);

unless ($ARGV[0]){
        $directory=".";
}else{
       $directory=$ARGV[0];
       chop($directory) if ($directory=~ /\/$/);
} 
&help unless ( -d "$directory");
# Here is the output format that ls must have. I have not
# seen any unix system that did not conform to this:
#
#ls -lR produces:
#-rw-r--r--   1 eedgus   tmos         1993 Jun  5 16:37 test.c
#-rw-r--r--   1 eedgus   tmos          752 Jun 19 11:18 whatIdid
#-rw-r--r--   1 guido    users      395776 Jan  9  1980 dircol.tar
#
#RCS:
#total 14
#-r--r--r--   1 eedgus   tmos        13693 Jun 26 15:22 calarm.c,v
#-------------------------
# The option --full-time is gnu specific:
#ls -lR --full-time
#
#vi/share:
#total 1
#drwxr-xr-x   2 guido    users        1024 Wed Apr 22 21:19:35 1998 vilearn
#
#vi/share/vilearn:
#total 43
#-r--r--r--   1 guido    users         531 Wed Feb 18 14:47:21 1998 3temp
#-r--r--r--   1 guido    users        5442 Wed Feb 18 14:47:21 1998 4inserting
#-r--r--r--   1 guido    users        9326 Wed Feb 18 14:47:21 1998 5tricks
#
#xsuse:
#total 1043
#-rw-r--r--   1 guido    users       69383 Sun Jun 21 21:58:42 1998 Supps.html
#
# be careful with device listings:
#crw-rw-r--   1 root     uucp       4,  65 Thu Sep 10 18:40:06 1998 ttyS1
#crw-rw-r--   1 root     uucp       4,  66 Thu Sep 10 18:40:06 1998 ttyS2
#crw-rw-r--   1 root     uucp       4,  67 Thu Sep 10 18:40:06 1998 ttyS3
#crw-r--r--   1 root     root       1,   9 Thu Sep 10 18:39:56 1998 urandom
#crw-r--r--   1 root     root       1,   5 Thu Sep 10 18:39:56 1998 zero
#
# 
if ($opt_f){
        $directory="."; #ignore any directory arg with option -f
        open(LSCMD,"$opt_f")||die "ERROR: can not read file $opt_f\n";
}else{
        open(LSCMD,"$lscmd $directory |")||die "ERROR: broken pipe on ls -alR\n";
}

while(<LSCMD>) {
        $i++;
        chomp;
        next unless(/\w/);
        @line = split;
        next if ($line[$#line] eq ".." || $line[$#line] eq ".");

        if($#line == 0) {
                if ($printed==0){
                        print "empty-directory                $directory\n";
                }
                $directory = $_;
                chop($directory);
                $printed=0;
                next;
        } elsif($#line == 1) {
                # skip this line 
                next;
        } elsif(substr($_,0,1) eq "c" || substr($_,0,1) eq "b") {
                # we are looking at devices
                # re-position the array to skip dev number:
                foreach $ii (4 .. $#line){
                        $line[$ii]=$line[$ii+1];
                }
        } elsif(substr($_,0,1) eq "d") {
        #       print "skipping directory\n";
                $printed=1;
                next;
        }
        $printed=1;

        #determine the ls format if not yet done:
        if ($lslong == -1){
                if (/\d\d:\d\d:\d\d \d\d\d\d/){
                        $lslong=1;
                }else{
                        $lslong=0;
                }
        }
        if($#line >= 8 && !$lslong) {
                # have group?   
                unless ($opt_s){
                        printf("%3s-%02d %5s",$line[5],$line[6],$line[7]);
                        printf " %17s ",$line[4];
                }
                print  "$directory/";
                #This is in-case the filename contains a space or is a 
                #softlink:
                for $file (@line[8..$#line]){
                        print "$file " if ($file);
                }
                print "\n";
        }elsif($lslong && $#line >= 10) {
                # --full-time option was used:
                unless ($opt_s){
                        printf("%4d-%3s-%02d %8s",$line[9],$line[6],$line[7],$line[8]);
                        printf " %9s ",$line[4];
                }
                print  "$directory/";
                #This is in-case the filename contains a space or is a 
                #softlink:
                for $file (@line[10..$#line]){
                        print "$file " if ($file);
                }
                print "\n";
        }else{
                print "====can not format ====";
                print;
                print "\n";
        }


}
if ($printed==0){
        print "empty-directory                $directory\n";
}
close LSCMD;

#------------------
sub help{
        print "lsperl -- do a ls -lR but include the path name on every item

USAGE: lsperl [-hs] [-f ls-output-file] [start_dir]

OPTIONS: -h this help
         -s short listing with file names only 
         -f format the output of a previous ls that was redirected to a file\n";
        exit;
}