2 # modules.pl: pseudo-Module handler
4 # Version: v0.2 (20000629)
8 if (&IsParam("useStrict")) { use strict; }
9 use vars qw($AUTOLOAD);
15 eval "use IO::Socket";
17 &ERROR("no IO::Socket?");
20 &showProc(" (IO::Socket)");
24 "countdown" => "Countdown.pl",
25 "debian" => "Debian.pl",
26 "debianExtra" => "DebianExtra.pl",
28 "dumpvars" => "DumpVars.pl",
29 "factoids" => "Factoids.pl",
30 "freshmeat" => "Freshmeat.pl",
31 "kernel" => "Kernel.pl",
32 "ircdcc" => "UserDCC.pl",
33 "perlMath" => "Math.pl",
35 "quote" => "Quote.pl",
36 "rootwarn" => "RootWarn.pl",
37 "search" => "Search.pl",
38 "slashdot" => "Slashdot3.pl",
39 "topic" => "Topic.pl",
40 "units" => "Units.pl",
41 "uptime" => "Uptime.pl",
42 "userinfo" => "UserInfo.pl",
43 "wwwsearch" => "W3Search.pl",
44 "whatis" => "WhatIs.pl",
45 "wingate" => "Wingate.pl",
46 "insult" => "insult.pl",
47 "nickometer" => "nickometer.pl",
48 "babelfish" => "babel.pl",
50 ### THIS IS NOT LOADED ON RELOAD :(
52 @myModulesLoadNow = ('topic', 'uptime', 'news', 'rootWarn');
53 @myModulesReloadNot = ('IRC/Irc.pl','IRC/Schedulers.pl');
57 my @mods = &getPerlFiles($bot_src_dir);
59 &status("Loading ".scalar(@mods)." CORE modules...");
61 foreach (sort @mods) {
62 my $mod = "$bot_src_dir/$_";
64 eval "require \"$mod\"";
71 $moduleAge{$mod} = (stat $mod)[9];
72 &showProc(" ($_)") if (&IsParam("DEBUG"));
77 &status("Loading DB modules...");
79 $moduleAge{"$bot_src_dir/modules.pl"} = time();
81 if ($param{'DBType'} =~ /^mysql$/i) {
84 &ERROR("libdbd-mysql-perl is not installed!");
87 &showProc(" (DBI // mysql)");
89 &status(" using MySQL support.");
90 require "$bot_src_dir/db_mysql.pl";
91 $moduleAge{"$bot_src_dir/db_mysql.pl"} = time();
93 } elsif ($param{'DBType'} =~ /^pgsql$/i) {
96 &ERROR("libpgperl is not installed!");
99 &showProc(" (Pg // postgreSQLl)");
101 &status(" using PostgreSQL support.");
102 require "$bot_src_dir/db_pgsql.pl";
103 } elsif ($param{'DBType'} =~ /^dbm$/i) {
105 &status(" using Berkeley DBM 1.85/2.0 support.");
106 &ERROR("dbm support is broken... you want it, you fix it!");
110 # require "$bot_src_dir/db_dbm.pl";
113 &status("DB support DISABLED.");
118 sub loadFactoidsModules {
119 if (!&IsParam("factoids")) {
120 &status("Factoid support DISABLED.");
124 &status("Loading Factoids modules...");
126 foreach ( &getPerlFiles("$bot_src_dir/Factoids") ) {
127 my $mod = "$bot_src_dir/Factoids/$_";
129 eval "require \"$mod\"";
135 $moduleAge{$mod} = (stat $mod)[9];
136 &showProc(" ($_)") if (&IsParam("DEBUG"));
141 if (&whatInterface() =~ /IRC/) {
142 &status("Loading IRC modules...");
146 &ERROR("libnet-irc-perl is not installed!");
149 &showProc(" (Net::IRC)");
152 &status("IRC support DISABLED.");
156 foreach ( &getPerlFiles("$bot_src_dir/IRC") ) {
157 my $mod = "$bot_src_dir/IRC/$_";
159 eval "require \"$mod\"";
161 &ERROR("lIRCM => $@");
166 $moduleAge{$mod} = (stat $mod)[9];
167 &showProc(" ($_)") if (&IsParam("DEBUG"));
171 sub loadMyModulesNow {
175 &status("Loading MyModules...");
176 foreach (@myModulesLoadNow) {
179 &WARN("mMLN: null element.");
183 if (!&IsParam($_) and !&IsChanConf($_) and !&getChanConfList($_)) {
184 if (exists $myModules{$_}) {
185 &status("myModule: $myModules{$_} or $_ (1) not loaded.");
187 &DEBUG("myModule: $_ (2) not loaded.");
193 # weird hack to get rootwarn to work.
194 # it may break on other cases though, any ideas?
195 &loadMyModule( $myModules{$_} || $myModules{lc $_} );
199 &status("Module: Runtime: Loaded/Total [$loaded/$total]");
202 ### rename to moduleReloadAll?
203 sub reloadAllModules {
204 &VERB("Module: reloading all.",2);
206 # obscure usage of map and regex :)
207 foreach (map { s/.*?\/?src/src/; $_ } keys %moduleAge) {
211 &VERB("Module: reloading done.",2);
214 ### rename to modulesReload?
217 my $file = (grep /\/$mod/, keys %INC)[0];
219 # don't reload if it's not our module.
220 if ($mod =~ /::/ or $mod !~ /pl$/) {
221 &VERB("Not reloading $mod.",3);
225 if (!defined $file) {
226 &WARN("rM: Cannot reload $mod since it was not loaded anyway.");
231 &ERROR("rM: file '$file' does not exist?");
235 if (grep /$mod/, @myModulesReloadNot) {
236 &DEBUG("rM: SHOULD NOT RELOAD $mod!!!");
240 my $age = (stat $file)[9];
242 if (!exists $moduleAge{$file}) {
243 &DEBUG("Looks like $file was not loaded; fixing.");
245 return if ($age == $moduleAge{$file});
247 if ($age < $moduleAge{$file}) {
248 &WARN("rM: we're not gonna downgrade the file. use 'touch'.");
252 my $dc = &Time2String($age - $moduleAge{$file});
253 my $ago = &Time2String(time() - $moduleAge{$file});
255 &VERB("Module: delta change: $dc",2);
256 &VERB("Module: ago: $ago",2);
259 &status("Module: Loading $mod...");
262 eval "require \"$file\""; # require or use?
264 &DEBUG("rM: failure: @$");
266 my $basename = $file;
267 $basename =~ s/^.*\///;
268 &status("Module: reloaded $basename");
269 $moduleAge{$file} = $age;
274 ### OPTIONAL MODULES.
277 local %perlModulesLoaded = ();
278 local %perlModulesMissing = ();
281 return 0 if (exists $perlModulesMissing{$_[0]});
282 &reloadModule($_[0]);
283 return 1 if (exists $perlModulesLoaded{$_[0]});
287 &WARN("Module: $_[0] is not installed!");
288 $perlModulesMissing{$_[0]} = 1;
291 $perlModulesLoaded{$_[0]} = 1;
292 &status("Module: Loaded $_[0] ...");
293 &showProc(" ($_[0])");
301 &WARN("loadMyModule: module is NULL.");
305 my ($modulebase, $modulefile);
306 if (exists $myModules{$tmp}) {
307 ($modulename, $modulebase) = ($tmp, $myModules{$tmp});
310 if ($tmp = grep /^$modulebase$/, keys %myModules) {
311 &DEBUG("lMM: lame hack, file => name => $tmp.");
315 $modulefile = "$bot_src_dir/Modules/$modulebase";
317 # call reloadModule() which checks age of file and reload.
318 if (grep /\/$modulebase$/, keys %INC) {
319 &reloadModule($modulebase);
320 return 1; # depend on reloadModule?
323 if (! -f $modulefile) {
324 &ERROR("lMM: module ($modulebase) does not exist.");
325 if ($$ == $bot_pid) { # parent.
326 &shutdown() if (defined $shm and defined $dbh);
328 &DEBUG("b4 delfork 1");
329 &delForked($modulebase);
335 eval "require \"$modulefile\"";
337 &ERROR("cannot load my module: $modulebase");
338 if ($bot_pid != $$) { # child.
339 &DEBUG("b4 delfork 2");
340 &delForked($modulebase);
346 $moduleAge{$modulefile} = (stat $modulefile)[9];
348 &status("myModule: Loaded $modulebase ...");
349 &showProc(" ($modulebase)");
355 eval "use Time::HiRes qw(gettimeofday tv_interval)";
357 &WARN("No Time::HiRes?");
360 &showProc(" (Time::HiRes)");
363 return if ($AUTOLOAD =~ /__/); # internal.
365 my $str = join(', ', @_);
366 &ERROR("UNKNOWN FUNCTION CALLED: $AUTOLOAD ($str)");
368 $AUTOLOAD =~ s/^(\S+):://g;
370 if (exists $myModules{lc $AUTOLOAD}) {
371 # hopefully this will work.
372 &DEBUG("Trying to load module $AUTOLOAD...");
373 &loadMyModule(lc $AUTOLOAD);
380 if (!opendir(DIR, $dir)) {
381 &ERROR("cannot open source directory $dir: $!");
386 while (defined(my $file = readdir DIR)) {
387 next unless $file =~ /\.pl$/;
388 next unless $file =~ /^[A-Z]/;
393 return reverse sort @mods;