]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
And fix typo
[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_fail 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                 $config{MAX_DESCRIPTORS} = $var;
620                 $continue = 1;
621                 print "\n";
622         }
623
624         my $continue = 0;
625         while (!$continue) {
626                 print "What is the maximum length of nicknames?\n";
627                 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
628                 chomp($var = <STDIN>);
629                 if ($var eq "") {
630                         $var = $config{NICK_LENGT};
631                 }
632                 if ($var =~ /^\d+$/) {
633                         # We don't care what the number is, set it and be on our way.
634                         $config{NICK_LENGT} = $var;
635                         $continue = 1;
636                         print "\n";
637                 } else {
638                         print "You must enter a number in this field. Please try again.\n\n";
639                 }
640         }
641
642         $continue = 0;
643         while (!$continue) {
644                 print "What is the maximum length of channel names?\n";
645                 print "[\033[1;32m$config{CHAN_LENGT}\033[0m] -> ";
646                 chomp($var = <STDIN>);
647                 if ($var eq "") {
648                         $var = $config{CHAN_LENGT};
649                 }
650                 if ($var =~ /^\d+$/) {
651                         # We don't care what the number is, set it and be on our way.
652                         $config{CHAN_LENGT} = $var;
653                         $continue = 1;
654                         print "\n";
655                 } else {
656                         print "You must enter a number in this field. Please try again.\n\n";
657                 }
658         }
659
660         $continue = 0;
661         while (!$continue) {
662                 print "What is the maximum number of channels a normal user may join at any one time?\n";
663                 print "[\033[1;32m$config{MAX_CHANNE}\033[0m] -> ";
664                 chomp($var = <STDIN>);
665                 if ($var eq "") {
666                         $var = $config{MAX_CHANNE};
667                 }
668                 if ($var =~ /^\d+$/) {
669                         # We don't care what the number is, set it and be on our way.
670                         $config{MAX_CHANNE} = $var;
671                         $continue = 1;
672                         print "\n";
673                 } else {
674                         print "You must enter a number in this field. Please try again.\n\n";
675                 }
676         }
677
678         $continue = 0;
679         while (!$continue) {
680                 print "What is the maximum number of channels an oper may join at any one time?\n";
681                 print "[\033[1;32m$config{MAX_OPERCH}\033[0m] -> ";
682                 chomp($var = <STDIN>);
683                 if ($var eq "") {
684                         $var = $config{MAX_OPERCH};
685                 }
686                 if ($var =~ /^\d+$/) {
687                         # We don't care what the number is, set it and be on our way.
688                         $config{MAX_OPERCH} = $var;
689                         $continue = 1;
690                         print "\n";
691                 }
692         }
693
694         $continue = 0;
695         while (!$continue) {
696                 print "What is the maximum number of mode changes in one line?\n";
697                 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
698                         chomp($var = <STDIN>);
699                 if ($var eq "") {
700                         $var = $config{MAXI_MODES};
701                 }
702                 if ($var =~ /^\d+$/) {
703                         # We don't care what the number is, set it and be on our way.
704                         $config{MAXI_MODES} = $var;
705                         $continue = 1;
706                         print "\n";
707                 } else {
708                         print "You must enter a number in this field. Please try again.\n\n";
709                 }
710         }
711
712         $continue = 0;
713         while (!$continue) {
714                 print "What is the maximum length of an ident (username)?\n";
715                 print "[\033[1;32m$config{MAX_IDENT}\033[0m] -> ";
716                 chomp($var = <STDIN>);
717                 if ($var eq "") {
718                         $var = $config{MAX_IDENT};
719                 }
720                 if ($var =~ /^\d+$/) {
721                         # We don't care what the number is, set it and be on our way.
722                         $config{MAX_IDENT} = $var;
723                         $continue = 1;
724                         print "\n";
725                 } else {
726                         print "You must enter a number in this field. Please try again.\n\n";
727                 }
728         }
729
730         $continue = 0;
731         while (!$continue) {
732                 print "What is the maximum length of a quit message?\n";
733                 print "[\033[1;32m$config{MAX_QUIT}\033[0m] -> ";
734                 chomp($var = <STDIN>);
735                 if ($var eq "") {
736                         $var = $config{MAX_QUIT};
737                 }
738                 if ($var =~ /^\d+$/) {
739                         # We don't care what the number is, set it and be on our way.
740                         $config{MAX_QUIT} = $var;
741                         $continue = 1;
742                         print "\n";
743                 } else {
744                         print "You must enter a number in this field. Please try again.\n\n";
745                 }
746         }
747
748         $continue = 0;
749         while (!$continue) {
750                 print "What is the maximum length of a channel topic?\n";
751                 print "[\033[1;32m$config{MAX_TOPIC}\033[0m] -> ";
752                 chomp($var = <STDIN>);
753                 if ($var eq "") {
754                         $var = $config{MAX_TOPIC};
755                 }
756                 if ($var =~ /^\d+$/) {
757                         # We don't care what the number is, set it and be on our way.
758                         $config{MAX_TOPIC} = $var;
759                         $continue = 1;
760                         print "\n";
761                 } else {
762                         print "You must enter a number in this field. Please try again.\n\n";
763                 }
764         }
765
766         $continue = 0;
767         while (!$continue) {
768                 print "What is the maximum length of a kick message?\n";
769                 print "[\033[1;32m$config{MAX_KICK}\033[0m] -> ";
770                 chomp($var = <STDIN>);
771                 if ($var eq "") {
772                         $var = $config{MAX_KICK};
773                 }
774                 if ($var =~ /^\d+$/) {
775                         # We don't care what the number is, set it and be on our way.
776                         $config{MAX_KICK} = $var;
777                         $continue = 1;
778                         print "\n";
779                 } else {
780                         print "You must enter a number in this field. Please try again.\n\n";
781                 }
782         }
783
784         $continue = 0;
785         while (!$continue) {
786                 print "What is the maximum length of a GECOS (real name) field?\n";
787                 print "[\033[1;32m$config{MAX_GECOS}\033[0m] -> ";
788                 chomp($var = <STDIN>);
789                 if ($var eq "") {
790                         $var = $config{MAX_GECOS};
791                 }
792                 if ($var =~ /^\d+$/) {
793                         # We don't care what the number is, set it and be on our way.
794                         $config{MAX_GECOS} = $var;
795                         $continue = 1;
796                         print "\n";
797                 } else {
798                         print "You must enter a number in this field. Please try again.\n\n";
799                 }
800         }
801
802         $continue = 0;
803         while (!$continue) {
804                 print "What is the maximum length of an away message?\n";
805                 print "[\033[1;32m$config{MAX_AWAY}\033[0m] -> ";
806                 chomp($var = <STDIN>);
807                 if ($var eq "") {
808                         $var = $config{MAX_AWAY};
809                 }
810                 if ($var =~ /^\d+$/) {
811                         # We don't care what the number is, set it and be on our way.
812                         $config{MAX_AWAY} = $var;
813                         $continue = 1;
814                         print "\n";
815                 } else {
816                         print "You must enter a number in this field. Please try again.\n\n";
817                 }
818         }
819 }
820
821 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
822 print "\033[0mBase install path:\033[1;32m\t\t$config{BASE_DIR}\033[0m\n";
823 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\033[0m\n";
824 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\033[0m\n";
825 print "\033[0mLibrary path:\033[1;32m\t\t\t$config{LIBRARY_DIR}\033[0m\n";
826 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\033[0m\n";
827 print "\033[0mMax User Channels:\033[1;32m\t\t$config{MAX_CHANNE}\033[0m\n";
828 print "\033[0mMax Oper Channels:\033[1;32m\t\t$config{MAX_OPERCH}\033[0m\n";
829 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\033[0m\n";
830 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\033[0m\n";
831 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\033[0m\n";
832 print "\033[0mMax ident length:\033[1;32m\t\t$config{MAX_IDENT}\033[0m\n";
833 print "\033[0mMax quit length:\033[1;32m\t\t$config{MAX_QUIT}\033[0m\n";
834 print "\033[0mMax topic length:\033[1;32m\t\t$config{MAX_TOPIC}\033[0m\n";
835 print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\033[0m\n";
836 print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\033[0m\n";
837 print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\033[0m\n";
838 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.x\033[0m\n";
839 # and not echo it out so we don't get some ricer fuck complaining
840 #print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
841 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
842 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n";
843 print "\033[0mIPv6 Support:\033[1;32m\t\t\t$config{IPV6}\033[0m\n";
844 print "\033[0mIPv6 to IPv4 Links:\033[1;32m\t\t$config{SUPPORT_IP6LINKS}\033[0m\n";
845 print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n";
846 print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n";
847
848 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
849 {
850         print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
851         exit(0);
852 }
853 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
854 {
855         print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
856         exit(0);
857 }
858
859 if ($config{USE_GNUTLS} eq "y") {
860         $failed = 0;
861         open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
862         close(TMP);
863         if ($failed) {
864                 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
865                 chdir("src/modules");
866                 system("ln -s extra/m_ssl_gnutls.cpp");
867                 system("ln -s extra/ssl_cert.h");
868                 chdir("../..");
869         }
870         getmodules();
871         if ($interactive)
872         {
873                 $failed = 0;
874                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
875                 close(TMP);
876                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
877                 close(TMP);
878                 if ($failed) {
879                         print "SSL Certificates Not found, Generating.. \n\n
880 *************************************************************
881 * Generating the Private Key may take some time, go grab a  *
882 * Coffee. Even better, to generate some more entropy if it  *
883 * is taking a while, open another console and type du / a   *
884 * few times and get that HD going :) Then answer the        *
885 * Questions which follow. If you are unsure, just hit enter *
886 *************************************************************\n\n";
887                         system("certtool --generate-privkey --outfile key.pem");
888                         system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
889                         print "\nCertificate generation complete, copying to config directory... ";
890                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
891                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
892                         print "Done.\n\n";
893                 } else {
894                         print "SSL Certificates found, skipping.\n\n"
895                 }
896         }
897         else
898         {
899                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
900         }
901 } elsif ($config{USE_OPENSSL} eq "y") {
902         $failed = 0;
903         open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
904         close(TMP);
905         if ($failed) {
906                 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
907                 chdir("src/modules");
908                 system("ln -s extra/m_ssl_openssl.cpp");
909                 system("ln -s extra/ssl_cert.h");
910                 chdir("../..");
911         }
912         getmodules();
913         $failed = 0;
914         if ($interactive)
915         {
916                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
917                 close(TMP);
918                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
919                 close(TMP);
920                 if ($failed) {
921                         print "SSL Certificates Not found, Generating.. \n\n
922 *************************************************************
923 * Generating the certificates may take some time, go grab a *
924 * coffee, or something.                                     *
925 *************************************************************\n\n";
926                         system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
927                         system("openssl dhparam -out dhparams.pem 1024");
928                         print "\nCertificate generation complete, copying to config directory... ";
929                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
930                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
931                         system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
932                         print "Done.\n\n";
933                 } else {
934                         print "SSL Certificates found, skipping.\n\n"
935                 }
936         }
937         else
938         {
939                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
940         }
941 }
942 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
943         print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
944 }
945
946 getosflags();
947 makecache();
948 writefiles(1);
949
950 print "\n\n";
951 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
952 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
953         print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
954         print "load the required modules in your config. This configure process\n";
955         print "has just prepared these modules to be compiled for you, and has not\n";
956         print "configured them to be compiled into the core of the ircd.\n";
957 }
958 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
959 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
960         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";
961 }
962
963 if ($config{GCCVER} < "3") {
964         print <<FOO2;
965 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
966 GCC 2.x series compilers only had partial (read as broken) C++ support, and
967 your compile will most likely fail horribly! If you have any problems, do NOT
968 report them to the bugtracker or forums without first upgrading your compiler
969 to a newer 3.x or 4.x (or whatever is available currently) version.
970 FOO2
971 }
972
973 ################################################################################
974 #                              HELPER FUNCTIONS                                #
975 ################################################################################
976 sub getcache {
977         # Retrieves the .config.cache file, and loads values into the main config hash.
978         open(CACHE, ".config.cache") or return undef;
979         while (<CACHE>) {
980                 chomp;
981                 # Ignore Blank lines, and comments..
982                 next if /^\s*$/;
983                 next if /^\s*#/;
984                 my ($key, $value) = split("=", $_);
985                 $value =~ /^\"(.*)\"$/;
986                 # Do something with data here!
987                 $config{$key} = $1;
988         }
989         close(CONFIG);
990         return "true";
991 }
992
993 sub makecache {
994         # Dump the contents of %config
995         print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
996         open(FILEHANDLE, ">.config.cache");
997         foreach $key (keys %config) {
998                 print FILEHANDLE "$key=\"$config{$key}\"\n";
999         }
1000         close(FILEHANDLE);
1001 }
1002
1003 sub dir_check {
1004         my ($desc, $hash_key) = @_;
1005         my $complete = 0;
1006         while (!$complete) {
1007                 print "In what directory $desc?\n";
1008                 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
1009                 chomp($var = <STDIN>);
1010                 if ($var eq "") {
1011                         $var = $config{$hash_key};
1012                 }
1013                 if ($var =~ /^\~\/(.+)$/) {
1014                         # Convert it to a full path..
1015                         $var = resolve_directory($ENV{HOME} . "/" . $1);
1016                 }
1017                 elsif ((($config{OSNAME} == "MINGW32") and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1018                 {
1019                         # Assume relative Path was given.. fill in the rest.
1020                         $var = $this . "/$var";
1021                 }
1022                 
1023                 $var = resolve_directory($var); 
1024                 if (! -e $var) {
1025                         print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
1026                         chomp($tmp = <STDIN>);
1027                         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1028                                 # Attempt to Create the Dir..
1029                                 
1030                                 system("mkdir -p \"$var\" >> /dev/null 2>&1");
1031                                 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
1032                                 if ($chk != 0) {
1033                                         print "Unable to create directory. ($var)\n\n";
1034                                         # Restart Loop..
1035                                         next;
1036                                 }
1037                         } else {
1038                                 # They said they don't want to create, and we can't install there.
1039                                 print "\n\n";
1040                                 next;
1041                         }
1042                 } else {
1043                         if (!is_dir($var)) {
1044                                 # Target exists, but is not a directory.
1045                                 print "File $var exists, but is not a directory.\n\n";
1046                                 next;
1047                         }
1048                 }
1049                 # Either Dir Exists, or was created fine.
1050                 $config{$hash_key} = $var;
1051                 $complete = 1;
1052                 print "\n";
1053         }
1054 }
1055
1056 sub getosflags {
1057         if ($config{OSNAME} =~ /BSD$/) {
1058                 $config{LDLIBS} = "-lstdc++";
1059                 $config{FLAGS}  = "-fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1060                 $config{MAKEPROG} = "gmake";
1061                 if ($config{OSNAME} eq "OpenBSD") {
1062                         chomp($foo = `eg++ -dumpversion | cut -c 1`);
1063                         # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1064                         # if theyre not running this, configure lets the build continue but they probably wont manage to
1065                         # compile as this standard version is 2.95.3!
1066                         if ($foo ne "") {
1067                                 $config{CC} = "eg++";
1068                                 chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1069                         }
1070                         return "OpenBSD";
1071                 }
1072                 return $config{OSNAME};
1073         } else {
1074                 $config{LDLIBS} = "-ldl -lstdc++";
1075                 $config{FLAGS}  = "-fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1076                 $config{MAKEPROG} = "make";
1077                 if ($config{OSNAME} =~ /CYGWIN/) {
1078                         $config{FLAGS}  = "-Wall -Woverloaded-virtual $config{OPTIMISATI}";
1079                         $config{LDLIBS} = "";
1080                         $config{MAKEPROG} = "/usr/bin/make";
1081                         $config{MAKEORDER} = "ircd mods";
1082                         return "Cygwin";
1083                 } elsif ($config{OSNAME} eq "CYG-STATIC") {
1084                         $config{FLAGS} = "-Wall -Woverloaded-virtual $config{OPTIMISATI}";
1085                         $config{LDLIBS} = "";
1086                         $config{MAKEPROG} = "/usr/bin/make";
1087                         $config{MAKEORDER} = "mods ircd";
1088                         $config{STATICLIBS} = "modules/mods.a";
1089                         $config{STATIC_LINK} = "yes";
1090                         return "Cygwin-Static";
1091                 }
1092                 return "Linux";
1093         }
1094         
1095         if ($config{OSNAME} =~ /SunOS/)
1096         {
1097                 # solaris/sunos needs these
1098                 # socket = bsd sockets api
1099                 # nsl = dns stuff
1100                 # rt = POSIX realtime extensions
1101                 # resolv = inet_aton only (why isnt this in nsl?!)
1102                 $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
1103                 return "Solaris";
1104         }
1105         
1106         if($config{OSNAME} eq "MINGW32")
1107         {
1108                 # All code is position-independent on windows
1109                 $config{FLAGS} =~ s/-fPIC //;
1110                 return "MinGW";
1111         }
1112 }
1113
1114 sub is_dir {
1115         my ($path) = @_;
1116         if (chdir($path)) {
1117                 chdir($this);
1118                 return 1;
1119         } else {
1120                 # Just in case..
1121                 chdir($this);
1122                 return 0;
1123         }
1124 }
1125
1126 sub getmodules {
1127         my $i = 0;
1128         print "Detecting modules ";
1129         opendir(DIRHANDLE, "src/modules");
1130         foreach $name (sort readdir(DIRHANDLE)) {
1131                 if ($name =~ /^m_(.+)\.cpp$/)
1132                 {
1133                         $mod = $1;
1134                         if ($mod !~ /_static$/) {
1135                                 $modlist[$i++] = $mod;
1136                                 print ".";
1137                         }
1138                 }
1139         }
1140         closedir(DIRHANDLE);
1141         print "\nOk, $i modules.\n";
1142 }
1143
1144 sub getrevision {
1145         if ($no_svn) {
1146                 return "0";
1147         }
1148         my $data = `svn info`;
1149         
1150         if ($data eq "") {
1151                 $no_svn = 1;
1152                 $rev = "0";
1153                 return $rev;
1154         }
1155         $data =~ /Revision: (\d+)/;
1156         my $rev = $1;
1157         if (!defined($rev)) {
1158                 $rev = "0";
1159         }
1160         return $rev;
1161 }
1162
1163 sub writefiles {
1164         my($writeheader) = @_;
1165         # First File.. inspircd_config.h
1166         chomp(my $incos = `uname -n -s -r`);
1167         chomp(my $version = `sh ./src/version.sh`);
1168         chomp(my $revision = getrevision());
1169         $version = "$version(r$revision)";
1170         chomp(my $revision2 = getrevision());
1171         if ($writeheader == 1)
1172         {
1173                 print "Writing \033[1;32minspircd_config.h\033[0m\n";
1174                 open(FILEHANDLE, ">include/inspircd_config.h");
1175                 my $NL = $config{NICK_LENGT}+1;
1176                 my $CL = $config{CHAN_LENGT}+1;
1177                 print FILEHANDLE <<EOF;
1178 /* Auto generated by configure, do not modify! */
1179 #ifndef __CONFIGURATION_AUTO__
1180 #define __CONFIGURATION_AUTO__
1181
1182 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1183 #define MOD_PATH "$config{MODULE_DIR}"
1184 #define VERSION "$version"
1185 #define REVISION "$revision2"
1186 #define MAXCLIENTS $config{MAX_CLIENT}
1187 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1188 #define NICKMAX $NL
1189 #define CHANMAX $CL
1190 #define MAXCHANS $config{MAX_CHANNE}
1191 #define OPERMAXCHANS $config{MAX_OPERCH}
1192 #define MAXMODES $config{MAXI_MODES}
1193 #define IDENTMAX $config{MAX_IDENT}
1194 #define MAXQUIT $config{MAX_QUIT}
1195 #define MAXTOPIC $config{MAX_TOPIC}
1196 #define MAXKICK $config{MAX_KICK}
1197 #define MAXGECOS $config{MAX_GECOS}
1198 #define MAXAWAY $config{MAX_AWAY}
1199 #define OPTIMISATION $config{OPTIMITEMP}
1200 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1201 #define SYSTEM "$incos"
1202 #define MAXBUF 514
1203 EOF
1204                 if ($config{OSNAME} =~ /SunOS/) {
1205                         print FILEHANDLE "#define IS_SOLARIS\n";
1206                 }
1207                 if ($config{OSNAME} =~ /CYGWIN/) {
1208                         print FILEHANDLE "#define IS_CYGWIN\n";
1209                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE        1024\n#endif\n";
1210                 }
1211                 if ($config{OSNAME} eq "MINGW32") {
1212                         print FILEHANDLE "#define IS_MINGW\n";
1213                 }
1214                 if ($config{OSNAME} eq "CYG-STATIC") {
1215                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE    1024\n#endif\n";
1216                 }
1217                 if ($config{STATIC_LINK} eq "yes") {
1218                         print FILEHANDLE "#define STATIC_LINK\n";
1219                 }
1220                 if ($config{GCCVER} >= 3) {
1221                         print FILEHANDLE "#define GCC3\n";
1222                 }
1223                 if ($config{HAS_STRLCPY} eq "true") {
1224                         print FILEHANDLE "#define HAS_STRLCPY\n";
1225                 }
1226                 if ($config{HAS_STDINT} eq "true") {
1227                         print FILEHANDLE "#define HAS_STDINT\n";
1228                 }
1229                 if ($config{IPV6} =~ /y/i) {
1230                         print FILEHANDLE "#define IPV6\n";
1231                 }
1232                 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1233                         print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1234                 }
1235                 my $use_hiperf = 0;
1236                 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1237                         print FILEHANDLE "#define USE_KQUEUE\n";
1238                         $se = "socketengine_kqueue";
1239                         $use_hiperf = 1;
1240                 }
1241                 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1242                         print FILEHANDLE "#define USE_EPOLL\n";
1243                         $se = "socketengine_epoll";
1244                         $use_hiperf = 1;
1245                 }
1246                 # user didn't choose either epoll or select for their OS.
1247                 # default them to USE_SELECT (ewwy puke puke)
1248                 if (!$use_hiperf) {
1249                         print FILEHANDLE "#define USE_SELECT\n";
1250                         $se = "socketengine_select";
1251                 }
1252                 print FILEHANDLE "\n#endif\n";
1253                 close(FILEHANDLE);
1254         }
1255
1256         if ($writeheader)
1257         {
1258                 open(FILEHANDLE, ">include/inspircd_se_config.h");
1259                 print FILEHANDLE <<EOF;
1260 /* Auto generated by configure, do not modify or commit to svn! */
1261 #ifndef __CONFIGURATION_SOCKETENGINE__
1262 #define __CONFIGURATION_SOCKETENGINE__
1263
1264 #include "$se.h"
1265
1266 #endif
1267 EOF
1268                 close(FILEHANDLE);
1269         }
1270
1271
1272         # Create a Modules List..
1273         my $modules = "";
1274         foreach $i (@modlist)
1275         {
1276                 if ($config{STATIC_LINK} eq "yes") {
1277                         $modules .= "m_".$i.".o ";
1278                 }
1279                 else {
1280                         $modules .= "m_".$i.".so ";
1281                 }
1282         }
1283         chomp($modules);   # Remove Redundant whitespace..
1284
1285
1286         # Write all .in files.
1287         my $tmp = "";
1288         my $file = "";
1289         my $exe = "inspircd";
1290
1291         if ($config{OSNAME} =~ /CYGWIN/) {
1292                 $exe = "inspircd.exe";
1293         }
1294
1295         opendir(DIRHANDLE, $this);
1296
1297         foreach $name (sort readdir(DIRHANDLE)) {
1298                 if ($name =~ /^\.(.+)\.inc$/) {
1299                         $file = $1;
1300                         # All .name.inc files need parsing!
1301                         $tmp = "";
1302                         open(FILEHANDLE, ".$file.inc");
1303                         while (<FILEHANDLE>) {
1304                                 $tmp .= $_;
1305                         }
1306                         close(FILEHANDLE);
1307
1308                         $tmp =~ s/\@CC\@/$config{CC}/;
1309                         $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1310                         $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1311                         $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1312                         $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1313                         $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1314                         $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1315                         $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1316                         $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1317                         $tmp =~ s/\@MODULES\@/$modules/;
1318                         $tmp =~ s/\@EXECUTABLE\@/$exe/;
1319                         $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1320                         $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
1321
1322                         print "Writing \033[1;32m$file\033[0m\n";
1323                         open(FILEHANDLE, ">$file");
1324                         print FILEHANDLE $tmp;
1325                 }
1326         }
1327         closedir(DIRHANDLE);
1328
1329         # Make inspircd executable!
1330         chmod 0744, 'inspircd';
1331
1332         if ($config{STATIC_LINK} eq "yes") {
1333                 print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
1334                 write_static_makefile();
1335                 write_static_modules_makefile();
1336         } elsif ($config{OSNAME} =~ /CYGWIN/) {
1337                 print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
1338                 write_static_makefile();
1339                 write_dynamic_modules_makefile();
1340         } else {
1341                 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1342                 write_dynamic_makefile();
1343                 write_dynamic_modules_makefile();
1344         }
1345 }
1346
1347 sub getcompilerflags {
1348         my ($file) = @_;
1349         open(FLAGS, $file);
1350         while (<FLAGS>) {
1351         if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
1352                 close(FLAGS);
1353                         return $1;
1354                 }
1355         }
1356         close(FLAGS);
1357         return undef;
1358 }
1359
1360 sub getlinkerflags {
1361         my ($file) = @_;
1362         open(FLAGS, $file);
1363         while (<FLAGS>) {
1364                 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
1365                         close(FLAGS);
1366                         return $1;
1367                 }
1368         }
1369         close(FLAGS);
1370         return undef;
1371 }
1372
1373 sub getdependencies {
1374         my ($file) = @_;
1375         open(FLAGS, $file);
1376         while (<FLAGS>) {
1377                 if ($_ =~ /^\/\* \$ModDep: (.+) \*\/$/) {
1378                         close(FLAGS);
1379                         return $1;
1380                 }
1381         }
1382         close(FLAGS);
1383         return undef;
1384 }
1385
1386 sub resolve_directory {
1387         use File::Spec;
1388         return File::Spec->rel2abs($_[0]);
1389 }
1390
1391 sub yesno {
1392         my ($flag,$prompt) = @_;
1393         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
1394         chomp($tmp = <STDIN>);
1395         if ($tmp eq "") { $tmp = $config{$flag} }
1396
1397         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1398                 $config{$flag} = "y";
1399         } else {
1400                 $config{$flag} = "n";
1401         }
1402         return;
1403 }
1404
1405 sub write_static_modules_makefile {
1406         # Modules Makefile..
1407         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1408         open(FILEHANDLE, ">src/modules/Makefile");
1409
1410         ###
1411         # Module Makefile Header
1412         ###
1413         print FILEHANDLE <<EOF;
1414 # (C) ChatSpike development team
1415 # Makefile by <Craig\@ChatSpike.net>
1416 # Many Thanks to Andrew Church <achurch\@achurch.org>
1417 #    for assisting with making this work right.
1418 #
1419 # Automatically Generated by ./configure to add a modules
1420 # please run ./configure --update
1421
1422 all: \$(MODULES)
1423
1424 EOF
1425         ###
1426         # End Module Makefile Header
1427         ###
1428
1429         # Create a Modules List..
1430         my $modules = "";
1431         my $cmflags = "";
1432         my $liflags = "";
1433
1434         open(MODLIST,">include/modlist.h");
1435
1436         ###
1437         # Include File Header
1438         ###
1439         print MODLIST <<HEADER;
1440 // Generated automatically by configure. DO NOT EDIT!
1441
1442 #ifndef __SYMBOLS__H_CONFIGURED__
1443 #define __SYMBOLS__H_CONFIGURED__
1444
1445 HEADER
1446         ###
1447         # End Include File Header
1448         ###
1449
1450         # Place Module List into Include
1451         foreach $i (@modlist) {
1452                 if ($i !~ /_static$/) {
1453                         print MODLIST "extern \"C\" void * $i\_init (void);\n";
1454                 }
1455         }
1456         print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
1457
1458         ###
1459         # Build Module Crap
1460         ###
1461         foreach $i (@modlist)
1462         {
1463                 if ($i !~ /_static$/) {
1464                         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1465                         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1466                         $deps = getdependencies("src/modules/m_".$i.".cpp");
1467
1468                         ###
1469                         # Write Entry to the Makefile
1470                         ###
1471                         print FILEHANDLE <<EOCHEESE;
1472 m_$i.o: .m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h $deps
1473         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c .m_$i\_static.cpp
1474         mv .m_$i\_static.o ../m_$i.o
1475
1476 EOCHEESE
1477                         ###
1478                         # End Write Entry to the MakeFile
1479                         ###
1480                         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
1481                         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
1482                         open(MUNGED,">src/modules/.m_".$i."_static.cpp") or die("Could not create .m_".$i."_static.cpp");
1483                         while (chomp($a = <MODULE>)) { 
1484                                 $a =~ s/init_module/$i\_init/g;
1485                                 print MUNGED "$a\n";
1486                         }
1487                         close(MODULE);
1488                         close(MUNGED);
1489                         print MODLIST <<EOENT;
1490 {"m_$i.so",\&$i\_init},
1491 EOENT
1492                         print "done\n";
1493                 }
1494         }
1495         print MODLIST "{0}};\n\n#endif\n";
1496         close(MODLIST);
1497 }
1498
1499 sub write_dynamic_modules_makefile {
1500         # Modules Makefile..
1501         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1502         open(FILEHANDLE, ">src/modules/Makefile");
1503         my $extra = "";
1504
1505         if ($config{OSNAME} =~ /CYGWIN/) {
1506                 $extra = "../inspircd.dll.a";
1507         }
1508
1509 ###
1510 # Module Makefile Header
1511 ###
1512         print FILEHANDLE <<EOF;
1513 # (C) ChatSpike development team
1514 # Makefile by <Craig\@ChatSpike.net>
1515 # Many Thanks to Andrew Church <achurch\@achurch.org>
1516 #    for assisting with making this work right.
1517 #
1518 # Automatically Generated by ./configure to add a modules
1519 # please run ./configure -update or ./configure -modupdate
1520
1521 all: \$(MODULES)
1522
1523 EOF
1524         ###
1525         # End Module Makefile Header
1526         ###
1527
1528         # Create a Modules List..
1529         my $modules = "";
1530         my $cmflags = "";
1531         my $liflags = "";
1532         my $crud = "";
1533
1534         foreach $i (@modlist) {
1535         ###
1536         # Write Entry to the MakeFile
1537         ###
1538         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1539         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1540         $deps = getdependencies("src/modules/m_".$i.".cpp");
1541         print FILEHANDLE <<EOCHEESE;
1542 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
1543         \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
1544         \$(CC) \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
1545
1546 EOCHEESE
1547         $crud = $crud . "       install -m 0700 m_$i.so \$(MODPATH)\n";
1548 ###
1549         # End Write Entry to the MakeFile
1550         ###
1551         }
1552         print FILEHANDLE "modinst:\n    \@echo \"Installing modules...\"\n" . $crud;
1553 }
1554
1555
1556 sub write_static_makefile {
1557         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
1558         my $i = 0;
1559         my @cmdlist = ();
1560         opendir(DIRHANDLE, "src");
1561         foreach $name (sort readdir(DIRHANDLE)) {
1562                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1563                         $cmdlist[$i++] = $1;
1564                 }
1565         }
1566         closedir(DIRHANDLE);
1567         my $cmdobjs = "";
1568         my $srcobjs = "";
1569         foreach my $cmd (@cmdlist) {
1570                 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1571                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1572         }
1573         print FH <<EOM;
1574 # Insp Makefile :p
1575 #
1576 # (C) ChatSpike development team
1577 # Makefile by <Craig\@ChatSpike.net>
1578 # Makefile version 2 (statically linked core) by <brain\@inspircd.org>
1579 #
1580
1581 CC = im a cheezeball
1582
1583 CXXFLAGS = -I../include \${FLAGS}
1584 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1585 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1586
1587 EOM
1588
1589 $se = "socketengine_select";
1590 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1591         $se = "socketengine_kqueue";
1592 }       
1593 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1594         $se = "socketengine_epoll";
1595 }
1596
1597         ###
1598         # This next section is for cygwin dynamic module builds.
1599         # Basically, what we do, is build the inspircd core as a library
1600         # then the main executable uses that. the library is capable of
1601         # loading / unloading the modules dynamically :)
1602         # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
1603         # make this work :)
1604         ###
1605
1606         if ($config{OSNAME} =~ /CYGWIN/) {
1607                 print FH <<EOM;
1608 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
1609
1610 inspircd.exe: inspircd.dll.a
1611         \$(CC) -o \$@ \$^
1612
1613 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
1614         \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
1615 EOM
1616         } else {
1617                 print FH <<EOM;
1618 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
1619
1620 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
1621         \$(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)
1622 EOM
1623         }
1624
1625         print FH <<EOM;
1626
1627 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
1628         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1629
1630 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
1631         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1632
1633 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
1634         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1635
1636 userprocess.o: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1637         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1638
1639 socketengine.o: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1640         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1641
1642 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1643         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1644
1645 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1646         \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1647
1648 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1649         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1650
1651 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
1652         \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS)
1653         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1654
1655 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
1656         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1657
1658 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
1659         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1660
1661 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
1662         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1663
1664 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1665         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1666
1667 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
1668         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1669
1670 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
1671         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp $cmdobjs
1672
1673 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
1674         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1675
1676 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
1677         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1678
1679 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
1680         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1681
1682 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
1683         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1684
1685 socket.o: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1686         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1687         
1688 inspsocket.o: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1689         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1690
1691 aes.o: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1692         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1693
1694 timer.o: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1695         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1696
1697 EOM
1698         foreach my $cmd (@cmdlist) {
1699                 print FH <<ITEM;
1700 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
1701         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1702 ITEM
1703         }
1704         close(FH);
1705 }
1706
1707 sub write_dynamic_makefile {
1708
1709         my $i = 0;
1710         my @cmdlist = ();
1711         opendir(DIRHANDLE, "src");
1712         foreach $name (sort readdir(DIRHANDLE)) {
1713                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1714                         $cmdlist[$i++] = $1;
1715                 }
1716         }
1717         closedir(DIRHANDLE);
1718
1719         my $cmdobjs = "";
1720         my $srcobjs = "";
1721         foreach my $cmd (@cmdlist) {
1722                 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1723                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1724         }
1725
1726         $se = "socketengine_select";
1727         if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1728                 $se = "socketengine_kqueue";
1729         }
1730         elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1731                 $se = "socketengine_epoll";
1732         }
1733
1734         open(FH,">src/Makefile") or die("Could not write src/Makefile");
1735         print FH <<EOM;
1736 # Insp Makefile :p
1737 #
1738 # (C) ChatSpike development team
1739 # Makefile by <Craig\@ChatSpike.net>
1740 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
1741 #
1742
1743 CC = im a cheezeball
1744
1745 CXXFLAGS = -I../include \${FLAGS}
1746 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1747 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1748
1749 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
1750
1751 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
1752         \$(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
1753
1754 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1755         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1756         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1757
1758 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
1759          \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1760           \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1761
1762 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
1763         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1764         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1765
1766 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
1767         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1768         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1769
1770 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1771         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1772         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1773
1774 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1775         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1776         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1777
1778 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1779         \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1780         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1781
1782 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1783         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1784         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1785
1786 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)
1787         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1788         \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1789         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1790
1791 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
1792         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1793         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1794
1795 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
1796         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1797         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1798
1799 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
1800         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1801         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1802
1803 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1804         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1805         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1806
1807 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
1808         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1809         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1810
1811 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
1812         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1813         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o
1814
1815 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
1816         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1817         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1818
1819 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
1820         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1821         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1822
1823 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
1824         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1825         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1826
1827 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
1828         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1829         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1830
1831 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1832         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1833         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1834
1835 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1836         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1837         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1838
1839 libIRCDaes.so: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1840         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1841         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDaes.so aes.o
1842
1843 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1844         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1845         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1846
1847 EOM
1848         foreach my $cmd (@cmdlist) {
1849                 print FH <<ITEM;
1850 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
1851         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1852         \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o cmd_$cmd.so cmd_$cmd.o
1853
1854 ITEM
1855         }
1856         close(FH);
1857 }
1858
1859 sub showhelp
1860 {
1861         chomp($PWD = `pwd`);
1862         print "Usage: configure [options]
1863
1864 *** NOTE: NON-INTERACTIVE CONFIGURE IS *NOT* SUPPORTED BY THE ***
1865 *** INSPIRCD DEVELOPMENT TEAM. DO NOT ASK FOR HELP REGARDING  ***
1866 ***     NON-INTERACTIVE CONFIGURE ON THE FORUMS OR ON IRC!    ***
1867
1868 Options: [defaults in brackets after descriptions]
1869
1870 When no options are specified, interactive
1871 configuration is started and you must specify
1872 any required values manually. If one or more
1873 options are specified, non-interactive configuration
1874 is started, and any omitted values are defaulted.
1875
1876 Arguments with a single \"-\" symbol, as in
1877 InspIRCd 1.0.x, are also allowed.
1878
1879   --disable-interactive        Sets no options intself, but
1880                                will disable any interactive prompting.
1881   --update                     Update makefiles and dependencies
1882   --modupdate                  Detect new modules and write makefiles
1883   --svnupdate {rebuild}        Update working copy via subversion
1884                                {and optionally rebuild it}
1885   --clean                      Remove .config.cache file and go interactive
1886   --enable-gnutls              Enable GnuTLS module [no]
1887   --enable-openssl             Enable OpenSSL module [no]
1888   --with-nick-length=[n]       Specify max. nick length [32]
1889   --with-channel-length=[n]    Specify max. channel length [64]
1890   --with-max-channels=[n]      Specify max. number of channels
1891                                a normal user may join [20]
1892   --with-max-oper-channels=[n] Specify max. number of channels
1893                                an irc operator may join [60]
1894   --with-max-clients=[n]       Specify maximum number of users
1895                                which may connect locally
1896   --enable-optimization=[n]    Optimize using -O[n] gcc flag
1897   --enable-epoll               Enable epoll() where supported [set]
1898   --enable-kqueue              Enable kqueue() where supported [set]
1899   --disable-epoll              Do not enable epoll(), fall back
1900                                to select() [not set]
1901   --disable-kqueue             Do not enable kqueue(), fall back
1902                                to select() [not set]
1903   --enable-ipv6                Build ipv6 native InspIRCd [no]
1904   --enable-remote-ipv6         Build with ipv6 support for remote
1905                                servers on the network [yes]
1906   --disable-remote-ipv6        Do not allow remote ipv6 servers [not set]
1907   --with-cc=[filename]         Use an alternative g++ binary to
1908                                build InspIRCd [g++]
1909   --with-ident-length=[n]      Specify max length of ident [12]
1910   --with-quit-length=[n]       Specify max length of quit [200]
1911   --with-topic-length=[n]      Specify max length of topic [350]
1912   --with-kick-length=[n]       Specify max length of kick [200]
1913   --with-gecos-length=[n]      Specify max length of gecos [150]
1914   --with-away-length=[n]       Specify max length of away [150]
1915   --with-max-modes=[n]         Specify max modes per line which
1916                                have parameters [20]
1917   --prefix=[directory]         Base directory to install into (if defined,
1918                                can automatically define config, module, bin
1919                                and library dirs as subdirectories of prefix)
1920                                [$PWD]
1921   --config-dir=[directory]     Config file directory for config and SSL certs
1922                                [$PWD/conf]
1923   --module-dir=[directory]     Modules directory for loadable modules
1924                                [$PWD/modules]
1925   --binary-dir=[directory]     Binaries directory for core binary
1926                                [$PWD/bin]
1927   --library-dir=[directory]    Library directory for core libraries
1928                                [$PWD/lib]
1929   --help                       Show this help text and exit
1930
1931 ";
1932         exit(0);
1933 }