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