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