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