2 # modules.pl: pseudo-Module handler
4 # Version: v0.2 (20000629)
10 use vars qw($AUTOLOAD $no_timehires $bot_version $bot_release);
16 eval 'use IO::Socket';
18 &ERROR('no IO::Socket?');
21 &showProc(' (IO::Socket)');
23 ### THIS IS NOT LOADED ON RELOAD :(
25 my @myModulesReloadNot;
29 'Topic', 'Uptime', 'News', 'RootWarn',
30 'DumpVars2', 'botmail', 'OnJoin'
32 @myModulesReloadNot = ( 'IRC/Irc.pl', 'IRC/Schedulers.pl' );
36 my @mods = &getPerlFiles($bot_src_dir);
38 &status('Loading CORE modules...');
40 foreach ( sort @mods ) {
41 my $mod = "$bot_src_dir/$_";
43 eval "require \"$mod\"";
50 $moduleAge{$mod} = ( stat $mod )[9];
51 &showProc(" ($_)") if ( &IsParam('DEBUG') );
58 # TODO: use function to load module.
60 if ( $param{'DBType'} =~ /^(mysql|SQLite(2)?|pgsql)$/i ) {
63 &ERROR( 'No support for DBI::' . $param{'DBType'} . ', exiting!' );
66 &status( 'Loading ' . $param{'DBType'} . ' support.' );
67 $f = "$bot_src_dir/dbi.pl";
69 $moduleAge{$f} = ( stat $f )[9];
71 &showProc( ' (DBI::' . $param{'DBType'} . ')' );
74 &WARN('DB support DISABLED.');
79 sub loadFactoidsModules {
80 if ( !&IsParam('factoids') ) {
81 &status('Factoid support DISABLED.');
85 &status('Loading Factoids modules...');
87 foreach ( &getPerlFiles("$bot_src_dir/Factoids") ) {
88 my $mod = "$bot_src_dir/Factoids/$_";
90 eval "require \"$mod\"";
96 $moduleAge{$mod} = ( stat $mod )[9];
97 &showProc(" ($_)") if ( &IsParam('DEBUG') );
102 my ($interface) = &whatInterface();
103 if ( $interface =~ /IRC/ ) {
104 &status('Loading IRC modules...');
108 &ERROR('libnet-irc-perl is not installed!');
111 &showProc(' (Net::IRC)');
114 &status('IRC support DISABLED.');
116 # disabling forking. Why?
117 #$param{forking} = 0;
121 foreach ( &getPerlFiles("$bot_src_dir/$interface") ) {
122 my $mod = "$bot_src_dir/$interface/$_";
124 # hrm... use another config option besides DEBUG to display
125 # change in memory usage.
126 &status("Loading Modules \"$mod\"") if ( !&IsParam('DEBUG') );
127 eval "require \"$mod\"";
129 &ERROR("require \"$mod\" => $@");
134 $moduleAge{$mod} = ( stat $mod )[9];
135 &showProc(" ($_)") if ( &IsParam('DEBUG') );
139 sub loadMyModulesNow {
143 &status('Loading MyModules...');
144 foreach (@myModulesLoadNow) {
147 &WARN('mMLN: null element.');
151 if ( !&IsParam($_) and &IsChanConf($_) <= 0 and !&getChanConfList($_) )
153 &DEBUG("loadMyModuleNow: $_ (2) not loaded.");
161 &status("Module: Runtime: Loaded/Total [$loaded/$total]");
164 ### rename to moduleReloadAll?
165 sub reloadAllModules {
168 &VERB( 'Module: reloading all.', 2 );
170 # Reload version and save
171 open( VERSION, '<VERSION' );
172 $bot_release = <VERSION> || '(unknown version)';
174 $bot_version = "infobot $bot_release -- $^O";
177 # obscure usage of map and regex :)
178 foreach ( map { s/.*?\/?src/src/; $_ } keys %moduleAge ) {
179 $retval .= &reloadModule($_);
182 &VERB( 'Module: reloading done.', 2 );
186 ### rename to modulesReload?
189 my $file = ( grep /\/$mod/, keys %INC )[0];
192 # don't reload if it's not our module.
193 if ( $mod =~ /::/ or $mod !~ /pl$/ ) {
194 &VERB( "Not reloading $mod.", 3 );
198 if ( !defined $file ) {
199 &WARN("rM: Cannot reload $mod since it was not loaded anyway.");
204 &ERROR("rM: file '$file' does not exist?");
208 if ( grep /$mod/, @myModulesReloadNot ) {
209 &DEBUG("rM: should not reload $mod");
213 my $age = ( stat $file )[9];
215 if ( !exists $moduleAge{$file} ) {
216 &DEBUG("Looks like $file was not loaded; fixing.");
219 return $retval if ( $age == $moduleAge{$file} );
221 if ( $age < $moduleAge{$file} ) {
222 &WARN("rM: we're not gonna downgrade '$file'; use touch.");
223 &DEBUG("age => $age, mA{$file} => $moduleAge{$file}");
227 my $dc = &Time2String( $age - $moduleAge{$file} );
228 my $ago = &Time2String( time() - $moduleAge{$file} );
230 &VERB( "Module: delta change: $dc", 2 );
231 &VERB( "Module: ago: $ago", 2 );
234 &status("Module: Loading $mod...");
237 eval "require \"$file\""; # require or use?
239 &DEBUG("rM: failure: @$ ");
242 my $basename = $file;
243 $basename =~ s/^.*\///;
244 &status("Module: reloaded $basename");
245 $retval = " $basename";
246 $moduleAge{$file} = $age;
252 ### OPTIONAL MODULES.
255 my %perlModulesLoaded = ();
256 my %perlModulesMissing = ();
259 return 0 if ( exists $perlModulesMissing{ $_[0] } );
260 &reloadModule( $_[0] );
261 return 1 if ( exists $perlModulesLoaded{ $_[0] } );
265 &WARN("Module: $_[0] is not installed!");
266 $perlModulesMissing{ $_[0] } = 1;
270 $perlModulesLoaded{ $_[0] } = 1;
271 &status("Loaded $_[0]");
272 &showProc(" ($_[0])");
278 my ($modulename) = @_;
279 if ( !defined $modulename ) {
280 &WARN('loadMyModule: module is NULL.');
284 my $modulefile = "$bot_src_dir/Modules/$modulename.pl";
286 # call reloadModule() which checks age of file and reload.
287 if ( grep /\/$modulename$/, keys %INC ) {
288 &reloadModule($modulename);
289 return 1; # depend on reloadModule?
292 if ( !-f $modulefile ) {
293 &ERROR("lMM: module ($modulename) does not exist.");
294 if ( $$ == $bot_pid ) { # parent.
295 &shutdown() if ( defined $shm and defined $dbh );
298 &DEBUG('b4 delfork 1');
299 &delForked($modulename);
305 eval "require \"$modulefile\"";
307 &ERROR("cannot load my module: $modulename");
308 if ( $bot_pid != $$ ) { # child.
309 &DEBUG('b4 delfork 2');
310 &delForked($modulename);
317 $moduleAge{$modulefile} = ( stat $modulefile )[9];
319 &status("Loaded $modulename");
320 &showProc(" ($modulename)");
326 eval 'use Time::HiRes qw(gettimeofday tv_interval)';
328 &WARN('No Time::HiRes?');
331 &showProc(' (Time::HiRes)');
334 if ( !defined $AUTOLOAD and defined $::AUTOLOAD ) {
335 &DEBUG('AUTOLOAD: hrm.. ::AUTOLOAD defined!');
337 return unless ( defined $AUTOLOAD );
338 return if ( $AUTOLOAD =~ /__/ ); # internal.
340 my $str = join( ', ', @_ );
341 my ( $package, $filename, $line ) = caller;
342 &ERROR("UNKNOWN FUNCTION CALLED: $AUTOLOAD ($str) $filename line $line");
344 $AUTOLOAD =~ s/^(\S+):://g;
346 # hopefully this will work.
347 &DEBUG("Trying to load module $AUTOLOAD...");
348 &loadMyModule($AUTOLOAD);
354 if ( !opendir( DIR, $dir ) ) {
355 &ERROR("Cannot open source directory ($dir): $!");
360 while ( defined( my $file = readdir DIR ) ) {
361 next unless $file =~ /\.pl$/;
362 next unless $file =~ /^[A-Z]/;
363 push( @mods, $file );
367 return reverse sort @mods;
372 # vim:ts=4:sw=4:expandtab:tw=80