]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Only output the 'AES on' message if the socket state isnt I_ERROR when its reached
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2
3 # InspIRCd Configuration Script
4 #
5 # Copyright 2002-2006 The ChatSpike Development Team
6 # <brain@chatspike.net>
7 # <Craig@chatspike.net>
8 #
9 # [14:21] Brain: <matrix impression> i know perl-fu!
10 #
11 # $Id$
12 #
13 ########################################
14
15 require 5.6.0;
16 use Cwd;
17 use Getopt::Long;
18
19 GetOptions (
20         'enable-gnutls' => \$opt_use_gnutls,
21         'enable-openssl' => \$opt_use_openssl,
22         'disable-interactive' => \$opt_nointeractive,
23         'with-nick-length=i' => \$opt_nick_length,
24         'with-channel-length=i' => \$opt_chan_length,
25         'with-max-channels=i' => \$opt_maxchans,
26         'with-max-oper-channels=i' => \$opt_opermaxchans,
27         'with-max-clients' => \$opt_maxclients,
28         'enable-optimization' => \$opt_optimise,
29         'enable-epoll' => \$opt_epoll,
30         'enable-kqueue' => \$opt_kqueue,
31         'disable-epoll' => \$opt_noepoll,
32         'disable-kqueue' => \$opt_nokqueue,
33         'enable-ipv6' => \$opt_ipv6,
34         'enable-remote-ipv6' => \$opt_ipv6links,
35         'disable-remote-ipv6' => \$opt_noipv6links,
36         'with-cc=s' => \$opt_cc,
37         'with-ident-length=i' => \$opt_ident,
38         'with-quit-length=i' => \$opt_quit,
39         'with-topic-length=i' => \$opt_topic,
40         'with-kick-length=i' => \$opt_kick,
41         'with-gecos-length=i' => \$opt_gecos,
42         'with-away-length=i' => \$opt_away,
43         'with-max-modes=i' => \$opt_modes,
44         'prefix=s' => \$opt_base_dir,
45         'config-dir=s' => \$opt_config_dir,
46         'module-dir=s' => \$opt_module_dir,
47         'binary-dir=s' => \$opt_binary_dir,
48         'library-dir=s' => \$opt_library_dir,
49         'help'  => sub { showhelp(); },
50         'modupdate' => sub { modupdate(); },
51         'update' => sub { update(); },
52         'svnupdate' => sub { svnupdate(); },
53         'clean' => sub { clean(); },
54 );
55
56 my $non_interactive = (
57         (defined $opt_library_dir) ||
58         (defined $opt_base_dir) ||
59         (defined $opt_config_dir) ||
60         (defined $opt_module_dir) ||
61         (defined $opt_base_dir) ||
62         (defined $opt_binary_dir) ||
63         (defined $opt_nointeractive) ||
64         (defined $opt_away) ||
65         (defined $opt_gecos) ||
66         (defined $opt_kick) ||
67         (defined $opt_maxclients) ||
68         (defined $opt_modes) ||
69         (defined $opt_topic) ||
70         (defined $opt_quit) ||
71         (defined $opt_ident) ||
72         (defined $opt_cc) ||
73         (defined $opt_ipv6) ||
74         (defined $opt_ipv6links) ||
75         (defined $opt_noipv6links) ||
76         (defined $opt_kqueue) ||
77         (defined $opt_epoll) ||
78         (defined $opt_maxchans) ||
79         (defined $opt_opermaxchans) ||
80         (defined $opt_chan_length) ||
81         (defined $opt_nick_length) ||
82         (defined $opt_optimise) ||
83         (defined $opt_use_openssl) ||
84         (defined $opt_nokqueue) ||
85         (defined $opt_noepoll) ||
86         (defined $opt_use_gnutls)
87 );
88 my $interactive = !$non_interactive;
89
90
91 chomp($topdir = getcwd());
92 $this = resolve_directory($topdir);                                             # PWD, Regardless.
93 @modlist = ();                                                                  # Declare for Module List..
94 %config = ();                                                                   # Initiate Configuration Hash..
95 $config{ME}                 = resolve_directory($topdir);                       # Present Working Directory
96
97 $config{BASE_DIR}           = $config{ME};
98
99 if (defined $opt_base_dir)
100 {
101         $config{BASE_DIR} = $opt_base_dir;
102 }
103
104 $config{CONFIG_DIR}         = resolve_directory($config{BASE_DIR}."/conf");             # Configuration Directory
105 $config{MODULE_DIR}         = resolve_directory($config{BASE_DIR}."/modules");          # Modules Directory
106 $config{BINARY_DIR}         = resolve_directory($config{BASE_DIR}."/bin");              # Binary Directory
107 $config{LIBRARY_DIR}        = resolve_directory($config{BASE_DIR}."/lib");              # Library Directory
108
109 if (defined $opt_config_dir)
110 {
111         $config{CONFIG_DIR} = $opt_config_dir;
112 }
113 if (defined $opt_module_dir)
114 {
115         $config{MODULE_DIR} = $opt_module_dir;
116 }
117 if (defined $opt_binary_dir)
118 {
119         $config{BINARY_DIR} = $opt_binary_dir;
120 }
121 if (defined $opt_library_dir)
122 {
123         $config{LIBRARY_DIR} = $opt_library_dir;
124 }
125 chomp($config{HAS_GNUTLS}   = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
126 chomp($config{HAS_OPENSSL}  = `openssl version 2>/dev/null`);                   # Openssl version
127 $config{USE_GNUTLS}         = "n";
128 if (defined $opt_use_gnutls)
129 {
130         $config{USE_GNUTLS} = "y";                                              # Use gnutls.
131 }
132 $config{USE_OPENSSL}        = "n";                                              # Use openssl.
133 if (defined $opt_use_openssl)
134 {
135         $config{USE_OPENSSL} = "y";
136 }
137 $config{OPTIMITEMP}         = "0";                                              # Default Optimisation Value
138 $config{OPTIMISATI}         = "-g";                                             # Optimisation Flag
139 if (defined $opt_optimise)
140 {
141         $config{OPTIMISATI} = "-O" . $opt_optimise;
142         $config{OPTIMITEMP} = $opt_optimise;
143 }
144 $config{NICK_LENGT}         = "31";                                             # Default Nick Length
145 if (defined $opt_nick_length)
146 {
147         $config{NICK_LENGT} = $opt_nick_length;
148 }
149 $config{CHAN_LENGT}         = "64";                                             # Default Channel Name Length
150 if (defined $opt_chan_length)
151 {
152         $config{CHAN_LENGT} = $opt_chan_length;
153 }
154 $config{MAX_CHANNE}         = "20";                                             # Default Max. Channels per user
155 if (defined $opt_maxchans)
156 {
157         $config{MAX_CHANNE} = $opt_maxchans;
158 }
159 $config{MAX_OPERCH}         = "60";                                             # Default Max. Channels per oper
160 if (defined $opt_opermaxchans)
161 {
162         $config{MAX_OPERCH} = $opt_opermaxchans;
163 }
164 $config{MAXI_MODES}         = "20";                                             # Default Max. Number of Modes set at once.
165 if (defined $opt_modes)
166 {
167         $config{MAXI_MODES} = $opt_modes;
168 }
169 $config{HAS_STRLCPY}        = "false";                                          # strlcpy Check.
170 $config{HAS_STDINT}         = "false";                                          # stdint.h check
171 $config{USE_KQUEUE}         = "y";                                              # kqueue enabled
172 if (defined $opt_kqueue)
173 {
174         $config{USE_KQUEUE} = "y";
175 }
176 if (defined $opt_nokqueue)
177 {
178         $config{USE_KQUEUE} = "n";
179 }
180 $config{USE_EPOLL}          = "y";                                              # epoll enabled
181 if (defined $opt_epoll)
182 {
183         $config{USE_EPOLL} = "y";
184 }
185 if (defined $opt_noepoll)
186 {
187         $config{USE_EPOLL} = "n";
188 }
189 $config{IPV6}               = "n";                                              # IPv6 support (experimental)
190 if (defined $opt_ipv6)
191 {
192         $config{IPV6} = "y";
193 }
194 $config{SUPPORT_IP6LINKS}   = "y";                                              # IPv4 supporting IPv6 links (experimental)
195 if (defined $opt_ipv6links)
196 {
197         $config{SUPPORT_IP6LINKS} = "y";
198 }
199 if (defined $opt_noipv6links)
200 {
201         $config{SUPPORT_IP6LINKS} = "n";
202 }
203 $config{STATIC_LINK}        = "no";                                             # are doing static modules?
204 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                           # FD Limit
205 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`);                        # Hard FD Limit
206 chomp($config{GCCVER}       = `g++ -dumpversion | cut -c 1`);                   # Major GCC Version
207 chomp($config{OSNAME}       = `uname`);                                         # Operating System Name
208 $config{CC}                 = "g++";                                            # C++ compiler
209 if (defined $opt_cc)
210 {
211         $config{CC} = $opt_cc;
212 }
213 $exec = $config{CC} . " -dumpversion | cut -c 1";
214 chomp($config{GCCVER}       = `$exec`);                                         # Major GCC Version
215 $config{MAKEORDER}          = "ircd mods";                                      # build order
216 $config{STATICLIBS}         = "";                                               # library archive path
217 $config{MAX_IDENT}          = "12";                                             # max ident size
218 $config{MAX_QUIT}           = "255";                                            # max quit message size
219 $config{MAX_TOPIC}          = "307";                                            # max topic size
220 $config{MAX_KICK}           = "255";                                            # max kick message size
221 $config{MAX_GECOS}          = "128";                                            # max GECOS size
222 $config{MAX_AWAY}           = "200";                                            # max AWAY size
223 if (defined $opt_ident)
224 {
225         $config{MAX_IDENT} = $opt_ident;
226 }
227 if (defined $opt_quit)
228 {
229         $config{MAX_QUIT} = $opt_quit;
230 }
231 if (defined $opt_topic)
232 {
233         $config{MAX_TOPIC} = $opt_topic;
234 }
235 if (defined $opt_kick)
236 {
237         $config{MAX_KICK} = $opt_kick;
238 }
239 if (defined $opt_gecos)
240 {
241         $config{MAX_GECOS} = $opt_gecos;
242 }
243 if (defined $opt_away)
244 {
245         $config{MAX_AWAY} = $opt_away;
246 }
247
248 $no_svn = 0;
249
250 $config{HAS_OPENSSL} =~ /OpenSSL ([-[:digit:].]+)([a-z])? (\w{3}|[0-9]+) (\w{3}|[0-9]+) [0-9]{4}/;
251 $config{HAS_OPENSSL} = $1;
252
253 if ($config{GCCVER} eq "") {
254         print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
255         exit;
256 }
257
258 # Minihack! Convert Cygwin to 'Cyg-Static' so i can
259 # Keep my dynamic module experiments here for later
260 # concideration!
261
262 if ($config{OSNAME} =~ /CYGWIN/)
263 {
264         $config{OSNAME} = "CYG-STATIC";
265 }
266 elsif($config{OSNAME} =~ /^MINGW32/)
267 {
268         $config{OSNAME} = "MINGW32";
269 }
270 elsif ((!$config{OSNAME}) || ($config{OSNAME} eq ""))
271 {
272         chomp($config{OSNAME} = `/usr/bin/uname`);
273         
274         if((!$config{OSNAME}) || ($config{OSNAME} eq ""))
275         {
276                 $config{OSNAME} = "Unknown";
277         }       
278 }
279
280 if (!$config{MAX_CLIENT_T}) { 
281         $config{MAX_CLIENT_T} = 1024;                                 # Set a reasonable 'Default'
282         $fd_scan_fail = "true";                                       # Used Later
283 }
284
285 # Get and Set some important vars..
286 getmodules();
287
288 sub clean
289 {
290         if ($arg eq "-clean") {
291                 system("rm -rf .config.cache");
292         }
293 }
294
295 sub update
296 {
297         getmodules();
298         # Does the cache file exist?
299         if (!getcache()) {
300                 # No, No it doesn't.. *BASH*
301                 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
302                 exit 0;
303         } else {
304                 # We've Loaded the cache file and all our variables..
305                 print "Updating Files..\n";
306                 getosflags();
307                 $has_epoll = $config{HAS_EPOLL};
308                 $has_kqueue = $config{HAS_KQUEUE};
309                 writefiles(1);
310                 print "Complete.\n";
311                 exit;
312         }
313 }
314
315 sub modupdate
316 {
317         getmodules();
318         # Does the cache file exist?
319         if (!getcache()) {
320                 # No, No it doesn't.. *BASH*
321                 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
322                 exit 0;
323         } else {
324                 # We've Loaded the cache file and all our variables..
325                 print "Updating Files..\n";
326                 getosflags();
327                 $has_epoll = $config{HAS_EPOLL};
328                 $has_kqueue = $config{HAS_KQUEUE};
329                 writefiles(0);
330                 print "Complete.\n";
331                 exit;
332         }
333 }
334
335
336
337 sub svnupdate
338 {
339         my $fail = 0;
340         open(FH,"<.svn/entries") or $fail = 1;
341         if ($fail) {
342                 print "This is not an SVN copy of InspIRCd.\n";
343                 exit;
344         }
345         system("svn update");
346         system("perl configure -update");
347         if ($ARGV[1] eq "rebuild") {
348                 system("make install");
349         }
350         exit;
351 }
352
353 print "Running non-interactive configure...\n" unless $interactive;
354 print "Checking for cache from previous configure... ";
355 print ((getcache() eq "true") ? "found\n" : "not found\n");
356 print "Checking operating system version... ";
357 print getosflags() . "\n";
358
359 if (defined $opt_maxclients)
360 {
361         $config{MAX_CLIENT} = $opt_maxclients;
362 }
363
364 if (!$config{MAX_CLIENT}) { 
365         # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
366         # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
367         # higher than the found value" :))
368         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
369 }
370
371 printf "Checking if stdint.h exists... ";
372 $config{HAS_STDINT} = "true";
373 my $fail = 0;
374 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
375 if ($config{HAS_STDINT} eq "true") {
376         close(STDINT);
377 }
378 print "yes\n" if $config{HAS_STDINT} eq "true";
379 print "no\n" if $config{HAS_STDINT} eq "false";
380
381
382 printf "Checking if strlcpy exists... ";
383 # Perform the strlcpy() test..
384 $config{HAS_STRLCPY} = "false";
385 my $fail = 0;
386 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
387 if (!$fail) {
388         while (chomp($line = <STRLCPY>)) {
389                 # try and find the delcaration of:
390                 # size_t strlcpy(...)
391                 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
392                         $config{HAS_STRLCPY} = "true";
393                 }
394         }
395         close(STRLCPY);
396 }
397 print "yes\n" if $config{HAS_STRLCPY} eq "true";
398 print "no\n" if $config{HAS_STRLCPY} eq "false";
399
400
401 printf "Checking if kqueue exists... ";
402 $has_kqueue = 0;
403 $fail = 0;
404 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
405 if (!$fail) {
406         while (chomp($line = <KQUEUE>)) {
407                 # try and find the delcaration of:
408                 # int kqueue(void);
409                 if ($line =~ /int(\0x9|\s)+kqueue/) {
410                         $has_kqueue = 1;
411                 }
412         }
413         close(KQUEUE);
414 }
415 print "yes\n" if $has_kqueue == 1;
416 print "no\n" if $has_kqueue == 0;
417
418 printf "Checking if epoll exists... ";
419 $has_epoll = 0;
420 $fail = 0;
421 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
422 if (!$fail) {
423         $has_epoll = 1;
424         close(EPOLL);
425 }
426 if ($has_epoll) {
427         my $kernel = `uname -r`;
428         chomp($kernel);
429         if (($kernel =~ /2\.0/) || ($kernel =~ /2\.2/) || ($kernel =~ /2\.4/)) {
430                 $has_epoll = 0;
431         }
432 }
433 print "yes\n" if $has_epoll == 1;
434 print "no\n" if $has_epoll == 0;
435
436 if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) {
437         $config{HAS_STRLCPY} = "true";
438 }
439
440 $config{HAS_EPOLL} = $has_epoll;
441 $config{HAS_KQUEUE} = $has_kqueue; 
442
443 printf "Checking for libgnutls... ";
444 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
445         print "yes\n";
446         $config{HAS_GNUTLS} = "y";
447 } else {
448         print "no\n";
449         $config{HAS_GNUTLS} = "n";
450 }
451
452 printf "Checking for openssl... ";
453 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
454         print "yes\n";
455         $config{HAS_OPENSSL} = "y";
456 } else {
457         print "no\n";
458         $config{HAS_OPENSSL} = "n";
459 }
460
461 ################################################################################
462 #                          BEGIN INTERACTIVE PART                              #
463 ################################################################################
464
465 # Clear the Screen..
466 if ($interactive)
467 {
468         system("clear");
469         chomp($wholeos = `uname -sr`);
470
471         my $rev = getrevision();
472         # Display Introduction Message..
473         print "
474 Welcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)
475 \033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m
476
477 *** If you are unsure of any of these values, leave it blank for    ***
478 *** standard settings that will work, and your server will run      ***
479 *** using them. Please consult your IRC network admin if in doubt.  ***
480
481 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
482 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
483 dir, otherwise you won't have a config file!
484
485 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos)
486 Maximum file descriptors: \033[1;32m$config{MAX_CLIENT_T}\033[0m
487 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
488         if ($rev eq "r0") {
489                 print " (Non-SVN build)";
490         }
491         print ".\n\n";
492
493         $config{CHANGE_COMPILER} = "n";
494         print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
495
496         while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
497                 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
498 should NOT be used. You should probably specify a newer compiler.\n\n";
499                 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
500                 if ($config{CHANGE_COMPILER} =~ /y/i) {
501                         print "What command do you want to use to invoke your compiler?\n";
502                         print "[\033[1;32m$config{CC}\033[0m] -> ";
503                         chomp($config{CC} = <STDIN>);
504                         if ($config{CC} eq "") {
505                                 $config{CC} = "g++";
506                         }
507                         chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
508                         if ($foo ne "") {
509                                 chomp($config{GCCVER}       = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
510                                 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
511                                 if ($config{GCCVER} < 3) {
512                                         print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
513                                 }
514                         }
515                         else {
516                                 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
517                         }
518                 }
519         }
520
521         print "\n";
522
523         # Directory Settings..
524         my $tmpbase = $config{BASE_DIR};
525         dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
526         if ($tmpbase ne $config{BASE_DIR}) {
527                 $config{CONFIG_DIR}         = resolve_directory($config{BASE_DIR}."/conf");           # Configuration Dir
528                 $config{MODULE_DIR}         = resolve_directory($config{BASE_DIR}."/modules");        # Modules Directory
529                 $config{BINARY_DIR}         = resolve_directory($config{BASE_DIR}."/bin");            # Binary Directory
530                 $config{LIBRARY_DIR}        = resolve_directory($config{BASE_DIR}."/lib");            # Library Directory
531         }
532
533         dir_check("are the configuration files", "CONFIG_DIR");
534         dir_check("are the modules to be compiled to", "MODULE_DIR");
535         dir_check("is the IRCd binary to be placed", "BINARY_DIR");
536         dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
537
538         if ($has_kqueue) {
539                 yesno(USE_KQUEUE,"You are running a BSD operating system, and kqueue\nwas detected. Would you like to enable kqueue support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable kqueue?");
540                 print "\n";
541         }
542         if ($has_epoll) {
543                 yesno(USE_EPOLL,"You are running a Linux 2.6+ operating system, and epoll\nwas detected. Would you like to enable epoll support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable epoll?");
544                 print "\n";
545         }
546         $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
547         if (!$chose_hiperf) {
548                 print "No high-performance socket engines are available, or you chose\n";
549                 print "not to enable one. Defaulting to select() engine.\n\n";
550         }
551
552         yesno(IPV6,"Would you like to build InspIRCd with IPv6 support?");
553         print "\n";
554
555         if ($config{IPV6} eq "y") {
556                 print "You have chosen to build an \033[1;32mIPV6-only\033[0m server.\nTo accept IPV4 users, you must use the '::ffff:' notation of addresses.\n\n";
557                 $config{SUPPORT_IP6LINKS} = "y";
558         } else {
559                 yesno(SUPPORT_IP6LINKS,"You have chosen to build an \033[1;32mIPV4-only\033[0m server.\nWould you like to enable support for linking to IPV6-enabled\nInspIRCd servers which are using '::ffff:' notation?\nIf you are using a recent operating\nsystem and are unsure, answer yes.");
560                 print "\n";
561         }
562
563         if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
564                 print "I have detected both GnuTLS and OpenSSL on your system.\n";
565                 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
566                 print "instead, you should enable the OpenSSL module yourself\n";
567                 print "by copying it from src/modules/extra to src/modules.\n\n";
568         }
569
570         if ($config{HAS_GNUTLS} eq "y") {
571                 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
572                 if ($config{USE_GNUTLS} eq "y") {
573                         print "\nUsing GnuTLS SSL module.\n";
574                 }
575         } elsif ($config{HAS_OPENSSL} eq "y") {
576                         yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
577         if ($config{USE_OPENSSL} eq "y") {
578                         print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
579                 }
580         }
581
582         print "\nThe following questions will ask you for various figures relating\n";
583         print "To your IRCd install. Please note that these should usually be left\n";
584         print "as defaults unless you have a real reason to change them. If they\n";
585         print "changed, then the values must be identical on all servers on your\n";
586         print "network, or malfunctions and/or crashes may occur, with the exception\n";
587         print "of the 'maximum number of clients' setting which may be different on\n";
588         print "different servers on the network.\n\n";
589
590         # File Descriptor Settings..
591         my $continue = 0;
592         while (!$continue) {
593                 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
594                 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
595                 chomp($var = <STDIN>);
596                 if ($var eq "") {
597                         $var = $config{MAX_CLIENT};
598                 }
599                 if ($var =~ /^\d+$/) {
600                         if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
601                                 # Client has entered a larger number than the 'discovered' value
602                                 # Confirm.
603                                 print "WARNING: Our scans have indicated that you are attempting
604 to use more sockets than there are avaliable. Are you sure
605 you wish to do this? It may cause the IRCd to malfunction [y/n]
606 [\033[1;32mn\033[0m] -> $c";
607                                 chomp($tmp = <STDIN>);
608                                 if ($tmp ne "y") {
609                                         print "Please enter the correct value.\n\n";
610                                         next;
611                                 }
612                         }
613                 } else {
614                         print "You must enter a number in this field. Please try again.\n\n";
615                         next;
616                 }
617                 # If we get here, we should be good to go.
618                 $config{MAX_CLIENT} = $var;
619                 $continue = 1;
620                 print "\n";
621         }
622
623         my $continue = 0;
624         while (!$continue) {
625                 print "What is the maximum length of nicknames?\n";
626                 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
627                 chomp($var = <STDIN>);
628                 if ($var eq "") {
629                         $var = $config{NICK_LENGT};
630                 }
631                 if ($var =~ /^\d+$/) {
632                         # We don't care what the number is, set it and be on our way.
633                         $config{NICK_LENGT} = $var;
634                         $continue = 1;
635                         print "\n";
636                 } else {
637                         print "You must enter a number in this field. Please try again.\n\n";
638                 }
639         }
640
641         $continue = 0;
642         while (!$continue) {
643                 print "What is the maximum length of channel names?\n";
644                 print "[\033[1;32m$config{CHAN_LENGT}\033[0m] -> ";
645                 chomp($var = <STDIN>);
646                 if ($var eq "") {
647                         $var = $config{CHAN_LENGT};
648                 }
649                 if ($var =~ /^\d+$/) {
650                         # We don't care what the number is, set it and be on our way.
651                         $config{CHAN_LENGT} = $var;
652                         $continue = 1;
653                         print "\n";
654                 } else {
655                         print "You must enter a number in this field. Please try again.\n\n";
656                 }
657         }
658
659         $continue = 0;
660         while (!$continue) {
661                 print "What is the maximum number of channels a normal user may join at any one time?\n";
662                 print "[\033[1;32m$config{MAX_CHANNE}\033[0m] -> ";
663                 chomp($var = <STDIN>);
664                 if ($var eq "") {
665                         $var = $config{MAX_CHANNE};
666                 }
667                 if ($var =~ /^\d+$/) {
668                         # We don't care what the number is, set it and be on our way.
669                         $config{MAX_CHANNE} = $var;
670                         $continue = 1;
671                         print "\n";
672                 } else {
673                         print "You must enter a number in this field. Please try again.\n\n";
674                 }
675         }
676
677         $continue = 0;
678         while (!$continue) {
679                 print "What is the maximum number of channels an oper may join at any one time?\n";
680                 print "[\033[1;32m$config{MAX_OPERCH}\033[0m] -> ";
681                 chomp($var = <STDIN>);
682                 if ($var eq "") {
683                         $var = $config{MAX_OPERCH};
684                 }
685                 if ($var =~ /^\d+$/) {
686                         # We don't care what the number is, set it and be on our way.
687                         $config{MAX_OPERCH} = $var;
688                         $continue = 1;
689                         print "\n";
690                 }
691         }
692
693         $continue = 0;
694         while (!$continue) {
695                 print "What is the maximum number of mode changes in one line?\n";
696                 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
697                         chomp($var = <STDIN>);
698                 if ($var eq "") {
699                         $var = $config{MAXI_MODES};
700                 }
701                 if ($var =~ /^\d+$/) {
702                         # We don't care what the number is, set it and be on our way.
703                         $config{MAXI_MODES} = $var;
704                         $continue = 1;
705                         print "\n";
706                 } else {
707                         print "You must enter a number in this field. Please try again.\n\n";
708                 }
709         }
710
711         $continue = 0;
712         while (!$continue) {
713                 print "What is the maximum length of an ident (username)?\n";
714                 print "[\033[1;32m$config{MAX_IDENT}\033[0m] -> ";
715                 chomp($var = <STDIN>);
716                 if ($var eq "") {
717                         $var = $config{MAX_IDENT};
718                 }
719                 if ($var =~ /^\d+$/) {
720                         # We don't care what the number is, set it and be on our way.
721                         $config{MAX_IDENT} = $var;
722                         $continue = 1;
723                         print "\n";
724                 } else {
725                         print "You must enter a number in this field. Please try again.\n\n";
726                 }
727         }
728
729         $continue = 0;
730         while (!$continue) {
731                 print "What is the maximum length of a quit message?\n";
732                 print "[\033[1;32m$config{MAX_QUIT}\033[0m] -> ";
733                 chomp($var = <STDIN>);
734                 if ($var eq "") {
735                         $var = $config{MAX_QUIT};
736                 }
737                 if ($var =~ /^\d+$/) {
738                         # We don't care what the number is, set it and be on our way.
739                         $config{MAX_QUIT} = $var;
740                         $continue = 1;
741                         print "\n";
742                 } else {
743                         print "You must enter a number in this field. Please try again.\n\n";
744                 }
745         }
746
747         $continue = 0;
748         while (!$continue) {
749                 print "What is the maximum length of a channel topic?\n";
750                 print "[\033[1;32m$config{MAX_TOPIC}\033[0m] -> ";
751                 chomp($var = <STDIN>);
752                 if ($var eq "") {
753                         $var = $config{MAX_TOPIC};
754                 }
755                 if ($var =~ /^\d+$/) {
756                         # We don't care what the number is, set it and be on our way.
757                         $config{MAX_TOPIC} = $var;
758                         $continue = 1;
759                         print "\n";
760                 } else {
761                         print "You must enter a number in this field. Please try again.\n\n";
762                 }
763         }
764
765         $continue = 0;
766         while (!$continue) {
767                 print "What is the maximum length of a kick message?\n";
768                 print "[\033[1;32m$config{MAX_KICK}\033[0m] -> ";
769                 chomp($var = <STDIN>);
770                 if ($var eq "") {
771                         $var = $config{MAX_KICK};
772                 }
773                 if ($var =~ /^\d+$/) {
774                         # We don't care what the number is, set it and be on our way.
775                         $config{MAX_KICK} = $var;
776                         $continue = 1;
777                         print "\n";
778                 } else {
779                         print "You must enter a number in this field. Please try again.\n\n";
780                 }
781         }
782
783         $continue = 0;
784         while (!$continue) {
785                 print "What is the maximum length of a GECOS (real name) field?\n";
786                 print "[\033[1;32m$config{MAX_GECOS}\033[0m] -> ";
787                 chomp($var = <STDIN>);
788                 if ($var eq "") {
789                         $var = $config{MAX_GECOS};
790                 }
791                 if ($var =~ /^\d+$/) {
792                         # We don't care what the number is, set it and be on our way.
793                         $config{MAX_GECOS} = $var;
794                         $continue = 1;
795                         print "\n";
796                 } else {
797                         print "You must enter a number in this field. Please try again.\n\n";
798                 }
799         }
800
801         $continue = 0;
802         while (!$continue) {
803                 print "What is the maximum length of an away message?\n";
804                 print "[\033[1;32m$config{MAX_AWAY}\033[0m] -> ";
805                 chomp($var = <STDIN>);
806                 if ($var eq "") {
807                         $var = $config{MAX_AWAY};
808                 }
809                 if ($var =~ /^\d+$/) {
810                         # We don't care what the number is, set it and be on our way.
811                         $config{MAX_AWAY} = $var;
812                         $continue = 1;
813                         print "\n";
814                 } else {
815                         print "You must enter a number in this field. Please try again.\n\n";
816                 }
817         }
818
819         # Code Optimisation
820         print "Enter the Level Of Binary optimisation. This is a number between 0 and 3.
821 The InspIRCd Team will NOT support any bug reports above 0. Also note,
822 the IRCd behaviour will be different depending on this value. Please
823 read the documentation for more information.
824
825 The higher the number, the more optimised your binary will be. This
826 value will default to 0 if you either don't enter a number, or enter
827 a value outside the range.
828
829 As always, if you are unsure, just press enter and accept the default.\n\n";
830         print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
831         chomp($var = <STDIN>);
832         if ($var eq "") {
833                 $var = $config{OPTIMITEMP};
834         }
835
836         if ($var eq "1") {
837                 $config{OPTIMITEMP} = 1;
838                 $config{OPTIMISATI} = "-O";
839         } elsif ($var eq "2") {
840                 $config{OPTIMITEMP} = 2;
841                 $config{OPTIMISATI} = "-O2";
842         } elsif ($var eq "3") {
843                 $config{OPTIMITEMP} = 3;
844                 $config{OPTIMISATI} = "-O3";
845         } else {
846                 $config{OPTIMITEMP} = 0;
847                 $config{OPTIMISATI} = "-g";
848         }
849 }
850
851 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
852 print "\033[0mBase install path:\033[1;32m\t\t$config{BASE_DIR}\033[0m\n";
853 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\033[0m\n";
854 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\033[0m\n";
855 print "\033[0mLibrary path:\033[1;32m\t\t\t$config{LIBRARY_DIR}\033[0m\n";
856 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\033[0m\n";
857 print "\033[0mMax User Channels:\033[1;32m\t\t$config{MAX_CHANNE}\033[0m\n";
858 print "\033[0mMax Oper Channels:\033[1;32m\t\t$config{MAX_OPERCH}\033[0m\n";
859 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\033[0m\n";
860 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\033[0m\n";
861 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\033[0m\n";
862 print "\033[0mMax ident length:\033[1;32m\t\t$config{MAX_IDENT}\033[0m\n";
863 print "\033[0mMax quit length:\033[1;32m\t\t$config{MAX_QUIT}\033[0m\n";
864 print "\033[0mMax topic length:\033[1;32m\t\t$config{MAX_TOPIC}\033[0m\n";
865 print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\033[0m\n";
866 print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\033[0m\n";
867 print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\033[0m\n";
868 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.x\033[0m\n";
869 print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
870 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
871 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n";
872 print "\033[0mIPv6 Support:\033[1;32m\t\t\t$config{IPV6}\033[0m\n";
873 print "\033[0mIPv6 to IPv4 Links:\033[1;32m\t\t$config{SUPPORT_IP6LINKS}\033[0m\n";
874 print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n";
875 print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n";
876
877 if ($config{USE_GNUTLS} eq "y") {
878         $failed = 0;
879         open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
880         close(TMP);
881         if ($failed) {
882                 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
883                 chdir("src/modules");
884                 system("ln -s extra/m_ssl_gnutls.cpp");
885                 system("ln -s extra/ssl_cert.h");
886                 chdir("../..");
887         }
888         getmodules();
889         if ($interactive)
890         {
891                 $failed = 0;
892                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
893                 close(TMP);
894                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
895                 close(TMP);
896                 if ($failed) {
897                         print "SSL Certificates Not found, Generating.. \n\n
898 *************************************************************
899 * Generating the Private Key may take some time, go grab a  *
900 * Coffee. Even better, to generate some more entropy if it  *
901 * is taking a while, open another console and type du / a   *
902 * few times and get that HD going :) Then answer the        *
903 * Questions which follow. If you are unsure, just hit enter *
904 *************************************************************\n\n";
905                         system("certtool --generate-privkey --outfile key.pem");
906                         system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
907                         print "\nCertificate generation complete, copying to config directory... ";
908                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
909                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
910                         print "Done.\n\n";
911                 } else {
912                         print "SSL Certificates found, skipping.\n\n"
913                 }
914         }
915         else
916         {
917                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
918         }
919 } elsif ($config{USE_OPENSSL} eq "y") {
920         $failed = 0;
921         open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
922         close(TMP);
923         if ($failed) {
924                 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
925                 chdir("src/modules");
926                 system("ln -s extra/m_ssl_openssl.cpp");
927                 system("ln -s extra/ssl_cert.h");
928                 chdir("../..");
929         }
930         getmodules();
931         $failed = 0;
932         if ($interactive)
933         {
934                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
935                 close(TMP);
936                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
937                 close(TMP);
938                 if ($failed) {
939                         print "SSL Certificates Not found, Generating.. \n\n
940 *************************************************************
941 * Generating the certificates may take some time, go grab a *
942 * coffee, or something.                                     *
943 *************************************************************\n\n";
944                         system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
945                         system("openssl dhparam -out dhparams.pem 1024");
946                         print "\nCertificate generation complete, copying to config directory... ";
947                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
948                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
949                         system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
950                         print "Done.\n\n";
951                 } else {
952                         print "SSL Certificates found, skipping.\n\n"
953                 }
954         }
955         else
956         {
957                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
958         }
959 }
960 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
961         print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
962 }
963
964 getosflags();
965 makecache();
966 writefiles(1);
967
968 print "\n\n";
969 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
970 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
971         print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
972         print "load the required modules in your config. This configure process\n";
973         print "has just prepared these modules to be compiled for you, and has not\n";
974         print "configured them to be compiled into the core of the ircd.\n";
975 }
976 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
977 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
978         print "\033[1;32mWARNING!\033[0m You are running OpenBSD but you are using the base gcc package\nrather than eg++. This compile will most likely fail, but i'm letting you\ngo ahead with it anyway, just in case i'm wrong :-)\n";
979 }
980
981 if ($config{GCCVER} < "3") {
982         print <<FOO2;
983 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
984 GCC 2.x series compilers only had partial (read as broken) C++ support, and
985 your compile will most likely fail horribly! If you have any problems, do NOT
986 report them to the bugtracker or forums without first upgrading your compiler
987 to a newer 3.x or 4.x (or whatever is available currently) version.
988 FOO2
989 }
990
991 ################################################################################
992 #                              HELPER FUNCTIONS                                #
993 ################################################################################
994 sub getcache {
995         # Retrieves the .config.cache file, and loads values into the main config hash.
996         open(CACHE, ".config.cache") or return undef;
997         while (<CACHE>) {
998                 chomp;
999                 # Ignore Blank lines, and comments..
1000                 next if /^\s*$/;
1001                 next if /^\s*#/;
1002                 my ($key, $value) = split("=", $_);
1003                 $value =~ /^\"(.*)\"$/;
1004                 # Do something with data here!
1005                 $config{$key} = $1;
1006         }
1007         close(CONFIG);
1008         return "true";
1009 }
1010
1011 sub makecache {
1012         # Dump the contents of %config
1013         print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
1014         open(FILEHANDLE, ">.config.cache");
1015         foreach $key (keys %config) {
1016                 print FILEHANDLE "$key=\"$config{$key}\"\n";
1017         }
1018         close(FILEHANDLE);
1019 }
1020
1021 sub dir_check {
1022         my ($desc, $hash_key) = @_;
1023         my $complete = 0;
1024         while (!$complete) {
1025                 print "In what directory $desc?\n";
1026                 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
1027                 chomp($var = <STDIN>);
1028                 if ($var eq "") {
1029                         $var = $config{$hash_key};
1030                 }
1031                 if ($var =~ /^\~\/(.+)$/) {
1032                         # Convert it to a full path..
1033                         $var = resolve_directory($ENV{HOME} . "/" . $1);
1034                 }
1035                 elsif ((($config{OSNAME} == "MINGW32") and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1036                 {
1037                         # Assume relative Path was given.. fill in the rest.
1038                         $var = $this . "/$var";
1039                 }
1040                 
1041                 $var = resolve_directory($var); 
1042                 if (! -e $var) {
1043                         print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
1044                         chomp($tmp = <STDIN>);
1045                         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1046                                 # Attempt to Create the Dir..
1047                                 
1048                                 system("mkdir -p \"$var\" >> /dev/null 2>&1");
1049                                 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
1050                                 if ($chk != 0) {
1051                                         print "Unable to create directory. ($var)\n\n";
1052                                         # Restart Loop..
1053                                         next;
1054                                 }
1055                         } else {
1056                                 # They said they don't want to create, and we can't install there.
1057                                 print "\n\n";
1058                                 next;
1059                         }
1060                 } else {
1061                         if (!is_dir($var)) {
1062                                 # Target exists, but is not a directory.
1063                                 print "File $var exists, but is not a directory.\n\n";
1064                                 next;
1065                         }
1066                 }
1067                 # Either Dir Exists, or was created fine.
1068                 $config{$hash_key} = $var;
1069                 $complete = 1;
1070                 print "\n";
1071         }
1072 }
1073
1074 sub getosflags {
1075         if ($config{OSNAME} =~ /BSD$/) {
1076                 $config{LDLIBS} = "-lstdc++";
1077                 $config{FLAGS}  = "-fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1078                 $config{MAKEPROG} = "gmake";
1079                 if ($config{OSNAME} eq "OpenBSD") {
1080                         chomp($foo = `eg++ -dumpversion | cut -c 1`);
1081                         # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1082                         # if theyre not running this, configure lets the build continue but they probably wont manage to
1083                         # compile as this standard version is 2.95.3!
1084                         if ($foo ne "") {
1085                                 $config{CC} = "eg++";
1086                                 chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1087                         }
1088                         return "OpenBSD";
1089                 }
1090                 return $config{OSNAME};
1091         } else {
1092                 $config{LDLIBS} = "-ldl -lstdc++";
1093                 $config{FLAGS}  = "-fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1094                 $config{MAKEPROG} = "make";
1095                 if ($config{OSNAME} =~ /CYGWIN/) {
1096                         $config{FLAGS}  = "-Wall -Woverloaded-virtual $config{OPTIMISATI}";
1097                         $config{LDLIBS} = "";
1098                         $config{MAKEPROG} = "/usr/bin/make";
1099                         $config{MAKEORDER} = "ircd mods";
1100                         return "Cygwin";
1101                 } elsif ($config{OSNAME} eq "CYG-STATIC") {
1102                         $config{FLAGS} = "-Wall -Woverloaded-virtual $config{OPTIMISATI}";
1103                         $config{LDLIBS} = "";
1104                         $config{MAKEPROG} = "/usr/bin/make";
1105                         $config{MAKEORDER} = "mods ircd";
1106                         $config{STATICLIBS} = "modules/mods.a";
1107                         $config{STATIC_LINK} = "yes";
1108                         return "Cygwin-Static";
1109                 }
1110                 return "Linux";
1111         }
1112         
1113         if ($config{OSNAME} =~ /SunOS/)
1114         {
1115                 # solaris/sunos needs these
1116                 # socket = bsd sockets api
1117                 # nsl = dns stuff
1118                 # rt = POSIX realtime extensions
1119                 # resolv = inet_aton only (why isnt this in nsl?!)
1120                 $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
1121                 return "Solaris";
1122         }
1123         
1124         if($config{OSNAME} eq "MINGW32")
1125         {
1126                 # All code is position-independent on windows
1127                 $config{FLAGS} =~ s/-fPIC //;
1128                 return "MinGW";
1129         }
1130 }
1131
1132 sub is_dir {
1133         my ($path) = @_;
1134         if (chdir($path)) {
1135                 chdir($this);
1136                 return 1;
1137         } else {
1138                 # Just in case..
1139                 chdir($this);
1140                 return 0;
1141         }
1142 }
1143
1144 sub getmodules {
1145         my $i = 0;
1146         print "Detecting modules ";
1147         opendir(DIRHANDLE, "src/modules");
1148         foreach $name (sort readdir(DIRHANDLE)) {
1149                 if ($name =~ /^m_(.+)\.cpp$/)
1150                 {
1151                         $mod = $1;
1152                         if ($mod !~ /_static$/) {
1153                                 $modlist[$i++] = $mod;
1154                                 print ".";
1155                         }
1156                 }
1157         }
1158         closedir(DIRHANDLE);
1159         print "\nOk, $i modules.\n";
1160 }
1161
1162 sub getrevision {
1163         if ($no_svn) {
1164                 return "0";
1165         }
1166         my $data = `svn info`;
1167         
1168         if ($data eq "") {
1169                 $no_svn = 1;
1170                 $rev = "0";
1171                 return $rev;
1172         }
1173         $data =~ /Revision: (\d+)/;
1174         my $rev = $1;
1175         if (!defined($rev)) {
1176                 $rev = "0";
1177         }
1178         return $rev;
1179 }
1180
1181 sub writefiles {
1182         my($writeheader) = @_;
1183         # First File.. inspircd_config.h
1184         chomp(my $incos = `uname -n -s -r`);
1185         chomp(my $version = `sh ./src/version.sh`);
1186         chomp(my $revision = getrevision());
1187         $version = "$version(r$revision)";
1188         chomp(my $revision2 = getrevision());
1189         if ($writeheader == 1)
1190         {
1191                 print "Writing \033[1;32minspircd_config.h\033[0m\n";
1192                 open(FILEHANDLE, ">include/inspircd_config.h");
1193                 my $NL = $config{NICK_LENGT}+1;
1194                 my $CL = $config{CHAN_LENGT}+1;
1195                 print FILEHANDLE <<EOF;
1196 /* Auto generated by configure, do not modify! */
1197 #ifndef __CONFIGURATION_AUTO__
1198 #define __CONFIGURATION_AUTO__
1199
1200 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1201 #define MOD_PATH "$config{MODULE_DIR}"
1202 #define VERSION "$version"
1203 #define REVISION "$revision2"
1204 #define MAXCLIENTS $config{MAX_CLIENT}
1205 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1206 #define NICKMAX $NL
1207 #define CHANMAX $CL
1208 #define MAXCHANS $config{MAX_CHANNE}
1209 #define OPERMAXCHANS $config{MAX_OPERCH}
1210 #define MAXMODES $config{MAXI_MODES}
1211 #define IDENTMAX $config{MAX_IDENT}
1212 #define MAXQUIT $config{MAX_QUIT}
1213 #define MAXTOPIC $config{MAX_TOPIC}
1214 #define MAXKICK $config{MAX_KICK}
1215 #define MAXGECOS $config{MAX_GECOS}
1216 #define MAXAWAY $config{MAX_AWAY}
1217 #define OPTIMISATION $config{OPTIMITEMP}
1218 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1219 #define SYSTEM "$incos"
1220 #define MAXBUF 514
1221 EOF
1222                 if ($config{OSNAME} =~ /SunOS/) {
1223                         print FILEHANDLE "#define IS_SOLARIS\n";
1224                 }
1225                 if ($config{OSNAME} =~ /CYGWIN/) {
1226                         print FILEHANDLE "#define IS_CYGWIN\n";
1227                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE        1024\n#endif\n";
1228                 }
1229                 if ($config{OSNAME} eq "MINGW32") {
1230                         print FILEHANDLE "#define IS_MINGW\n";
1231                 }
1232                 if ($config{OSNAME} eq "CYG-STATIC") {
1233                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE    1024\n#endif\n";
1234                 }
1235                 if ($config{STATIC_LINK} eq "yes") {
1236                         print FILEHANDLE "#define STATIC_LINK\n";
1237                 }
1238                 if ($config{GCCVER} >= 3) {
1239                         print FILEHANDLE "#define GCC3\n";
1240                 }
1241                 if ($config{HAS_STRLCPY} eq "true") {
1242                         print FILEHANDLE "#define HAS_STRLCPY\n";
1243                 }
1244                 if ($config{HAS_STDINT} eq "true") {
1245                         print FILEHANDLE "#define HAS_STDINT\n";
1246                 }
1247                 if ($config{IPV6} =~ /y/i) {
1248                         print FILEHANDLE "#define IPV6\n";
1249                 }
1250                 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1251                         print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1252                 }
1253                 my $use_hiperf = 0;
1254                 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1255                         print FILEHANDLE "#define USE_KQUEUE\n";
1256                         $se = "socketengine_kqueue";
1257                         $use_hiperf = 1;
1258                 }
1259                 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1260                         print FILEHANDLE "#define USE_EPOLL\n";
1261                         $se = "socketengine_epoll";
1262                         $use_hiperf = 1;
1263                 }
1264                 # user didn't choose either epoll or select for their OS.
1265                 # default them to USE_SELECT (ewwy puke puke)
1266                 if (!$use_hiperf) {
1267                         print FILEHANDLE "#define USE_SELECT\n";
1268                         $se = "socketengine_select";
1269                 }
1270                 print FILEHANDLE "\n#endif\n";
1271                 close(FILEHANDLE);
1272         }
1273
1274         if ($writeheader)
1275         {
1276                 open(FILEHANDLE, ">include/inspircd_se_config.h");
1277                 print FILEHANDLE <<EOF;
1278 /* Auto generated by configure, do not modify or commit to svn! */
1279 #ifndef __CONFIGURATION_SOCKETENGINE__
1280 #define __CONFIGURATION_SOCKETENGINE__
1281
1282 #include "$se.h"
1283
1284 #endif
1285 EOF
1286                 close(FILEHANDLE);
1287         }
1288
1289
1290         # Create a Modules List..
1291         my $modules = "";
1292         foreach $i (@modlist)
1293         {
1294                 if ($config{STATIC_LINK} eq "yes") {
1295                         $modules .= "m_".$i.".o ";
1296                 }
1297                 else {
1298                         $modules .= "m_".$i.".so ";
1299                 }
1300         }
1301         chomp($modules);   # Remove Redundant whitespace..
1302
1303
1304         # Write all .in files.
1305         my $tmp = "";
1306         my $file = "";
1307         my $exe = "inspircd";
1308
1309         if ($config{OSNAME} =~ /CYGWIN/) {
1310                 $exe = "inspircd.exe";
1311         }
1312
1313         opendir(DIRHANDLE, $this);
1314
1315         foreach $name (sort readdir(DIRHANDLE)) {
1316                 if ($name =~ /^\.(.+)\.inc$/) {
1317                         $file = $1;
1318                         # All .name.inc files need parsing!
1319                         $tmp = "";
1320                         open(FILEHANDLE, ".$file.inc");
1321                         while (<FILEHANDLE>) {
1322                                 $tmp .= $_;
1323                         }
1324                         close(FILEHANDLE);
1325
1326                         $tmp =~ s/\@CC\@/$config{CC}/;
1327                         $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1328                         $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1329                         $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1330                         $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1331                         $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1332                         $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1333                         $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1334                         $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1335                         $tmp =~ s/\@MODULES\@/$modules/;
1336                         $tmp =~ s/\@EXECUTABLE\@/$exe/;
1337                         $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1338                         $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
1339
1340                         print "Writing \033[1;32m$file\033[0m\n";
1341                         open(FILEHANDLE, ">$file");
1342                         print FILEHANDLE $tmp;
1343                 }
1344         }
1345         closedir(DIRHANDLE);
1346
1347         # Make inspircd executable!
1348         chmod 0744, 'inspircd';
1349
1350         if ($config{STATIC_LINK} eq "yes") {
1351                 print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
1352                 write_static_makefile();
1353                 write_static_modules_makefile();
1354         } elsif ($config{OSNAME} =~ /CYGWIN/) {
1355                 print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
1356                 write_static_makefile();
1357                 write_dynamic_modules_makefile();
1358         } else {
1359                 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1360                 write_dynamic_makefile();
1361                 write_dynamic_modules_makefile();
1362         }
1363 }
1364
1365 sub getcompilerflags {
1366         my ($file) = @_;
1367         open(FLAGS, $file);
1368         while (<FLAGS>) {
1369         if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
1370                 close(FLAGS);
1371                         return $1;
1372                 }
1373         }
1374         close(FLAGS);
1375         return undef;
1376 }
1377
1378 sub getlinkerflags {
1379         my ($file) = @_;
1380         open(FLAGS, $file);
1381         while (<FLAGS>) {
1382                 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
1383                         close(FLAGS);
1384                         return $1;
1385                 }
1386         }
1387         close(FLAGS);
1388         return undef;
1389 }
1390
1391 sub resolve_directory {
1392         use File::Spec;
1393         return File::Spec->rel2abs($_[0]);
1394 }
1395
1396 sub yesno {
1397         my ($flag,$prompt) = @_;
1398         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
1399         chomp($tmp = <STDIN>);
1400         if ($tmp eq "") { $tmp = $config{$flag} }
1401
1402         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1403                 $config{$flag} = "y";
1404         } else {
1405                 $config{$flag} = "n";
1406         }
1407         return;
1408 }
1409
1410 sub write_static_modules_makefile {
1411         # Modules Makefile..
1412         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1413         open(FILEHANDLE, ">src/modules/Makefile");
1414
1415         ###
1416         # Module Makefile Header
1417         ###
1418         print FILEHANDLE <<EOF;
1419 # (C) ChatSpike development team
1420 # Makefile by <Craig\@ChatSpike.net>
1421 # Many Thanks to Andrew Church <achurch\@achurch.org>
1422 #    for assisting with making this work right.
1423 #
1424 # Automatically Generated by ./configure to add a modules
1425 # please run ./configure --update
1426
1427 all: \$(MODULES)
1428
1429 EOF
1430         ###
1431         # End Module Makefile Header
1432         ###
1433
1434         # Create a Modules List..
1435         my $modules = "";
1436         my $cmflags = "";
1437         my $liflags = "";
1438
1439         open(MODLIST,">include/modlist.h");
1440
1441         ###
1442         # Include File Header
1443         ###
1444         print MODLIST <<HEADER;
1445 // Generated automatically by configure. DO NOT EDIT!
1446
1447 #ifndef __SYMBOLS__H_CONFIGURED__
1448 #define __SYMBOLS__H_CONFIGURED__
1449
1450 HEADER
1451         ###
1452         # End Include File Header
1453         ###
1454
1455         # Place Module List into Include
1456         foreach $i (@modlist) {
1457                 if ($i !~ /_static$/) {
1458                         print MODLIST "extern \"C\" void * $i\_init (void);\n";
1459                 }
1460         }
1461         print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
1462
1463         ###
1464         # Build Module Crap
1465         ###
1466         foreach $i (@modlist)
1467         {
1468                 if ($i !~ /_static$/) {
1469                         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1470                         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1471
1472                         ###
1473                         # Write Entry to the Makefile
1474                         ###
1475                         print FILEHANDLE <<EOCHEESE;
1476 m_$i.o: .m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h
1477         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c .m_$i\_static.cpp
1478         mv .m_$i\_static.o ../m_$i.o
1479
1480 EOCHEESE
1481                         ###
1482                         # End Write Entry to the MakeFile
1483                         ###
1484                         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
1485                         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
1486                         open(MUNGED,">src/modules/.m_".$i."_static.cpp") or die("Could not create .m_".$i."_static.cpp");
1487                         while (chomp($a = <MODULE>)) { 
1488                                 $a =~ s/init_module/$i\_init/g;
1489                                 print MUNGED "$a\n";
1490                         }
1491                         close(MODULE);
1492                         close(MUNGED);
1493                         print MODLIST <<EOENT;
1494 {"m_$i.so",\&$i\_init},
1495 EOENT
1496                         print "done\n";
1497                 }
1498         }
1499         print MODLIST "{0}};\n\n#endif\n";
1500         close(MODLIST);
1501 }
1502
1503 sub write_dynamic_modules_makefile {
1504         # Modules Makefile..
1505         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1506         open(FILEHANDLE, ">src/modules/Makefile");
1507         my $extra = "";
1508
1509         if ($config{OSNAME} =~ /CYGWIN/) {
1510                 $extra = "../inspircd.dll.a";
1511         }
1512
1513 ###
1514 # Module Makefile Header
1515 ###
1516         print FILEHANDLE <<EOF;
1517 # (C) ChatSpike development team
1518 # Makefile by <Craig\@ChatSpike.net>
1519 # Many Thanks to Andrew Church <achurch\@achurch.org>
1520 #    for assisting with making this work right.
1521 #
1522 # Automatically Generated by ./configure to add a modules
1523 # please run ./configure -update or ./configure -modupdate
1524
1525 all: \$(MODULES)
1526
1527 EOF
1528         ###
1529         # End Module Makefile Header
1530         ###
1531
1532         # Create a Modules List..
1533         my $modules = "";
1534         my $cmflags = "";
1535         my $liflags = "";
1536         my $crud = "";
1537
1538         foreach $i (@modlist) {
1539         ###
1540         # Write Entry to the MakeFile
1541         ###
1542         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1543         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1544         print FILEHANDLE <<EOCHEESE;
1545 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h
1546         \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
1547         \$(CC) \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
1548
1549 EOCHEESE
1550         $crud = $crud . "       install -m 0700 m_$i.so \$(MODPATH)\n";
1551 ###
1552         # End Write Entry to the MakeFile
1553         ###
1554         }
1555         print FILEHANDLE "modinst:\n    \@echo \"Installing modules...\"\n" . $crud;
1556 }
1557
1558
1559 sub write_static_makefile {
1560         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
1561         my $i = 0;
1562         my @cmdlist = ();
1563         opendir(DIRHANDLE, "src");
1564         foreach $name (sort readdir(DIRHANDLE)) {
1565                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1566                         $cmdlist[$i++] = $1;
1567                 }
1568         }
1569         closedir(DIRHANDLE);
1570         my $cmdobjs = "";
1571         my $srcobjs = "";
1572         foreach my $cmd (@cmdlist) {
1573                 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1574                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1575         }
1576         print FH <<EOM;
1577 # Insp Makefile :p
1578 #
1579 # (C) ChatSpike development team
1580 # Makefile by <Craig\@ChatSpike.net>
1581 # Makefile version 2 (statically linked core) by <brain\@inspircd.org>
1582 #
1583
1584 CC = im a cheezeball
1585
1586 CXXFLAGS = -I../include \${FLAGS}
1587 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1588 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1589
1590 EOM
1591
1592 $se = "socketengine_select";
1593 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1594         $se = "socketengine_kqueue";
1595 }       
1596 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1597         $se = "socketengine_epoll";
1598 }
1599
1600         ###
1601         # This next section is for cygwin dynamic module builds.
1602         # Basically, what we do, is build the inspircd core as a library
1603         # then the main executable uses that. the library is capable of
1604         # loading / unloading the modules dynamically :)
1605         # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
1606         # make this work :)
1607         ###
1608
1609         if ($config{OSNAME} =~ /CYGWIN/) {
1610                 print FH <<EOM;
1611 all: timer.o aes.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o inspircd.exe
1612
1613 inspircd.exe: inspircd.dll.a
1614         \$(CC) -o \$@ \$^
1615
1616 inspircd.dll inspircd.dll.a: inspircd.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs  commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o aes.o timer.o snomasks.o
1617         \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
1618 EOM
1619         } else {
1620                 print FH <<EOM;
1621 all: timer.o aes.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o \$(MODULES) inspircd.exe
1622
1623 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/base.h
1624         \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspsocket.o configreader.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o aes.o timer.o snomasks.o modes/modeclasses.a \$(MODULES)
1625 EOM
1626         }
1627
1628         print FH <<EOM;
1629
1630 cull_list.o: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1631         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1632
1633 snomasks.o: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1634         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1635
1636 command_parse.o: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1637         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1638
1639 userprocess.o: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1640         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1641
1642 socketengine.o: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1643         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1644
1645 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1646         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1647
1648 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1649         \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1650
1651 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1652         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1653
1654 mode.o: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES) modes/modeclasses.a
1655         \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS)
1656         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1657
1658 xline.o: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1659         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1660
1661 inspstring.o: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1662         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1663
1664 dns.o: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1665         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1666
1667 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1668         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1669
1670 configreader.o: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1671         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1672
1673 commands.o: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h $srcobjs
1674         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp $cmdobjs
1675
1676 dynamic.o: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1677         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1678
1679 users.o: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1680         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1681
1682 modules.o: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1683         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1684
1685 wildcard.o: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1686         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1687
1688 socket.o: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1689         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1690         
1691 inspsocket.o: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1692         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1693
1694 aes.o: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1695         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1696
1697 timer.o: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1698         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1699
1700 EOM
1701         foreach my $cmd (@cmdlist) {
1702                 print FH <<ITEM;
1703 cmd_$cmd.o: cmd_$cmd.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/commands/cmd_$cmd.h
1704         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1705 ITEM
1706         }
1707         close(FH);
1708 }
1709
1710 sub write_dynamic_makefile {
1711
1712         my $i = 0;
1713         my @cmdlist = ();
1714         opendir(DIRHANDLE, "src");
1715         foreach $name (sort readdir(DIRHANDLE)) {
1716                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1717                         $cmdlist[$i++] = $1;
1718                 }
1719         }
1720         closedir(DIRHANDLE);
1721
1722         my $cmdobjs = "";
1723         my $srcobjs = "";
1724         foreach my $cmd (@cmdlist) {
1725                 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1726                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1727         }
1728
1729         $se = "socketengine_select";
1730         if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1731                 $se = "socketengine_kqueue";
1732         }
1733         elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1734                 $se = "socketengine_epoll";
1735         }
1736
1737         open(FH,">src/Makefile") or die("Could not write src/Makefile");
1738         print FH <<EOM;
1739 # Insp Makefile :p
1740 #
1741 # (C) ChatSpike development team
1742 # Makefile by <Craig\@ChatSpike.net>
1743 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
1744 #
1745
1746 CC = im a cheezeball
1747
1748 CXXFLAGS = -I../include \${FLAGS}
1749 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1750 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1751
1752 all: libIRCDtimer.so libIRCDaes.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so libIRCDsnomasks.so inspircd
1753
1754 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h libIRCDtimer.so libIRCDaes.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDsnomasks.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so
1755         \$(CC) -I../include $extra -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so libIRCDuserprocess.so libIRCDcull_list.so libIRCDcommand_parse.so libIRCDaes.so libIRCDtimer.so libIRCDsnomasks.so
1756
1757 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1758         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1759         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1760
1761 libIRCDsnomasks.so: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1762          \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1763           \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1764
1765 libIRCDcommand_parse.so: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1766         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1767         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1768
1769 libIRCDcull_list.so: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1770         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1771         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1772
1773 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1774         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1775         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1776
1777 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1778         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1779         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1780
1781 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1782         \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1783         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1784
1785 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1786         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1787         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1788
1789 libIRCDmode.so: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1790         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1791         \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1792         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1793
1794 libIRCDxline.so: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1795         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1796         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1797
1798 libIRCDstring.so: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1799         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1800         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1801
1802 libIRCDasyncdns.so: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1803         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1804         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1805
1806 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1807         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1808         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1809
1810 libIRCDconfigreader.so: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1811         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1812         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1813
1814 libIRCDcommands.so: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1815         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1816         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o
1817
1818 libIRCDdynamic.so: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1819         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1820         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1821
1822 libIRCDusers.so: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1823         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1824         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1825
1826 libIRCDmodules.so: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1827         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1828         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1829
1830 libIRCDwildcard.so: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1831         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1832         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1833
1834 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1835         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1836         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1837
1838 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1839         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1840         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1841
1842 libIRCDaes.so: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1843         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1844         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDaes.so aes.o
1845
1846 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1847         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1848         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1849
1850 EOM
1851         foreach my $cmd (@cmdlist) {
1852                 print FH <<ITEM;
1853 cmd_$cmd.so: cmd_$cmd.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/commands/cmd_$cmd.h
1854         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1855         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o cmd_$cmd.so cmd_$cmd.o
1856
1857 ITEM
1858         }
1859         close(FH);
1860 }
1861
1862 sub showhelp
1863 {
1864         chomp($PWD = `pwd`);
1865         print "Usage: configure [options]
1866 Options: [defaults in brackets after descriptions]
1867
1868 When no options are specified, interactive
1869 configuration is started and you must specify
1870 any required values manually. If one or more
1871 options are specified, non-interactive configuration
1872 is started, and any omitted values are defaulted.
1873
1874 Arguments with a single \"-\" symbol, as in
1875 InspIRCd 1.0.x, are also allowed.
1876
1877   --disable-interactive        Sets no options intself, but
1878                                will disable any interactive prompting.
1879   --update                     Update makefiles and dependencies
1880   --modupdate                  Detect new modules and write makefiles
1881   --svnupdate {rebuild}        Update working copy via subversion
1882                                {and optionally rebuild it}
1883   --clean                      Remove .config.cache file and go interactive
1884   --enable-gnutls              Enable GnuTLS module [no]
1885   --enable-openssl             Enable OpenSSL module [no]
1886   --with-nick-length=[n]       Specify max. nick length [32]
1887   --with-channel-length=[n]    Specify max. channel length [64]
1888   --with-max-channels=[n]      Specify max. number of channels
1889                                a normal user may join [20]
1890   --with-max-oper-channels=[n] Specify max. number of channels
1891                                an irc operator may join [60]
1892   --with-max-clients=[n]       Specify maximum number of users
1893                                which may connect locally
1894   --enable-optimization=[n]    Optimize using -O[n] gcc flag
1895   --enable-epoll               Enable epoll() where supported [set]
1896   --enable-kqueue              Enable kqueue() where supported [set]
1897   --disable-epoll              Do not enable epoll(), fall back
1898                                to select() [not set]
1899   --disable-kqueue             Do not enable kqueue(), fall back
1900                                to select() [not set]
1901   --enable-ipv6                Build ipv6 native InspIRCd [no]
1902   --enable-remote-ipv6         Build with ipv6 support for remote
1903                                servers on the network [yes]
1904   --disable-remote-ipv6        Do not allow remote ipv6 servers [not set]
1905   --with-cc=[filename]         Use an alternative g++ binary to
1906                                build InspIRCd [g++]
1907   --with-ident-length=[n]      Specify max length of ident [12]
1908   --with-quit-length=[n]       Specify max length of quit [200]
1909   --with-topic-length=[n]      Specify max length of topic [350]
1910   --with-kick-length=[n]       Specify max length of kick [200]
1911   --with-gecos-length=[n]      Specify max length of gecos [150]
1912   --with-away-length=[n]       Specify max length of away [150]
1913   --with-max-modes=[n]         Specify max modes per line which
1914                                have parameters [20]
1915   --prefix=[directory]         Base directory to install into (if defined,
1916                                can automatically define config, module, bin
1917                                and library dirs as subdirectories of prefix)
1918                                [$PWD]
1919   --config-dir=[directory]     Config file directory for config and SSL certs
1920                                [$PWD/conf]
1921   --module-dir=[directory]     Modules directory for loadable modules
1922                                [$PWD/modules]
1923   --binary-dir=[directory]     Binaries directory for core binary
1924                                [$PWD/bin]
1925   --library-dir=[directory]    Library directory for core libraries
1926                                [$PWD/lib]
1927   --help                       Show this help text and exit
1928
1929 ";
1930         exit(0);
1931 }