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/>.
35 use warnings FATAL => qw(all);
42 # Utility functions for our buildsystem
46 use make::opensslcert;
48 ###############################################################################################
50 # NON-EDITABLE VARIABLES
52 ###############################################################################################
54 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
55 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
56 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
57 $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 'rebuild' => \$opt_rebuild,
73 'system' => \$opt_system,
75 'enable-openssl' => \$opt_use_openssl,
76 'disable-interactive' => \$opt_nointeractive,
77 'enable-ports' => \$opt_ports,
78 'enable-epoll' => \$opt_epoll,
79 'enable-kqueue' => \$opt_kqueue,
80 'disable-ports' => \$opt_noports,
81 'disable-epoll' => \$opt_noepoll,
82 'disable-kqueue' => \$opt_nokqueue,
83 'disable-ipv6' => \$opt_noipv6,
84 'with-cc=s' => \$opt_cc,
85 'with-maxbuf=i' => \$opt_maxbuf,
86 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
87 'prefix=s' => \$opt_base_dir,
88 'config-dir=s' => \$opt_config_dir,
89 'module-dir=s' => \$opt_module_dir,
90 'binary-dir=s' => \$opt_binary_dir,
91 'data-dir=s' => \$opt_data_dir,
92 'log-dir=s' => \$opt_log_dir,
93 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
94 'help' => sub { showhelp(); },
95 'update' => sub { update(); },
96 'clean' => sub { clean(); },
97 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
98 'enable-extras=s@' => \@opt_enableextras, # ^
99 'disable-extras=s@' => \@opt_disableextras, # ^
100 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
101 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
104 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
105 @opt_enableextras = split /,/, join(',', @opt_enableextras);
106 @opt_disableextras = split /,/, join(',', @opt_disableextras);
107 enable_extras(@opt_enableextras);
108 disable_extras(@opt_disableextras);
110 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
114 our $interactive = !(
115 (defined $opt_base_dir) ||
116 (defined $opt_config_dir) ||
117 (defined $opt_module_dir) ||
118 (defined $opt_base_dir) ||
119 (defined $opt_binary_dir) ||
120 (defined $opt_data_dir) ||
121 (defined $opt_log_dir) ||
122 (defined $opt_nointeractive) ||
124 (defined $opt_noipv6) ||
125 (defined $opt_kqueue) ||
126 (defined $opt_epoll) ||
127 (defined $opt_ports) ||
128 (defined $opt_use_openssl) ||
129 (defined $opt_nokqueue) ||
130 (defined $opt_noepoll) ||
131 (defined $opt_noports) ||
132 (defined $opt_maxbuf) ||
133 (defined $opt_system) ||
134 (defined $opt_uid) ||
135 (defined $opt_use_gnutls) ||
136 (defined $opt_freebsd_port)
139 chomp(our $topdir = getcwd());
140 our $this = resolve_directory($topdir); # PWD, Regardless.
141 our @modlist = (); # Declare for Module List..
142 our %config = (); # Initiate Configuration Hash..
143 our $cache_loaded = getcache();
144 $config{ME} = resolve_directory($topdir); # Present Working Directory
146 $config{BASE_DIR} ||= $config{ME}."/run";
148 if (defined $opt_base_dir) {
149 $config{BASE_DIR} = $opt_base_dir;
150 } elsif (defined $opt_system) {
151 $config{BASE_DIR} = '/var/lib/inspircd';
154 if (defined $opt_system) {
155 $config{UID} = $opt_uid || 'ircd';
156 $config{CONFIG_DIR} = '/etc/inspircd';
157 $config{MODULE_DIR} = '/usr/lib/inspircd';
158 $config{BINARY_DIR} = '/usr/sbin/';
159 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
160 $config{DATA_DIR} = '/var/inspircd';
161 $config{LOG_DIR} = '/var/log/inspircd';
163 $config{UID} = $opt_uid || $config{UID} || $<;
164 $config{CONFIG_DIR} ||= resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
165 $config{MODULE_DIR} ||= resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
166 $config{BINARY_DIR} ||= resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
167 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build"); # Build Directory
168 $config{DATA_DIR} ||= resolve_directory($config{BASE_DIR}."/data"); # Data directory
169 $config{LOG_DIR} ||= resolve_directory($config{BASE_DIR}."/logs"); # Log directory
172 if (defined $opt_config_dir) {
173 $config{CONFIG_DIR} = $opt_config_dir;
175 if (defined $opt_module_dir) {
176 $config{MODULE_DIR} = $opt_module_dir;
178 if (defined $opt_binary_dir) {
179 $config{BINARY_DIR} = $opt_binary_dir;
181 if (defined $opt_data_dir) {
182 $config{DATA_DIR} = $opt_data_dir;
184 if (defined $opt_log_dir) {
185 $config{LOG_DIR} = $opt_log_dir;
187 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null`); # GNUTLS Version.
189 if (defined $opt_freebsd_port)
191 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
192 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
193 $config{USE_FREEBSD_BASE_SSL} = "n";
197 if ($^O eq "freebsd")
199 # default: use base ssl
200 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
201 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
205 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
206 $config{HAS_OPENSSL_PORT} = "";
207 $config{USE_FREEBSD_BASE_SSL} = "n";
211 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
212 chomp(our $openssl_ver = $config{HAS_OPENSSL});
213 $config{USE_GNUTLS} ||= "n";
214 if (defined $opt_use_gnutls)
216 $config{USE_GNUTLS} = "y"; # Use gnutls.
218 $config{USE_OPENSSL} ||= "n"; # Use openssl.
219 if (defined $opt_use_openssl)
221 $config{USE_OPENSSL} = "y";
224 if (!defined $opt_disable_debug) {
225 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
227 $config{OPTIMISATI} = "-O2";
230 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
231 $config{HAS_STDINT} = "false"; # stdint.h check
232 $config{USE_KQUEUE} = "y"; # kqueue enabled
233 if (defined $opt_nokqueue) {
234 $config{USE_KQUEUE} = "n";
236 $config{USE_POLL} = "y"; # poll enabled
237 $config{USE_EPOLL} = "y"; # epoll enabled
238 if (defined $opt_noepoll)
240 $config{USE_EPOLL} = "n";
242 $config{USE_PORTS} = "y"; # epoll enabled
243 if (defined $opt_noports)
245 $config{USE_PORTS} = "n";
247 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
248 $config{OSNAME} = $^O; # Operating System Name
249 $config{IS_DARWIN} = "NO"; # Is OSX?
250 $config{STARTSCRIPT} = "inspircd"; # start script?
251 $config{DESTINATION} = "BASE"; # Is target path.
252 if ($config{OSNAME} =~ /darwin/i)
254 $config{IS_DARWIN} = "YES";
255 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
256 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
258 elsif ($config{OSNAME} =~ /freebsd/i)
260 chomp(my $fbsd_version = `uname -r`);
261 $fbsd_version =~ s/^(\d+\.\d+).*/$1/g;
262 $config{CC} = $fbsd_version >= 10.0 ? 'clang++' : 'g++';
266 $config{CC} = "g++"; # C++ compiler
270 $config{CC} = $opt_cc;
272 `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
273 $config{GCCVER} = defined $1 ? $1 : '';
274 $config{GCCMINOR} = defined $2 ? $2 : '0';
275 $config{MAXBUF} = "512"; # Max buffer size
277 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
278 $config{HAS_OPENSSL} = $1;
280 $config{HAS_OPENSSL} = "";
283 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
284 print "`$config{CC}` was not found! A C++ compiler is required to build InspIRCd!\n";
285 print "You can pass a custom compiler to $0 using --with-cc=[name].\n";
289 # Get and Set some important vars..
294 unlink(".config.cache");
297 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
302 chomp($topdir = getcwd());
303 $this = resolve_directory($topdir); # PWD, Regardless.
305 # Does the cache file exist?
307 # No, No it doesn't.. *BASH*
308 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
311 # We've Loaded the cache file and all our variables..
312 print "Updating files...\n";
313 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
315 print "Disabling debug information (-g).\n";
316 $config{OPTIMISATI} = "";
318 $has_epoll = $config{HAS_EPOLL};
319 $has_ports = $config{HAS_PORTS};
320 $has_kqueue = $config{HAS_KQUEUE};
329 print "Configure update failed: $@\n";
338 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
339 $fail ||= system "./test_$feature";
340 unlink "test_$feature";
344 print "Running non-interactive configure...\n" unless $interactive;
345 print "Checking for cache from previous configure... ";
346 print ($cache_loaded ? "found\n" : "not found\n");
347 $config{SYSTEM} = lc $^O;
348 print "Checking operating system version... $config{SYSTEM}\n";
350 `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
351 $config{GCCVER} = defined $1 ? $1 : '';
352 $config{GCCMINOR} = defined $2 ? $2 : '0';
354 printf "Checking if stdint.h exists... ";
355 $config{HAS_STDINT} = test_compile('stdint');
356 print $config{HAS_STDINT} ? "yes\n" : "no\n";
358 printf "Checking if strlcpy exists... ";
359 $config{HAS_STRLCPY} = test_compile('strlcpy');
360 print $config{HAS_STRLCPY} ? "yes\n" : "no\n";
362 printf "Checking if kqueue exists... ";
363 $has_kqueue = test_compile('kqueue');
364 print $has_kqueue ? "yes\n" : "no\n";
366 printf "Checking for epoll support... ";
367 $has_epoll = test_compile('epoll');
368 print $has_epoll ? "yes\n" : "no\n";
370 printf "Checking for eventfd support... ";
371 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
372 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
374 printf "Checking if Solaris I/O completion ports are available... ";
376 our $system = `uname -s`;
378 $has_ports = 1 if ($system eq "SunOS");
381 my $kernel = `uname -r`;
383 if (($kernel !~ /^5\.1./)) {
387 print "yes\n" if $has_ports == 1;
388 print "no\n" if $has_ports == 0;
390 $config{HAS_EPOLL} = $has_epoll;
391 $config{HAS_KQUEUE} = $has_kqueue;
393 printf "Checking for libgnutls... ";
394 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
395 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
397 $config{HAS_GNUTLS} = "y";
400 $config{HAS_GNUTLS} = "n";
404 $config{HAS_GNUTLS} = "n";
407 printf "Checking for openssl... ";
408 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
409 if (defined($openssl_ver) && ($openssl_ver ne "")) {
411 $config{HAS_OPENSSL} = "y";
414 $config{HAS_OPENSSL} = "n";
418 $config{HAS_OPENSSL} = "n";
421 printf "Checking if you are running an ancient, unsupported OS... ";
422 if ($config{OSNAME} =~ /FreeBSD/i)
424 my $version = `uname -r`;
425 if ($version =~ /^4\./)
428 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
429 print "To build, you will need to add the following to CXXFLAGS:\n";
430 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
434 print "no ($version)\n";
439 print "no ($config{OSNAME})\n";
442 ################################################################################
443 # BEGIN INTERACTIVE PART #
444 ################################################################################
449 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
452 my $rev = getrevision();
453 # Display Introduction Message..
455 Welcome to the \e[1mInspIRCd\e[0m configuration program! (\e[1minteractive mode\e[0m)
456 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
458 *** If you are unsure of any of these values, leave it blank for ***
459 *** standard settings that will work, and your server will run ***
460 *** using them. Please consult your IRC network admin if in doubt. ***
462 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
463 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
464 dir, otherwise you won't have a config file!
466 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
467 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
470 print " (Non-SVN build)";
474 $config{CHANGE_COMPILER} = "n";
475 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";
477 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
478 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
479 should NOT be used. You should probably specify a newer compiler.\n\n";
480 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
481 if ($config{CHANGE_COMPILER} =~ /y/i) {
482 print "What command do you want to use to invoke your compiler?\n";
483 print "[\e[1;32m$config{CC}\e[0m] -> ";
484 chomp($config{CC} = <STDIN>);
485 if ($config{CC} eq "") {
488 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
490 `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/;
491 $config{GCCVER} = defined $1 ? $1 : '';
492 $config{GCCMINOR} = defined $2 ? $2 : '0';
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{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
513 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
514 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
517 dir_check("are the configuration files", "CONFIG_DIR");
518 dir_check("are the modules to be compiled to", "MODULE_DIR");
519 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
520 dir_check("are variable data files to be located in", "DATA_DIR");
521 dir_check("are the logs to be stored in", "LOG_DIR");
522 dir_check("do you want the build to take place", "BUILD_DIR");
524 my $chose_hiperf = 0;
526 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?");
528 if ($config{USE_KQUEUE} eq "y") {
533 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?");
535 if ($config{USE_EPOLL} eq "y") {
540 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?");
542 if ($config{USE_PORTS} eq "y") {
547 if (!$chose_hiperf) {
548 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?");
549 if ($config{USE_POLL} ne "y")
551 print "No high-performance socket engines are available, or you chose\n";
552 print "not to enable one. Defaulting to select() engine.\n\n";
556 $config{USE_FREEBSD_BASE_SSL} = "n";
557 $config{USE_FREEBSD_PORTS_SSL} = "n";
558 if ($config{HAS_OPENSSL_PORT} ne "")
560 $config{USE_FREEBSD_PORTS_SSL} = "y";
561 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
562 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";
563 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
565 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
567 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
569 # update to port version
570 $openssl_ver = $config{HAS_OPENSSL_PORT};
575 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
578 $config{USE_SSL} ||= "n";
579 $config{MODUPDATE} ||= 'n';
581 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
583 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
584 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
586 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
587 if ($config{USE_SSL} eq "y")
589 if ($config{HAS_GNUTLS} eq "y")
591 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
592 if ($config{USE_GNUTLS} eq "y")
594 print "\nUsing GnuTLS SSL module.\n";
598 if ($config{HAS_OPENSSL} eq "y")
600 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
601 if ($config{USE_OPENSSL} eq "y")
603 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
610 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
611 print "is in your path.\n\n";
614 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
616 if ($config{MODUPDATE} eq "y") {
617 print "Checking for upgrades to extra and third-party modules... ";
618 system "./modulemanager upgrade";
622 # We are on a POSIX system, we can enable POSIX extras without asking
623 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
627 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
629 print "Sorry, but I couldn't detect GnuTLS. Make sure pkg-config is in your path.\n";
632 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
634 print "Sorry, but I couldn't detect OpenSSL. Make sure pkg-config and openssl are in your path.\n";
639 $config{CERTGEN} ||= 'y';
640 yesno('CERTGEN',"Would you like to generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
642 if ($config{USE_GNUTLS} eq "y") {
643 unless (-r "src/modules/m_ssl_gnutls.cpp") {
644 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
645 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
647 if ($interactive && $config{CERTGEN} eq 'y')
649 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
650 print "SSL certificates not found, generating.. \n\n
651 *************************************************************
652 * Generating the private key may take some time, once done, *
653 * answer the questions which follow. If you are unsure, *
655 *************************************************************\n\n";
656 $failed = make_gnutls_cert();
658 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
660 print "\nCertificate generation complete, copying to config directory... ";
661 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
662 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
667 print "SSL certificates found, skipping.\n\n";
672 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
676 if ($config{USE_OPENSSL} eq "y") {
677 unless (-r "src/modules/m_ssl_openssl.cpp") {
678 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
679 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
682 if ($interactive && $config{CERTGEN} eq 'y')
684 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
685 print "SSL certificates not found, generating.. \n\n
686 *************************************************************
687 * Generating the certificates may take some time, go grab a *
688 * coffee or something. *
689 *************************************************************\n\n";
691 print "\nCertificate generation complete, copying to config directory... ";
692 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
693 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
694 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
697 print "SSL certificates found, skipping.\n\n"
702 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
705 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
706 print "Skipping SSL certificate generation as SSL support is not available.\n\n";
714 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
715 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
716 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
717 print "modules in your config. This configure script has added those modules to the\n";
718 print "build process. For more info, please refer to:\n";
719 print "\e[1;32mhttps://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
721 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
722 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
723 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";
726 if ($config{GCCVER} < "3") {
728 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
729 GCC 2.x series compilers only had partial (read as broken) C++ support, and
730 your compile will most likely fail horribly! If you have any problems, do NOT
731 report them to the bugtracker or forums without first upgrading your compiler
732 to a newer 3.x or 4.x (or whatever is available currently) version.
736 if ($^O eq 'openbsd') {
737 print <<__OPENBSD_WARNING__;
738 \e[1;32mWARNING!\e[0m OpenBSD 6.5 changed Make to no longer look for BSDmakefile when
739 searching for the makefile. If the version of OpenBSD you are using is 6.5 or
740 newer then you will need to run '\e[1;32mmake -f BSDmakefile\e[0m' or '\e[1;32mgmake\e[0m' instead.
744 ################################################################################
746 ################################################################################
748 # Retrieves the .config.cache file, and loads values into the main config hash.
749 open(CACHE, ".config.cache") or return 0;
752 # Ignore Blank lines, and comments..
755 my ($key, $value) = split("=", $_, 2);
756 $value =~ /^\"(.*)\"$/;
757 # Do something with data here!
765 # Dump the contents of %config
766 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
767 open(FILEHANDLE, ">.config.cache");
768 foreach my $key (keys %config) {
769 print FILEHANDLE "$key=\"$config{$key}\"\n";
775 my ($desc, $hash_key) = @_;
778 print "In what directory $desc?\n";
779 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
780 chomp(my $var = <STDIN>);
782 $var = $config{$hash_key};
784 if ($var =~ /^\~\/(.+)$/) {
785 # Convert it to a full path..
786 $var = resolve_directory($ENV{HOME} . "/" . $1);
788 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
790 # Assume relative Path was given.. fill in the rest.
791 $var = $this . "/$var";
794 $var = resolve_directory($var);
796 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
797 chomp(my $tmp = <STDIN>);
798 if (($tmp eq "") || ($tmp =~ /^y/i)) {
799 # Attempt to Create the Dir..
802 File::Path::mkpath($var, 0, 0777);
805 unless (defined($chk) && -d $var) {
806 print "Unable to create directory. ($var)\n\n";
811 # They said they don't want to create, and we can't install there.
817 # Target exists, but is not a directory.
818 print "File $var exists, but is not a directory.\n\n";
822 # Either Dir Exists, or was created fine.
823 $config{$hash_key} = $var;
831 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
834 my($writeheader) = @_;
835 # First File.. inspircd_config.h
836 chomp(my $incos = `uname -n -s -r`);
837 chomp(my $version = `sh src/version.sh`);
838 chomp(my $revision2 = getrevision());
839 my $branch = "InspIRCd-0.0";
840 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
844 if ($writeheader == 1)
846 print "Writing \e[1;32minspircd_config.h\e[0m\n";
847 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
848 print FILEHANDLE <<EOF;
849 /* Auto generated by configure, do not modify! */
850 #ifndef INSPIRCD_CONFIG_H
851 #define INSPIRCD_CONFIG_H
853 /* this is for windows support. */
854 #define CoreExport /**/
855 #define DllExport /**/
857 #define CONFIG_PATH "$config{CONFIG_DIR}"
858 #define DATA_PATH "$config{DATA_DIR}"
859 #define LOG_PATH "$config{LOG_DIR}"
860 #define MOD_PATH "$config{MODULE_DIR}"
861 #define SOMAXCONN_S "$config{_SOMAXCONN}"
862 #define ENTRYPOINT int main(int argc, char** argv)
865 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
867 if ($config{OSNAME} =~ /SunOS/i) {
868 print FILEHANDLE "#define IS_SOLARIS\n";
870 if ($config{OSNAME} =~ /MINGW32/i) {
871 print FILEHANDLE "#define IS_MINGW\n";
873 if ($config{GCCVER} >= 3) {
874 print FILEHANDLE "#define GCC3\n";
876 if ($config{HAS_STRLCPY} eq "true") {
877 print FILEHANDLE "#define HAS_STRLCPY\n";
879 if ($config{HAS_STDINT} eq "true") {
880 print FILEHANDLE "#define HAS_STDINT\n";
882 if ($config{HAS_EVENTFD} eq 'true') {
883 print FILEHANDLE "#define HAS_EVENTFD\n";
885 if ($config{OSNAME} !~ /DARWIN/i) {
886 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
888 print FILEHANDLE "#ifdef MAC_OS_X_VERSION_10_12\n";
889 print FILEHANDLE "# define HAS_CLOCK_GETTIME\n";
890 print FILEHANDLE "#endif\n";
893 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
894 print FILEHANDLE "#define USE_KQUEUE\n";
895 $config{SOCKETENGINE} = "socketengine_kqueue";
898 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
899 print FILEHANDLE "#define USE_EPOLL\n";
900 $config{SOCKETENGINE} = "socketengine_epoll";
903 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
904 print FILEHANDLE "#define USE_PORTS\n";
905 $config{SOCKETENGINE} = "socketengine_ports";
908 # user didn't choose either epoll or select for their OS.
909 # default them to USE_SELECT (ewwy puke puke)
911 print "no hi-perf, " . $config{USE_POLL};
912 if ($config{USE_POLL} eq "y")
914 print FILEHANDLE "#define USE_POLL\n";
915 $config{SOCKETENGINE} = "socketengine_poll";
919 print FILEHANDLE "#define USE_SELECT\n";
920 $config{SOCKETENGINE} = "socketengine_select";
923 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
926 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
927 print FILEHANDLE <<EOF;
928 #define BRANCH "$branch"
929 #define VERSION "$version"
930 #define REVISION "$revision2"
931 #define SYSTEM "$incos"
935 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
937 open my $fh1, $file or $diff = 1;
938 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
942 if (defined($line1) != defined($line2)) {
944 } elsif (!defined $line1) {
947 $diff = ($line1 ne $line2);
952 rename "$file.tmp", $file;
959 # Write all .in files.
962 my $exe = "inspircd";
964 # Do this once here, and cache it in the .*.inc files,
965 # rather than attempting to read src/version.sh from
966 # compiled code -- we might not have the source to hand.
967 # Fix for bug#177 by Brain.
969 chomp($version = `sh ./src/version.sh`);
970 chomp(my $revision = getrevision());
971 $version = "$version(r$revision)";
973 # We can actually parse any file starting with . and ending with .inc,
974 # but right now we only parse .inspircd.inc to form './inspircd'
975 prepare_dynamic_makefile();
977 my @dotfiles = qw(main.mk inspircd);
978 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
980 # HACK: we need to know if we are on GCC6 to disable the omission of `this` null pointer checks.
981 $config{GCC6} = `$config{CC} --version 2>/dev/null` =~ /gcc/i && $config{GCCVER} ge "6" ? "true" : "false";
983 foreach my $file (@dotfiles) {
984 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
985 $_ = join '', <FILEHANDLE>;
988 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
991 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
992 STARTSCRIPT DESTINATION SOCKETENGINE LOG_DIR GCC6
994 s/\@$var\@/$config{$var}/g;
996 s/\@EXECUTABLE\@/$exe/ if defined $exe;
997 s/\@VERSION\@/$version/ if defined $version;
999 if ($file eq 'main.mk') {
1000 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1003 s/\@IFDEF (\S+)/ifdef $1/g;
1004 s/\@IFNDEF (\S+)/ifndef $1/g;
1005 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1006 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1009 s/ *\@BSD_ONLY .*\n//g;
1011 s/\@DO_EXPORT (.*)/export $1/g;
1012 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1016 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1018 s/\@IFDEF (\S+)/.if defined($1)/g;
1019 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1020 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1021 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1025 s/ *\@GNU_ONLY .*\n//g;
1027 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1028 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1032 print "Writing \e[1;32m$file\e[0m ...\n";
1033 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1034 print FILEHANDLE $_;
1039 chmod 0755, 'inspircd';
1045 for my $mod (@modlist) {
1046 getcompilerflags("src/modules/m_$mod.cpp");
1047 getlinkerflags("src/modules/m_$mod.cpp");
1051 sub prepare_dynamic_makefile
1057 $config{USE_EPOLL} = 0;
1061 $config{USE_KQUEUE} = 0;
1065 $config{USE_PORTS} = 0;
1069 # Routine to list out the extra/ modules that have been enabled.
1070 # Note: when getting any filenames out and comparing, it's important to lc it if the
1071 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1072 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1073 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1074 sub list_extras () {
1077 my $srcdir = File::Spec->catdir("src", "modules");
1078 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1081 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1082 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1085 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1086 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1089 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1091 EXTRA: for my $extra (@extras) {
1092 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1093 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1094 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1095 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1096 if (-l $abs_source) {
1097 # Symlink, is it in the right place?
1098 my $targ = readlink($abs_source);
1099 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1100 if ($abs_targ eq $abs_extra) {
1101 $extras{$extra} = "\e[32;1menabled\e[0m";
1103 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1105 } elsif (-e $abs_source) {
1106 my ($devext, $inoext) = stat($abs_extra);
1107 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1109 if ($devsrc == $devext && $inosrc == $inoext) {
1110 $extras{$extra} = "\e[32;1menabled\e[0m";
1112 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1115 open my $extfd, "<", $abs_extra;
1116 open my $srcfd, "<", $abs_source;
1118 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1119 $extras{$extra} = "\e[32;1menabled\e[0m";
1121 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1125 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1128 # Now let's add dependency info
1129 for my $extra (keys(%extras)) {
1130 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1131 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1132 my @deps = split / +/, getdependencies($abs_extra);
1133 for my $dep (@deps) {
1134 if (exists($extras{$dep})) {
1135 my $ref = \$extras{$dep}; # Take reference.
1136 if ($$ref !~ m/needed by/) {
1137 # First dependency found.
1138 if ($$ref =~ m/enabled/) {
1139 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1141 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1142 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1145 if ($$ref =~ m/enabled/) {
1146 $$ref .= ", \e[32;1m$extra\e[0m";
1148 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1154 for my $extra (sort {$a cmp $b} keys(%extras)) {
1155 my $text = $extras{$extra};
1156 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1157 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1159 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1162 return keys(%extras) if wantarray; # Can be used by manage_extras.
1165 sub enable_extras (@) {
1167 for my $extra (@extras) {
1168 my $extrapath = "src/modules/extra/$extra";
1169 if (!-e $extrapath) {
1170 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1173 my $source = "src/modules/$extra";
1175 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1178 # Get dependencies, and add them to be processed.
1179 my @deps = split / +/, getdependencies($extrapath);
1180 for my $dep (@deps) {
1181 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1182 if (!-e "src/modules/$dep") {
1183 if (-e "src/modules/extra/$dep") {
1184 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1187 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";
1191 print "Enabling $extra ... \n";
1192 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1196 sub disable_extras (@)
1198 opendir my $dd, "src/modules/extra/";
1199 my @files = readdir($dd);
1202 EXTRA: for my $extra (@extras) {
1203 my $extrapath = "src/modules/extra/$extra";
1204 my $source = "src/modules/$extra";
1205 if (!-e $extrapath) {
1206 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1209 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1210 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";
1213 # Check if anything needs this.
1214 for my $file (@files) {
1215 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1216 # File depends on this extra...
1217 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1218 # And is both enabled and not about to be disabled.
1219 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1220 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1226 print "Disabling $extra ... \n";
1227 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";