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