Stat-lsMode-0.50/ 40755 167 144 0 6516710730 11655 5ustar mjdusersStat-lsMode-0.50/Makefile.PL100644 167 144 664 6516664713 13723 0ustar mjdusersuse ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Stat::lsMode', 'VERSION_FROM' => 'lsMode.pm', # finds $VERSION # 'LIBS' => [''], # e.g., '-lm' # 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' # 'INC' => '', # e.g., '-I/usr/include/other' 'dist' => {COMPRESS => 'gzip', SUFFIX => 'gz'}, ); Stat-lsMode-0.50/t/ 40755 167 144 0 6516710730 12120 5ustar mjdusersStat-lsMode-0.50/t/t.t100644 167 144 2537 6516706701 12657 0ustar mjdusers#!/usr/bin/perl use lib '../lib/blib'; use Stat::lsMode qw(format_mode file_mode); print "1..14\n"; foreach $i (0 .. 7) { my $t = $i * 73; my $mode = format_mode(oct("0$i$i$i")); $mode =~ s/^\?//; $mode =~ tr/-/0/; $mode =~ tr/0/1/c; my $total = 0; foreach $bit (split //, $mode) { $total = $total * 2 + $bit; } if ($total/73 != $i) { print "not ok ", $i+1, "\n"; } else { print "ok ", $i+1, "\n"; } } umask 000; $dir = "/tmp/SlsM.$$." . time; if (mkdir $dir, 0700) { print (((file_mode($dir) eq 'drwx------') ? '' : 'not '), "ok 9\n"); } else { print "not ok 9\n"; } if (open F, "> $dir/file") { print (((file_mode("$dir/file") eq '-rw-rw-rw-') ? '' : 'not '), "ok 10\n"); } else { print "not ok 10\n"; } umask 022; if (open F, "> $dir/file2") { print (((file_mode("$dir/file2") eq '-rw-r--r--') ? '' : 'not '), "ok 11\n"); } else { print "not ok 11\n"; } if (symlink "$dir/file2", "$dir/link") { print (((file_mode("$dir/link") =~ /^l/) ? '' : 'not '), "ok 12\n"); } else { print "not ok 12\n"; } # Test with a umask if (mkdir "$dir/dir", 0236) { print (((file_mode("$dir/dir") eq 'd-w---xr--') ? '' : 'not '), "ok 13\n"); } else { print "not ok 13\n"; } umask 0; if (mkdir "$dir/dir2", 0236) { print (((file_mode("$dir/dir2") eq 'd-w--wxrw-') ? '' : 'not '), "ok 14\n"); } else { print "not ok 14\n"; } Stat-lsMode-0.50/README100644 167 144 506 6516707176 12625 0ustar mjdusers This module is for formatting file modes and permissions the way that ls -l does. For example, if you have a file that is world-readable, but only writable by its owner, you can use file_mode($file) which will return the string '-rw-r--r--'. Beta version 0.50. 20 April 1998. M-J. Dominus (mjd-perl-lsmode@plover.com) Stat-lsMode-0.50/lsMode.pm100644 167 144 14720 6516710645 13564 0ustar mjdusers# # # Stat::lsMode # # Copyright 1998 M-J. Dominus # (mjd-perl-lsmode@plover.com) # # You may distribute this module under the same terms as Perl itself. # # $Revision: 1.2 $ $Date: 1998/04/20 01:27:25 $ package Stat::lsMode; $VERSION = '0.50'; use Carp; use Exporter; @ISA = qw(Exporter); @EXPORT = qw(format_mode file_mode format_perms); @perms = qw(--- --x -w- -wx r-- r-x rw- rwx); @ftype = qw(. p c ? d ? b ? - ? l ? s ? ? ?); $ftype[0] = ''; $NOVICE_MODE = 1; # Default on? sub novice { my $pack = shift; croak "novice_mode requires one boolean argument" unless @_ == 1; my $old = $NOVICE_MODE; # Should this be localized t $pack? $NOVICE_MODE = $_[0]; $old; } sub format_mode { croak "format_mode requires a mode as an argument" unless @_ >= 1; my $mode = shift; my %opts = @_; unless (defined $mode) { return wantarray() ? () : undef; } _novice_warning($mode) if $NOVICE_MODE; my $setids = ($mode & 07000)>>9; my @permstrs = @perms[($mode&0700)>>6, ($mode&0070)>>3, $mode&0007]; my $ftype = $ftype[($mode & 0170000)>>12]; my @ftype = $opts{no_ftype} ? () : ($ftype); if ($setids) { if ($setids & 01) { # Sticky bit $permstrs[2] =~ s/([-x])$/$1 eq 'x' ? 't' : 'T'/e; } if ($setids & 04) { # Setuid bit $permstrs[0] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e; } if ($setids & 02) { # Setgid bit $permstrs[1] =~ s/([-x])$/$1 eq 'x' ? 's' : 'S'/e; } } if (wantarray) { (@ftype, @permstrs); } else { join '', @ftype, @permstrs; } } sub file_mode { croak "file_mode requires one filename as an argument" unless @_ == 1; my $file = shift; my $mode = (lstat $file)[2]; unless (defined $mode) { if (wantarray) { return (); } else { carp "Couldn't get mode for file `$file': $!" if $NOVICE_MODE; return undef; } } format_mode($mode, @_); } sub format_perms { croak "format_perms requires a permission mode as an argument" unless @_ == 1; format_mode($_[0], no_ftype => 1); } # None of these are really plausible modes. # They are all almost certain to have occurred # when someone used decimal instead of octal to specify a mode. @badmodes = (777, 775, 755, 770, 700, 750, 751, 666, 664, 644, 660, 600, 640, 444, 440, 400, # 400 = rw--w---- which is just barely plausible. # 000 *is* OK. It means just what you think. 711, 771, 751, 551, 111, ); %badmode = map {($_ => 1)} @badmodes; # Novices like to ask for the bits for mode `666' instead of `0666'. # Try to detect and diagnose that. sub _novice_warning { my $mode = shift; if ($badmode{$mode}) { carp "mode $mode is very surprising. Perhaps you meant 0$mode"; } } =head1 NAME Stat::lsMode - format file modes like the C command does =head1 SYNOPSIS use Stat::lsMode; $mode = (stat $file)[2]; $permissions = format_mode($mode); # $permissions is now something like `drwxr-xr-x' $permissions = file_mode($file); # Same as above $permissions = format_perms(0644); # Produces just 'rw-r--r--' $permissions = format_perms(644); # This generates a warning message: # mode 644 is very surprising. Perhaps you meant 0644... Stat::lsMode->novice(0); # Disable warning messages =head1 DESCRIPTION C generates mode and permission strings that look like the ones generated by the Unix C command. For example, a regular file that is readable by everyone and writable only by its owner has the mode string C<-rw-r--r-->. C will either examine the file and produce the right mode string for you, or you can pass it the mode that you get back from Perl's C call. =head2 C Given a mode number (such as the third element of the list returned by C), return the appopriate ten-character mode string as it would have been generated by C. For example, consider a directory that is readable and searchable by everyone, and also writable by its owner. Such a directory will have mode 040755. When passed this value, C will return the string C. If C is passed a permission number like C<0755>, it will return a nine-character string insted, with no leading character to say what the file type is. For example, C will return just C, without the leading C. =head2 C Given a filename, do C on the file to determine the mode, and return the mode, formatted as above. =head2 Novice Operation Mode A common mistake when dealing with permission modes is to use C<644> where you meant to use C<0644>. Every permission has a numeric representation, but the representation only makes sense when you write the number in octal. The decimal number 644 corresponds to a permission setting, but not the one you think. If you write it in octal you get 01204, which corresponds to the unlikely permissions C<-w----r-T>, not to C. The appearance of the bizarre permission C<-w----r-T> in a program is almost a sure sign that someone used C<644> when they meant to use C<0644>. By default, this module will detect the use of such unlikely permissions and issue a warning if you try to format them. To disable these warnings, use Stat::lsMode->novice(0); # disable novice mode Stat::lsMode->novice(1); # enable novice mode again The surprising permissions that are diagnosed by this mode are: 111 => --xr-xrwx 400 => rw--w---- 440 => rw-rwx--- 444 => rw-rwxr-- 551 => ---r--rwt 600 => --x-wx--T 640 => -w------T 644 => -w----r-T 660 => -w--w-r-T 664 => -w--wx--T 666 => -w--wx-wT 700 => -w-rwxr-T 711 => -wx---rwt 750 => -wxr-xrwT 751 => -wxr-xrwt 751 => -wxr-xrwt 755 => -wxrw--wt 770 => r------wT 771 => r------wt 775 => r-----rwt 777 => r----x--t Of these, only 400 is remotely plausible. =head1 BUGS As far as I know, the precise definition of the mode bits is portable between varieties of Unix. The module should, however, examine C or use some other method to find out if there are any local variations, because Unix being Unix, someone somewhere probably does it differently. Maybe it C should have an option that says that if the file is a symlink, to format the mode of the pointed to file instead of the mode of the link itself, the way C does. =head1 SEE ALSO =over 4 =item * C. =item * L =item * L =item * L =back =head1 AUTHOR Mark-Jason Dominus (C). =cut Stat-lsMode-0.50/MANIFEST100644 167 144 54 6516707027 13047 0ustar mjdusersREADME MANIFEST lsMode.pm Makefile.PL t/t.t