in reply to Re: Re: Permissions Utility Script for sysadmins - seeking comments
in thread Permissions Utility Script for sysadmins - seeking comments

Also, do you have any insight into why (as you mentioned) if there are both dir-mode and dir-owner that the latter will be silently ignored.

Looking again, this was an error on my part - I'd missed the surrounding loop. Apologies for the misdirection.

Update: bother, I was right the first time. See Re^5: Permissions Utility Script for sysadmins - seeking comments instead.

I'll try tomorrow to come up with a couple of examples of how you might use a hash to improve things.

Hugo

  • Comment on Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments

Replies are listed 'Best First'.
Re: Re: Re: Re: Permissions Utility Script for sysadmins - seeking comments
by BuddhaNature (Beadle) on Apr 21, 2004 at 23:51 UTC
    Ah, but you _were_ right - it does happen (or did since I fixed it). It was because the wanted_c function was only being called once for each file, and if it had more than one applicable directive it just passed up the other two. So I changed the wanted_c function calls to something like this:

    sub wanted_c { if ((-d $_) && ($d_mode) { change_mode($_, $d_mode); $d_mode = ""; wanted_c(); } elsif ((-d $_) && ($d_own)) { change_owner($_, $d_own); $d_own = ""; wanted_c(); }

    That way it gets called as many times as is applicable to the file. Thanks for the pointer - I look forward to looking into your hash idea, which is slightly coalescing in my brain, but wouldn't mind your nudging it a bit with some advice/examples.

    -Shane UPDATE: This fixed the problem but created another - it is doing everything, but only on one file! I see it is because of setting the variables to "", but am kinda unsure of what to do instead...

    2nd UPDATE: Things are good now except for one thing, in order to fix the problem I created

    my %info = %{ $config{$test}{$tester} };

    after the spot you suggest a hash. I then put

    else { while(my($key,$val) = each(%info)) { if ($key eq "dir-mode") { $d_mode = $val} elsif ($key eq "file-mode") { $f_mode = $val} elsif ($key eq "link-mode") { $l_mode = $val} elsif ($key eq "dir-owner") { $d_own = $val} elsif ($key eq "file-owner") { $f_own = $val} elsif ($key eq "link-owner") { $l_own = $val} elsif ($key eq "dir-group") { $d_grp = $val} elsif ($key eq "file-group") { $f_grp = $val} elsif ($key eq "link-group") { $l_grp = $val} } return 0; }

    as the final part of the wanted_c function. Everything works fine now, except since I am using diagnostics I get:

    Variable "%info" will not stay shared at permmy6.pl line 372 (#1) (W closure) An inner (nested) named subroutine is referencing a lexical variable defined in an outer subroutine. When the inner subroutine is called, it will probably see the value of the outer subroutine's variable as it was before and during the *first +* call to the outer subroutine; in this case, after the first call to th +e outer subroutine is complete, the inner and outer subroutines will no longer share a common value for the variable. In other words, the variable will no longer be shared. Furthermore, if the outer subroutine is anonymous and references a lexical variable outside itself, then the outer and inner subroutines will never share the given variable. This problem can usually be solved by making the inner subroutine anonymous, using the sub {} syntax. When inner anonymous subs that reference variables in outer subroutines are called or referenced, the +y are automatically rebound to the current values of such variables.

    Any thoughts?

      Bother, I was right the first time, and looking at the wrong bit of code the second time.

      The wanted_c routine is called once for each file, and in the original code it goes through a series of elsifs until it finds a match, so it will only act on the first match - the first combination of filetype and updatetype that is appropriate.

      So to fix it you need to avoid that; the minimal fix would probably be something like this:

      sub wanted_c { if (-d $_) { if ($d_mode) { change_mode($_, $d_mode); } if ($d_owner) { change_owner($_, $d_owner); } if ($d_group) { change_group($_, $d_group); } } elsif (-l $_) { ... } elsif (-f $_) { ... } }

      The point is that the different filetypes are exclusive: you're only interested in the first type that matches, so an if/elsif chain is appropriate. The updatetypes are not exclusive: you want to act on each updatetype that is specified, so you much check each of them without jumping out on the first one. An if/elsif chain is not appropriate for that case.

      Hugo