On Thu, Dec 20, 2001 at 09:31:20AM +1030, Daniel Falkenberg wrote:
> Now the problem is is that the code never updates.  Ie if I happed to add
> a * in front username with a GID of 45 in /etc/passwd then then code below
> won't read from it and remove it from my hash?  If I restart the daemon
> the code has no problems reading from it and everythink works fine.  Of
> coarse I don't want to do this everytime I change the /etc/passwd file.:)
> So it seems to me that the hash I am using isn't being u ndefined (Think
> this is the correct terminology).  Can any one give any ideas?  Does this
> even make sense to any one? Would the following work...?

I'm having difficulty gleaning from your description exactly what problem
you're having.  What did you expect?  What did you get?

You mention having an issue with %users.  Should this hash persist for the
life of your daemon, or is it just for use within this block of code?  If
the latter, then you should scope it so that it goes out of scope where you
need it to.  For example:

    {
        my %users;

        open PASSWD ...
        while (<PASSWD>) {
            ...
        }

        ...
    }



Below are some corrections to your code.  Perhaps one of them will catch
your problem.


> open PASSWD, "$passwd" or warn "$passwd: $!\n";

I'd think this would be a fatal error.  If it isn't, you still shouldn't go
on to try to lock it, or read from the handle.


> flock(PASSWD, 2) || warn "Can't lock $passwd exclusively: $!";

This appears to be a misunderstanding on how flock works.  If the file is
already locked the flock call will block until it's unlocked.  Unless you
want to potentially block forever, you should either have a timeout on the
call, or, use a non-blocking flock call in a loop.  See perldoc -q lock and
perldoc -f flock.

The idiom I usually prefer is something like this:

    use Fcntl qw(LOCK_EX LOCK_NB);

    my $try             = 0;
    my $max_lock_tries  = 20;
    my $lock_sleep_time = 10;

    until (flock(PASSWD, LOCK_EX|LOCK_NB)) {
        $try++;
        die("Unable to lock file ... after $try tries: \l$!.\n")
            if $try > $max_lock_tries;

        sleep($lock_sleep_time);
    }

Which will try to lock the file 20 times, with 10 second intervals between,
and give up after that.


> while (<PASSWD>) {
>   my ($username, $groupid, $fullname) = (split/:/)[0, 3, 4];
>   next if $username =~ /^\*/;
>   next if $username =~ /^ruby/;

    next if $username =~ /^(\*|ruby)/;

or, if you actually want the username to be equal to 'ruby', and not just
start with it:

    next if $username eq 'ruby' || substr($username, 0, 1) eq '*';


>   if ( $groupid == 45 ) {
>     $users{$username}{$fullname} = 0;
>     if (-e "/home/$username/$homeproc") {$users{$username}{$fullname} =
> 'YES';}
>     else {$users{$username}{$fullname} = 'NO';}
>     }
>   }

I got a little confused at this point.  Your indentation style is very odd.
This closing brace closes the while (<PASSWD>) loop, but it's indented
further in, and everything beyond it is indented at the same level, making
it look like all of the code is part of the aforementioned while
loop.

So, you have:

    while (<PASSWD>) {
        ...
        }

        close PASSWD;
        open FILE ...
        ...

Where I would expect:

    while (<PASSWD>) {
        ...
    }

    close PASSWD;
    open FILE ...
    ...


>   close PASSWD || warn "$passwd: $!\n";

>   open FILE, ">$userfile" or warn "cannot open $userfile: $!\n";
>   flock(FILE, 2) || warn "Can't lock $userfile exclusively: $!";

Here's another flock misunderstanding.  You just truncated the file, then
proceeded to try and lock it; the damage has already been done.  The file
should be opened with the mode "+>", flocked, then truncated.


>   print FILE "[USERS]\n";
>   foreach my $user (keys %users) {
>     foreach my $name (keys %{ $users{$user} } ) {
>       print FILE "$user:$name:$users{$user}{$name}\n";
>     }
>   }

>   print Data::Dumper -> Dump( [\%users], ['*users']);

A good aid for those helping you is to send the output of this to the list,
along with what you think it should look like.


>   close(FILE)       or warn "Closing: $!";


Michael
--
Administrator                      www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to