]> git.treefish.org Git - fex.git/blobdiff - bin/l
Original release 20160919
[fex.git] / bin / l
diff --git a/bin/l b/bin/l
index affd4a21f93475d1a0a24e24c4aaf7016bce703e..203e3101069f1976ca9261f8a180ba2bfdaa28c2 100755 (executable)
--- a/bin/l
+++ b/bin/l
@@ -13,7 +13,7 @@ use Getopt::Std;
 # the name of the game
 $0 =~ s:.*/::;
 
-$ENV{LC_CTYPE} = 'C';
+$ENV{LC_ALL} = 'C';
 
 # unshift @ARGV,split /\s+/,$ENV{'l_opt'} if $ENV{'l_opt'};
 
@@ -32,9 +32,20 @@ $opt_l = 1                            if $0 eq 'll';
 $opt_l = $opt_i = $opt_a = $opt_S = 1 if $0 eq 'lll';
 &examples if $opt_E;
 if ($0 eq 'lf' or $0 eq 'llf') {
-  $opt_F ||= shift or usage(1);
-  $opt_R ||= scalar(@ARGV) || ($opt_F eq '.');
-  $opt_l ||= $0 eq 'llf';
+  $opt_l = $0 eq 'llf';
+  if (scalar(@ARGV) == 0) {
+    die usage(1);
+  } elsif (scalar(@ARGV) == 1) {
+    $opt_F = shift;
+    $opt_R = $opt_F if $opt_F eq '.';
+  } elsif (-d $ARGV[-1]) {
+    $opt_R = pop(@ARGV);
+    $opt_F = join('|',@ARGV);
+  } else {
+    $opt_F = join('|',@ARGV);
+  }
+  @ARGV = ();
+  @ARGV = ($opt_R) if -d $opt_R;
 }
 
 $postsort = $opt_t||$opt_s;
@@ -138,6 +149,8 @@ sub collect {
   my @files = @_;
   my $f;
 
+  getacl(@files) if $opt_l and not $opt_n;
+
   # loop over all argument files/directories
   foreach $f (@files) {
 
@@ -175,8 +188,8 @@ sub collect {
       $f =~ s:/$:: if $opt_d;
 
       # on trailing / list subdirs, too
-      if ($f =~ m:/$:) { &list(&getfiles($f)) }
-      elsif ($f eq '') { &list('/') }
+      if ($f =~ m:/$:) { list(getfiles($f)) }
+      elsif ($f eq '') { list('/') }
       else {
         if ($opt_L) {
           unless (-e $f) {
@@ -262,6 +275,8 @@ sub list {
            elsif ($i eq 'a') { $line .= sprintf '%10s %10s %10s ',
                                         $dates{'a'},$dates{'m'},$dates{'c'} }
          } else {
+            # $mode =~ s/(....)(...)/sprintf($1.uc($2))/e if $ACL{$file};
+            substr($mode,4,3) = uc(substr($mode,4,3)) if $ACL{$file};
            if    ($i eq 'm') { $line .= $mode.' ' }
            elsif ($i eq 'u') { $line .= sprintf '%-8s ',  $uid }
            elsif ($i eq 'g') { $line .= sprintf '%-8s ',  $gid }
@@ -283,15 +298,22 @@ sub list {
       } else {
 
        if ($opt_n) {
-          if ($opt_l) { $line .= sprintf "%06o %6d %6d $z%15s %10d ",
-                                        $mode,$uid,$gid,$size,$date }
-          else        { $line .= sprintf "%06o $z%15s %10d ",
-                                        $mode,$size,$date }
+          if ($opt_l) {
+            $line .= sprintf "%06o %6d %6d $z%15s %10d ",
+                            $mode,$uid,$gid,$size,$date;
+          } else {
+            $line .= sprintf "%06o $z%15s %10d ",$mode,$size,$date;
+          }
        } else {
-          if ($opt_l) { $line .= sprintf "%s %-8s %-8s $z%19s %s ",
-                                        $mode,$uid,$gid,$size,$date }
-          else        { $line .= sprintf "%s $z%19s %s ",
-                                        $mode,$size,substr($date,0,-3) }
+          if ($opt_l) {
+            # $mode .= $ACL{$file} ? '+' : ' ';
+            # $mode =~ s/(....)(...)/sprintf($1.uc($2))/e if $ACL{$file};
+            substr($mode,4,3) = uc(substr($mode,4,3)) if $ACL{$file};
+            $line .= sprintf "%s %-8s %-8s $z%19s %s ",
+                             $mode,$uid,$gid,$size,$date;
+          } else {
+            $line .= sprintf "%s $z%19s %s ",$mode,$size,substr($date,0,-3);
+          }
         }
 
        if ($opt_i)   { $line .= sprintf '%3s %10s ',$links,$inode }
@@ -375,13 +397,14 @@ sub info {
         substr($mode,8,1) =~ tr/-x/Tt/ if -k _;
         $mode = $type.$mode;
       } else {
-        # with short list display only effektive file access modes
+        # with short list display only effective file access modes
+        use filetest 'access'; # respect ACLs ==> cannot use pseudofile _
         $mode = $type
-               . (-r _ ? 'R' : '-')
-                . (-w _ ? 'W' : '-')
-                . (-x _ ? 'X' : '-');
-        substr($mode,2,1) =~ tr/-x/Ss/ if -u _ or -g _;
-        substr($mode,3,1) =~ tr/-x/Tt/ if -k _;
+               . (-r $file ? 'R' : '-')
+                . (-w $file ? 'W' : '-')
+                . (-x $file ? 'X' : '-');
+        substr($mode,2,1) =~ tr/-x/Ss/ if -u $file or -g $file;
+        substr($mode,3,1) =~ tr/-x/Tt/ if -k $file;
       }
     }
 
@@ -425,6 +448,25 @@ sub info {
   return ($linkname,$inode,$links,$size,$mode,$uid,$gid,$date,%dates);
 }
 
+# get ACLs
+#
+# INPUT: filenames
+#
+# GLOBAL: @ACL
+sub getacl {
+  my @files;
+
+  $getfacl ||= pathsearch('getfacl') or return;
+  # warn "### @_\n";
+  foreach my $file (@_) { push @files,$file if -e $file }
+  if (@files and open my $acl,'-|',$getfacl,'-ps',@files) {
+    while (<$acl>) {
+      $ACL{$1} = $1 if /^# file: (.+)/;
+    }
+    close $acl;
+  }
+}
+
 
 # reformat integer into 3-digit doted format
 # (when non-numerical mode is set)
@@ -482,6 +524,7 @@ sub getfiles {
     warn "$0: cannot read $dir : $!\n";
   }
 
+  getacl(@dirs,@files) if $opt_l and not $opt_n;
   return (@dirs,@files);
 }
 
@@ -497,6 +540,15 @@ sub nodes {
 }
 
 
+sub pathsearch {
+  my $prg = shift;
+
+  foreach my $dir (split(':',$ENV{PATH})) {
+    return "$dir/$prg" if -x "$dir/$prg";
+  }
+}
+
+
 # reformat timetick to ISO date string
 #
 # INPUT: timetick
@@ -552,7 +604,7 @@ sub usage {
     print OUT "usage: $0 $opts [-F regexp] [file...]\n";
   }
   $opts =~ s/R//;
-  print OUT "usage: lf $opts regexp [directory...]\n";
+  print OUT "usage: lf $opts regexp [regexp...] [directory]\n";
   print OUT <<EOD;
 options: -l  long list (implicit if called 'll')
          -a  list also .* files
@@ -566,7 +618,7 @@ options: -l  long list (implicit if called 'll')
          -n  numerical output
          -r  reverse list
          -z  squeeze size field (slows down output)
-         -L  derefernce symbolic links
+         -L  show absolute real path (dereference symbolic links)
          -R  recursive into subdirs
          -x  do not cross filesystem boundaries with -R
          -F  find files matching case insensitive regexp