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 "allowDNS" => "DNS.pl",
26 "debian" => "Debian.pl",
27 "debianExtra" => "DebianExtra.pl",
29 "dumpvars" => "DumpVars.pl",
30 "factoids" => "Factoids.pl",
31 "freshmeat" => "Freshmeat.pl",
32 "kernel" => "Kernel.pl",
33 "ircdcc" => "UserDCC.pl",
34 "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",
49 @myModulesLoadNow = ('topic', 'uptime',);
50 @myModulesReloadNot = ('IRC/Irc.pl','IRC/Schedulers.pl');
53 if (!opendir(DIR, $bot_src_dir)) {
54 &ERROR("can't open source directory $bot_src_dir: $!");
58 &status("Loading CORE modules...");
60 while (defined(my $file = readdir DIR)) {
61 next unless $file =~ /\.pl$/;
62 next unless $file =~ /^[A-Z]/;
63 my $mod = "$bot_src_dir/$file";
64 ### TODO: use eval and exit gracefully?
66 $moduleAge{$mod} = (stat $mod)[9];
67 &showProc(" ($file)") if (&IsParam("DEBUG"));
73 &status("Loading DB modules...");
75 if ($param{'DBType'} =~ /^mysql$/i) {
78 &ERROR("libdbd-mysql-perl is not installed!");
81 &showProc(" (DBI // mysql)");
83 &status(" using MySQL support.");
84 require "$bot_src_dir/db_mysql.pl";
86 } elsif ($param{'DBType'} =~ /^pgsql$/i) {
89 &ERROR("libpgperl is not installed!");
92 &showProc(" (Pg // postgreSQLl)");
94 &status(" using PostgreSQL support.");
95 require "$bot_src_dir/db_pgsql.pl";
96 } elsif ($param{'DBType'} =~ /^dbm$/i) {
98 &status(" using Berkeley DBM 1.85/2.0 support.");
99 require "$bot_src_dir/db_dbm.pl";
102 &status("DB support DISABLED.");
107 sub loadFactoidsModules {
108 &status("Loading Factoids modules...");
110 if (!&IsParam("factoids")) {
111 &status("Factoid support DISABLED.");
115 if (!opendir(DIR, "$bot_src_dir/Factoids")) {
116 &ERROR("can't open source directory Factoids: $!");
120 while (defined(my $file = readdir DIR)) {
121 next unless $file =~ /\.pl$/;
122 next unless $file =~ /^[A-Z]/;
123 my $mod = "$bot_src_dir/Factoids/$file";
124 ### TODO: use eval and exit gracefully?
126 $moduleAge{$mod} = (stat $mod)[9];
127 &showProc(" ($file)") if (&IsParam("DEBUG"));
133 &status("Loading IRC modules...");
134 if (&whatInterface() =~ /IRC/) {
137 &ERROR("libnet-irc-perl is not installed!");
140 &showProc(" (Net::IRC)");
143 &status("IRC support DISABLED.");
147 if (!opendir(DIR, "$bot_src_dir/IRC")) {
148 &ERROR("can't open source directory Factoids: $!");
152 while (defined(my $file = readdir DIR)) {
153 next unless $file =~ /\.pl$/;
154 next unless $file =~ /^[A-Z]/;
155 my $mod = "$bot_src_dir/IRC/$file";
156 ### TODO: use eval and exit gracefully?
158 $moduleAge{$mod} = (stat $mod)[9];
159 &showProc(" ($file)") if (&IsParam("DEBUG"));
164 sub loadMyModulesNow {
168 &status("Loading MyModules...");
169 foreach (@myModulesLoadNow) {
172 if (!exists $param{$_}) {
173 &DEBUG("myModule: $myModules{$_} not loaded.");
176 &loadMyModule($myModules{$_});
180 &status("Module: Loaded/Total [$loaded/$total]");
183 ### rename to moduleReloadAll?
184 sub reloadAllModules {
185 ### &status("Module: reloading all.");
186 foreach (map { substr($_,2) } keys %moduleAge) {
189 ### &status("Module: reloading done.");
192 ### rename to modulesReload?
195 my $file = (grep /\/$mod/, keys %INC)[0];
197 # don't reload if it's not our module.
198 if ($mod =~ /::/ or $mod !~ /pl$/) {
199 &VERB("Not reloading $mod.",3);
203 if (!defined $file) {
204 &WARN("rM: Cannot reload $mod since it was not loaded anyway.");
209 &ERROR("rM: file '$file' does not exist?");
213 my $age = (stat $file)[9];
214 return if ($age == $moduleAge{$file});
216 if ($age < $moduleAge{$file}) {
217 &WARN("rM: we're not gonna downgrade the file. use 'touch'.");
221 if (grep /$mod/, @myModulesReloadNot) {
222 &DEBUG("rM: SHOULD NOT RELOAD $mod!!!");
226 my $dc = &Time2String($age - $moduleAge{$file});
227 my $ago = &Time2String(time() - $moduleAge{$file});
229 &status("Module: Loading $mod...");
230 &VERB("Module: delta change: $dc",2);
231 &VERB("Module: ago: $ago",2);
234 eval "require \"$file\""; # require or use?
236 &DEBUG("rM: failure: @$");
238 my $basename = $file;
239 $basename =~ s/^.*\///;
240 &status("Module: reloaded $basename");
241 $moduleAge{$file} = $age;
246 ### OPTIONAL MODULES.
249 local %perlModulesLoaded = ();
250 local %perlModulesMissing = ();
253 return 0 if (exists $perlModulesMissing{$_[0]});
254 &reloadModule($_[0]);
255 return 1 if (exists $perlModulesLoaded{$_[0]});
259 &WARN("Module: $_[0] is not installed!");
260 $perlModulesMissing{$_[0]} = 1;
263 $perlModulesLoaded{$_[0]} = 1;
264 &status("Module: Loaded $_[0] ...");
265 &showProc(" ($_[0])");
273 &WARN("loadMyModule: module is NULL.");
277 my ($modulebase, $modulefile);
278 if (exists $myModules{$tmp}) {
279 ($modulename, $modulebase) = ($tmp, $myModules{$tmp});
282 if ($tmp = grep /^$modulebase$/, keys %myModules) {
283 &DEBUG("lMM: lame hack, file => name => $tmp.");
287 my $modulefile = "$bot_src_dir/Modules/$modulebase";
289 # call reloadModule() which checks age of file and reload.
290 if (grep /\/$modulebase$/, keys %INC) {
291 &reloadModule($modulebase);
292 return 1; # depend on reloadModule?
295 if (! -f $modulefile) {
296 &ERROR("lMM: module ($modulebase) does not exist.");
297 if ($$ == $bot_pid) { # parent.
298 &shutdown() if (defined $shm and defined $dbh);
300 &DEBUG("b4 delfork 1");
301 &delForked($modulebase);
307 eval "require \"$modulefile\"";
309 &ERROR("cannot load my module: $modulebase");
310 if ($bot_pid != $$) { # child.
311 &DEBUG("b4 delfork 2");
312 &delForked($modulebase);
318 $moduleAge{$modulefile} = (stat $modulefile)[9];
320 &status("myModule: Loaded $modulebase ...");
321 &showProc(" ($modulebase)");
326 ### this chews 3megs on potato, 300 kB on slink.
328 #eval "require 'sys/syscall.ph'";
330 # &WARN("sys/syscall.ph has not been installed//generated.
331 #gettimeofday will use time() instead");
334 &showProc(" (syscall)");
337 &ERROR("UNKNOWN FUNCTION CALLED: $AUTOLOAD");
339 next unless (defined $_);