in reply to lock files vs. non-predictable file names

Thank you monks for your wise and astute observations. I have included in my script that wisdom which fits with its purpose. Other wisdom is still being digested...(yummy). The check_private_dir sub seems twisted and its only purpose it to make sure there is a protected dir to write to, if anyone can enlighten me with more elegant code, I'd be smarter for it (and thankfull). UPDATE: I suppose I could create the private dir in /var/tmp, which on my systems is not cleared upon reboot, and I could remove all but one line from check_private_dir to test for the existance of the directory. However, I'd still be intersted in a cleaner way of executing the current check_private_dir for academic purposes.
#!/usr/bin/perl -w # Run this perl code from cron every 5 minutes # 0,5,10,15,20,25,30,35,40,45,50,55 * * * * /.ping_hosts.pl 2>&1 # use strict; use Net::Ping; my $private_dir = "/tmp/ping_hosts_dir"; sub check_private_dir { unless (-e $private_dir){ mkdir($private_dir, 0700) or die "Can't +mkdir $private_dir\n" } if (-d $private_dir) { my $dec_mode = (stat($private_dir))[2]; my $oct_mode = sprintf "%lo", $dec_mode; if (-O $private_dir and ($oct_mode == 40700)) { return } elsif (-O $private_dir and ($oct_mode != 40700)) { chmod(0700, $private_dir); return; } else { die "We don't own the directory\n" } } else { die "$private_dir exists and is not a directory\n"; } } sub ping_hosts { my $ws; my $timeout = 2; my @hosts = qw(host1 host2 host3 host4); my $ping_obj = Net::Ping->new("icmp"); foreach $ws (@hosts) { unless ($ping_obj->ping($ws, $timeout)) { print "$ws did not respond to ping within the $timeout sec +ond timeout period\n"; notify_admins($ws); } sleep(1); # To prevent flooding } $ping_obj->close(); # Redundant since open network conn is auto-cl +osed when leaving sub } sub notify_admins { # Called from ping_hosts() my $ws = shift(@_); my $nfile = "${ws}.notify"; my $admins = "admin1\@mailhost.com, " . "18005551212\@page.com, " . "admin2\@mailhost.com, " . "19005551212\@page.com"; unless (-e "${private_dir}/${nfile}") { open(NOTIFY, ">>${private_dir}/${nfile}") or die "Can't create + notify file\n"; close(NOTIFY); open(MAIL, "|mailx $admins") or die "Can't fork for mailx: $!\ +n"; print MAIL "$ws doesn't respond to ping\n"; close(MAIL); } } ### MAIN ### check_private_dir(); ping_hosts();

Replies are listed 'Best First'.
RE: RE: lock files vs. non-predictable file names
by merlyn (Sage) on Aug 26, 2000 at 08:29 UTC
    This code scares me a bit:
    my $oct_mode = sprintf "%lo", $dec_mode; if (-O $private_dir and ($oct_mode == 40700)) { return } elsif (-O $private_dir and ($oct_mode != 40700)) {
    You are probably lucky that 40,700 decimal is a nice integer value. Why not leave it at octal?
    if (-O $private_dir and ($dec_mode == 040700)) { return } elsif (-O $private_dir) {
    And that value isn't really a "decimal" mode. It's the value of "the mode", which usually prints out as decimal. Internally, it's binary, unless you have a BCD-coded machine (not likely {grin}).

    The other scary code here is your use of mailx. While the content of your message cannot possibly contain a line that begins with tilde, you might get complacent some day and permit such a line, and then you can say buh-bye to security. Get in the right groove by looking at Mail::Mailer pretty durn quick.

    -- Randal L. Schwartz, Perl hacker

      So, what you are trying to say is that perl stores the value that stat returns as a binary, but when I printed it out perl converted it to decimal. OK I think I got that now, but this other bit of code you left, I'm not sure I fully understand. Is that leading character a zero in 040700 and if so what does it do? presumably it causes an octal comparison? I guess where I got the code I came up with was by
      mkdir($private_dir, 0700); $mode = (stat($private_dir))[2]; print "stat[2] returned $mode for a value\n"
      the value returned was 16832 which clearly wasn't an octal value. Could you explain to me a little bit about arbitrary base comparisons? I can't find any examples that I recognise. Also thank you for the bit o' wisdom on mailx, I didn't know it had that vunerability(sp).
        Perl stores the value as a "number". This could be binary, or hex, or bcd, or whatever. Interpolation of that value causes it to be rendered in decimal, yes, and that's why you don't recognize it, because you aren't RainMan and can't convert from decimal to "bits" in your head. {grin}

        The leading 0 in 040700 tells Perl to accept this number in octal (again, easier to encode bits as a human that way), but once accepted, it's again a "number", and can be compared with other "numbers".

        -- Randal L. Schwartz, Perl hacker