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