From: <jgr...@us...> - 2003-03-03 15:22:10
|
Update of /cvsroot/popfile/engine In directory sc8-pr-cvs1:/tmp/cvs-serv12042 Modified Files: popfile.pl Log Message: Partial and broken work on POPFile refactoring; READ ONLY at this point; do not bother running unless you are very brave Index: popfile.pl =================================================================== RCS file: /cvsroot/popfile/engine/popfile.pl,v retrieving revision 1.204 retrieving revision 1.205 diff -C2 -d -r1.204 -r1.205 *** popfile.pl 25 Feb 2003 22:17:40 -0000 1.204 --- popfile.pl 3 Mar 2003 15:21:29 -0000 1.205 *************** *** 5,9 **** # # Acts as a POP3 server and client designed to sit between a real mail client and a real mail ! # server using POP3. Inserts an extra header X-Text-Classification: into the mail header to # tell the client whether the mail is spam or not based on a text classification algorithm # --- 5,9 ---- # # Acts as a POP3 server and client designed to sit between a real mail client and a real mail ! # server using POP3. Inserts an extra header X-Text-Classification: into the mail header to # tell the client whether the mail is spam or not based on a text classification algorithm # *************** *** 15,57 **** use locale; - # NOTE: POPFile is constructed from a collection of classes which all have special - # interface functions and variables: - # - # initialize() - called after the class is created to set default values for internal - # variables and global configuration information - # start() - called once all configuration has been read and POPFile is ready to start - # operating - # stop() - called when POPFile is shutting down - # - # service() - called by the main POPFile process to allow a submodule to do its own - # work (this is optional for modules that do not need to perform any service) - # - # forked() - called when a module has forked the process. This is called within the child - # process and should be used to clean up - # - # reaper() - called when a process has terminated to give a module a chance to do - # whatever clean up is needed - # - # name() - returns a simple name for the module by which other modules can get access - # through the %components hash. The name returned here will be the name - # used as the key for this module in %components - # - # pipeready - This is a reference to the pipeready() function in this file that it used - # to determine if a pipe if ready for reading - # - # alive - Gets set to 1 when the parent wants to kill all the running sub modules - # - # forker - This is a reference to a function (forker) in this file that performs a fork - # and informs modules that a fork has occurred. - # # The POPFile classes are stored by reference in the %components hash, the top level key is ! # the type of the component (see load_modules) and then the name of the component derived from # calls to each loadable modules name() method and which points to the actual module my %components; ! # This is the A PIECE OF PLATFORM SPECIFIC CODE and all it does is force Windows users to have # v5.8.0 because that's the version with good fork() support everyone else can use whatever they ! # want. This is probably only temporary because at some point I am going to force 5.8.0 for # everyone because of the better Unicode support --- 15,27 ---- use locale; # The POPFile classes are stored by reference in the %components hash, the top level key is ! # the type of the component (see load_modules) and then the name of the component derived from # calls to each loadable modules name() method and which points to the actual module my %components; ! # This is the A PIECE OF PLATFORM SPECIFIC CODE and all it does is force Windows users to have # v5.8.0 because that's the version with good fork() support everyone else can use whatever they ! # want. This is probably only temporary because at some point I am going to force 5.8.0 for # everyone because of the better Unicode support *************** *** 59,64 **** if ( $^O eq 'MSWin32' ) { ! require v5.8.0; ! $on_windows = 1; } --- 29,34 ---- if ( $^O eq 'MSWin32' ) { ! require v5.8.0; ! $on_windows = 1; } *************** *** 71,88 **** # --------------------------------------------------------------------------------------------- # ! # aborting # ! # Called if we are going to be aborted or are being asked to abort our operation. Sets the # alive flag to 0 that will cause us to abort at the next convenient moment # # --------------------------------------------------------------------------------------------- ! sub aborting { $alive = 0; ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->{alive} = 0; ! $components{$type}{$name}->stop(); ! } } } --- 41,58 ---- # --------------------------------------------------------------------------------------------- # ! # aborting # ! # Called if we are going to be aborted or are being asked to abort our operation. Sets the # alive flag to 0 that will cause us to abort at the next convenient moment # # --------------------------------------------------------------------------------------------- ! sub aborting { $alive = 0; ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->alive(0); ! $components{$type}{$name}->stop(); ! } } } *************** *** 94,127 **** # Returns 1 if there is data available to be read on the passed in pipe handle # ! # $pipe Pipe handle # # --------------------------------------------------------------------------------------------- sub pipeready { ! my ( $pipe ) = @_; ! # Check that the $pipe is still a valid handle ! ! if ( !defined( $pipe ) ) { ! return 0; ! } ! if ( $on_windows ) { ! ! # I am NOT doing a select() here because that does not work ! # on Perl running on Windows. -s returns the "size" of the file ! # (in this case a pipe) and will be non-zero if there is data to read ! ! return ( ( -s $pipe ) > 0 ); ! } else { ! ! # Here I do a select because we are not running on Windows where ! # you can't select() on a pipe ! my $rin = ''; ! vec( $rin, fileno( $pipe ), 1 ) = 1; ! my $ready = select( $rin, undef, undef, 0.01 ); ! return ( $ready > 0 ); ! } } --- 64,97 ---- # Returns 1 if there is data available to be read on the passed in pipe handle # ! # $pipe Pipe handle # # --------------------------------------------------------------------------------------------- sub pipeready { ! my ( $pipe ) = @_; ! # Check that the $pipe is still a valid handle ! ! if ( !defined( $pipe ) ) { ! return 0; ! } ! if ( $on_windows ) { ! ! # I am NOT doing a select() here because that does not work ! # on Perl running on Windows. -s returns the "size" of the file ! # (in this case a pipe) and will be non-zero if there is data to read ! ! return ( ( -s $pipe ) > 0 ); ! } else { ! ! # Here I do a select because we are not running on Windows where ! # you can't select() on a pipe ! my $rin = ''; ! vec( $rin, fileno( $pipe ), 1 ) = 1; ! my $ready = select( $rin, undef, undef, 0.01 ); ! return ( $ready > 0 ); ! } } *************** *** 137,147 **** sub reaper { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->reaper(); ! } } ! $SIG{CHLD} = \&reaper; } --- 107,117 ---- sub reaper { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->reaper(); ! } } ! $SIG{CHLD} = \&reaper; } *************** *** 161,173 **** sub forker { ! # Create the pipe that will be used to send data from the child to the parent process, # $writer will be returned to the child process and $reader to the parent process ! pipe my $reader, my $writer; my $pid = fork(); ! # If fork() returns an undefined value then we failed to fork and are # in serious trouble (probably out of resources) so we return undef ! if ( !defined( $pid ) ) { close $reader; --- 131,143 ---- sub forker { ! # Create the pipe that will be used to send data from the child to the parent process, # $writer will be returned to the child process and $reader to the parent process ! pipe my $reader, my $writer; my $pid = fork(); ! # If fork() returns an undefined value then we failed to fork and are # in serious trouble (probably out of resources) so we return undef ! if ( !defined( $pid ) ) { close $reader; *************** *** 177,205 **** # If fork returns a PID of 0 then we are in the child process so close the ! # reading pipe file handle, inform all modules that are fork has occurred and # then return 0 as the PID so that the caller knows that we are in the child ! if ( $pid == 0 ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->forked(); ! } } ! close $reader; ! # Set autoflush on the write handle so that output goes straight through # to the parent without buffering it until the socket closes ! use IO::Handle; $writer->autoflush(1); ! return (0, $writer); } ! # Reach here because we are in the parent process, close out the writer pipe # file handle and return our PID (non-zero) indicating that this is the parent # process ! close $writer; return ($pid, $reader); --- 147,175 ---- # If fork returns a PID of 0 then we are in the child process so close the ! # reading pipe file handle, inform all modules that are fork has occurred and # then return 0 as the PID so that the caller knows that we are in the child ! if ( $pid == 0 ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->forked(); ! } } ! close $reader; ! # Set autoflush on the write handle so that output goes straight through # to the parent without buffering it until the socket closes ! use IO::Handle; $writer->autoflush(1); ! return (0, $writer); } ! # Reach here because we are in the parent process, close out the writer pipe # file handle and return our PID (non-zero) indicating that this is the parent # process ! close $writer; return ($pid, $reader); *************** *** 213,220 **** # comment on first line) in a specific subdirectory # ! # $directory The directory to search for loadable modules ! # $type The 'type' of module being loaded (e.g. proxy, core, ui) which is used ! # below when fixing up references between modules (e.g. proxy modules all ! # need access to the classifier module) # # --- 183,190 ---- # comment on first line) in a specific subdirectory # ! # $directory The directory to search for loadable modules ! # $type The 'type' of module being loaded (e.g. proxy, core, ui) which is used ! # below when fixing up references between modules (e.g. proxy modules all ! # need access to the classifier module) # # *************** *** 222,254 **** sub load_modules { ! my ( $directory, $type ) = @_; ! # Look for all the .pm files in named directory and then see which of them ! # are POPFile modules indicated by the first line of the file being and ! # comment (# POPFILE LOADABLE MODULE) and load that module into the %components ! # hash getting the name from the module by calling name() ! ! my @modules = glob "$directory/*.pm"; ! ! foreach my $module (@modules) { ! if ( open MODULE, "<$module" ) { ! my $first = <MODULE>; ! close MODULE; ! ! if ( $first =~ /^# POPFILE LOADABLE MODULE/ ) { ! require $module; ! $module =~ s/\//::/; ! $module =~ s/\.pm//; ! my $mod = new $module; ! my $name = $mod->name(); ! $components{$type}{$name} = $mod; ! ! print " {$name}"; ! } ! } ! } } --- 192,224 ---- sub load_modules { ! my ( $directory, $type ) = @_; ! # Look for all the .pm files in named directory and then see which of them ! # are POPFile modules indicated by the first line of the file being and ! # comment (# POPFILE LOADABLE MODULE) and load that module into the %components ! # hash getting the name from the module by calling name() ! my @modules = glob "$directory/*.pm"; ! foreach my $module (@modules) { ! if ( open MODULE, "<$module" ) { ! my $first = <MODULE>; ! close MODULE; ! if ( $first =~ /^# POPFILE LOADABLE MODULE/ ) { ! require $module; ! ! $module =~ s/\//::/; ! $module =~ s/\.pm//; ! ! my $mod = new $module; ! my $name = $mod->name(); ! ! $components{$type}{$name} = $mod; ! ! print " {$name}"; ! } ! } ! } } *************** *** 276,280 **** print " Loading... "; ! load_modules( 'POPFile', 'core' ); load_modules( 'Classifier', 'classifier' ); load_modules( 'UI', 'ui' ); --- 246,250 ---- print " Loading... "; ! load_modules( 'POPFile', 'core' ); load_modules( 'Classifier', 'classifier' ); load_modules( 'UI', 'ui' ); *************** *** 293,300 **** foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->{configuration} = $components{core}{config} if ( $name ne 'config' ); ! $components{$type}{$name}->{logger} = $components{core}{logger} if ( $name ne 'logger' ); ! } } --- 263,270 ---- foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->configuration( $components{core}{config} ) if ( $name ne 'config' ); ! $components{$type}{$name}->logger( $components{core}{logger} ) if ( $name ne 'logger' ); ! } } *************** *** 302,307 **** foreach my $name (keys %{$components{proxy}}) { ! $components{proxy}{$name}->{classifier} = $components{classifier}{classifier}; ! $components{proxy}{$name}->{ui} = $components{ui}{html}; } --- 272,277 ---- foreach my $name (keys %{$components{proxy}}) { ! $components{proxy}{$name}->classifier( $components{classifier}{bayes} ); ! $components{proxy}{$name}->ui( $components{ui}{ui} ); } *************** *** 309,313 **** foreach my $name (keys %{$components{ui}}) { ! $components{ui}{$name}->{classifier} = $components{classifier}{classifier}; } --- 279,283 ---- foreach my $name (keys %{$components{ui}}) { ! $components{ui}{$name}->classifier( $components{classifier}{bayes} ); } *************** *** 317,331 **** foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! flush STDOUT; ! if ( $components{$type}{$name}->initialize() == 0 ) { ! die "Failed to start while initializing the $name module"; ! } ! $components{$type}{$name}->{alive} = 1; ! $components{$type}{$name}->{forker} = \&forker; ! $components{$type}{$name}->{pipeready} = \&pipeready; ! } } --- 287,301 ---- foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! flush STDOUT; ! if ( $components{$type}{$name}->initialize() == 0 ) { ! die "Failed to start while initializing the $name module"; ! } ! $components{$type}{$name}->alive( 1 ); ! $components{$type}{$name}->forker( \&forker ); ! $components{$type}{$name}->pipeready( \&pipeready ); ! } } *************** *** 341,354 **** foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! flush STDOUT; ! if ( $components{$type}{$name}->start() == 0 ) { ! die "Failed to start while starting the $name module"; ! } ! } } print "\nPOPFile Engine v$components{core}{config}->{major_version}.$components{core}{config}->{minor_version}.$components{core}{config}->{build_version} running\n"; # MAIN LOOP - Call each module's service() method to all it to --- 311,325 ---- foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! flush STDOUT; ! if ( $components{$type}{$name}->start() == 0 ) { ! die "Failed to start while starting the $name module"; ! } ! } } print "\nPOPFile Engine v$components{core}{config}->{major_version}.$components{core}{config}->{minor_version}.$components{core}{config}->{build_version} running\n"; + flush STDOUT; # MAIN LOOP - Call each module's service() method to all it to *************** *** 356,381 **** while ( $alive == 1 ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! if ( $components{$type}{$name}->service() == 0 ) { ! $alive = 0; ! last; ! } ! } } ! # Sleep for 0.05 of a second to ensure that POPFile does not hog the machine's # CPU select(undef, undef, undef, 0.05); ! # If we are on Windows then reap children here if ( $on_windows ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->reaper(); ! } ! } } } --- 327,352 ---- while ( $alive == 1 ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! if ( $components{$type}{$name}->service() == 0 ) { ! $alive = 0; ! last; ! } ! } } ! # Sleep for 0.05 of a second to ensure that POPFile does not hog the machine's # CPU select(undef, undef, undef, 0.05); ! # If we are on Windows then reap children here if ( $on_windows ) { ! foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! $components{$type}{$name}->reaper(); ! } ! } } } *************** *** 386,397 **** foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! $components{$type}{$name}->{alive} = 0; ! $components{$type}{$name}->stop(); ! } } print "\n Saving configuration\n"; # Write the final configuration to disk --- 357,370 ---- foreach my $type (keys %components) { ! foreach my $name (keys %{$components{$type}}) { ! print "{$name} "; ! flush STDOUT; ! $components{$type}{$name}->alive(0); ! $components{$type}{$name}->stop(); ! } } print "\n Saving configuration\n"; + flush STDOUT; # Write the final configuration to disk |