In my search I found the following nodes
File permission converter and
Converting Permission string to Octal. However, these are working the problem I am faced with in a backward manner to my situation.
I have written a lil perl script that stats files for mac times (mtime, atime, ctime) and some other various tidbits of data. One these data is the absolute permissions mode. I want to convert these modes to the all too recognizeable masked notation eg. drwxrwxrwx.
I am currently using bitwise operations to get something (not sure what it is though because it isn't the real permissions mode of the file as far as I can tell). I will post the script and the output.
#!/usr/local/bin/perl -w
# Written by Jim Conner
# 4/10/2001
# Nifty lil utility I wrote to be able to
# get the mtime, ctime, and atime values from
# any file of your choice.
###################################################
# HOW TO USE!!
# It is quite simple. All you do is supply this
# script with the directory(ies)/file(s) you want to get
# info on and voila! there's your info.
#
# Examples:
#
# macls /tmp
# This will give you a listing of all files in /tmp
#
# macls file1 file2 file3
# This will give you a listing of files 1 2 and 3.
#
# macls
# This will give you a listing of all files in the
# present working directory.
#
# TODO:
# Add command line args and options. One of the
# most important of which would be -h (help)
#
# Fix the mode. Currently, it does not report
# an understandable mode.
#
# Translate the mode to human readable (laman)
# terms (drwxrwxr-x)
#
# Audit Trail:
# 4/9/2k1 - First conceptualized and started on authoring
# 4/10/2k1 - Released version 1.0
#
###################################################
use strict;
use File::Basename;
use vars qw($DEBUG);
####################
$DEBUG = "0";
####################
my $plProgName = basename($0);
my $count = "0";
my $total = "0";
my @filename;
####################
if ( $#ARGV == "-1" ) {
@filename = &readall();
} elsif ( $#ARGV >= "0" ) {
if ( -d $ARGV[0] ) {
@filename = &readall($ARGV[0]);
} else {
@filename = @ARGV;
}
}
print "\n";
for ( @filename ) {
my $filename = $_;
my($dev,$inode,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$c
+time,$blksize,$blocks);
if ( $count >= "1" ) {
print "*******************************************************
+\n\n";
}
warn "$0: $filename: $!\n" and next if ( ! open (F,"$filename") );
# I just found this :(
# 0 dev device number of filesystem
# 1 ino inode number
# 2 mode file mode (type and permissions)
# 3 nlink number of (hard) links to the file
# 4 uid numeric user ID of file's owner
# 5 gid numeric group ID of file's owner
# 6 rdev the device identifier (special files only)
# 7 size total size of file, in bytes
# 8 atime last access time since the epoch
# 9 mtime last modify time since the epoch
# 10 ctime inode change time (NOT creation time!) since the epoch
+<-- NNNOOOTTT GOOD!! :(
# 11 blksize preferred block size for file system I/O
# 12 blocks actual number of blocks allocated
#
#(The epoch was at 00:00 January 1, 1970 GMT.)
($dev, $inode,
$mode, $nlink,
$uid, $gid,
$rdev, $size,
$atime, $mtime,
$ctime, $blksize,
$blocks ) = lstat(F);
# from mknod(2) (good info!)
# S_ISUID 04000 Set user ID on execution.
# S_ISGID 020#0 Set group ID on execution if # is 7, 5, 3,
+or 1.
# Enable mandatory file/record locking if # i
+s
# 6, 4, 2, or 0.
# S_ISVTX 01000 Save text image after execution.
# S_IRWXU 00700 Read, write, execute by owner.
# S_IRUSR 00400 Read by owner.
# S_IWUSR 00200 Write by owner.
# S_IXUSR 00100 Execute (search if a directory) by owner.
# S_IRWXG 00070 Read, write, execute by group.
# S_IRGRP 00040 Read by group.
# S_IWGRP 00020 Write by group.
# S_IXGRP 00010 Execute by group.
# S_IRWXO 00007 Read, write, execute (search) by others.
# S_IROTH 00004 Read by others.
# S_IWOTH 00002 Write by others
# S_IXOTH 00001 Execute by others.
# S_ISVTX On directories, restricted deletion flag.
$mode &= 07777;
my $username = getpwuid($uid);
my $grpname = getgrgid($gid);
my @atime_readable = &fixgmt("$atime",'atime');
my @mtime_readable = &fixgmt("$mtime",'mtime');
my @ctime_readable = &fixgmt("$ctime",'ctime');
print "MACtime for: $filename\n";
print "Mode($mode) $username($uid) $grpname($gid)\t$size bytes $b
+locks blocks\n";
print "Modified time\t........ @mtime_readable\n";
print "Access time \t........ @atime_readable\n";
print "Inode Change \t........ @ctime_readable\n\n";
close(F);
$count++;
$total = $total + $size;
}
print "\nTotal files checked : $count\n";
print "Total size in bytes : $total\n";
printf("Total size in Kbytes: %iK\n", $total / 1024);
printf("Total size in Mbytes: %iM\n\n", ($total / 1024) / 1024);
sub fixgmt() {
my ($object, $type) = @_ ;
print gmtime($object) ."\n" if $DEBUG == "1";
my($aday,$mon,$nday,$gmtime,$year) = split(/\s+/,gmtime($object));
my($hour,$min,$sec) = split(/:/,$gmtime);
# Do math on gmt time to make it localtime.
# Should get this from system LCTIME but I dunno
# how to do that yet...sooo
# Im gonna brute force the math for now.
$hour = abs($hour - 4);
$hour = "0$hour" if ( $hour < 10 );
$nday = "0$nday" if ( $nday < 10 );
my $ltime = "$hour:$min:$sec";
if ( $DEBUG == "1" ) {
print "Object type is: $type\n";
print "Object value is: $object\n";
print "Alpha day = $aday\nMonth = $mon\nNumber day =
+ $nday\nGMTTime = $gmtime\nYear = $year\n";
print "Hour = $hour\nMinute = $min\nSecond = $sec\n"
+;
print "LocalTime = $ltime\n\n";
}
return($aday,$mon,$nday,$ltime,$year);
}
sub readall() {
my $dir = "@_" ;
if ( $dir ) {
chdir($dir);
opendir(ALL,".") or die("Unable to read: $!\n");
} else {
opendir(ALL,".") or die("Unable to read: $!\n");
}
my @files = grep(!/(^\.\.?)/,readdir(ALL)) or die("Unable to get f
+ile list: $!\n");
return(@files);
}
I would appreciate a couple of things. Constructive code criticism. This will help me learn as I am still (what I consider to be) extremely new to Perl. May hurt my pride some but oh well. I would also like to find out how to get the permissions thing to work right. More specifically, how to get the proper permissions (ie 0755, or 0644, or 4750). Once I get to that point, I believe I can take it from there (to be seen). Here is what I get for output:
[jconner@kwan ~/bin/dev]$ perl macls macls
MACtime for: macls
Mode(416) jconner(10036) other(1) 5727 bytes 12 blocks
Modified time ........ Wed May 23 17:37:57 2001
Access time ........ Wed May 23 17:42:24 2001
Inode Change ........ Wed May 23 17:37:57 2001
Total files checked : 1
Total size in bytes : 5727
Total size in Kbytes: 5K
Total size in Mbytes: 0M
The part that says:
mode (416) is the obvious broken part and where I need the most help. The permissions the filesystem sees is 640.
[jconner@kwan ~/bin/dev]$ ls -l macls
-rw-r----- 1 jconner other 5727 May 23 17:37 macls
I appreciate any assistance in advance.
Thanks everyone!
----------
- Jim
Edited 2001-05-24 by Ovid