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