Hello, i'm desperate

i need to watch some 20 textfiles in one special directory. whenever one or 
more of the files are updated, i need to inform a script on a linux server, 
that its supposed to check the referring - updated - file on the share, the 
win32 system has written it to. since there is no real approach to 
changenotify on linux, i'm forced - or rather prefer - taking the 
perl/win32 solution using Win32:ChangeNotify. ok, now the filechange occurs 
and i connect the linux server, so that he can supply database and mail 
procession according to the updates in the file, wich filename has been 
just submitted from my watcher script. problem is that the watcher script, 
when detecting such a change is busy for half a minute, until it gets the 
confiramtion from the linux script, that all has been very well. if, in the 
meantime another fileupdate occurs, the watcher script will not take any 
notic - simply ignore it. this update will not be recognised until the next 
accepted notification change happens.

then there was this stuff about fork(), the ability to delegate all 
incomming requests to child threads, so that the main one could check for 
further updates. then, build 613 popped up like a miracle, just the moment 
i've recognised, that i would need this function.

however, developement turned out to be very difficult for me. i was now 
able to start a new thread whenever updating one of the files. apart from 
the fact, that it ended up in an error like 'panic: pseudo fork()....' when 
updates where too fast, it all looked great. but trying the exact thing a 
little later in my script to do the socket for my connect the linux host, 
it stopped working.

removing the first fork() resulted into a bizarre error: Bizarre SvTYPE[35] 
pointint to a line written like this:

die "can't fork: $!" unless defined($kidpid = fork());

i think, this is not a bug in the fork implementation, i presume, its some 
error in my code. therefore i take the liberty to post it here, maybe 
somebody could check.. :)

however, the script should end up meeting the following requirements:

- whenever update on file in respective folder made, connect to server, 
submitting file info, if other thread busy with that, wait until the 
other's finished and then try again

- the server must be fed with the file name, session time and the 
file-updatetime. the server returns error, or success to be evaluated by 
the script

#!c:\perl\bin\perl.exe
use Win32::ChangeNotify;
use File::Find;
use IO::Socket;


$path="r:";
$Sig_Path = $path . "\\sig";
$key_file = $path . "\\key\\files.key";
$LOG = $path . "\\client.log";
$php_script = "C:\\php3\\php.exe -q r:\\scripts\\connect-local.php3";

$host = "192.168.0.1";
$port = 9000;


$WatchSubTree=0;
$Events='FILE_NAME';
$changes=0;

$notify = Win32::ChangeNotify->new($Sig_Path,$WatchSubTree,$Events);

while (1) {
        $notify->wait;
        ++$changes;
# this fork code is mostly copied from an expample for fork
# in the perl book from larry wall
        FORK: {
                if($pid=fork){
                        wait;
                } elsif(defined $pid){
                        &update_list;
                } elsif($! =~ /No more processes/){
                        print "NO MORE!!\n";
                        sleep 5;
                        redo FORK;
                } else {
                        die "Kann nix Fork: $!\n";
                }
        }
        $notify->reset;
}

sub update_list
{

        $SID = time;
        if(-e $key_file){
                open(KEY_FILE,"<$key_file") || die "Keyfile unreadable!\n$!\n";
                while(<KEY_FILE>){
                        chop($_);
                        ($this_file,$this_date) = split/;/,$_;
                        $old_file{$this_file} = $this_date;
                }
                close(KEY_FILE);
        }
        &scan_dir;
        &write_keys;
        &connect_server;
}

sub scan_dir
{

        find(\&wanted, $Sig_Path);
        sub wanted
        {

                $status = -T $_;
                if(($status) && ($_ =~ m/\.sig/i)){

                        push @file_path, $File::Find::name;
                        push @file_name, $_;
                        $this_time = (stat($File::Find::name))[9];
                        if(!defined($file{$_})){
                                $this_action = "AD";
                        } else {
                                $this_action = "UP";
                        }
                        if($old_file{$_} < $this_time){
                                $file{$_} = $this_time;
                                push @file_cue, $_ . "*" . $SID . "*" . $this_time;
                                &client_log($this_action,$SID);
                        } else {
                                $file{$_} = $old_file{$_};

                        }

                }

        }

}

sub write_keys
{
        open(KEY_FILE, ">$key_file") || die "Invalid folder!!\n$!\n";
        while(($key,$val) = each %file){
                print KEY_FILE $key . ";" . $val . "\n";
        }
        close(KEY_FILE);


}

sub connect_server
{
        $status_type[1] = "Failed..........";
        $status_line[1] = "Unknown Reason";
        $status_type[2] = "Failed..........";
        $status_line[2] = "Access denied";
        $status_type[3] = "Success.........";
        $status_line[3] = "Data transmitted";
        my ($kidpid, $handle, $line);

        $handle = 
IO::Socket::INET->new(Proto=>"tcp",PeerAddr=>$host,PeerPort=>$port) or die 
"can't connect to port $port on $host: $!";
        $handle->autoflush(1);              # so output gets there right away

# The script will hang itself up right here... the server detects a connect 
but afterword get's stuck.

        FORK: {
                if($pid=fork){
                        while (defined ($line = <$handle>)) {
                                if($_ =~ "Data 
recieved-([0-9]{4}).([0-9]{2}).([0-9]{2}) 
([0-9]{2}):([0-9]{2}):([0-9]{2})"){
                                        $date = $3 . "." . $2 . "." . $1 . " " . $4 . 
":" . $5 . ":" . $6;
                                        if($status<3){
                                                $status = 3;
                                        }
                                } elsif($_ =~ "Access Denied"){
                                        if($status<2){
                                                $status = 2;
                                        }
                                } else {
                                        if($status<1){
                                                $status = 1;
                                        }
                                }
                                
&client_log($status_type[$status],$status_line[$status])
                        }
                        kill("TERM", $kidpid);  
                } elsif(defined $pid){
                        print $handle "files#" . join(":",@file_cue);
                        print STDERR "[" . &get_date . "] Sending: files#" . 
join(":",@file_cue) 
. "\n";
                        undef @file_cue;
                } elsif($! =~ /No more processes/){
                        print "NO MORE!!\n";
                        sleep 5;
                        redo FORK;
                } else {
                        die "Kann nix Fork: $!\n";
                }
        }
}

sub client_log
{
        $alias{"OH"} = "Update pending..";
        $alias{"AD"} = "New Signalfile..";
        $alias{"UP"} = "Signals updated.";
        $date = &get_date;
        open(LOG,">>$LOG") || die "No Debugging,\n$!\n";
        print LOG "[" . $date . "] " . $alias{$_[0]} . ": " . $_[1] . "\n";
        close(LOG);
        print "[" . $date . "] " . $alias{$_[0]} . ": " . $_[1] . "\n";
        print STDERR "[" . $date . "] " . $alias{$_[0]} . ": " . $_[1] . "\n";
}

sub get_date
{
        ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
        $date = sprintf("%02d.%02d.%04d %02d:%02d:%02d", $mday, ($mon+1), 
($year+1900), $hour, $min, $sec);
        return scalar $date;

}

---
You are currently subscribed to perl-win32-users as: [archive@jab.org]
To unsubscribe, forward this message to
         [EMAIL PROTECTED]
For non-automated Mailing List support, send email to  
         [EMAIL PROTECTED]

Reply via email to