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