Click here to register.
      
Bazaar


     Discuss > WebGUI Dev

Help With Octal Math

User JT
Date 11/30/2008 11:15 am
Views 567
Rating 0    Rate [
|
]
Previous · Next
User Message
JT

I'm very bad at math, and even worse when you leave base 10 math. So I need one of the math geniuses that lurk on this list to help me out.

Perl's stat() element 2 (the third in the array) is file mode. And it outputs this mode as an integer. From this you can turn the number into something more familiar (from a unix command line) like this:

$mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;

The problem is that I want to go the opposite direction. So since I don't know how to do that, I've created a rather lame brute force mechanism to do it. I'm hoping one of you can tell me the right way to do it. Here's the crappy way I created:

 

    # the next 20 lines or so are because i don't know how to calculate the number for mode

    my $mode = ($asset->isa('WebGUI::Asset::Wobject::Folder')) ? 'd' : '-';

    $mode .= "rwx";

    if ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) {

        $mode .= "rwx";

    }

    else {

        $mode .= "r-x";

    }

    if ($asset->get('groupIdEdit') eq '7') {

        $mode .= "rwx";

    }

    elsif ($asset->get('groupIdView') eq '7') {

        $mode .= "r-x";

    }

    else {

        $mode .= "---";

    }

    my %modes = (

        "-rwxr-x---" => 33256,

        "drwxr-x---" => 16872,

        "-rwxr-xr-x" => 33261,

        "drwxr-xr-x" => 16877,

        "-rwxrwx---" => 33272,

        "drwxrwx---" => 16888,

        "-rwxrwxr-x" => 33277,

        "drwxrwxr-x" => 16893,

        "-rwxrwxrwx" => 33279,

        "drwxrwxrwx" => 16895,

    );

    my $modeNumber = $modes{$mode};

 



Back to Top
Rate [
|
]
 
 
JT

Here are the transformations for each mode in case that helps:

-rwxr-x--- | 33256 | 0750
drwxr-x--- | 16872 | 0750
-rwxr-xr-x | 33261 | 0755
drwxr-xr-x | 16877 | 0755
-rwxrwx--- | 33272 | 0770
drwxrwx--- | 16888 | 0770
-rwxrwxr-x | 33277 | 0775
drwxrwxr-x | 16893 | 0775
-rwxrwxrwx | 33279 | 0777
drwxrwxrwx | 16895 | 0777



Back to Top
Rate [
|
]
 
 
Mike_S
I'm not quite sure what you are trying to accomplish, but I think the issue is that you need to include the file type info in the octal before converting to decimal.

From http://www.itworld.com/nls_unix_fileattributes_060309

$mode = (stat($filename))[2];

What you're going to notice right away, however, when you use the stat command is that not all of the attributes are going to be extracted in a form that makes them easy to use. If we retrieve the mode value, using the command shown above, for example, and then print the value, we're going to see something like this:

33188

This is because the mode field contains the file type along with its permissions matrix, so you still need to extract the information you want. This can be done by logically anding the field with the number 07777 like this:

printf "Permissions are %04o\n", $mode & 07777;

The number 33188 is 0100644 in octal and that number ANDed with 07777 yields 644. This printf statement will, therefore, print the phrase "Permissions are 0644".

Based on that the short octal value (0750 for example) just doesn't have enough info to construct the decimal values you are looking for.  Try out this little script:


my @types = qw( 33256 16872 33261 16877 33272 16888 33277 16893 33279 16895 );
foreach my $int ( @types ) {
   my $tmp = sprintf("0%o", $int);
   print "$int is $tmp\n";
   my $dec = oct($tmp);
   print "$tmp is back to $dec\n";
   print "------------------------\n";
}

You can always AND off the unused info to display simple perms like 0750 later, but if you want the 33256 representation, you need to specify file type I think.

Does that help?

On Sun, Nov 30, 2008 at 10:23 AM, <jt@plainblack.com> wrote:
JT wrote:

Here are the transformations for each mode in case that helps:

-rwxr-x--- | 33256 | 0750
drwxr-x--- | 16872 | 0750
-rwxr-xr-x | 33261 | 0755
drwxr-xr-x | 16877 | 0755
-rwxrwx--- | 33272 | 0770
drwxrwx--- | 16888 | 0770
-rwxrwxr-x | 33277 | 0775
drwxrwxr-x | 16893 | 0775
-rwxrwxrwx | 33279 | 0777
drwxrwxrwx | 16895 | 0777



http://www.plainblack.com/webgui/dev/discuss/help-with-octal-math/1


--

Plain Black&#44; makers of WebGUI
http://plainblack.com




Back to Top
Rate [
|
]
 
 
len
JT,
The stat() element 2 contains not only file permissions, but also the file type. If you want to construct the mode, you need to be aware of the filetype bit fields.You can find them all in the stat(2) man page, but the most important are:
0040000 -> directory0100000 -> regular file
Now it's easy... 
Suppose you want to create a file with permission 755, the filemode will be:
printf( "%#d", 0100000 + 0755); # gives  33261
I've adjusted your code so it calculates the mode directly in octal. 
my $mode = 0;
# Other file permission if ($asset->get('groupIdEdit') eq '7') {        $mode += 07;    # rwx} elsif ($asset->get('groupIdView') eq '7') {        $mode += 05;    # r-x;} else {        $mode += 0;     # ---   (duh)}
# Group file permissionif ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) {        $mode += 070;   # rwx;} else {        $mode += 050;   # r-x;}
# User file permission$mode += 0700;
# Directory if($asset->isa('WebGUI::Asset::Wobject::Folder')) {        $mode += 0040000; # Dir} else {        $mode += 0100000; # File}
my $modeNumber = sprintf("%#d",$mode); # Convert octal to decimal


Hope this helps.
Len







On 30 nov 2008, at 18:15, <jt@plainblack.com> wrote:
JT wrote:

I'm very bad at math, and even worse when you leave base 10 math. So I need one of the math geniuses that lurk on this list to help me out.

Perl's stat() element 2 (the third in the array) is file mode. And it outputs this mode as an integer. From this you can turn the number into something more familiar (from a unix command line) like this:


$mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;

The problem is that I want to go the opposite direction. So since I don't know how to do that, I've created a rather lame brute force mechanism to do it. I'm hoping one of you can tell me the right way to do it. Here's the crappy way I created:

 

    # the next 20 lines or so are because i don't know how to calculate the number for mode

    my $mode = ($asset->isa('WebGUI::Asset::Wobject::Folder')) ? 'd' : '-';

    $mode .= "rwx";

    if ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) {

        $mode .= "rwx";

    }

    else {

        $mode .= "r-x";

    }

    if ($asset->get('groupIdEdit') eq '7') {

        $mode .= "rwx";

    }

    elsif ($asset->get('groupIdView') eq '7') {

        $mode .= "r-x";

    }

    else {

        $mode .= "---";

    }

    my %modes = (

        "-rwxr-x---" => 33256,

        "drwxr-x---" => 16872,

        "-rwxr-xr-x" => 33261,

        "drwxr-xr-x" => 16877,

        "-rwxrwx---" => 33272,

        "drwxrwx---" => 16888,

        "-rwxrwxr-x" => 33277,

        "drwxrwxr-x" => 16893,

        "-rwxrwxrwx" => 33279,

        "drwxrwxrwx" => 16895,

    );

    my $modeNumber = $modes{$mode};

 


http://www.plainblack.com/webgui/dev/discuss/help-with-octal-math

--

Plain Black&#44; makers of WebGUI
http://plainblack.com



Back to Top
Rate [
|
]
 
 
len

The formatting was lost in my reply. Anyway, here's a fix


my $mode = 0;

# Other file permission
if ($asset->get('groupIdEdit') eq '7') {
        $mode += 07;    # rwx
} elsif ($asset->get('groupIdView') eq '7') {
        $mode += 05;    # r-x;
} else {
        $mode += 0;     # ---   (duh)
}

# Group file permission
if ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) {
        $mode += 070;   # rwx;
} else {
        $mode += 050;   # r-x;
}

# User file permission
$mode += 0700;

# Directory
if($asset->isa('WebGUI::Asset::Wobject::Folder')) {
        $mode += 0040000; # Dir
} else {
        $mode += 0100000; # File
}

my $modeNumber = sprintf("%#d",$mode);    # Convert octal to decimal

Len Kranendonk, www.ilance.nl



Back to Top
Rate [
|
]
 
 
JT

 Thanks guys, that helps a lot. From another friend of mine I worked out another more convoluted solution that looks like:

    # calculate mode

    my @parts = qw(r w x r);

    if ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) {

        push @parts, qw(w x);

    }

    else {

        push @parts, qw(- x);

    }

    if ($asset->get('groupIdEdit') eq '7') {

        push @parts, qw(r w x);

    }

    elsif ($asset->get('groupIdView') eq '7') {

        push @parts, qw(r - x);

    }

    else {

        push @parts, qw(- - -);

    }

    my $mode = 0;

    for my $part (@parts) {

        $mode = ($mode << 1) | ($part eq '-' ? 0 : 1);

    }

    $mode += ($asset->isa('WebGUI::Asset::Wobject::Folder')) ? 0040000 : 0100000; # got from RFC1094

But now thanks to you guys, I have a much more readable solution, that's shorter also:     # calculate the mode     my $mode = 0700; # owner permission: rwx      $mode += ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) ?  070 :  050;   # group permission: rwx || r-x     # world file permission      if ($asset->get('groupIdEdit') eq '7') {         $mode += 07;    # rwx     }     elsif ($asset->get('groupIdView') eq '7') {         $mode += 05;    # r-x;     }     $mode += ($asset->isa('WebGUI::Asset::Wobject::Folder')) ? 0040000 : 0100000; # asset type: folder || file     $mode = sprintf("%#d",$mode);    # Convert octal to decimal



Back to Top
Rate [
|
]
 
 
JT

 oops, the final solution got mangled. Here's another post to correct that:

    # calculate the mode

    my $mode = 0700; # owner permission: rwx 

    $mode += ($asset->get('groupIdEdit') eq $asset->get('groupIdView')) ?  070 :  050;   # group permission: rwx || r-x

    # world file permission 

    if ($asset->get('groupIdEdit') eq '7') {

        $mode += 07;    # rwx

    }

    elsif ($asset->get('groupIdView') eq '7') {

        $mode += 05;    # r-x;

    }

    $mode += ($asset->isa('WebGUI::Asset::Wobject::Folder')) ? 0040000 : 0100000; # asset type: folder || file

    $mode = sprintf("%#d",$mode);    # Convert octal to decimal

 



Back to Top
Rate [
|
]
 
 
perlDreamer

http://search.cpan.org/~pinyan/File-chmod-0.32/chmod.pm



Back to Top
Rate [
|
]
 
 
     Discuss > WebGUI Dev



Recent Discussions Color Key

Design:

Development:

Et Cetera:

Install/Upgrade:  

Smoketest:

Template Group:


Re: Newbie with a very basic inquiry by dtebh916 - Fri @ 07:11am

Re: Pagination markup by roryzweistra - Fri @ 06:30am

Windows Install by fishingfan - Fri @ 05:59am

Re: Newbie with a very basic inquiry by pvanthony - Fri @ 01:47am

Re: WUC 2009 by Albert2 - Fri @ 01:43am

Smoke Test for WebGUI (Stable) (2009-01-09) by botaction - Thu @ 11:59pm

Re: 2009 Presidents Meeting by knowmad - Thu @ 11:20pm

Re: WUC 2009 by knowmad - Thu @ 10:55pm

Re: Strategic Roadmap by knowmad - Thu @ 10:41pm

Re: Newbie with a very basic inquiry by knowmad - Thu @ 10:01pm

Re: Advanced Search template by limedzeze - Thu @ 06:45pm

Newbie with a very basic inquiry by dtebh916 - Thu @ 01:35pm

Re: Editing the login page by techwriter - Thu @ 09:01am

Re: a random act of kindness by arjan - Thu @ 04:25am

Re: navigation new window by arjan - Thu @ 04:15am