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 our $exec = $config{CC} . " -dumpversion | cut -c 1";
273 chomp($config{GCCVER} = `$exec`); # Major GCC Version
274 $exec = $config{CC} . " -dumpversion | cut -c 3";
275 chomp($config{GCCMINOR} = `$exec`);
276 $config{MAXBUF} = "512"; # Max buffer size
278 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
279 $config{HAS_OPENSSL} = $1;
281 $config{HAS_OPENSSL} = "";
284 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
285 print "`$config{CC}` was not found! A C++ compiler is required to build InspIRCd!\n";
286 print "You can pass a custom compiler to $0 using --with-cc=[name].\n";
290 # Get and Set some important vars..
295 unlink(".config.cache");
298 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
303 chomp($topdir = getcwd());
304 $this = resolve_directory($topdir); # PWD, Regardless.
306 # Does the cache file exist?
308 # No, No it doesn't.. *BASH*
309 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
312 # We've Loaded the cache file and all our variables..
313 print "Updating files...\n";
314 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
316 print "Disabling debug information (-g).\n";
317 $config{OPTIMISATI} = "";
319 $has_epoll = $config{HAS_EPOLL};
320 $has_ports = $config{HAS_PORTS};
321 $has_kqueue = $config{HAS_KQUEUE};
330 print "Configure update failed: $@\n";
339 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
340 $fail ||= system "./test_$feature";
341 unlink "test_$feature";
345 print "Running non-interactive configure...\n" unless $interactive;
346 print "Checking for cache from previous configure... ";
347 print ($cache_loaded ? "found\n" : "not found\n");
348 $config{SYSTEM} = lc $^O;
349 print "Checking operating system version... $config{SYSTEM}\n";
351 $exec = $config{CC} . " -dumpversion | cut -c 1";
352 chomp($config{GCCVER} = `$exec`); # Major GCC Version
353 $exec = $config{CC} . " -dumpversion | cut -c 3";
354 chomp($config{GCCMINOR} = `$exec`);
356 printf "Checking if stdint.h exists... ";
357 $config{HAS_STDINT} = test_compile('stdint');
358 print $config{HAS_STDINT} ? "yes\n" : "no\n";
360 printf "Checking if strlcpy exists... ";
361 $config{HAS_STRLCPY} = test_compile('strlcpy');
362 print $config{HAS_STRLCPY} ? "yes\n" : "no\n";
364 printf "Checking if kqueue exists... ";
365 $has_kqueue = test_compile('kqueue');
366 print $has_kqueue ? "yes\n" : "no\n";
368 printf "Checking for epoll support... ";
369 $has_epoll = test_compile('epoll');
370 print $has_epoll ? "yes\n" : "no\n";
372 printf "Checking for eventfd support... ";
373 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
374 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
376 printf "Checking if Solaris I/O completion ports are available... ";
378 our $system = `uname -s`;
380 $has_ports = 1 if ($system eq "SunOS");
383 my $kernel = `uname -r`;
385 if (($kernel !~ /^5\.1./)) {
389 print "yes\n" if $has_ports == 1;
390 print "no\n" if $has_ports == 0;
392 $config{HAS_EPOLL} = $has_epoll;
393 $config{HAS_KQUEUE} = $has_kqueue;
395 printf "Checking for libgnutls... ";
396 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
397 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
399 $config{HAS_GNUTLS} = "y";
402 $config{HAS_GNUTLS} = "n";
406 $config{HAS_GNUTLS} = "n";
409 printf "Checking for openssl... ";
410 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
411 if (defined($openssl_ver) && ($openssl_ver ne "")) {
413 $config{HAS_OPENSSL} = "y";
416 $config{HAS_OPENSSL} = "n";
420 $config{HAS_OPENSSL} = "n";
423 printf "Checking if you are running an ancient, unsupported OS... ";
424 if ($config{OSNAME} =~ /FreeBSD/i)
426 my $version = `uname -r`;
427 if ($version =~ /^4\./)
430 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
431 print "To build, you will need to add the following to CXXFLAGS:\n";
432 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
436 print "no ($version)\n";
441 print "no ($config{OSNAME})\n";
444 ################################################################################
445 # BEGIN INTERACTIVE PART #
446 ################################################################################
451 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
454 my $rev = getrevision();
455 # Display Introduction Message..
457 Welcome to the \e[1mInspIRCd\e[0m configuration program! (\e[1minteractive mode\e[0m)
458 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
460 *** If you are unsure of any of these values, leave it blank for ***
461 *** standard settings that will work, and your server will run ***
462 *** using them. Please consult your IRC network admin if in doubt. ***
464 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
465 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
466 dir, otherwise you won't have a config file!
468 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
469 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
472 print " (Non-SVN build)";
476 $config{CHANGE_COMPILER} = "n";
477 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";
479 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
480 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
481 should NOT be used. You should probably specify a newer compiler.\n\n";
482 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
483 if ($config{CHANGE_COMPILER} =~ /y/i) {
484 print "What command do you want to use to invoke your compiler?\n";
485 print "[\e[1;32m$config{CC}\e[0m] -> ";
486 chomp($config{CC} = <STDIN>);
487 if ($config{CC} eq "") {
490 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
492 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
493 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
494 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
495 if ($config{GCCVER} < 3) {
496 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
500 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
507 # Directory Settings..
508 my $tmpbase = $config{BASE_DIR};
509 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
510 if ($tmpbase ne $config{BASE_DIR}) {
511 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
512 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
513 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
514 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
515 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
518 dir_check("are the configuration files", "CONFIG_DIR");
519 dir_check("are the modules to be compiled to", "MODULE_DIR");
520 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
521 dir_check("are variable data files to be located in", "DATA_DIR");
522 dir_check("are the logs to be stored in", "LOG_DIR");
523 dir_check("do you want the build to take place", "BUILD_DIR");
525 my $chose_hiperf = 0;
527 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?");
529 if ($config{USE_KQUEUE} eq "y") {
534 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?");
536 if ($config{USE_EPOLL} eq "y") {
541 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?");
543 if ($config{USE_PORTS} eq "y") {
548 if (!$chose_hiperf) {
549 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?");
550 if ($config{USE_POLL} ne "y")
552 print "No high-performance socket engines are available, or you chose\n";
553 print "not to enable one. Defaulting to select() engine.\n\n";
557 $config{USE_FREEBSD_BASE_SSL} = "n";
558 $config{USE_FREEBSD_PORTS_SSL} = "n";
559 if ($config{HAS_OPENSSL_PORT} ne "")
561 $config{USE_FREEBSD_PORTS_SSL} = "y";
562 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
563 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";
564 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
566 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
568 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
570 # update to port version
571 $openssl_ver = $config{HAS_OPENSSL_PORT};
576 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
579 $config{USE_SSL} ||= "n";
580 $config{MODUPDATE} ||= 'n';
582 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
584 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
585 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
587 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
588 if ($config{USE_SSL} eq "y")
590 if ($config{HAS_GNUTLS} eq "y")
592 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
593 if ($config{USE_GNUTLS} eq "y")
595 print "\nUsing GnuTLS SSL module.\n";
599 if ($config{HAS_OPENSSL} eq "y")
601 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
602 if ($config{USE_OPENSSL} eq "y")
604 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
611 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
612 print "is in your path.\n\n";
615 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
617 if ($config{MODUPDATE} eq "y") {
618 print "Checking for upgrades to extra and third-party modules... ";
619 system "./modulemanager upgrade";
623 # We are on a POSIX system, we can enable POSIX extras without asking
624 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
628 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
630 print "Sorry, but I couldn't detect GnuTLS. Make sure pkg-config is in your path.\n";
633 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
635 print "Sorry, but I couldn't detect OpenSSL. Make sure pkg-config and openssl are in your path.\n";
640 $config{CERTGEN} ||= 'y';
641 yesno('CERTGEN',"Would you like to generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
643 if ($config{USE_GNUTLS} eq "y") {
644 unless (-r "src/modules/m_ssl_gnutls.cpp") {
645 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
646 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
648 if ($interactive && $config{CERTGEN} eq 'y')
650 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
651 print "SSL certificates not found, generating.. \n\n
652 *************************************************************
653 * Generating the private key may take some time, once done, *
654 * answer the questions which follow. If you are unsure, *
656 *************************************************************\n\n";
657 $failed = make_gnutls_cert();
659 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
661 print "\nCertificate generation complete, copying to config directory... ";
662 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
663 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
668 print "SSL certificates found, skipping.\n\n";
673 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
677 if ($config{USE_OPENSSL} eq "y") {
678 unless (-r "src/modules/m_ssl_openssl.cpp") {
679 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
680 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
683 if ($interactive && $config{CERTGEN} eq 'y')
685 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
686 print "SSL certificates not found, generating.. \n\n
687 *************************************************************
688 * Generating the certificates may take some time, go grab a *
689 * coffee or something. *
690 *************************************************************\n\n";
692 print "\nCertificate generation complete, copying to config directory... ";
693 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
694 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
695 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
698 print "SSL certificates found, skipping.\n\n"
703 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
706 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
707 print "Skipping SSL certificate generation as SSL support is not available.\n\n";
715 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
716 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
717 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
718 print "modules in your config. This configure script has added those modules to the\n";
719 print "build process. For more info, please refer to:\n";
720 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
722 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
723 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
724 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";
727 if ($config{GCCVER} < "3") {
729 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
730 GCC 2.x series compilers only had partial (read as broken) C++ support, and
731 your compile will most likely fail horribly! If you have any problems, do NOT
732 report them to the bugtracker or forums without first upgrading your compiler
733 to a newer 3.x or 4.x (or whatever is available currently) version.
737 ################################################################################
739 ################################################################################
741 # Retrieves the .config.cache file, and loads values into the main config hash.
742 open(CACHE, ".config.cache") or return 0;
745 # Ignore Blank lines, and comments..
748 my ($key, $value) = split("=", $_, 2);
749 $value =~ /^\"(.*)\"$/;
750 # Do something with data here!
758 # Dump the contents of %config
759 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
760 open(FILEHANDLE, ">.config.cache");
761 foreach my $key (keys %config) {
762 print FILEHANDLE "$key=\"$config{$key}\"\n";
768 my ($desc, $hash_key) = @_;
771 print "In what directory $desc?\n";
772 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
773 chomp(my $var = <STDIN>);
775 $var = $config{$hash_key};
777 if ($var =~ /^\~\/(.+)$/) {
778 # Convert it to a full path..
779 $var = resolve_directory($ENV{HOME} . "/" . $1);
781 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
783 # Assume relative Path was given.. fill in the rest.
784 $var = $this . "/$var";
787 $var = resolve_directory($var);
789 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
790 chomp(my $tmp = <STDIN>);
791 if (($tmp eq "") || ($tmp =~ /^y/i)) {
792 # Attempt to Create the Dir..
795 File::Path::mkpath($var, 0, 0777);
798 unless (defined($chk) && -d $var) {
799 print "Unable to create directory. ($var)\n\n";
804 # They said they don't want to create, and we can't install there.
810 # Target exists, but is not a directory.
811 print "File $var exists, but is not a directory.\n\n";
815 # Either Dir Exists, or was created fine.
816 $config{$hash_key} = $var;
824 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
827 my($writeheader) = @_;
828 # First File.. inspircd_config.h
829 chomp(my $incos = `uname -n -s -r`);
830 chomp(my $version = `sh src/version.sh`);
831 chomp(my $revision2 = getrevision());
832 my $branch = "InspIRCd-0.0";
833 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
837 if ($writeheader == 1)
839 print "Writing \e[1;32minspircd_config.h\e[0m\n";
840 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
841 print FILEHANDLE <<EOF;
842 /* Auto generated by configure, do not modify! */
843 #ifndef INSPIRCD_CONFIG_H
844 #define INSPIRCD_CONFIG_H
846 /* this is for windows support. */
847 #define CoreExport /**/
848 #define DllExport /**/
850 #define CONFIG_PATH "$config{CONFIG_DIR}"
851 #define DATA_PATH "$config{DATA_DIR}"
852 #define LOG_PATH "$config{LOG_DIR}"
853 #define MOD_PATH "$config{MODULE_DIR}"
854 #define SOMAXCONN_S "$config{_SOMAXCONN}"
855 #define ENTRYPOINT int main(int argc, char** argv)
858 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
860 if ($config{OSNAME} =~ /SunOS/i) {
861 print FILEHANDLE "#define IS_SOLARIS\n";
863 if ($config{OSNAME} =~ /MINGW32/i) {
864 print FILEHANDLE "#define IS_MINGW\n";
866 if ($config{GCCVER} >= 3) {
867 print FILEHANDLE "#define GCC3\n";
869 if ($config{HAS_STRLCPY} eq "true") {
870 print FILEHANDLE "#define HAS_STRLCPY\n";
872 if ($config{HAS_STDINT} eq "true") {
873 print FILEHANDLE "#define HAS_STDINT\n";
875 if ($config{HAS_EVENTFD} eq 'true') {
876 print FILEHANDLE "#define HAS_EVENTFD\n";
878 if ($config{OSNAME} !~ /DARWIN/i) {
879 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
881 print FILEHANDLE "#ifdef MAC_OS_X_VERSION_10_12\n";
882 print FILEHANDLE "# define HAS_CLOCK_GETTIME\n";
883 print FILEHANDLE "#endif\n";
886 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
887 print FILEHANDLE "#define USE_KQUEUE\n";
888 $config{SOCKETENGINE} = "socketengine_kqueue";
891 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
892 print FILEHANDLE "#define USE_EPOLL\n";
893 $config{SOCKETENGINE} = "socketengine_epoll";
896 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
897 print FILEHANDLE "#define USE_PORTS\n";
898 $config{SOCKETENGINE} = "socketengine_ports";
901 # user didn't choose either epoll or select for their OS.
902 # default them to USE_SELECT (ewwy puke puke)
904 print "no hi-perf, " . $config{USE_POLL};
905 if ($config{USE_POLL} eq "y")
907 print FILEHANDLE "#define USE_POLL\n";
908 $config{SOCKETENGINE} = "socketengine_poll";
912 print FILEHANDLE "#define USE_SELECT\n";
913 $config{SOCKETENGINE} = "socketengine_select";
916 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
919 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
920 print FILEHANDLE <<EOF;
921 #define BRANCH "$branch"
922 #define VERSION "$version"
923 #define REVISION "$revision2"
924 #define SYSTEM "$incos"
928 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
930 open my $fh1, $file or $diff = 1;
931 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
935 if (defined($line1) != defined($line2)) {
937 } elsif (!defined $line1) {
940 $diff = ($line1 ne $line2);
945 rename "$file.tmp", $file;
952 # Write all .in files.
955 my $exe = "inspircd";
957 # Do this once here, and cache it in the .*.inc files,
958 # rather than attempting to read src/version.sh from
959 # compiled code -- we might not have the source to hand.
960 # Fix for bug#177 by Brain.
962 chomp($version = `sh ./src/version.sh`);
963 chomp(my $revision = getrevision());
964 $version = "$version(r$revision)";
966 # We can actually parse any file starting with . and ending with .inc,
967 # but right now we only parse .inspircd.inc to form './inspircd'
968 prepare_dynamic_makefile();
970 my @dotfiles = qw(main.mk inspircd);
971 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
973 # HACK: we need to know if we are on GCC6 to disable the omission of `this` null pointer checks.
974 $config{GCC6} = `$config{CC} --version 2>/dev/null` =~ /gcc/i && $config{GCCVER} ge "6" ? "true" : "false";
976 foreach my $file (@dotfiles) {
977 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
978 $_ = join '', <FILEHANDLE>;
981 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
984 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
985 STARTSCRIPT DESTINATION SOCKETENGINE LOG_DIR GCC6
987 s/\@$var\@/$config{$var}/g;
989 s/\@EXECUTABLE\@/$exe/ if defined $exe;
990 s/\@VERSION\@/$version/ if defined $version;
992 if ($file eq 'main.mk') {
993 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
996 s/\@IFDEF (\S+)/ifdef $1/g;
997 s/\@IFNDEF (\S+)/ifndef $1/g;
998 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
999 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1002 s/ *\@BSD_ONLY .*\n//g;
1004 s/\@DO_EXPORT (.*)/export $1/g;
1005 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1009 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1011 s/\@IFDEF (\S+)/.if defined($1)/g;
1012 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1013 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1014 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1018 s/ *\@GNU_ONLY .*\n//g;
1020 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1021 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1025 print "Writing \e[1;32m$file\e[0m ...\n";
1026 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1027 print FILEHANDLE $_;
1032 chmod 0755, 'inspircd';
1038 for my $mod (@modlist) {
1039 getcompilerflags("src/modules/m_$mod.cpp");
1040 getlinkerflags("src/modules/m_$mod.cpp");
1044 sub prepare_dynamic_makefile
1050 $config{USE_EPOLL} = 0;
1054 $config{USE_KQUEUE} = 0;
1058 $config{USE_PORTS} = 0;
1062 # Routine to list out the extra/ modules that have been enabled.
1063 # Note: when getting any filenames out and comparing, it's important to lc it if the
1064 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1065 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1066 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1067 sub list_extras () {
1070 my $srcdir = File::Spec->catdir("src", "modules");
1071 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1074 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1075 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1078 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1079 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1082 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1084 EXTRA: for my $extra (@extras) {
1085 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1086 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1087 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1088 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1089 if (-l $abs_source) {
1090 # Symlink, is it in the right place?
1091 my $targ = readlink($abs_source);
1092 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1093 if ($abs_targ eq $abs_extra) {
1094 $extras{$extra} = "\e[32;1menabled\e[0m";
1096 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1098 } elsif (-e $abs_source) {
1099 my ($devext, $inoext) = stat($abs_extra);
1100 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1102 if ($devsrc == $devext && $inosrc == $inoext) {
1103 $extras{$extra} = "\e[32;1menabled\e[0m";
1105 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1108 open my $extfd, "<", $abs_extra;
1109 open my $srcfd, "<", $abs_source;
1111 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1112 $extras{$extra} = "\e[32;1menabled\e[0m";
1114 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1118 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1121 # Now let's add dependency info
1122 for my $extra (keys(%extras)) {
1123 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1124 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1125 my @deps = split / +/, getdependencies($abs_extra);
1126 for my $dep (@deps) {
1127 if (exists($extras{$dep})) {
1128 my $ref = \$extras{$dep}; # Take reference.
1129 if ($$ref !~ m/needed by/) {
1130 # First dependency found.
1131 if ($$ref =~ m/enabled/) {
1132 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1134 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1135 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1138 if ($$ref =~ m/enabled/) {
1139 $$ref .= ", \e[32;1m$extra\e[0m";
1141 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1147 for my $extra (sort {$a cmp $b} keys(%extras)) {
1148 my $text = $extras{$extra};
1149 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1150 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1152 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1155 return keys(%extras) if wantarray; # Can be used by manage_extras.
1158 sub enable_extras (@) {
1160 for my $extra (@extras) {
1161 my $extrapath = "src/modules/extra/$extra";
1162 if (!-e $extrapath) {
1163 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1166 my $source = "src/modules/$extra";
1168 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1171 # Get dependencies, and add them to be processed.
1172 my @deps = split / +/, getdependencies($extrapath);
1173 for my $dep (@deps) {
1174 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1175 if (!-e "src/modules/$dep") {
1176 if (-e "src/modules/extra/$dep") {
1177 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1180 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";
1184 print "Enabling $extra ... \n";
1185 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1189 sub disable_extras (@)
1191 opendir my $dd, "src/modules/extra/";
1192 my @files = readdir($dd);
1195 EXTRA: for my $extra (@extras) {
1196 my $extrapath = "src/modules/extra/$extra";
1197 my $source = "src/modules/$extra";
1198 if (!-e $extrapath) {
1199 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1202 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1203 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";
1206 # Check if anything needs this.
1207 for my $file (@files) {
1208 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1209 # File depends on this extra...
1210 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1211 # And is both enabled and not about to be disabled.
1212 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1213 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1219 print "Disabling $extra ... \n";
1220 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";