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;
47 # Utility functions for our buildsystem
51 ###############################################################################################
53 # NON-EDITABLE VARIABLES
55 ###############################################################################################
57 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
58 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
59 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
60 $opt_system, $opt_uid);
62 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_data_dir, $opt_log_dir);
66 sub enable_extras (@);
68 sub disable_extras (@);
71 my @opt_disableextras;
74 'enable-gnutls' => \$opt_use_gnutls,
75 'rebuild' => \$opt_rebuild,
76 'system' => \$opt_system,
78 'enable-openssl' => \$opt_use_openssl,
79 'disable-interactive' => \$opt_nointeractive,
80 'enable-ports' => \$opt_ports,
81 'enable-epoll' => \$opt_epoll,
82 'enable-kqueue' => \$opt_kqueue,
83 'disable-ports' => \$opt_noports,
84 'disable-epoll' => \$opt_noepoll,
85 'disable-kqueue' => \$opt_nokqueue,
86 'disable-ipv6' => \$opt_noipv6,
87 'with-cc=s' => \$opt_cc,
88 'with-maxbuf=i' => \$opt_maxbuf,
89 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
90 'prefix=s' => \$opt_base_dir,
91 'config-dir=s' => \$opt_config_dir,
92 'module-dir=s' => \$opt_module_dir,
93 'binary-dir=s' => \$opt_binary_dir,
94 'data-dir=s' => \$opt_data_dir,
95 'log-dir=s' => \$opt_log_dir,
96 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
97 'help' => sub { showhelp(); },
98 'update' => sub { update(); },
99 'clean' => sub { clean(); },
100 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
101 'enable-extras=s@' => \@opt_enableextras, # ^
102 'disable-extras=s@' => \@opt_disableextras, # ^
103 'generate-openssl-cert' => sub { exec './tools/genssl openssl'; },
104 'generate-gnutls-cert' => sub { exec './tools/genssl gnutls'; }
107 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
108 @opt_enableextras = split /,/, join(',', @opt_enableextras);
109 @opt_disableextras = split /,/, join(',', @opt_disableextras);
110 enable_extras(@opt_enableextras);
111 disable_extras(@opt_disableextras);
113 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
117 our $interactive = !(
118 (defined $opt_base_dir) ||
119 (defined $opt_config_dir) ||
120 (defined $opt_module_dir) ||
121 (defined $opt_base_dir) ||
122 (defined $opt_binary_dir) ||
123 (defined $opt_data_dir) ||
124 (defined $opt_log_dir) ||
125 (defined $opt_nointeractive) ||
127 (defined $opt_noipv6) ||
128 (defined $opt_kqueue) ||
129 (defined $opt_epoll) ||
130 (defined $opt_ports) ||
131 (defined $opt_use_openssl) ||
132 (defined $opt_nokqueue) ||
133 (defined $opt_noepoll) ||
134 (defined $opt_noports) ||
135 (defined $opt_maxbuf) ||
136 (defined $opt_system) ||
137 (defined $opt_uid) ||
138 (defined $opt_use_gnutls) ||
139 (defined $opt_freebsd_port)
142 chomp(our $topdir = getcwd());
143 our $this = resolve_directory($topdir); # PWD, Regardless.
144 our @modlist = (); # Declare for Module List..
145 our %config = (); # Initiate Configuration Hash..
146 our $cache_loaded = getcache();
147 $config{ME} = resolve_directory($topdir); # Present Working Directory
149 $config{BASE_DIR} = $config{ME}."/run";
151 if (defined $opt_base_dir) {
152 $config{BASE_DIR} = $opt_base_dir;
153 } elsif (defined $opt_system) {
154 $config{BASE_DIR} = '/var/lib/inspircd';
157 if (defined $opt_system) {
158 $config{UID} = $opt_uid || 'ircd';
159 $config{CONFIG_DIR} = '/etc/inspircd';
160 $config{MODULE_DIR} = '/usr/lib/inspircd';
161 $config{BINARY_DIR} = '/usr/sbin/';
162 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
163 $config{DATA_DIR} = '/var/inspircd';
164 $config{LOG_DIR} = '/var/log/inspircd';
166 $config{UID} = $opt_uid || $<;
167 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
168 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
169 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
170 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
171 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data directory
172 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log directory
175 if (defined $opt_config_dir) {
176 $config{CONFIG_DIR} = $opt_config_dir;
178 if (defined $opt_module_dir) {
179 $config{MODULE_DIR} = $opt_module_dir;
181 if (defined $opt_binary_dir) {
182 $config{BINARY_DIR} = $opt_binary_dir;
184 if (defined $opt_data_dir) {
185 $config{DATA_DIR} = $opt_data_dir;
187 if (defined $opt_log_dir) {
188 $config{LOG_DIR} = $opt_log_dir;
190 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
192 if (defined $opt_freebsd_port)
194 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
195 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
196 $config{USE_FREEBSD_BASE_SSL} = "n";
200 if ($^O eq "freebsd")
202 # default: use base ssl
203 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
204 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
208 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
209 $config{HAS_OPENSSL_PORT} = "";
213 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
214 chomp(our $openssl_ver = $config{HAS_OPENSSL});
215 $config{USE_GNUTLS} = "n";
216 if (defined $opt_use_gnutls)
218 $config{USE_GNUTLS} = "y"; # Use gnutls.
220 $config{USE_OPENSSL} = "n"; # Use openssl.
221 if (defined $opt_use_openssl)
223 $config{USE_OPENSSL} = "y";
226 if (!defined $opt_disable_debug) {
227 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
229 $config{OPTIMISATI} = "-O2";
232 $config{HAS_STDINT} = "false"; # stdint.h check
233 $config{USE_KQUEUE} = "y"; # kqueue enabled
234 if (defined $opt_nokqueue) {
235 $config{USE_KQUEUE} = "n";
237 $config{USE_POLL} = "y"; # poll enabled
238 $config{USE_EPOLL} = "y"; # epoll enabled
239 if (defined $opt_noepoll)
241 $config{USE_EPOLL} = "n";
243 $config{USE_PORTS} = "y"; # epoll enabled
244 if (defined $opt_noports)
246 $config{USE_PORTS} = "n";
248 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
249 $config{OSNAME} = $^O; # Operating System Name
250 $config{IS_DARWIN} = "NO"; # Is OSX?
251 $config{STARTSCRIPT} = "inspircd"; # start script?
252 $config{DESTINATION} = "BASE"; # Is target path.
253 if ($config{OSNAME} =~ /darwin/i)
255 $config{IS_DARWIN} = "YES";
256 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
257 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
261 $config{CC} = "g++"; # C++ compiler
265 $config{CC} = $opt_cc;
267 our $exec = $config{CC} . " -dumpversion | cut -c 1";
268 chomp($config{GCCVER} = `$exec`); # Major GCC Version
269 $exec = $config{CC} . " -dumpversion | cut -c 3";
270 chomp($config{GCCMINOR} = `$exec`);
271 $config{MAXBUF} = "512"; # Max buffer size
273 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
274 $config{HAS_OPENSSL} = $1;
276 $config{HAS_OPENSSL} = "";
279 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
280 if ($config{IS_DARWIN} eq "YES") {
281 print $config{CC} . " was not found! You require clang++ (the LLVM C++ compiler, part of the OSX developer tools) to build InspIRCd!\n";
283 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
288 # Get and Set some important vars..
293 unlink(".config.cache");
296 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
301 chomp($topdir = getcwd());
302 $this = resolve_directory($topdir); # PWD, Regardless.
304 # Does the cache file exist?
306 # No, No it doesn't.. *BASH*
307 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
310 # We've Loaded the cache file and all our variables..
311 print "Updating files...\n";
312 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
314 print "Disabling debug information (-g).\n";
315 $config{OPTIMISATI} = "";
317 $has_epoll = $config{HAS_EPOLL};
318 $has_ports = $config{HAS_PORTS};
319 $has_kqueue = $config{HAS_KQUEUE};
328 print "Configure update failed: $@\n";
333 print "Running non-interactive configure...\n" unless $interactive;
334 print "Checking for cache from previous configure... ";
335 print ($cache_loaded ? "found\n" : "not found\n");
336 $config{SYSTEM} = lc $^O;
337 print "Checking operating system version... $config{SYSTEM}\n";
339 $exec = $config{CC} . " -dumpversion | cut -c 1";
340 chomp($config{GCCVER} = `$exec`); # Major GCC Version
341 $exec = $config{CC} . " -dumpversion | cut -c 3";
342 chomp($config{GCCMINOR} = `$exec`);
345 print "Checking whether <stdint.h> exists... ";
346 if (test_header($config{CC}, "stdint.h")) {
347 $config{HAS_STDINT} = "true";
350 $config{HAS_STDINT} = "false";
354 printf "Checking whether clock_gettime() exists... ";
355 if (test_file($config{CC}, "clock_gettime.cpp", "-lrt")) {
356 $config{HAS_CLOCK_GETTIME} = "true";
359 $config{HAS_CLOCK_GETTIME} = "false";
363 printf "Checking whether eventfd() exists... ";
364 if (test_file($config{CC}, "eventfd.cpp")) {
365 $config{HAS_EVENTFD} = "true";
368 $config{HAS_EVENTFD} = "false";
372 print "Checking whether epoll is available... ";
373 $has_epoll = test_header($config{CC}, "sys/epoll.h");
374 print $has_epoll ? "yes\n" : "no\n";
376 print "Checking whether Kqueue is available... ";
377 $has_kqueue = test_file($config{CC}, "kqueue.cpp");
378 print $has_kqueue ? "yes\n" : "no\n";
380 print 'Checking whether Solaris IOCP is available... ';
381 $has_ports = test_header($config{CC}, 'port.h');
382 print $has_ports ? "yes\n" : "no\n";
384 $config{HAS_EPOLL} = $has_epoll;
385 $config{HAS_KQUEUE} = $has_kqueue;
387 printf "Checking for libgnutls... ";
388 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
389 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
391 $config{HAS_GNUTLS} = "y";
394 $config{HAS_GNUTLS} = "n";
398 $config{HAS_GNUTLS} = "n";
401 printf "Checking for openssl... ";
402 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
403 if (defined($openssl_ver) && ($openssl_ver ne "")) {
405 $config{HAS_OPENSSL} = "y";
408 $config{HAS_OPENSSL} = "n";
412 $config{HAS_OPENSSL} = "n";
415 printf "Checking if you are running an ancient, unsupported OS... ";
416 if ($config{OSNAME} =~ /FreeBSD/i)
418 my $version = `uname -r`;
419 if ($version =~ /^4\./)
422 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
423 print "To build, you will need to add the following to CXXFLAGS:\n";
424 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
428 print "no ($version)\n";
433 print "no ($config{OSNAME})\n";
436 ################################################################################
437 # BEGIN INTERACTIVE PART #
438 ################################################################################
443 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
446 my $rev = getrevision();
447 # Display Introduction Message..
449 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
450 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
452 *** If you are unsure of any of these values, leave it blank for ***
453 *** standard settings that will work, and your server will run ***
454 *** using them. Please consult your IRC network admin if in doubt. ***
456 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
457 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
458 dir, otherwise you won't have a config file!
460 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
461 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
464 print " (Non-SVN build)";
468 $config{CHANGE_COMPILER} = "n";
469 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";
471 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
472 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
473 should NOT be used. You should probably specify a newer compiler.\n\n";
474 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
475 if ($config{CHANGE_COMPILER} =~ /y/i) {
476 print "What command do you want to use to invoke your compiler?\n";
477 print "[\e[1;32m$config{CC}\e[0m] -> ";
478 chomp($config{CC} = <STDIN>);
479 if ($config{CC} eq "") {
482 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
484 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
485 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
486 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
487 if ($config{GCCVER} < 3) {
488 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
492 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
499 # Directory Settings..
500 my $tmpbase = $config{BASE_DIR};
501 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
502 if ($tmpbase ne $config{BASE_DIR}) {
503 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
504 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
505 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
506 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
507 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
510 dir_check("are the configuration files", "CONFIG_DIR");
511 dir_check("are the modules to be compiled to", "MODULE_DIR");
512 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
513 dir_check("are variable data files to be located in", "DATA_DIR");
514 dir_check("are the logs to be stored in", "LOG_DIR");
515 dir_check("do you want the build to take place", "BUILD_DIR");
517 my $chose_hiperf = 0;
519 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?");
521 if ($config{USE_KQUEUE} eq "y") {
526 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?");
528 if ($config{USE_EPOLL} eq "y") {
533 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?");
535 if ($config{USE_PORTS} eq "y") {
540 if (!$chose_hiperf) {
541 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?");
542 if ($config{USE_POLL} ne "y")
544 print "No high-performance socket engines are available, or you chose\n";
545 print "not to enable one. Defaulting to select() engine.\n\n";
549 $config{USE_FREEBSD_BASE_SSL} = "n";
550 $config{USE_FREEBSD_PORTS_SSL} = "n";
551 if ($config{HAS_OPENSSL_PORT} ne "")
553 $config{USE_FREEBSD_PORTS_SSL} = "y";
554 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
555 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";
556 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
558 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
560 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
562 # update to port version
563 $openssl_ver = $config{HAS_OPENSSL_PORT};
568 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
571 $config{USE_SSL} = "n";
572 $config{MODUPDATE} = 'n';
574 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
576 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
577 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
579 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
580 if ($config{USE_SSL} eq "y")
582 if ($config{HAS_GNUTLS} eq "y")
584 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
585 if ($config{USE_GNUTLS} eq "y")
587 print "\nUsing GnuTLS SSL module.\n";
591 if ($config{HAS_OPENSSL} eq "y")
593 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
594 if ($config{USE_OPENSSL} eq "y")
596 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
603 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
604 print "is in your path.\n\n";
607 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
609 if ($config{MODUPDATE} eq "y") {
610 print "Checking for upgrades to extra and third party modules... ";
611 system "./modulemanager upgrade";
615 # We are on a POSIX system, we can enable POSIX extras without asking
616 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
620 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
622 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
625 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
627 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
632 $config{CERTGEN} ||= 'y';
633 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
635 if ($config{USE_GNUTLS} eq "y") {
636 unless (-r "src/modules/m_ssl_gnutls.cpp") {
637 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
638 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
640 if ($interactive && $config{CERTGEN} eq 'y')
642 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
643 print "SSL Certificates Not found, Generating.. \n\n
644 *************************************************************
645 * Generating the Private Key may take some time, go grab a *
646 * Coffee. Even better, to generate some more entropy if it *
647 * is taking a while, open another console and type du / a *
648 * few times and get that HD going :) Then answer the *
649 * Questions which follow. If you are unsure, just hit enter *
650 *************************************************************\n\n";
651 $failed = system "./tools/genssl gnutls";
653 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
655 print "\nCertificate generation complete, copying to config directory... ";
656 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
657 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
662 print "SSL Certificates found, skipping.\n\n";
667 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
671 if ($config{USE_OPENSSL} eq "y") {
672 unless (-r "src/modules/m_ssl_openssl.cpp") {
673 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
674 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
677 if ($interactive && $config{CERTGEN} eq 'y')
679 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
680 print "SSL Certificates Not found, Generating.. \n\n
681 *************************************************************
682 * Generating the certificates may take some time, go grab a *
683 * coffee, or something. *
684 *************************************************************\n\n";
685 system "./tools/genssl openssl";
686 print "\nCertificate generation complete, copying to config directory... ";
687 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
688 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
689 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
692 print "SSL Certificates found, skipping.\n\n"
697 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
700 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
701 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
709 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
710 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
711 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
712 print "modules in your config. This configure script has added those modules to the\n";
713 print "build process. For more info please refer to:\n";
714 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
716 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
717 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
718 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";
721 if ($config{GCCVER} < "3") {
723 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
724 GCC 2.x series compilers only had partial (read as broken) C++ support, and
725 your compile will most likely fail horribly! If you have any problems, do NOT
726 report them to the bugtracker or forums without first upgrading your compiler
727 to a newer 3.x or 4.x (or whatever is available currently) version.
731 ################################################################################
733 ################################################################################
735 # Retrieves the .config.cache file, and loads values into the main config hash.
736 open(CACHE, ".config.cache") or return 0;
739 # Ignore Blank lines, and comments..
742 my ($key, $value) = split("=", $_, 2);
743 $value =~ /^\"(.*)\"$/;
744 # Do something with data here!
752 # Dump the contents of %config
753 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
754 open(FILEHANDLE, ">.config.cache");
755 foreach my $key (keys %config) {
756 print FILEHANDLE "$key=\"$config{$key}\"\n";
762 my ($desc, $hash_key) = @_;
765 print "In what directory $desc?\n";
766 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
767 chomp(my $var = <STDIN>);
769 $var = $config{$hash_key};
771 if ($var =~ /^\~\/(.+)$/) {
772 # Convert it to a full path..
773 $var = resolve_directory($ENV{HOME} . "/" . $1);
775 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
777 # Assume relative Path was given.. fill in the rest.
778 $var = $this . "/$var";
781 $var = resolve_directory($var);
783 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
784 chomp(my $tmp = <STDIN>);
785 if (($tmp eq "") || ($tmp =~ /^y/i)) {
786 # Attempt to Create the Dir..
789 File::Path::mkpath($var, 0, 0777);
792 unless (defined($chk) && -d $var) {
793 print "Unable to create directory. ($var)\n\n";
798 # They said they don't want to create, and we can't install there.
804 # Target exists, but is not a directory.
805 print "File $var exists, but is not a directory.\n\n";
809 # Either Dir Exists, or was created fine.
810 $config{$hash_key} = $var;
818 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
821 my($writeheader) = @_;
822 # First File.. config.h
823 chomp(my $incos = `uname -n -s -r`);
824 chomp(my $version = `sh src/version.sh`);
825 chomp(my $revision2 = getrevision());
826 my $branch = "InspIRCd-0.0";
827 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
831 if ($writeheader == 1)
833 print "Writing \e[1;32mconfig.h\e[0m\n";
834 open(FILEHANDLE, ">include/config.h.tmp");
835 print FILEHANDLE <<EOF;
836 /* Auto generated by configure, do not modify! */
839 #define BRANCH "$branch"
840 #define VERSION "$version"
841 #define REVISION "$revision2"
842 #define SYSTEM "$incos"
844 #define CONFIG_PATH "$config{CONFIG_DIR}"
845 #define DATA_PATH "$config{DATA_DIR}"
846 #define LOG_PATH "$config{LOG_DIR}"
847 #define MOD_PATH "$config{MODULE_DIR}"
848 #define SOMAXCONN_S "$config{_SOMAXCONN}"
849 #define ENTRYPOINT int main(int argc, char** argv)
852 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
854 if ($config{OSNAME} =~ /SunOS/i) {
855 print FILEHANDLE "#define IS_SOLARIS\n";
857 if ($config{OSNAME} =~ /MINGW32/i) {
858 print FILEHANDLE "#define IS_MINGW\n";
860 if ($config{GCCVER} >= 3) {
861 print FILEHANDLE "#define GCC3\n";
863 if ($config{HAS_STDINT} eq "true") {
864 print FILEHANDLE "#define HAS_STDINT\n";
866 if ($config{HAS_EVENTFD} eq 'true') {
867 print FILEHANDLE "#define HAS_EVENTFD\n";
869 if ($config{HAS_CLOCK_GETTIME} eq 'true') {
870 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
873 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
874 print FILEHANDLE "#define USE_KQUEUE\n";
875 $config{SOCKETENGINE} = "socketengine_kqueue";
878 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
879 print FILEHANDLE "#define USE_EPOLL\n";
880 $config{SOCKETENGINE} = "socketengine_epoll";
883 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
884 print FILEHANDLE "#define USE_PORTS\n";
885 $config{SOCKETENGINE} = "socketengine_ports";
888 # user didn't choose either epoll or select for their OS.
889 # default them to USE_SELECT (ewwy puke puke)
891 print "no hi-perf, " . $config{USE_POLL};
892 if ($config{USE_POLL} eq "y")
894 print FILEHANDLE "#define USE_POLL\n";
895 $config{SOCKETENGINE} = "socketengine_poll";
899 print FILEHANDLE "#define USE_SELECT\n";
900 $config{SOCKETENGINE} = "socketengine_select";
903 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n";
906 my $file = 'include/config.h';
908 open my $fh1, $file or $diff = 1;
909 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
913 if (defined($line1) != defined($line2)) {
915 } elsif (!defined $line1) {
918 $diff = ($line1 ne $line2);
923 rename "$file.tmp", $file;
929 # Write all .in files.
932 my $exe = "inspircd";
934 # Do this once here, and cache it in the .*.inc files,
935 # rather than attempting to read src/version.sh from
936 # compiled code -- we might not have the source to hand.
937 # Fix for bug#177 by Brain.
939 chomp($version = `sh ./src/version.sh`);
940 chomp(my $revision = getrevision());
941 $version = "$version(r$revision)";
943 # We can actually parse any file starting with . and ending with .inc,
944 # but right now we only parse .inspircd.inc to form './inspircd'
945 prepare_dynamic_makefile();
947 my @dotfiles = qw(main.mk inspircd);
948 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
950 foreach my $file (@dotfiles) {
951 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
952 $_ = join '', <FILEHANDLE>;
955 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
958 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
959 STARTSCRIPT DESTINATION SOCKETENGINE
961 s/\@$var\@/$config{$var}/g;
963 s/\@EXECUTABLE\@/$exe/ if defined $exe;
964 s/\@VERSION\@/$version/ if defined $version;
966 if ($file eq 'main.mk') {
967 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
970 s/\@IFDEF (\S+)/ifdef $1/g;
971 s/\@IFNDEF (\S+)/ifndef $1/g;
972 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
973 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
976 s/ *\@BSD_ONLY .*\n//g;
978 s/\@DO_EXPORT (.*)/export $1/g;
979 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
983 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
985 s/\@IFDEF (\S+)/.if defined($1)/g;
986 s/\@IFNDEF (\S+)/.if !defined($1)/g;
987 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
988 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
992 s/ *\@GNU_ONLY .*\n//g;
994 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
995 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
999 print "Writing \e[1;32m$file\e[0m ...\n";
1000 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1001 print FILEHANDLE $_;
1006 chmod 0755, 'inspircd';
1012 for my $mod (@modlist) {
1013 getcompilerflags("src/modules/m_$mod.cpp");
1014 getlinkerflags("src/modules/m_$mod.cpp");
1018 sub prepare_dynamic_makefile
1024 $config{USE_EPOLL} = 0;
1028 $config{USE_KQUEUE} = 0;
1032 $config{USE_PORTS} = 0;
1036 # Routine to list out the extra/ modules that have been enabled.
1037 # Note: when getting any filenames out and comparing, it's important to lc it if the
1038 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1039 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1040 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1041 sub list_extras () {
1044 my $srcdir = File::Spec->catdir("src", "modules");
1045 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1048 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1049 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1052 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1053 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1056 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1058 EXTRA: for my $extra (@extras) {
1059 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1060 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1061 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1062 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1063 if (-l $abs_source) {
1064 # Symlink, is it in the right place?
1065 my $targ = readlink($abs_source);
1066 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1067 if ($abs_targ eq $abs_extra) {
1068 $extras{$extra} = "\e[32;1menabled\e[0m";
1070 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1072 } elsif (-e $abs_source) {
1073 my ($devext, $inoext) = stat($abs_extra);
1074 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1076 if ($devsrc == $devext && $inosrc == $inoext) {
1077 $extras{$extra} = "\e[32;1menabled\e[0m";
1079 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1082 open my $extfd, "<", $abs_extra;
1083 open my $srcfd, "<", $abs_source;
1085 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1086 $extras{$extra} = "\e[32;1menabled\e[0m";
1088 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1092 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1095 # Now let's add dependency info
1096 for my $extra (keys(%extras)) {
1097 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1098 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1099 my @deps = split / +/, getdependencies($abs_extra);
1100 for my $dep (@deps) {
1101 if (exists($extras{$dep})) {
1102 my $ref = \$extras{$dep}; # Take reference.
1103 if ($$ref !~ m/needed by/) {
1104 # First dependency found.
1105 if ($$ref =~ m/enabled/) {
1106 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1108 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1109 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1112 if ($$ref =~ m/enabled/) {
1113 $$ref .= ", \e[32;1m$extra\e[0m";
1115 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1121 for my $extra (sort {$a cmp $b} keys(%extras)) {
1122 my $text = $extras{$extra};
1123 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1124 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1126 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1129 return keys(%extras) if wantarray; # Can be used by manage_extras.
1132 sub enable_extras (@) {
1134 for my $extra (@extras) {
1135 my $extrapath = "src/modules/extra/$extra";
1136 if (!-e $extrapath) {
1137 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1140 my $source = "src/modules/$extra";
1142 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1145 # Get dependencies, and add them to be processed.
1146 my @deps = split / +/, getdependencies($extrapath);
1147 for my $dep (@deps) {
1148 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1149 if (!-e "src/modules/$dep") {
1150 if (-e "src/modules/extra/$dep") {
1151 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1154 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";
1158 print "Enabling $extra ... \n";
1159 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1163 sub disable_extras (@)
1165 opendir my $dd, "src/modules/extra/";
1166 my @files = readdir($dd);
1169 EXTRA: for my $extra (@extras) {
1170 my $extrapath = "src/modules/extra/$extra";
1171 my $source = "src/modules/$extra";
1172 if (!-e $extrapath) {
1173 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1176 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1177 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";
1180 # Check if anything needs this.
1181 for my $file (@files) {
1182 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1183 # File depends on this extra...
1184 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1185 # And is both enabled and not about to be disabled.
1186 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1187 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1193 print "Disabling $extra ... \n";
1194 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";