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