Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Unwanted Octal to Decimal Conversion

by djantzen (Priest)
on Feb 18, 2004 at 20:36 UTC ( [id://330050]=perlquestion: print w/replies, xml ) Need Help??

djantzen has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I've got a module that utilizes Unix style octal permissions to regulate whether users can perform certain tasks depending on ownership and group membership criteria. Basically what I want to do is set up class constants for various permissions like:

use constant OTHER_READ => 0004 use constant OTHER_WRITE => 0002; use constant OTHER_EXEC => 0001; use constant GROUP_READ => 0040; use constant GROUP_WRITE => 0020; use constant GROUP_EXEC => 0010; use constant OWNER_READ => 0400; use constant OWNER_WRITE => 0200; use constant OWNER_EXEC => 0100;

and then use these to create masks for comparison to the actual permissions associated with the object. Unfortunately for me, perl automatically converts these into their decimal form when I really do want them to be octals, which means that to use them I have to run them through sprintf like sprintf("%o", OWNER_READ). But even that's trouble because I can't get the proper zero-padding to work so e.g., '0040' comes back '40'. This means for example, that my $mask = 40 | 400 comes back '400' while what I need is '440'.

Complicating matters is the fact that Oracle drops leading zeros in a NUMBER column so when I pull my permissions from the database I have still another conversion to do. So far, the only way I can actually get this to work is to treat it like a string in Perl e.g., use constant OTHER_READ => '0001'; and then prepend the zeros as a string when pulling it from the database, but clearly this is a nasty hack.

Thanks for any help.
Update: Okay, I realized I was misreading the sprintf documentation on padding during numeric conversions. How about this:

use constant OTHER_READ => sprintf("%.4o", 0004)
etc?


"The dead do not recognize context" -- Kai, Lexx

Replies are listed 'Best First'.
Re: Unwanted Octal to Decimal Conversion
by Limbic~Region (Chancellor) on Feb 18, 2004 at 20:53 UTC
    djantzen,
    I am pretty sure you can reduce all your use constant lines to just:
    use Fcntl ':mode';
    See perldoc -f stat for more information as it exports both constants and functions.

    So it sounds like the issue is to prevent Oracle from dropping the leading zeros. Is there any reason this must be a NUMBER column?

    Cheers - L~R

Re: Unwanted Octal to Decimal Conversion
by borisz (Canon) on Feb 18, 2004 at 20:56 UTC
    I can't see the real problem here.
    #!/usr/bin/perl use constant GROUP_READ => 0040; use constant OWNER_READ => 0400; my $mask = GROUP_READ | OWNER_READ; printf "my mask is %04o", $mask;
    Boris

      I recommend "%05o" or "%#04o" because permission are 12 bit long and this way there will always be a preceding zero to indicate octalness.

        You are right. then I like "0%04o". It is most readable for me.
        Boris
Re: Unwanted Octal to Decimal Conversion
by iburrell (Chaplain) on Feb 18, 2004 at 21:02 UTC
    First, you can pad the sprintf output by adding "04" to the format string:
    my $octal = sprintf("%04o", OWNER_READ);
    Second, I would suggest storing the permissions in the database as decimal integers instead of octal integers or strings. You would display them in octal. This will save all kinds of headaches since the database won't know the numbers are in octal and either won't operate on strings or won't operate wrong thinking they are decimal.
Re: Unwanted Octal to Decimal Conversion
by borisz (Canon) on Feb 18, 2004 at 21:29 UTC
    Update: Okay, I realized I was misreading the sprintf documentation on padding during numeric conversions. How about this:
    use constant OTHER_READ => sprintf("%.4o", 0001)
    No, why that? If you put soemthing into your db it does not matter if the num is oct hex or dec. The same goes for other operators that you like to use +-|& for example.
    # all three lines do exactly the same. chmod 0644, $file; chmod 420, $file; chmod 0x1a4, $file;
    Boris

      The reason I like this is that it makes evaluation of permissions in the code much simpler because they are already in octal form. Thus my permssions checking can do bitwise operations without having to reformat them. The code that writes to the database now uses oct so in the db the permissions are in decimal form.


      "The dead do not recognize context" -- Kai, Lexx
        The reason I like this is that it makes evaluation of permissions in the code much simpler because they are already in octal form. Thus my permssions checking can do bitwise operations without having to reformat them.

        Why would you have to "reformat" them to do bitwise operations? octal 040 and decimal 32 have exactly the same bit pattern.

Re: Unwanted Octal to Decimal Conversion
by ysth (Canon) on Feb 19, 2004 at 01:34 UTC
    You really haven't given us enough information as to how you are *using* these values. Normally you would want to keep even octal numbers in numeric form and convert them when you store or display to whatever format you want.

    You can preserve e.g. octal string form but have it come out as the correct number in a decimal context with:

    use Scalar::Util "dualvar"; use constant Foo => dualvar(0040,"0040");
Re: Unwanted Octal to Decimal Conversion
by djantzen (Priest) on Feb 20, 2004 at 19:19 UTC
    Ever have one of those days where your brain just didn't work? Well after a lot of frustration, I just went to the movies and came back to the problem later. Thanks to borisz and duff's common sense observations, I stopped trying to force the issue and I'm just going along with Perl's natural conversions and doing bitwise operations on those. It seems to work. Thanks for your responses.


    "The dead do not recognize context" -- Kai, Lexx

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://330050]
Approved by Old_Gray_Bear
Front-paged by dbwiz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-20 08:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found