]> git.donarmstrong.com Git - infobot.git/blob - src/modules.pl
Initial revision
[infobot.git] / src / modules.pl
1 #
2 #  modules.pl: pseudo-Module handler
3 #      Author: xk <xk@leguin.openprojects.net>
4 #     Version: v0.2 (20000629)
5 #     Created: 20000624
6 #
7
8 if (&IsParam("useStrict")) { use strict; }
9
10 ###
11 ### REQUIRED MODULES.
12 ###
13
14 eval "use IO::Socket";
15 if ($@) {
16     &ERROR("no IO::Socket?");
17     exit 1;
18 }
19 &showProc(" (IO::Socket)");
20
21 ### MODULES.
22 %myModules = (
23         "countdown"     => "Countdown.pl",
24         "allowDNS"      => "DNS.pl",
25         "debian"        => "Debian.pl",
26         "debianExtra"   => "DebianExtra.pl",
27         "dict"          => "Dict.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",
34         "quote"         => "Quote.pl",
35         "rootwarn"      => "RootWarn.pl",
36         "search"        => "Search.pl",
37         "slashdot"      => "Slashdot3.pl",
38         "topic"         => "Topic.pl",
39         "units"         => "Units.pl",
40         "uptime"        => "Uptime.pl",
41         "userinfo"      => "UserInfo.pl",
42         "wwwsearch"     => "W3Search.pl",
43         "whatis"        => "WhatIs.pl",
44         "wingate"       => "Wingate.pl",
45         "insult"        => "insult.pl",
46         "nickometer"    => "nickometer.pl",
47 );
48 @myModulesLoadNow       = ('topic', 'uptime',);
49 @myModulesReloadNot     = ('IRC/Irc.pl','IRC/Schedulers.pl');
50
51 sub loadCoreModules {
52     if (!opendir(DIR, $infobot_src_dir)) {
53         &ERROR("can't open source directory $infobot_src_dir: $!");
54         exit 1;
55     }
56
57     &status("Loading CORE modules...");
58
59     while (defined(my $file = readdir DIR)) {
60         next unless $file =~ /\.pl$/;
61         next unless $file =~ /^[A-Z]/;
62         my $mod = "$infobot_src_dir/$file";
63         ### TODO: use eval and exit gracefully?
64         require $mod;
65         $moduleAge{$mod} = (stat $mod)[9];
66         &showProc(" ($file)") if (&IsParam("DEBUG"));
67     }
68     closedir DIR;
69 }
70
71 sub loadDBModules {
72     &status("Loading DB modules...");
73
74     if ($param{'DBType'} =~ /^mysql$/i) {
75         eval "use DBI";
76         if ($@) {
77             &ERROR("libdbd-mysql-perl is not installed!");
78             exit 1;
79         }
80         &showProc(" (DBI // mysql)");
81
82         &status("  using MySQL support.");
83         require "$infobot_src_dir/db_mysql.pl";
84
85     } elsif ($param{'DBType'} =~ /^pgsql$/i) {
86         eval "use Pg";
87         if ($@) {
88             &ERROR("libpgperl is not installed!");
89             exit 1;
90         }
91         &showProc(" (Pg // postgreSQLl)");
92
93         &status("  using PostgreSQL support.");
94         require "$infobot_src_dir/db_pgsql.pl";
95     } elsif ($param{'DBType'} =~ /^dbm$/i) {
96
97         &status("  using Berkeley DBM 1.85/2.0 support.");
98         require "$infobot_src_dir/db_dbm.pl";
99     } else {
100
101         &status("DB support DISABLED.");
102         return;
103     }
104 }
105
106 sub loadFactoidsModules {
107     &status("Loading Factoids modules...");
108
109     if (!&IsParam("factoids")) {
110         &status("Factoid support DISABLED.");
111         return;
112     }
113
114     if (!opendir(DIR, "$infobot_src_dir/Factoids")) {
115         &ERROR("can't open source directory Factoids: $!");
116         exit 1;
117     }
118
119     while (defined(my $file = readdir DIR)) {
120         next unless $file =~ /\.pl$/;
121         next unless $file =~ /^[A-Z]/;
122         my $mod = "$infobot_src_dir/Factoids/$file";
123         ### TODO: use eval and exit gracefully?
124         require $mod;
125         $moduleAge{$mod} = (stat $mod)[9];
126         &showProc(" ($file)") if (&IsParam("DEBUG"));
127     }
128     closedir DIR;
129 }
130
131 sub loadIRCModules {
132     &status("Loading IRC modules...");
133     if (&whatInterface() =~ /IRC/) {
134         eval "use Net::IRC";
135         if ($@) {
136             &ERROR("libnet-irc-perl is not installed!");
137             exit 1;
138         }
139         &showProc(" (Net::IRC)");
140     } else {
141         &status("IRC support DISABLED.");
142         return;
143     }
144
145     if (!opendir(DIR, "$infobot_src_dir/IRC")) {
146         &ERROR("can't open source directory Factoids: $!");
147         exit 1;
148     }
149
150     while (defined(my $file = readdir DIR)) {
151         next unless $file =~ /\.pl$/;
152         next unless $file =~ /^[A-Z]/;
153         my $mod = "$infobot_src_dir/IRC/$file";
154         ### TODO: use eval and exit gracefully?
155         require $mod;
156         $moduleAge{$mod} = (stat $mod)[9];
157         &showProc(" ($file)") if (&IsParam("DEBUG"));
158     }
159     closedir DIR;
160 }
161
162 sub loadMyModulesNow {
163     my $loaded = 0;
164     my $total  = 0;
165
166     &status("Loading MyModules...");
167     foreach (@myModulesLoadNow) {
168         $total++;
169
170         if (!exists $param{$_}) {
171             &DEBUG("myModule: $myModules{$_} not loaded.");
172             next;
173         }
174         &loadMyModule($myModules{$_});
175         $loaded++;
176     }
177
178     &status("Modules: Loaded/Total [$loaded/$total]");
179 }
180
181 ### rename to modulesReload?
182 sub reloadModules {
183 ##    my @check = map { $myModules{$_} } keys %myModules;
184 ##    push(@check, map { substr($_,2) } keys %moduleAge);
185     my @check = map { substr($_,2) } keys %moduleAge;
186
187     &DEBUG("rM: moduleAge must be in src/BLAH format?");
188     foreach (keys %moduleAge) {
189         &DEBUG("rM: moduleAge{$_} => '...'.");
190     }
191
192     foreach (@check) {
193         my $mod = $_;
194         my $file = (grep /\/$mod/, keys %INC)[0];
195
196         if (!defined $file) {
197             &DEBUG("rM: mod '$mod' was not found in \%INC.");
198             next;
199         }
200
201         if (! -f $file) {
202             &DEBUG("rM: file '$file' does not exist?");
203             next;
204         }
205
206         my $age = (stat $file)[9];
207         next if ($age == $moduleAge{$file});
208
209         if (grep /$mod/, @myModulesReloadNot) {
210             &DEBUG("rM: SHOULD NOT RELOAD $mod!!!");
211             next;
212         }
213
214         &DEBUG("rM: (loading) => '$mod' or ($_).");
215         delete $INC{$file};
216         eval "require \"$file\"";
217         if (@$) {
218             &DEBUG("rM: failure: @$");
219         } else {
220             &DEBUG("rM: good! (reloaded)");
221         }
222     }
223     &DEBUG("rM: Done.");
224 }
225
226 ###
227 ### OPTIONAL MODULES.
228 ###
229
230 local %perlModulesLoaded  = ();
231 local %perlModulesMissing = ();
232
233 sub loadPerlModule {
234     return 0 if (exists $perlModulesMissing{$_[0]});
235     return 1 if (exists $perlModulesLoaded{$_[0]});
236
237     eval "use $_[0]";
238     if ($@) {
239         &WARN("Module: $_[0] is not installed!");
240         $perlModulesMissing{$_[0]} = 1;
241         return 0;
242     } else {
243         $perlModulesLoaded{$_[0]} = 1;
244         &status("Module: Loaded $_[0] ...");
245         &showProc(" ($_[0])");
246         return 1;
247     }
248 }
249
250 sub loadMyModule {
251     my ($tmp) = @_;
252     if (!defined $tmp) {
253         &WARN("loadMyModule: module is NULL.");
254         return 0; 
255     }
256
257     my ($modulebase, $modulefile);
258     if (exists $myModules{$tmp}) {
259         ($modulename, $modulebase) = ($tmp, $myModules{$tmp});
260     } else {
261         $modulebase = $tmp;
262     }
263     my $modulefile = "$infobot_src_dir/Modules/$modulebase";
264
265     return 1 if (grep /$modulefile/, keys %INC);
266
267     if (! -f $modulefile) {
268         &ERROR("lMM: module ($modulebase) does not exist.");
269         if ($$ == $infobot_pid) {       # parent.
270             &shutdown() if (defined $shm and defined $dbh);
271         } else {                        # child.
272             &delForked($modulename);
273         }
274
275         exit 1;
276     }
277
278     eval "require \"$modulefile\"";
279     if ($@) {
280         &ERROR("cannot load my module: $modulebase");
281         if ($infobot_pid == $$) {       # parent.
282             &shutdown() if (defined $shm and defined $dbh);
283         } else {                        # child.
284             &delForked($modulebase);
285         }
286
287         exit 1;
288     } else {
289         $moduleAge{$modulefile} = (stat $modulefile)[9];
290         &DEBUG("lMM: setting moduleAge{$modulefile} = time();");
291
292         &status("myModule: Loaded $modulebase ...");
293         &showProc(" ($modulebase)");
294         return 1;
295     }
296 }
297
298 ### this chews 3megs on potato, 300 kB on slink.
299 $no_syscall = 0;
300 ###eval "require 'sys/syscall.ph'";
301 #if ($@) {
302 #    &WARN("sys/syscall.ph has not been installed//generated. gettimeofday
303 #will use time() instead");
304     $no_syscall = 1;
305 #}
306 #&showProc(" (syscall)");
307
308 1;