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]