2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2010 The InspIRCd Development Team
6 # http://wiki.inspircd.org/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
41 # NON-EDITABLE VARIABLES
43 ###############################################################################################
45 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
46 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
47 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
48 $opt_system, $opt_uid);
50 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir);
54 sub enable_extras (@);
56 sub disable_extras (@);
59 my @opt_disableextras;
62 'enable-gnutls' => \$opt_use_gnutls,
63 'rebuild' => \$opt_rebuild,
64 'system' => \$opt_system,
66 'enable-openssl' => \$opt_use_openssl,
67 'disable-interactive' => \$opt_nointeractive,
68 'enable-ports' => \$opt_ports,
69 'enable-epoll' => \$opt_epoll,
70 'enable-kqueue' => \$opt_kqueue,
71 'disable-ports' => \$opt_noports,
72 'disable-epoll' => \$opt_noepoll,
73 'disable-kqueue' => \$opt_nokqueue,
74 'disable-ipv6' => \$opt_noipv6,
75 'with-cc=s' => \$opt_cc,
76 'with-maxbuf=i' => \$opt_maxbuf,
77 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
78 'prefix=s' => \$opt_base_dir,
79 'config-dir=s' => \$opt_config_dir,
80 'module-dir=s' => \$opt_module_dir,
81 'binary-dir=s' => \$opt_binary_dir,
82 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
83 'help' => sub { showhelp(); },
84 'update' => sub { update(); },
85 'clean' => sub { clean(); },
86 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
87 'enable-extras=s@' => \@opt_enableextras, # ^
88 'disable-extras=s@' => \@opt_disableextras, # ^
89 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
90 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
93 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
94 @opt_enableextras = split /,/, join(',', @opt_enableextras);
95 @opt_disableextras = split /,/, join(',', @opt_disableextras);
96 enable_extras(@opt_enableextras);
97 disable_extras(@opt_disableextras);
99 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
103 our $interactive = !(
104 (defined $opt_base_dir) ||
105 (defined $opt_config_dir) ||
106 (defined $opt_module_dir) ||
107 (defined $opt_base_dir) ||
108 (defined $opt_binary_dir) ||
109 (defined $opt_nointeractive) ||
111 (defined $opt_noipv6) ||
112 (defined $opt_kqueue) ||
113 (defined $opt_epoll) ||
114 (defined $opt_ports) ||
115 (defined $opt_use_openssl) ||
116 (defined $opt_nokqueue) ||
117 (defined $opt_noepoll) ||
118 (defined $opt_noports) ||
119 (defined $opt_maxbuf) ||
120 (defined $opt_system) ||
121 (defined $opt_uid) ||
122 (defined $opt_use_gnutls) ||
123 (defined $opt_freebsd_port)
126 chomp(our $topdir = getcwd());
127 our $this = resolve_directory($topdir); # PWD, Regardless.
128 our @modlist = (); # Declare for Module List..
129 our %config = (); # Initiate Configuration Hash..
130 $config{ME} = resolve_directory($topdir); # Present Working Directory
132 $config{BASE_DIR} = $config{ME}."/run";
134 if (defined $opt_base_dir) {
135 $config{BASE_DIR} = $opt_base_dir;
136 } elsif (defined $opt_system || defined $opt_uid) {
137 $config{BASE_DIR} = '/var/lib/inspircd';
140 if (defined $opt_system || defined $opt_uid) {
141 $config{UID} = $opt_uid || 'ircd';
142 $config{CONFIG_DIR} = '/etc/inspircd';
143 $config{MODULE_DIR} = '/usr/lib/inspircd';
144 $config{BINARY_DIR} = '/usr/sbin/';
145 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
148 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
149 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
150 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
151 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
154 if (defined $opt_config_dir) {
155 $config{CONFIG_DIR} = $opt_config_dir;
157 if (defined $opt_module_dir) {
158 $config{MODULE_DIR} = $opt_module_dir;
160 if (defined $opt_binary_dir) {
161 $config{BINARY_DIR} = $opt_binary_dir;
163 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
165 if (defined $opt_freebsd_port)
167 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
168 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
169 $config{USE_FREEBSD_BASE_SSL} = "n";
173 if ($^O eq "freebsd")
175 # default: use base ssl
176 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
177 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
181 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
182 $config{HAS_OPENSSL_PORT} = "";
186 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
187 chomp(our $openssl_ver = $config{HAS_OPENSSL});
188 $config{USE_GNUTLS} = "n";
189 if (defined $opt_use_gnutls)
191 $config{USE_GNUTLS} = "y"; # Use gnutls.
193 $config{USE_OPENSSL} = "n"; # Use openssl.
194 if (defined $opt_use_openssl)
196 $config{USE_OPENSSL} = "y";
199 if (!defined $opt_disable_debug) {
200 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
202 $config{OPTIMISATI} = "-O2";
205 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
206 $config{HAS_STDINT} = "false"; # stdint.h check
207 $config{USE_KQUEUE} = "y"; # kqueue enabled
208 if (defined $opt_nokqueue) {
209 $config{USE_KQUEUE} = "n";
211 $config{USE_POLL} = "y"; # poll enabled
212 $config{USE_EPOLL} = "y"; # epoll enabled
213 if (defined $opt_noepoll)
215 $config{USE_EPOLL} = "n";
217 $config{USE_PORTS} = "y"; # epoll enabled
218 if (defined $opt_noports)
220 $config{USE_PORTS} = "n";
222 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
223 $config{OSNAME} = $^O; # Operating System Name
224 $config{IS_DARWIN} = "NO"; # Is OSX?
225 $config{STARTSCRIPT} = "inspircd"; # start script?
226 $config{DESTINATION} = "BASE"; # Is target path.
227 if ($config{OSNAME} =~ /darwin/i)
229 $config{IS_DARWIN} = "YES";
230 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
232 $config{CC} = "g++"; # C++ compiler
235 $config{CC} = $opt_cc;
237 our $exec = $config{CC} . " -dumpversion | cut -c 1";
238 chomp($config{GCCVER} = `$exec`); # Major GCC Version
239 $exec = $config{CC} . " -dumpversion | cut -c 3";
240 chomp($config{GCCMINOR} = `$exec`);
241 $config{MAXBUF} = "512"; # Max buffer size
243 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
244 $config{HAS_OPENSSL} = $1;
246 $config{HAS_OPENSSL} = "";
249 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
250 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
254 # Get and Set some important vars..
259 unlink(".config.cache");
262 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
267 chomp($topdir = getcwd());
268 $this = resolve_directory($topdir); # PWD, Regardless.
270 # Does the cache file exist?
272 # No, No it doesn't.. *BASH*
273 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
276 # We've Loaded the cache file and all our variables..
277 print "Updating files...\n";
278 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
280 print "Disabling debug information (-g).\n";
281 $config{OPTIMISATI} = "";
283 $has_epoll = $config{HAS_EPOLL};
284 $has_ports = $config{HAS_PORTS};
285 $has_kqueue = $config{HAS_KQUEUE};
294 print "Configure update failed: $@\n";
303 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
304 $fail ||= system "./test_$feature";
305 unlink "test_$feature";
309 print "Running non-interactive configure...\n" unless $interactive;
310 print "Checking for cache from previous configure... ";
311 print ((!getcache()) ? "not found\n" : "found\n");
312 $config{SYSTEM} = lc $^O;
313 print "Checking operating system version... $config{SYSTEM}\n";
315 $exec = $config{CC} . " -dumpversion | cut -c 1";
316 chomp($config{GCCVER} = `$exec`); # Major GCC Version
317 $exec = $config{CC} . " -dumpversion | cut -c 3";
318 chomp($config{GCCMINOR} = `$exec`);
320 printf "Checking if stdint.h exists... ";
321 $config{HAS_STDINT} = "true";
323 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
324 if ($config{HAS_STDINT} eq "true") {
327 print "yes\n" if $config{HAS_STDINT} eq "true";
328 print "no\n" if $config{HAS_STDINT} eq "false";
330 printf "Checking if strlcpy exists... ";
331 # Perform the strlcpy() test..
332 $config{HAS_STRLCPY} = "false";
334 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
336 while (defined(my $line = <STRLCPY>)) {
338 # try and find the delcaration of:
339 # size_t strlcpy(...)
340 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
341 $config{HAS_STRLCPY} = "true";
346 print "yes\n" if $config{HAS_STRLCPY} eq "true";
347 print "no\n" if $config{HAS_STRLCPY} eq "false";
349 printf "Checking if kqueue exists... ";
352 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
354 while (defined(my $line = <KQUEUE>)) {
356 # try and find the delcaration of:
358 if ($line =~ /int(\0x9|\s)+kqueue/) {
364 print "yes\n" if $has_kqueue == 1;
365 print "no\n" if $has_kqueue == 0;
367 printf "Checking for epoll support... ";
368 $has_epoll = test_compile('epoll');
369 print $has_epoll ? "yes\n" : "no\n";
371 printf "Checking for eventfd support... ";
372 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
373 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
375 printf "Checking if Solaris I/O completion ports are available... ";
377 our $system = `uname -s`;
379 $has_ports = 1 if ($system eq "SunOS");
382 my $kernel = `uname -r`;
384 if (($kernel !~ /^5\.1./)) {
388 print "yes\n" if $has_ports == 1;
389 print "no\n" if $has_ports == 0;
391 $config{HAS_EPOLL} = $has_epoll;
392 $config{HAS_KQUEUE} = $has_kqueue;
394 printf "Checking for libgnutls... ";
395 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
396 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
398 $config{HAS_GNUTLS} = "y";
401 $config{HAS_GNUTLS} = "n";
405 $config{HAS_GNUTLS} = "n";
408 printf "Checking for openssl... ";
409 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
410 if (defined($openssl_ver) && ($openssl_ver ne "")) {
412 $config{HAS_OPENSSL} = "y";
415 $config{HAS_OPENSSL} = "n";
419 $config{HAS_OPENSSL} = "n";
422 printf "Checking if you are running an ancient, unsupported OS... ";
423 if ($config{OSNAME} =~ /FreeBSD/i)
425 my $version = `uname -r`;
426 if ($version =~ /^4\./)
429 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
430 print "To build, you will need to add the following to CXXFLAGS:\n";
431 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
435 print "no ($version)\n";
440 print "no ($config{OSNAME})\n";
443 ################################################################################
444 # BEGIN INTERACTIVE PART #
445 ################################################################################
450 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
453 my $rev = getrevision();
454 # Display Introduction Message..
456 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
457 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
459 *** If you are unsure of any of these values, leave it blank for ***
460 *** standard settings that will work, and your server will run ***
461 *** using them. Please consult your IRC network admin if in doubt. ***
463 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
464 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
465 dir, otherwise you won't have a config file!
467 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
468 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
471 print " (Non-SVN build)";
475 $config{CHANGE_COMPILER} = "n";
476 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
478 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
479 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
480 should NOT be used. You should probably specify a newer compiler.\n\n";
481 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
482 if ($config{CHANGE_COMPILER} =~ /y/i) {
483 print "What command do you want to use to invoke your compiler?\n";
484 print "[\e[1;32m$config{CC}\e[0m] -> ";
485 chomp($config{CC} = <STDIN>);
486 if ($config{CC} eq "") {
489 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
491 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
492 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
493 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
494 if ($config{GCCVER} < 3) {
495 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
499 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
506 # Directory Settings..
507 my $tmpbase = $config{BASE_DIR};
508 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
509 if ($tmpbase ne $config{BASE_DIR}) {
510 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
511 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
512 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
515 dir_check("are the configuration files", "CONFIG_DIR");
516 dir_check("are the modules to be compiled to", "MODULE_DIR");
517 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
518 dir_check("do you want the build to take place", "BUILD_DIR");
520 my $chose_hiperf = 0;
522 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?");
524 if ($config{USE_KQUEUE} eq "y") {
529 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?");
531 if ($config{USE_EPOLL} eq "y") {
536 yesno('USE_PORTS',"You are running Solaris 10.\nWould you like to enable I/O completion ports support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable support for I/O completion ports?");
538 if ($config{USE_PORTS} eq "y") {
543 if (!$chose_hiperf) {
544 yesno('USE_POLL', "Would you like to use poll?\n This is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable poll?");
545 if ($config{USE_POLL} ne "y")
547 print "No high-performance socket engines are available, or you chose\n";
548 print "not to enable one. Defaulting to select() engine.\n\n";
552 $config{USE_FREEBSD_BASE_SSL} = "n";
553 $config{USE_FREEBSD_PORTS_SSL} = "n";
554 if ($config{HAS_OPENSSL_PORT} ne "")
556 $config{USE_FREEBSD_PORTS_SSL} = "y";
557 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
558 print "version \e[1;32m".$config{HAS_OPENSSL_PORT}."\e[0m. Your base system OpenSSL is version \e[1;32m".$openssl_ver."\e[0m.\n\n";
559 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
561 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
563 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
565 # update to port version
566 $openssl_ver = $config{HAS_OPENSSL_PORT};
571 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
574 $config{USE_SSL} = "n";
575 $config{MODUPDATE} = 'n';
577 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
579 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
580 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
582 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
583 if ($config{USE_SSL} eq "y")
585 if ($config{HAS_GNUTLS} eq "y")
587 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
588 if ($config{USE_GNUTLS} eq "y")
590 print "\nUsing GnuTLS SSL module.\n";
594 if ($config{HAS_OPENSSL} eq "y")
596 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
597 if ($config{USE_OPENSSL} eq "y")
599 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
606 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
607 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
610 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
612 if ($config{MODUPDATE} eq "y") {
613 print "Checking for upgrades to extra and third party modules... ";
614 system "./modulemanager upgrade";
618 # We are on a POSIX system, we can enable POSIX extras without asking
619 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
623 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
625 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
628 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
630 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
635 $config{CERTGEN} ||= 'y';
636 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
638 if ($config{USE_GNUTLS} eq "y") {
639 unless (-r "src/modules/m_ssl_gnutls.cpp") {
640 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
641 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
643 if ($interactive && $config{CERTGEN} eq 'y')
645 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
646 print "SSL Certificates Not found, Generating.. \n\n
647 *************************************************************
648 * Generating the Private Key may take some time, go grab a *
649 * Coffee. Even better, to generate some more entropy if it *
650 * is taking a while, open another console and type du / a *
651 * few times and get that HD going :) Then answer the *
652 * Questions which follow. If you are unsure, just hit enter *
653 *************************************************************\n\n";
654 $failed = make_gnutls_cert();
656 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
658 print "\nCertificate generation complete, copying to config directory... ";
659 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
660 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
665 print "SSL Certificates found, skipping.\n\n";
670 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
674 if ($config{USE_OPENSSL} eq "y") {
675 unless (-r "src/modules/m_ssl_openssl.cpp") {
676 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
677 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
680 if ($interactive && $config{CERTGEN} eq 'y')
682 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
683 print "SSL Certificates Not found, Generating.. \n\n
684 *************************************************************
685 * Generating the certificates may take some time, go grab a *
686 * coffee, or something. *
687 *************************************************************\n\n";
689 print "\nCertificate generation complete, copying to config directory... ";
690 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
691 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
692 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
695 print "SSL Certificates found, skipping.\n\n"
700 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
703 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
704 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
712 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
713 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
714 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
715 print "modules in your config. This configure script has added those modules to the\n";
716 print "build process. For more info please refer to:\n";
717 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
719 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
720 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
721 print "\e[1;32mWARNING!\e[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";
724 if ($config{GCCVER} < "3") {
726 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
727 GCC 2.x series compilers only had partial (read as broken) C++ support, and
728 your compile will most likely fail horribly! If you have any problems, do NOT
729 report them to the bugtracker or forums without first upgrading your compiler
730 to a newer 3.x or 4.x (or whatever is available currently) version.
734 ################################################################################
736 ################################################################################
738 # Retrieves the .config.cache file, and loads values into the main config hash.
739 open(CACHE, ".config.cache") or return 0;
742 # Ignore Blank lines, and comments..
745 my ($key, $value) = split("=", $_, 2);
746 $value =~ /^\"(.*)\"$/;
747 # Do something with data here!
755 # Dump the contents of %config
756 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
757 open(FILEHANDLE, ">.config.cache");
758 foreach my $key (keys %config) {
759 print FILEHANDLE "$key=\"$config{$key}\"\n";
765 my ($desc, $hash_key) = @_;
768 print "In what directory $desc?\n";
769 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
770 chomp(my $var = <STDIN>);
772 $var = $config{$hash_key};
774 if ($var =~ /^\~\/(.+)$/) {
775 # Convert it to a full path..
776 $var = resolve_directory($ENV{HOME} . "/" . $1);
778 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
780 # Assume relative Path was given.. fill in the rest.
781 $var = $this . "/$var";
784 $var = resolve_directory($var);
786 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
787 chomp(my $tmp = <STDIN>);
788 if (($tmp eq "") || ($tmp =~ /^y/i)) {
789 # Attempt to Create the Dir..
792 File::Path::mkpath($var, 0, 0777);
795 unless (defined($chk) && -d $var) {
796 print "Unable to create directory. ($var)\n\n";
801 # They said they don't want to create, and we can't install there.
807 # Target exists, but is not a directory.
808 print "File $var exists, but is not a directory.\n\n";
812 # Either Dir Exists, or was created fine.
813 $config{$hash_key} = $var;
821 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
824 my($writeheader) = @_;
825 # First File.. inspircd_config.h
826 chomp(my $incos = `uname -n -s -r`);
827 chomp(my $version = `sh src/version.sh`);
828 chomp(my $revision2 = getrevision());
829 if ($writeheader == 1)
831 print "Writing \e[1;32minspircd_config.h\e[0m\n";
832 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
833 print FILEHANDLE <<EOF;
834 /* Auto generated by configure, do not modify! */
835 #ifndef __CONFIGURATION_AUTO__
836 #define __CONFIGURATION_AUTO__
838 /* this is for windows support. */
839 #define CoreExport /**/
840 #define DllExport /**/
842 #define MOD_PATH "$config{MODULE_DIR}"
843 #define SOMAXCONN_S "$config{_SOMAXCONN}"
844 #define ENTRYPOINT int main(int argc, char** argv)
847 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
849 if ($config{OSNAME} =~ /SunOS/i) {
850 print FILEHANDLE "#define IS_SOLARIS\n";
852 if ($config{OSNAME} =~ /MINGW32/i) {
853 print FILEHANDLE "#define IS_MINGW\n";
855 if ($config{GCCVER} >= 3) {
856 print FILEHANDLE "#define GCC3\n";
859 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
861 ($config{GCCVER} > 4)
863 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
865 if ($config{HAS_STRLCPY} eq "true") {
866 print FILEHANDLE "#define HAS_STRLCPY\n";
868 if ($config{HAS_STDINT} eq "true") {
869 print FILEHANDLE "#define HAS_STDINT\n";
871 if ($config{HAS_EVENTFD} eq 'true') {
872 print FILEHANDLE "#define HAS_EVENTFD\n";
874 if ($config{OSNAME} !~ /DARWIN/i) {
875 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
878 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
879 print FILEHANDLE "#define USE_KQUEUE\n";
880 $config{SOCKETENGINE} = "socketengine_kqueue";
883 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
884 print FILEHANDLE "#define USE_EPOLL\n";
885 $config{SOCKETENGINE} = "socketengine_epoll";
888 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
889 print FILEHANDLE "#define USE_PORTS\n";
890 $config{SOCKETENGINE} = "socketengine_ports";
893 # user didn't choose either epoll or select for their OS.
894 # default them to USE_SELECT (ewwy puke puke)
896 print "no hi-perf, " . $config{USE_POLL};
897 if ($config{USE_POLL} eq "y")
899 print FILEHANDLE "#define USE_POLL\n";
900 $config{SOCKETENGINE} = "socketengine_poll";
904 print FILEHANDLE "#define USE_SELECT\n";
905 $config{SOCKETENGINE} = "socketengine_select";
908 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
911 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
912 print FILEHANDLE <<EOF;
913 #define VERSION "$version"
914 #define REVISION "$revision2"
915 #define SYSTEM "$incos"
919 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
921 open my $fh1, $file or $diff = 1;
922 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
926 if (defined($line1) != defined($line2)) {
928 } elsif (!defined $line1) {
931 $diff = ($line1 ne $line2);
936 rename "$file.tmp", $file;
943 # Write all .in files.
946 my $exe = "inspircd";
948 # Do this once here, and cache it in the .*.inc files,
949 # rather than attempting to read src/version.sh from
950 # compiled code -- we might not have the source to hand.
951 # Fix for bug#177 by Brain.
953 chomp($version = `sh ./src/version.sh`);
954 chomp(my $revision = getrevision());
955 $version = "$version(r$revision)";
957 # We can actually parse any file starting with . and ending with .inc,
958 # but right now we only parse .inspircd.inc to form './inspircd'
959 prepare_dynamic_makefile();
961 my @dotfiles = qw(main.mk inspircd);
962 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
964 foreach my $file (@dotfiles) {
965 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
966 $_ = join '', <FILEHANDLE>;
969 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
972 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR UID
973 STARTSCRIPT DESTINATION SOCKETENGINE
975 s/\@$var\@/$config{$var}/g;
977 s/\@EXECUTABLE\@/$exe/ if defined $exe;
978 s/\@VERSION\@/$version/ if defined $version;
980 if ($file eq 'main.mk') {
981 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
984 s/\@IFDEF (\S+)/ifdef $1/g;
985 s/\@IFNDEF (\S+)/ifndef $1/g;
986 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
987 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
990 s/ *\@BSD_ONLY .*\n//g;
992 s/\@DO_EXPORT (.*)/export $1/g;
993 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
997 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
999 s/\@IFDEF (\S+)/.if defined($1)/g;
1000 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1001 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1002 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1006 s/ *\@GNU_ONLY .*\n//g;
1008 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1009 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1013 print "Writing \e[1;32m$file\e[0m ...\n";
1014 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1015 print FILEHANDLE $_;
1020 chmod 0755, 'inspircd';
1026 for my $mod (@modlist) {
1027 getcompilerflags("src/modules/m_$mod.cpp");
1028 getlinkerflags("src/modules/m_$mod.cpp");
1032 sub prepare_dynamic_makefile
1038 $config{USE_EPOLL} = 0;
1042 $config{USE_KQUEUE} = 0;
1046 $config{USE_PORTS} = 0;
1050 # Routine to list out the extra/ modules that have been enabled.
1051 # Note: when getting any filenames out and comparing, it's important to lc it if the
1052 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1053 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1054 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1055 sub list_extras () {
1058 my $srcdir = File::Spec->catdir("src", "modules");
1059 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1062 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1063 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1066 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1067 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1070 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1072 EXTRA: for my $extra (@extras) {
1073 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1074 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1075 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1076 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1077 if (-l $abs_source) {
1078 # Symlink, is it in the right place?
1079 my $targ = readlink($abs_source);
1080 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1081 if ($abs_targ eq $abs_extra) {
1082 $extras{$extra} = "\e[32;1menabled\e[0m";
1084 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1086 } elsif (-e $abs_source) {
1087 my ($devext, $inoext) = stat($abs_extra);
1088 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1090 if ($devsrc == $devext && $inosrc == $inoext) {
1091 $extras{$extra} = "\e[32;1menabled\e[0m";
1093 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1096 open my $extfd, "<", $abs_extra;
1097 open my $srcfd, "<", $abs_source;
1099 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1100 $extras{$extra} = "\e[32;1menabled\e[0m";
1102 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1106 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1109 # Now let's add dependency info
1110 for my $extra (keys(%extras)) {
1111 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1112 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1113 my @deps = split / +/, getdependencies($abs_extra);
1114 for my $dep (@deps) {
1115 if (exists($extras{$dep})) {
1116 my $ref = \$extras{$dep}; # Take reference.
1117 if ($$ref !~ m/needed by/) {
1118 # First dependency found.
1119 if ($$ref =~ m/enabled/) {
1120 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1122 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1123 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1126 if ($$ref =~ m/enabled/) {
1127 $$ref .= ", \e[32;1m$extra\e[0m";
1129 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1135 for my $extra (sort {$a cmp $b} keys(%extras)) {
1136 my $text = $extras{$extra};
1137 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1138 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1140 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1143 return keys(%extras) if wantarray; # Can be used by manage_extras.
1146 sub enable_extras (@) {
1148 for my $extra (@extras) {
1149 my $extrapath = "src/modules/extra/$extra";
1150 if (!-e $extrapath) {
1151 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1154 my $source = "src/modules/$extra";
1156 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1159 # Get dependencies, and add them to be processed.
1160 my @deps = split / +/, getdependencies($extrapath);
1161 for my $dep (@deps) {
1162 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1163 if (!-e "src/modules/$dep") {
1164 if (-e "src/modules/extra/$dep") {
1165 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1168 print STDERR "\e[33;1mWARNING:\e[0m module \e[32;1m$extra\e[0m might be missing dependency \e[32;1m$dep\e[0m - YOU are responsible for satisfying it!\n";
1172 print "Enabling $extra ... \n";
1173 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1177 sub disable_extras (@)
1179 opendir my $dd, "src/modules/extra/";
1180 my @files = readdir($dd);
1183 EXTRA: for my $extra (@extras) {
1184 my $extrapath = "src/modules/extra/$extra";
1185 my $source = "src/modules/$extra";
1186 if (!-e $extrapath) {
1187 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1190 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1191 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Source is not a link or doesn't refer to the right file. Remove manually if this is in error.\n";
1194 # Check if anything needs this.
1195 for my $file (@files) {
1196 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1197 # File depends on this extra...
1198 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1199 # And is both enabled and not about to be disabled.
1200 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1201 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1207 print "Disabling $extra ... \n";
1208 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";