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