4 # InspIRCd -- Internet Relay Chat Daemon
6 # Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
7 # Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
8 # Copyright (C) 2003, 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
9 # Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
10 # Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
11 # Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
12 # Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
13 # Copyright (C) 2003-2006 Craig McLure <craig@chatspike.net>
15 # This file is part of InspIRCd. InspIRCd is free software: you can
16 # redistribute it and/or modify it under the terms of the GNU General Public
17 # License as published by the Free Software Foundation, version 2.
19 # This program is distributed in the hope that it will be useful, but WITHOUT
20 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
34 use warnings FATAL => qw(all);
38 $Data::Dumper::Sortkeys = 1;
39 $Data::Dumper::Useqq = 1;
46 # Utility functions for our buildsystem
50 ###############################################################################################
52 # NON-EDITABLE VARIABLES
54 ###############################################################################################
56 our ($opt_use_gnutls, $opt_use_openssl, $opt_nointeractive, $opt_ports, $opt_epoll, $opt_kqueue,
57 $opt_noports, $opt_noepoll, $opt_nokqueue, $opt_maxbuf, $opt_freebsd_port, $opt_system, $opt_uid);
59 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_data_dir, $opt_log_dir);
63 sub enable_extras (@);
65 sub disable_extras (@);
68 my @opt_disableextras;
71 'enable-gnutls' => \$opt_use_gnutls,
72 'system' => \$opt_system,
74 'enable-openssl' => \$opt_use_openssl,
75 'disable-interactive' => \$opt_nointeractive,
76 'enable-ports' => \$opt_ports,
77 'enable-epoll' => \$opt_epoll,
78 'enable-kqueue' => \$opt_kqueue,
79 'disable-ports' => \$opt_noports,
80 'disable-epoll' => \$opt_noepoll,
81 'disable-kqueue' => \$opt_nokqueue,
82 'with-cc=s' => \$opt_cc,
83 'with-maxbuf=i' => \$opt_maxbuf,
84 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
85 'prefix=s' => \$opt_base_dir,
86 'config-dir=s' => \$opt_config_dir,
87 'module-dir=s' => \$opt_module_dir,
88 'binary-dir=s' => \$opt_binary_dir,
89 'data-dir=s' => \$opt_data_dir,
90 'log-dir=s' => \$opt_log_dir,
91 'help' => sub { showhelp(); },
92 'update' => sub { update(); },
93 'clean' => sub { clean(); },
94 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
95 'enable-extras=s@' => \@opt_enableextras, # ^
96 'disable-extras=s@' => \@opt_disableextras, # ^
99 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
100 @opt_enableextras = split /,/, join(',', @opt_enableextras);
101 @opt_disableextras = split /,/, join(',', @opt_disableextras);
102 enable_extras(@opt_enableextras);
103 disable_extras(@opt_disableextras);
105 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
109 our $interactive = !(
110 (defined $opt_base_dir) ||
111 (defined $opt_config_dir) ||
112 (defined $opt_module_dir) ||
113 (defined $opt_base_dir) ||
114 (defined $opt_binary_dir) ||
115 (defined $opt_data_dir) ||
116 (defined $opt_log_dir) ||
117 (defined $opt_nointeractive) ||
119 (defined $opt_kqueue) ||
120 (defined $opt_epoll) ||
121 (defined $opt_ports) ||
122 (defined $opt_use_openssl) ||
123 (defined $opt_nokqueue) ||
124 (defined $opt_noepoll) ||
125 (defined $opt_noports) ||
126 (defined $opt_maxbuf) ||
127 (defined $opt_system) ||
128 (defined $opt_uid) ||
129 (defined $opt_use_gnutls) ||
130 (defined $opt_freebsd_port)
133 chomp(our $topdir = getcwd());
134 our $this = resolve_directory($topdir); # PWD, Regardless.
135 our @modlist = (); # Declare for Module List..
136 our %config = (); # Initiate Configuration Hash..
137 our $cache_loaded = getcache();
138 $config{ME} = resolve_directory($topdir); # Present Working Directory
140 $config{BASE_DIR} = $config{ME}."/run";
142 if (defined $opt_base_dir) {
143 $config{BASE_DIR} = $opt_base_dir;
144 } elsif (defined $opt_system) {
145 $config{BASE_DIR} = '/var/lib/inspircd';
148 if (defined $opt_system) {
149 $config{UID} = $opt_uid || 'ircd';
150 $config{CONFIG_DIR} = '/etc/inspircd';
151 $config{MODULE_DIR} = '/usr/lib/inspircd';
152 $config{BINARY_DIR} = '/usr/sbin/';
153 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
154 $config{DATA_DIR} = '/var/inspircd';
155 $config{LOG_DIR} = '/var/log/inspircd';
157 $config{UID} = $opt_uid || $<;
158 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
159 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
160 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
161 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
162 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data directory
163 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log directory
166 if (defined $opt_config_dir) {
167 $config{CONFIG_DIR} = $opt_config_dir;
169 if (defined $opt_module_dir) {
170 $config{MODULE_DIR} = $opt_module_dir;
172 if (defined $opt_binary_dir) {
173 $config{BINARY_DIR} = $opt_binary_dir;
175 if (defined $opt_data_dir) {
176 $config{DATA_DIR} = $opt_data_dir;
178 if (defined $opt_log_dir) {
179 $config{LOG_DIR} = $opt_log_dir;
181 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
183 if (defined $opt_freebsd_port)
185 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
186 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
187 $config{USE_FREEBSD_BASE_SSL} = "n";
191 if ($^O eq "freebsd")
193 # default: use base ssl
194 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
195 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
199 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
200 $config{HAS_OPENSSL_PORT} = "";
204 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
205 chomp(our $openssl_ver = $config{HAS_OPENSSL});
206 $config{USE_GNUTLS} = "n";
207 if (defined $opt_use_gnutls)
209 $config{USE_GNUTLS} = "y"; # Use gnutls.
211 $config{USE_OPENSSL} = "n"; # Use openssl.
212 if (defined $opt_use_openssl)
214 $config{USE_OPENSSL} = "y";
217 $config{HAS_STDINT} = "false"; # stdint.h check
218 $config{USE_KQUEUE} = "y"; # kqueue enabled
219 if (defined $opt_nokqueue) {
220 $config{USE_KQUEUE} = "n";
222 $config{USE_POLL} = "y"; # poll enabled
223 $config{USE_EPOLL} = "y"; # epoll enabled
224 if (defined $opt_noepoll)
226 $config{USE_EPOLL} = "n";
228 $config{USE_PORTS} = "y"; # epoll enabled
229 if (defined $opt_noports)
231 $config{USE_PORTS} = "n";
233 $config{OSNAME} = $^O; # Operating System Name
234 $config{STARTSCRIPT} = "inspircd"; # start script?
235 $config{DESTINATION} = "BASE"; # Is target path.
236 if ($config{OSNAME} =~ /darwin/i)
238 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
239 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
243 $config{CC} = "g++"; # C++ compiler
247 $config{CC} = $opt_cc;
249 our $exec = $config{CC} . " -dumpversion | cut -c 1";
250 chomp($config{GCCVER} = `$exec`); # Major GCC Version
251 $exec = $config{CC} . " -dumpversion | cut -c 3";
252 chomp($config{GCCMINOR} = `$exec`);
253 $config{MAXBUF} = "512"; # Max buffer size
255 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
256 $config{HAS_OPENSSL} = $1;
258 $config{HAS_OPENSSL} = "";
261 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
262 if ($config{OSNAME} eq 'darwin') {
263 print $config{CC} . " was not found! You require clang++ (the LLVM C++ compiler, part of the OSX developer tools) to build InspIRCd!\n";
265 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
270 # Get and Set some important vars..
275 unlink(".config.cache");
278 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
283 chomp($topdir = getcwd());
284 $this = resolve_directory($topdir); # PWD, Regardless.
286 # Does the cache file exist?
288 # No, No it doesn't.. *BASH*
289 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
292 # We've Loaded the cache file and all our variables..
293 print "Updating files...\n";
294 $has_epoll = $config{HAS_EPOLL};
295 $has_ports = $config{HAS_PORTS};
296 $has_kqueue = $config{HAS_KQUEUE};
305 print "Configure update failed: $@\n";
310 print "Running non-interactive configure...\n" unless $interactive;
311 print "Checking for cache from previous configure... ";
312 print ($cache_loaded ? "found\n" : "not found\n");
313 $config{SYSTEM} = lc $^O;
314 print "Checking operating system version... $config{SYSTEM}\n";
316 $exec = $config{CC} . " -dumpversion | cut -c 1";
317 chomp($config{GCCVER} = `$exec`); # Major GCC Version
318 $exec = $config{CC} . " -dumpversion | cut -c 3";
319 chomp($config{GCCMINOR} = `$exec`);
322 print "Checking whether <stdint.h> exists... ";
323 if (test_header($config{CC}, "stdint.h")) {
324 $config{HAS_STDINT} = "true";
327 $config{HAS_STDINT} = "false";
331 printf "Checking whether clock_gettime() exists... ";
332 if (test_file($config{CC}, "clock_gettime.cpp", "-lrt")) {
333 $config{HAS_CLOCK_GETTIME} = "true";
336 $config{HAS_CLOCK_GETTIME} = "false";
340 printf "Checking whether eventfd() exists... ";
341 if (test_file($config{CC}, "eventfd.cpp")) {
342 $config{HAS_EVENTFD} = "true";
345 $config{HAS_EVENTFD} = "false";
349 printf "Checking if a TCP deferring mechanism is available... ";
350 if (test_file($config{CC}, "tcp_defer_accept.cpp")) {
351 $config{HAS_DEFER} = "TCP_DEFER_ACCEPT";
352 print "yes (TCP_DEFER_ACCEPT)\n";
353 } elsif (test_file($config{CC}, "so_acceptfilter.cpp")) {
354 $config{HAS_DEFER} = "SO_ACCEPTFILTER";
355 print "yes (SO_ACCEPTFILTER)\n";
357 $config{HAS_DEFER} = "false";
361 print "Checking whether epoll is available... ";
362 $has_epoll = test_header($config{CC}, "sys/epoll.h");
363 print $has_epoll ? "yes\n" : "no\n";
365 print "Checking whether Kqueue is available... ";
366 $has_kqueue = test_file($config{CC}, "kqueue.cpp");
367 print $has_kqueue ? "yes\n" : "no\n";
369 print 'Checking whether Solaris IOCP is available... ';
370 $has_ports = test_header($config{CC}, 'port.h');
371 print $has_ports ? "yes\n" : "no\n";
373 $config{HAS_EPOLL} = $has_epoll;
374 $config{HAS_KQUEUE} = $has_kqueue;
376 printf "Checking for libgnutls... ";
377 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
378 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
380 $config{HAS_GNUTLS} = "y";
383 $config{HAS_GNUTLS} = "n";
387 $config{HAS_GNUTLS} = "n";
390 printf "Checking for openssl... ";
391 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
392 if (defined($openssl_ver) && ($openssl_ver ne "")) {
394 $config{HAS_OPENSSL} = "y";
397 $config{HAS_OPENSSL} = "n";
401 $config{HAS_OPENSSL} = "n";
404 printf "Checking if you are running an ancient, unsupported OS... ";
405 if ($config{OSNAME} =~ /FreeBSD/i)
407 my $version = `uname -r`;
408 if ($version =~ /^4\./)
411 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
412 print "To build, you will need to add the following to CXXFLAGS:\n";
413 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
417 print "no ($version)\n";
422 print "no ($config{OSNAME})\n";
425 ################################################################################
426 # BEGIN INTERACTIVE PART #
427 ################################################################################
432 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
435 my $rev = getrevision();
436 # Display Introduction Message..
438 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
439 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
441 *** If you are unsure of any of these values, leave it blank for ***
442 *** standard settings that will work, and your server will run ***
443 *** using them. Please consult your IRC network admin if in doubt. ***
445 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
446 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
447 dir, otherwise you won't have a config file!
449 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
450 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
453 print " (Non-SVN build)";
457 $config{CHANGE_COMPILER} = "n";
458 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";
460 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
461 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
462 should NOT be used. You should probably specify a newer compiler.\n\n";
463 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
464 if ($config{CHANGE_COMPILER} =~ /y/i) {
465 print "What command do you want to use to invoke your compiler?\n";
466 print "[\e[1;32m$config{CC}\e[0m] -> ";
467 chomp($config{CC} = <STDIN>);
468 if ($config{CC} eq "") {
471 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
473 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
474 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
475 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
476 if ($config{GCCVER} < 4 || $config{GCCVER} == 4 && $config{GCCMINOR} < 1) {
477 print "\e[1;32mGCC 4.1 and earlier WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
481 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
488 # Directory Settings..
489 my $tmpbase = $config{BASE_DIR};
490 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
491 if ($tmpbase ne $config{BASE_DIR}) {
492 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
493 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
494 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
495 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
496 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
499 dir_check("are the configuration files", "CONFIG_DIR");
500 dir_check("are the modules to be compiled to", "MODULE_DIR");
501 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
502 dir_check("are variable data files to be located in", "DATA_DIR");
503 dir_check("are the logs to be stored in", "LOG_DIR");
504 dir_check("do you want the build to take place", "BUILD_DIR");
506 my $chose_hiperf = 0;
508 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?");
510 if ($config{USE_KQUEUE} eq "y") {
515 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?");
517 if ($config{USE_EPOLL} eq "y") {
522 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?");
524 if ($config{USE_PORTS} eq "y") {
529 if (!$chose_hiperf) {
530 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?");
531 if ($config{USE_POLL} ne "y")
533 print "No high-performance socket engines are available, or you chose\n";
534 print "not to enable one. Defaulting to select() engine.\n\n";
538 $config{USE_FREEBSD_BASE_SSL} = "n";
539 $config{USE_FREEBSD_PORTS_SSL} = "n";
540 if ($config{HAS_OPENSSL_PORT} ne "")
542 $config{USE_FREEBSD_PORTS_SSL} = "y";
543 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
544 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";
545 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
547 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
549 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
551 # update to port version
552 $openssl_ver = $config{HAS_OPENSSL_PORT};
557 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
560 $config{USE_SSL} = "n";
561 $config{MODUPDATE} = 'n';
563 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
565 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
566 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
568 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
569 if ($config{USE_SSL} eq "y")
571 if ($config{HAS_GNUTLS} eq "y")
573 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
574 if ($config{USE_GNUTLS} eq "y")
576 print "\nUsing GnuTLS SSL module.\n";
580 if ($config{HAS_OPENSSL} eq "y")
582 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
583 if ($config{USE_OPENSSL} eq "y")
585 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
592 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
593 print "is in your path.\n\n";
596 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
598 if ($config{MODUPDATE} eq "y") {
599 print "Checking for upgrades to extra and third party modules... ";
600 system "./modulemanager upgrade";
604 # We are on a POSIX system, we can enable POSIX extras without asking
605 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
609 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
611 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
614 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
616 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
621 $config{CERTGEN} ||= 'y';
622 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
624 if ($config{USE_GNUTLS} eq "y") {
625 unless (-r "src/modules/m_ssl_gnutls.cpp") {
626 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
627 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
629 if ($interactive && $config{CERTGEN} eq 'y')
631 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
632 print "SSL Certificates Not found, Generating.. \n\n
633 *************************************************************
634 * Generating the Private Key may take some time, go grab a *
635 * Coffee. Even better, to generate some more entropy if it *
636 * is taking a while, open another console and type du / a *
637 * few times and get that HD going :) Then answer the *
638 * Questions which follow. If you are unsure, just hit enter *
639 *************************************************************\n\n";
640 $failed = system "./tools/genssl gnutls";
642 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
644 print "\nCertificate generation complete, copying to config directory... ";
645 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
646 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
651 print "SSL Certificates found, skipping.\n\n";
656 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
660 if ($config{USE_OPENSSL} eq "y") {
661 unless (-r "src/modules/m_ssl_openssl.cpp") {
662 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
663 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
666 if ($interactive && $config{CERTGEN} eq 'y')
668 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
669 print "SSL Certificates Not found, Generating.. \n\n
670 *************************************************************
671 * Generating the certificates may take some time, go grab a *
672 * coffee, or something. *
673 *************************************************************\n\n";
674 system "./tools/genssl openssl";
675 print "\nCertificate generation complete, copying to config directory... ";
676 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
677 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
678 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
681 print "SSL Certificates found, skipping.\n\n"
686 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
689 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
690 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
698 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
699 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
700 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
701 print "modules in your config. This configure script has added those modules to the\n";
702 print "build process. For more info please refer to:\n";
703 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
705 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
706 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
707 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";
710 if ($config{GCCVER} < "3") {
712 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
713 GCC 2.x series compilers only had partial (read as broken) C++ support, and
714 your compile will most likely fail horribly! If you have any problems, do NOT
715 report them to the bugtracker or forums without first upgrading your compiler
716 to a newer 3.x or 4.x (or whatever is available currently) version.
720 ################################################################################
722 ################################################################################
724 # Retrieves the .config.cache file, and loads values into the main config hash.
725 open(CACHE, ".config.cache") or return 0;
728 # Ignore Blank lines, and comments..
731 my ($key, $value) = split("=", $_, 2);
732 $value =~ /^\"(.*)\"$/;
733 # Do something with data here!
741 # Dump the contents of %config
742 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
743 open(FILEHANDLE, ">.config.cache");
744 foreach my $key (keys %config) {
745 print FILEHANDLE "$key=\"$config{$key}\"\n";
751 my ($desc, $hash_key) = @_;
754 print "In what directory $desc?\n";
755 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
756 chomp(my $var = <STDIN>);
758 $var = $config{$hash_key};
760 if ($var =~ /^\~\/(.+)$/) {
761 # Convert it to a full path..
762 $var = resolve_directory($ENV{HOME} . "/" . $1);
764 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
766 # Assume relative Path was given.. fill in the rest.
767 $var = $this . "/$var";
770 $var = resolve_directory($var);
772 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
773 chomp(my $tmp = <STDIN>);
774 if (($tmp eq "") || ($tmp =~ /^y/i)) {
775 # Attempt to Create the Dir..
778 File::Path::mkpath($var, 0, 0777);
781 unless (defined($chk) && -d $var) {
782 print "Unable to create directory. ($var)\n\n";
787 # They said they don't want to create, and we can't install there.
793 # Target exists, but is not a directory.
794 print "File $var exists, but is not a directory.\n\n";
798 # Either Dir Exists, or was created fine.
799 $config{$hash_key} = $var;
807 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
810 my($writeheader) = @_;
811 # First File.. config.h
812 chomp(my $incos = `uname -n -s -r`);
813 chomp(my $version = `sh src/version.sh`);
814 chomp(my $revision2 = getrevision());
815 my $branch = "InspIRCd-0.0";
816 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
820 if ($writeheader == 1)
822 print "Writing \e[1;32mconfig.h\e[0m\n";
823 open(FILEHANDLE, ">include/config.h.tmp");
824 print FILEHANDLE <<EOF;
825 /* Auto generated by configure, do not modify! */
828 #define BRANCH "$branch"
829 #define VERSION "$version"
830 #define REVISION "$revision2"
831 #define SYSTEM "$incos"
833 #define CONFIG_PATH "$config{CONFIG_DIR}"
834 #define DATA_PATH "$config{DATA_DIR}"
835 #define LOG_PATH "$config{LOG_DIR}"
836 #define MOD_PATH "$config{MODULE_DIR}"
839 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
841 if ($config{OSNAME} =~ /SunOS/i) {
842 print FILEHANDLE "#define IS_SOLARIS\n";
844 if ($config{OSNAME} =~ /MINGW32/i) {
845 print FILEHANDLE "#define IS_MINGW\n";
847 if ($config{GCCVER} >= 3) {
848 print FILEHANDLE "#define GCC3\n";
850 if ($config{HAS_STDINT} eq "true") {
851 print FILEHANDLE "#define HAS_STDINT\n";
853 if ($config{HAS_EVENTFD} eq 'true') {
854 print FILEHANDLE "#define HAS_EVENTFD\n";
856 if ($config{HAS_CLOCK_GETTIME} eq 'true') {
857 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
860 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
861 print FILEHANDLE "#define USE_KQUEUE\n";
862 $config{SOCKETENGINE} = "socketengine_kqueue";
865 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
866 print FILEHANDLE "#define USE_EPOLL\n";
867 $config{SOCKETENGINE} = "socketengine_epoll";
870 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
871 print FILEHANDLE "#define USE_PORTS\n";
872 $config{SOCKETENGINE} = "socketengine_ports";
875 # user didn't choose either epoll or select for their OS.
876 # default them to USE_SELECT (ewwy puke puke)
878 print "no hi-perf, " . $config{USE_POLL};
879 if ($config{USE_POLL} eq "y")
881 print FILEHANDLE "#define USE_POLL\n";
882 $config{SOCKETENGINE} = "socketengine_poll";
886 print FILEHANDLE "#define USE_SELECT\n";
887 $config{SOCKETENGINE} = "socketengine_select";
891 if ($config{HAS_DEFER} eq "TCP_DEFER_ACCEPT") {
892 print FILEHANDLE "#define USE_TCP_DEFER_ACCEPT";
893 } elsif ($config{HAS_DEFER} eq "SO_ACCEPTFILTER") {
894 print FILEHANDLE "#define USE_SO_ACCEPTFILTER"
897 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n";
900 my $file = 'include/config.h';
902 open my $fh1, $file or $diff = 1;
903 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
907 if (defined($line1) != defined($line2)) {
909 } elsif (!defined $line1) {
912 $diff = ($line1 ne $line2);
917 rename "$file.tmp", $file;
923 # Write all .in files.
926 my $exe = "inspircd";
928 # Do this once here, and cache it in the .*.inc files,
929 # rather than attempting to read src/version.sh from
930 # compiled code -- we might not have the source to hand.
931 # Fix for bug#177 by Brain.
933 chomp($version = `sh ./src/version.sh`);
934 chomp(my $revision = getrevision());
935 $version = "$version(r$revision)";
937 # We can actually parse any file starting with . and ending with .inc,
938 # but right now we only parse .inspircd.inc to form './inspircd'
939 prepare_dynamic_makefile();
941 my @dotfiles = qw(main.mk inspircd);
942 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
944 foreach my $file (@dotfiles) {
945 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
946 $_ = join '', <FILEHANDLE>;
949 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
952 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
953 STARTSCRIPT DESTINATION SOCKETENGINE
955 s/\@$var\@/$config{$var}/g;
957 s/\@EXECUTABLE\@/$exe/ if defined $exe;
958 s/\@VERSION\@/$version/ if defined $version;
960 if ($file eq 'main.mk') {
961 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
964 s/\@IFDEF (\S+)/ifdef $1/g;
965 s/\@IFNDEF (\S+)/ifndef $1/g;
966 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
967 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
970 s/ *\@BSD_ONLY .*\n//g;
972 s/\@DO_EXPORT (.*)/export $1/g;
973 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
977 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
979 s/\@IFDEF (\S+)/.if defined($1)/g;
980 s/\@IFNDEF (\S+)/.if !defined($1)/g;
981 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
982 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
986 s/ *\@GNU_ONLY .*\n//g;
988 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
989 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
993 print "Writing \e[1;32m$file\e[0m ...\n";
994 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1000 chmod 0755, 'inspircd';
1006 for my $mod (@modlist) {
1007 getcompilerflags("src/modules/m_$mod.cpp");
1008 getlinkerflags("src/modules/m_$mod.cpp");
1012 sub prepare_dynamic_makefile
1018 $config{USE_EPOLL} = 0;
1022 $config{USE_KQUEUE} = 0;
1026 $config{USE_PORTS} = 0;
1030 # Routine to list out the extra/ modules that have been enabled.
1031 # Note: when getting any filenames out and comparing, it's important to lc it if the
1032 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1033 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1034 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1035 sub list_extras () {
1038 my $srcdir = File::Spec->catdir("src", "modules");
1039 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1042 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1043 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1046 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1047 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1050 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1052 EXTRA: for my $extra (@extras) {
1053 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1054 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1055 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1056 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1057 if (-l $abs_source) {
1058 # Symlink, is it in the right place?
1059 my $targ = readlink($abs_source);
1060 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1061 if ($abs_targ eq $abs_extra) {
1062 $extras{$extra} = "\e[32;1menabled\e[0m";
1064 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1066 } elsif (-e $abs_source) {
1067 my ($devext, $inoext) = stat($abs_extra);
1068 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1070 if ($devsrc == $devext && $inosrc == $inoext) {
1071 $extras{$extra} = "\e[32;1menabled\e[0m";
1073 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1076 open my $extfd, "<", $abs_extra;
1077 open my $srcfd, "<", $abs_source;
1079 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1080 $extras{$extra} = "\e[32;1menabled\e[0m";
1082 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1086 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1089 # Now let's add dependency info
1090 for my $extra (keys(%extras)) {
1091 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1092 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1093 my @deps = split / +/, getdependencies($abs_extra);
1094 for my $dep (@deps) {
1095 if (exists($extras{$dep})) {
1096 my $ref = \$extras{$dep}; # Take reference.
1097 if ($$ref !~ m/needed by/) {
1098 # First dependency found.
1099 if ($$ref =~ m/enabled/) {
1100 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1102 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1103 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1106 if ($$ref =~ m/enabled/) {
1107 $$ref .= ", \e[32;1m$extra\e[0m";
1109 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1115 for my $extra (sort {$a cmp $b} keys(%extras)) {
1116 my $text = $extras{$extra};
1117 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1118 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1120 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1123 return keys(%extras) if wantarray; # Can be used by manage_extras.
1126 sub enable_extras (@) {
1128 for my $extra (@extras) {
1129 my $extrapath = "src/modules/extra/$extra";
1130 if (!-e $extrapath) {
1131 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1134 my $source = "src/modules/$extra";
1136 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1139 # Get dependencies, and add them to be processed.
1140 my @deps = split / +/, getdependencies($extrapath);
1141 for my $dep (@deps) {
1142 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1143 if (!-e "src/modules/$dep") {
1144 if (-e "src/modules/extra/$dep") {
1145 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1148 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";
1152 print "Enabling $extra ... \n";
1153 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1157 sub disable_extras (@)
1159 opendir my $dd, "src/modules/extra/";
1160 my @files = readdir($dd);
1163 EXTRA: for my $extra (@extras) {
1164 my $extrapath = "src/modules/extra/$extra";
1165 my $source = "src/modules/$extra";
1166 if (!-e $extrapath) {
1167 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1170 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1171 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";
1174 # Check if anything needs this.
1175 for my $file (@files) {
1176 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1177 # File depends on this extra...
1178 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1179 # And is both enabled and not about to be disabled.
1180 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1181 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1187 print "Disabling $extra ... \n";
1188 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";