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