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