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