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