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;
27 @myModulesLoadNow = ('Topic', 'Uptime', 'News', 'RootWarn', 'DumpVars2', 'botmail', 'OnJoin');
28 @myModulesReloadNot = ('IRC/Irc.pl','IRC/Schedulers.pl');
32 my @mods = &getPerlFiles($bot_src_dir);
34 &status("Loading CORE modules...");
36 foreach (sort @mods) {
37 my $mod = "$bot_src_dir/$_";
39 eval "require \"$mod\"";
46 $moduleAge{$mod} = (stat $mod)[9];
47 &showProc(" ($_)") if (&IsParam('DEBUG'));
53 # TODO: use function to load module.
55 if ($param{'DBType'} =~ /^(mysql|SQLite(2)?|pgsql)$/i) {
58 &ERROR("No support for DBI::" . $param{'DBType'} . ", exiting!");
61 &status("Loading " . $param{'DBType'} . " support.");
62 $f = "$bot_src_dir/dbi.pl";
64 $moduleAge{$f} = (stat $f)[9];
66 &showProc(" (DBI::" . $param{'DBType'} . ")");
68 &WARN("DB support DISABLED.");
73 sub loadFactoidsModules {
74 if (!&IsParam('factoids')) {
75 &status("Factoid support DISABLED.");
79 &status("Loading Factoids modules...");
81 foreach ( &getPerlFiles("$bot_src_dir/Factoids") ) {
82 my $mod = "$bot_src_dir/Factoids/$_";
84 eval "require \"$mod\"";
90 $moduleAge{$mod} = (stat $mod)[9];
91 &showProc(" ($_)") if (&IsParam('DEBUG'));
96 my ($interface) = &whatInterface();
97 if ($interface =~ /IRC/) {
98 &status("Loading IRC modules...");
102 &ERROR("libnet-irc-perl is not installed!");
105 &showProc(" (Net::IRC)");
107 &status("IRC support DISABLED.");
108 # disabling forking. Why?
109 #$param{forking} = 0;
113 foreach ( &getPerlFiles("$bot_src_dir/$interface") ) {
114 my $mod = "$bot_src_dir/$interface/$_";
116 # hrm... use another config option besides DEBUG to display
117 # change in memory usage.
118 &status("Loading Modules \"$mod\"") if (!&IsParam('DEBUG'));
119 eval "require \"$mod\"";
121 &ERROR("require \"$mod\" => $@");
126 $moduleAge{$mod} = (stat $mod)[9];
127 &showProc(" ($_)") if (&IsParam('DEBUG'));
131 sub loadMyModulesNow {
135 &status("Loading MyModules...");
136 foreach (@myModulesLoadNow) {
139 &WARN("mMLN: null element.");
143 if (!&IsParam($_) and &IsChanConf($_) <= 0 and !&getChanConfList($_)) {
144 &DEBUG("loadMyModuleNow: $_ (2) not loaded.");
152 &status("Module: Runtime: Loaded/Total [$loaded/$total]");
155 ### rename to moduleReloadAll?
156 sub reloadAllModules {
159 &VERB("Module: reloading all.",2);
161 # Reload version and save
162 open(VERSION,"<VERSION");
163 $bot_release = <VERSION> || "(unknown version)";
165 $bot_version = "infobot $bot_release -- $^O";
168 # obscure usage of map and regex :)
169 foreach (map { s/.*?\/?src/src/; $_ } keys %moduleAge) {
170 $retval .= &reloadModule($_);
173 &VERB("Module: reloading done.",2);
177 ### rename to modulesReload?
180 my $file = (grep /\/$mod/, keys %INC)[0];
183 # don't reload if it's not our module.
184 if ($mod =~ /::/ or $mod !~ /pl$/) {
185 &VERB("Not reloading $mod.",3);
189 if (!defined $file) {
190 &WARN("rM: Cannot reload $mod since it was not loaded anyway.");
195 &ERROR("rM: file '$file' does not exist?");
199 if (grep /$mod/, @myModulesReloadNot) {
200 &DEBUG("rM: should not reload $mod");
204 my $age = (stat $file)[9];
206 if (!exists $moduleAge{$file}) {
207 &DEBUG("Looks like $file was not loaded; fixing.");
209 return $retval if ($age == $moduleAge{$file});
211 if ($age < $moduleAge{$file}) {
212 &WARN("rM: we're not gonna downgrade '$file'; use touch.");
213 &DEBUG("age => $age, mA{$file} => $moduleAge{$file}");
217 my $dc = &Time2String($age - $moduleAge{$file});
218 my $ago = &Time2String(time() - $moduleAge{$file});
220 &VERB("Module: delta change: $dc",2);
221 &VERB("Module: ago: $ago",2);
224 &status("Module: Loading $mod...");
227 eval "require \"$file\""; # require or use?
229 &DEBUG("rM: failure: @$ ");
231 my $basename = $file;
232 $basename =~ s/^.*\///;
233 &status("Module: reloaded $basename");
234 $retval = " $basename";
235 $moduleAge{$file} = $age;
241 ### OPTIONAL MODULES.
244 my %perlModulesLoaded = ();
245 my %perlModulesMissing = ();
248 return 0 if (exists $perlModulesMissing{$_[0]});
249 &reloadModule($_[0]);
250 return 1 if (exists $perlModulesLoaded{$_[0]});
254 &WARN("Module: $_[0] is not installed!");
255 $perlModulesMissing{$_[0]} = 1;
258 $perlModulesLoaded{$_[0]} = 1;
259 &status("Loaded $_[0]");
260 &showProc(" ($_[0])");
266 my ($modulename) = @_;
267 if (!defined $modulename) {
268 &WARN("loadMyModule: module is NULL.");
272 my $modulefile = "$bot_src_dir/Modules/$modulename.pl";
274 # call reloadModule() which checks age of file and reload.
275 if (grep /\/$modulename$/, keys %INC) {
276 &reloadModule($modulename);
277 return 1; # depend on reloadModule?
280 if (! -f $modulefile) {
281 &ERROR("lMM: module ($modulename) does not exist.");
282 if ($$ == $bot_pid) { # parent.
283 &shutdown() if (defined $shm and defined $dbh);
285 &DEBUG("b4 delfork 1");
286 &delForked($modulename);
292 eval "require \"$modulefile\"";
294 &ERROR("cannot load my module: $modulename");
295 if ($bot_pid != $$) { # child.
296 &DEBUG("b4 delfork 2");
297 &delForked($modulename);
303 $moduleAge{$modulefile} = (stat $modulefile)[9];
305 &status("Loaded $modulename");
306 &showProc(" ($modulename)");
312 eval "use Time::HiRes qw(gettimeofday tv_interval)";
314 &WARN("No Time::HiRes?");
317 &showProc(" (Time::HiRes)");
320 if (!defined $AUTOLOAD and defined $::AUTOLOAD) {
321 &DEBUG("AUTOLOAD: hrm.. ::AUTOLOAD defined!");
323 return unless (defined $AUTOLOAD);
324 return if ($AUTOLOAD =~ /__/); # internal.
326 my $str = join(', ', @_);
327 my ($package, $filename, $line) = caller;
328 &ERROR("UNKNOWN FUNCTION CALLED: $AUTOLOAD ($str) $filename line $line");
330 $AUTOLOAD =~ s/^(\S+):://g;
332 # hopefully this will work.
333 &DEBUG("Trying to load module $AUTOLOAD...");
334 &loadMyModule($AUTOLOAD);
340 if (!opendir(DIR, $dir)) {
341 &ERROR("Cannot open source directory ($dir): $!");
346 while (defined(my $file = readdir DIR)) {
347 next unless $file =~ /\.pl$/;
348 next unless $file =~ /^[A-Z]/;
353 return reverse sort @mods;
358 # vim:ts=4:sw=4:expandtab:tw=80