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);
41 # Utility functions for our buildsystem
45 use make::opensslcert;
47 ###############################################################################################
49 # NON-EDITABLE VARIABLES
51 ###############################################################################################
53 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
54 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
55 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
56 $opt_system, $opt_uid);
58 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_data_dir, $opt_log_dir);
62 sub enable_extras (@);
64 sub disable_extras (@);
67 my @opt_disableextras;
70 'enable-gnutls' => \$opt_use_gnutls,
71 'rebuild' => \$opt_rebuild,
72 'system' => \$opt_system,
74 'enable-openssl' => \$opt_use_openssl,
75 'disable-interactive' => \$opt_nointeractive,
76 'enable-ports' => \$opt_ports,
77 'enable-epoll' => \$opt_epoll,
78 'enable-kqueue' => \$opt_kqueue,
79 'disable-ports' => \$opt_noports,
80 'disable-epoll' => \$opt_noepoll,
81 'disable-kqueue' => \$opt_nokqueue,
82 'disable-ipv6' => \$opt_noipv6,
83 'with-cc=s' => \$opt_cc,
84 'with-maxbuf=i' => \$opt_maxbuf,
85 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
86 'prefix=s' => \$opt_base_dir,
87 'config-dir=s' => \$opt_config_dir,
88 'module-dir=s' => \$opt_module_dir,
89 'binary-dir=s' => \$opt_binary_dir,
90 'data-dir=s' => \$opt_data_dir,
91 'log-dir=s' => \$opt_log_dir,
92 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
93 'help' => sub { showhelp(); },
94 'update' => sub { update(); },
95 'clean' => sub { clean(); },
96 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
97 'enable-extras=s@' => \@opt_enableextras, # ^
98 'disable-extras=s@' => \@opt_disableextras, # ^
99 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
100 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
103 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
104 @opt_enableextras = split /,/, join(',', @opt_enableextras);
105 @opt_disableextras = split /,/, join(',', @opt_disableextras);
106 enable_extras(@opt_enableextras);
107 disable_extras(@opt_disableextras);
109 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
113 our $interactive = !(
114 (defined $opt_base_dir) ||
115 (defined $opt_config_dir) ||
116 (defined $opt_module_dir) ||
117 (defined $opt_base_dir) ||
118 (defined $opt_binary_dir) ||
119 (defined $opt_data_dir) ||
120 (defined $opt_log_dir) ||
121 (defined $opt_nointeractive) ||
123 (defined $opt_noipv6) ||
124 (defined $opt_kqueue) ||
125 (defined $opt_epoll) ||
126 (defined $opt_ports) ||
127 (defined $opt_use_openssl) ||
128 (defined $opt_nokqueue) ||
129 (defined $opt_noepoll) ||
130 (defined $opt_noports) ||
131 (defined $opt_maxbuf) ||
132 (defined $opt_system) ||
133 (defined $opt_uid) ||
134 (defined $opt_use_gnutls) ||
135 (defined $opt_freebsd_port)
138 chomp(our $topdir = getcwd());
139 our $this = resolve_directory($topdir); # PWD, Regardless.
140 our @modlist = (); # Declare for Module List..
141 our %config = (); # Initiate Configuration Hash..
142 our $cache_loaded = getcache();
143 $config{ME} = resolve_directory($topdir); # Present Working Directory
145 $config{BASE_DIR} ||= $config{ME}."/run";
147 if (defined $opt_base_dir) {
148 $config{BASE_DIR} = $opt_base_dir;
149 } elsif (defined $opt_system) {
150 $config{BASE_DIR} = '/var/lib/inspircd';
153 if (defined $opt_system) {
154 $config{UID} = $opt_uid || 'ircd';
155 $config{CONFIG_DIR} = '/etc/inspircd';
156 $config{MODULE_DIR} = '/usr/lib/inspircd';
157 $config{BINARY_DIR} = '/usr/sbin/';
158 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
159 $config{DATA_DIR} = '/var/inspircd';
160 $config{LOG_DIR} = '/var/log/inspircd';
162 $config{UID} = $opt_uid || $config{UID} || $<;
163 $config{CONFIG_DIR} ||= resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
164 $config{MODULE_DIR} ||= resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
165 $config{BINARY_DIR} ||= resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
166 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build"); # Build Directory
167 $config{DATA_DIR} ||= resolve_directory($config{BASE_DIR}."/data"); # Data directory
168 $config{LOG_DIR} ||= resolve_directory($config{BASE_DIR}."/logs"); # Log directory
171 if (defined $opt_config_dir) {
172 $config{CONFIG_DIR} = $opt_config_dir;
174 if (defined $opt_module_dir) {
175 $config{MODULE_DIR} = $opt_module_dir;
177 if (defined $opt_binary_dir) {
178 $config{BINARY_DIR} = $opt_binary_dir;
180 if (defined $opt_data_dir) {
181 $config{DATA_DIR} = $opt_data_dir;
183 if (defined $opt_log_dir) {
184 $config{LOG_DIR} = $opt_log_dir;
186 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null`); # GNUTLS Version.
188 if (defined $opt_freebsd_port)
190 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
191 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
192 $config{USE_FREEBSD_BASE_SSL} = "n";
196 if ($^O eq "freebsd")
198 # default: use base ssl
199 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
200 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
204 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
205 $config{HAS_OPENSSL_PORT} = "";
206 $config{USE_FREEBSD_BASE_SSL} = "n";
210 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
211 chomp(our $openssl_ver = $config{HAS_OPENSSL});
212 $config{USE_GNUTLS} ||= "n";
213 if (defined $opt_use_gnutls)
215 $config{USE_GNUTLS} = "y"; # Use gnutls.
217 $config{USE_OPENSSL} ||= "n"; # Use openssl.
218 if (defined $opt_use_openssl)
220 $config{USE_OPENSSL} = "y";
223 if (!defined $opt_disable_debug) {
224 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
226 $config{OPTIMISATI} = "-O2";
229 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
230 $config{HAS_STDINT} = "false"; # stdint.h check
231 $config{USE_KQUEUE} = "y"; # kqueue enabled
232 if (defined $opt_nokqueue) {
233 $config{USE_KQUEUE} = "n";
235 $config{USE_POLL} = "y"; # poll enabled
236 $config{USE_EPOLL} = "y"; # epoll enabled
237 if (defined $opt_noepoll)
239 $config{USE_EPOLL} = "n";
241 $config{USE_PORTS} = "y"; # epoll enabled
242 if (defined $opt_noports)
244 $config{USE_PORTS} = "n";
246 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
247 $config{OSNAME} = $^O; # Operating System Name
248 $config{IS_DARWIN} = "NO"; # Is OSX?
249 $config{STARTSCRIPT} = "inspircd"; # start script?
250 $config{DESTINATION} = "BASE"; # Is target path.
251 if ($config{OSNAME} =~ /darwin/i)
253 $config{IS_DARWIN} = "YES";
254 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
255 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
257 elsif ($config{OSNAME} =~ /freebsd/i)
259 chomp(my $fbsd_version = `uname -r`);
260 $fbsd_version =~ s/^(\d+\.\d+).*/$1/g;
261 $config{CC} = $fbsd_version >= 10.0 ? 'clang++' : 'g++';
265 $config{CC} = "g++"; # C++ compiler
269 $config{CC} = $opt_cc;
271 our $exec = $config{CC} . " -dumpversion | cut -c 1";
272 chomp($config{GCCVER} = `$exec`); # Major GCC Version
273 $exec = $config{CC} . " -dumpversion | cut -c 3";
274 chomp($config{GCCMINOR} = `$exec`);
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 $exec = $config{CC} . " -dumpversion | cut -c 1";
351 chomp($config{GCCVER} = `$exec`); # Major GCC Version
352 $exec = $config{CC} . " -dumpversion | cut -c 3";
353 chomp($config{GCCMINOR} = `$exec`);
355 printf "Checking if stdint.h exists... ";
356 $config{HAS_STDINT} = "true";
358 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
359 if ($config{HAS_STDINT} eq "true") {
362 print "yes\n" if $config{HAS_STDINT} eq "true";
363 print "no\n" if $config{HAS_STDINT} eq "false";
365 printf "Checking if strlcpy exists... ";
366 $config{HAS_STRLCPY} = test_compile('strlcpy');
367 print $config{HAS_STRLCPY} ? "yes\n" : "no\n";
369 printf "Checking if kqueue exists... ";
370 $has_kqueue = test_compile('kqueue');
371 print $has_kqueue ? "yes\n" : "no\n";
373 printf "Checking for epoll support... ";
374 $has_epoll = test_compile('epoll');
375 print $has_epoll ? "yes\n" : "no\n";
377 printf "Checking for eventfd support... ";
378 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
379 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
381 printf "Checking if Solaris I/O completion ports are available... ";
383 our $system = `uname -s`;
385 $has_ports = 1 if ($system eq "SunOS");
388 my $kernel = `uname -r`;
390 if (($kernel !~ /^5\.1./)) {
394 print "yes\n" if $has_ports == 1;
395 print "no\n" if $has_ports == 0;
397 $config{HAS_EPOLL} = $has_epoll;
398 $config{HAS_KQUEUE} = $has_kqueue;
400 printf "Checking for libgnutls... ";
401 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
402 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
404 $config{HAS_GNUTLS} = "y";
407 $config{HAS_GNUTLS} = "n";
411 $config{HAS_GNUTLS} = "n";
414 printf "Checking for openssl... ";
415 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
416 if (defined($openssl_ver) && ($openssl_ver ne "")) {
418 $config{HAS_OPENSSL} = "y";
421 $config{HAS_OPENSSL} = "n";
425 $config{HAS_OPENSSL} = "n";
428 printf "Checking if you are running an ancient, unsupported OS... ";
429 if ($config{OSNAME} =~ /FreeBSD/i)
431 my $version = `uname -r`;
432 if ($version =~ /^4\./)
435 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
436 print "To build, you will need to add the following to CXXFLAGS:\n";
437 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
441 print "no ($version)\n";
446 print "no ($config{OSNAME})\n";
449 ################################################################################
450 # BEGIN INTERACTIVE PART #
451 ################################################################################
456 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
459 my $rev = getrevision();
460 # Display Introduction Message..
462 Welcome to the \e[1mInspIRCd\e[0m configuration program! (\e[1minteractive mode\e[0m)
463 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
465 *** If you are unsure of any of these values, leave it blank for ***
466 *** standard settings that will work, and your server will run ***
467 *** using them. Please consult your IRC network admin if in doubt. ***
469 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
470 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
471 dir, otherwise you won't have a config file!
473 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
474 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
477 print " (Non-SVN build)";
481 $config{CHANGE_COMPILER} = "n";
482 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";
484 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
485 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
486 should NOT be used. You should probably specify a newer compiler.\n\n";
487 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
488 if ($config{CHANGE_COMPILER} =~ /y/i) {
489 print "What command do you want to use to invoke your compiler?\n";
490 print "[\e[1;32m$config{CC}\e[0m] -> ";
491 chomp($config{CC} = <STDIN>);
492 if ($config{CC} eq "") {
495 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
497 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
498 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
499 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
500 if ($config{GCCVER} < 3) {
501 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
505 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
512 # Directory Settings..
513 my $tmpbase = $config{BASE_DIR};
514 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
515 if ($tmpbase ne $config{BASE_DIR}) {
516 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
517 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
518 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
519 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
520 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
523 dir_check("are the configuration files", "CONFIG_DIR");
524 dir_check("are the modules to be compiled to", "MODULE_DIR");
525 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
526 dir_check("are variable data files to be located in", "DATA_DIR");
527 dir_check("are the logs to be stored in", "LOG_DIR");
528 dir_check("do you want the build to take place", "BUILD_DIR");
530 my $chose_hiperf = 0;
532 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?");
534 if ($config{USE_KQUEUE} eq "y") {
539 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?");
541 if ($config{USE_EPOLL} eq "y") {
546 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?");
548 if ($config{USE_PORTS} eq "y") {
553 if (!$chose_hiperf) {
554 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?");
555 if ($config{USE_POLL} ne "y")
557 print "No high-performance socket engines are available, or you chose\n";
558 print "not to enable one. Defaulting to select() engine.\n\n";
562 $config{USE_FREEBSD_BASE_SSL} = "n";
563 $config{USE_FREEBSD_PORTS_SSL} = "n";
564 if ($config{HAS_OPENSSL_PORT} ne "")
566 $config{USE_FREEBSD_PORTS_SSL} = "y";
567 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
568 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";
569 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
571 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
573 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
575 # update to port version
576 $openssl_ver = $config{HAS_OPENSSL_PORT};
581 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
584 $config{USE_SSL} ||= "n";
585 $config{MODUPDATE} ||= 'n';
587 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
589 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
590 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
592 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
593 if ($config{USE_SSL} eq "y")
595 if ($config{HAS_GNUTLS} eq "y")
597 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
598 if ($config{USE_GNUTLS} eq "y")
600 print "\nUsing GnuTLS SSL module.\n";
604 if ($config{HAS_OPENSSL} eq "y")
606 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
607 if ($config{USE_OPENSSL} eq "y")
609 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
616 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
617 print "is in your path.\n\n";
620 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
622 if ($config{MODUPDATE} eq "y") {
623 print "Checking for upgrades to extra and third-party modules... ";
624 system "./modulemanager upgrade";
628 # We are on a POSIX system, we can enable POSIX extras without asking
629 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
633 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
635 print "Sorry, but I couldn't detect GnuTLS. Make sure pkg-config is in your path.\n";
638 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
640 print "Sorry, but I couldn't detect OpenSSL. Make sure pkg-config and openssl are in your path.\n";
645 $config{CERTGEN} ||= 'y';
646 yesno('CERTGEN',"Would you like to generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
648 if ($config{USE_GNUTLS} eq "y") {
649 unless (-r "src/modules/m_ssl_gnutls.cpp") {
650 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
651 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
653 if ($interactive && $config{CERTGEN} eq 'y')
655 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
656 print "SSL certificates not found, generating.. \n\n
657 *************************************************************
658 * Generating the private key may take some time, once done, *
659 * answer the questions which follow. If you are unsure, *
661 *************************************************************\n\n";
662 $failed = make_gnutls_cert();
664 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
666 print "\nCertificate generation complete, copying to config directory... ";
667 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
668 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
673 print "SSL certificates found, skipping.\n\n";
678 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
682 if ($config{USE_OPENSSL} eq "y") {
683 unless (-r "src/modules/m_ssl_openssl.cpp") {
684 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
685 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
688 if ($interactive && $config{CERTGEN} eq 'y')
690 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
691 print "SSL certificates not found, generating.. \n\n
692 *************************************************************
693 * Generating the certificates may take some time, go grab a *
694 * coffee or something. *
695 *************************************************************\n\n";
697 print "\nCertificate generation complete, copying to config directory... ";
698 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
699 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
700 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
703 print "SSL certificates found, skipping.\n\n"
708 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
711 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
712 print "Skipping SSL certificate generation as SSL support is not available.\n\n";
720 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
721 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
722 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
723 print "modules in your config. This configure script has added those modules to the\n";
724 print "build process. For more info, please refer to:\n";
725 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
727 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
728 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
729 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";
732 if ($config{GCCVER} < "3") {
734 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
735 GCC 2.x series compilers only had partial (read as broken) C++ support, and
736 your compile will most likely fail horribly! If you have any problems, do NOT
737 report them to the bugtracker or forums without first upgrading your compiler
738 to a newer 3.x or 4.x (or whatever is available currently) version.
742 ################################################################################
744 ################################################################################
746 # Retrieves the .config.cache file, and loads values into the main config hash.
747 open(CACHE, ".config.cache") or return 0;
750 # Ignore Blank lines, and comments..
753 my ($key, $value) = split("=", $_, 2);
754 $value =~ /^\"(.*)\"$/;
755 # Do something with data here!
763 # Dump the contents of %config
764 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
765 open(FILEHANDLE, ">.config.cache");
766 foreach my $key (keys %config) {
767 print FILEHANDLE "$key=\"$config{$key}\"\n";
773 my ($desc, $hash_key) = @_;
776 print "In what directory $desc?\n";
777 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
778 chomp(my $var = <STDIN>);
780 $var = $config{$hash_key};
782 if ($var =~ /^\~\/(.+)$/) {
783 # Convert it to a full path..
784 $var = resolve_directory($ENV{HOME} . "/" . $1);
786 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
788 # Assume relative Path was given.. fill in the rest.
789 $var = $this . "/$var";
792 $var = resolve_directory($var);
794 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
795 chomp(my $tmp = <STDIN>);
796 if (($tmp eq "") || ($tmp =~ /^y/i)) {
797 # Attempt to Create the Dir..
800 File::Path::mkpath($var, 0, 0777);
803 unless (defined($chk) && -d $var) {
804 print "Unable to create directory. ($var)\n\n";
809 # They said they don't want to create, and we can't install there.
815 # Target exists, but is not a directory.
816 print "File $var exists, but is not a directory.\n\n";
820 # Either Dir Exists, or was created fine.
821 $config{$hash_key} = $var;
829 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
832 my($writeheader) = @_;
833 # First File.. inspircd_config.h
834 chomp(my $incos = `uname -n -s -r`);
835 chomp(my $version = `sh src/version.sh`);
836 chomp(my $revision2 = getrevision());
837 my $branch = "InspIRCd-0.0";
838 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
842 if ($writeheader == 1)
844 print "Writing \e[1;32minspircd_config.h\e[0m\n";
845 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
846 print FILEHANDLE <<EOF;
847 /* Auto generated by configure, do not modify! */
848 #ifndef __CONFIGURATION_AUTO__
849 #define __CONFIGURATION_AUTO__
851 /* this is for windows support. */
852 #define CoreExport /**/
853 #define DllExport /**/
855 #define CONFIG_PATH "$config{CONFIG_DIR}"
856 #define DATA_PATH "$config{DATA_DIR}"
857 #define LOG_PATH "$config{LOG_DIR}"
858 #define MOD_PATH "$config{MODULE_DIR}"
859 #define SOMAXCONN_S "$config{_SOMAXCONN}"
860 #define ENTRYPOINT int main(int argc, char** argv)
863 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
865 if ($config{OSNAME} =~ /SunOS/i) {
866 print FILEHANDLE "#define IS_SOLARIS\n";
868 if ($config{OSNAME} =~ /MINGW32/i) {
869 print FILEHANDLE "#define IS_MINGW\n";
871 if ($config{GCCVER} >= 3) {
872 print FILEHANDLE "#define GCC3\n";
874 if ($config{HAS_STRLCPY} eq "true") {
875 print FILEHANDLE "#define HAS_STRLCPY\n";
877 if ($config{HAS_STDINT} eq "true") {
878 print FILEHANDLE "#define HAS_STDINT\n";
880 if ($config{HAS_EVENTFD} eq 'true') {
881 print FILEHANDLE "#define HAS_EVENTFD\n";
883 if ($config{OSNAME} !~ /DARWIN/i) {
884 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
887 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
888 print FILEHANDLE "#define USE_KQUEUE\n";
889 $config{SOCKETENGINE} = "socketengine_kqueue";
892 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
893 print FILEHANDLE "#define USE_EPOLL\n";
894 $config{SOCKETENGINE} = "socketengine_epoll";
897 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
898 print FILEHANDLE "#define USE_PORTS\n";
899 $config{SOCKETENGINE} = "socketengine_ports";
902 # user didn't choose either epoll or select for their OS.
903 # default them to USE_SELECT (ewwy puke puke)
905 print "no hi-perf, " . $config{USE_POLL};
906 if ($config{USE_POLL} eq "y")
908 print FILEHANDLE "#define USE_POLL\n";
909 $config{SOCKETENGINE} = "socketengine_poll";
913 print FILEHANDLE "#define USE_SELECT\n";
914 $config{SOCKETENGINE} = "socketengine_select";
917 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
920 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
921 print FILEHANDLE <<EOF;
922 #define BRANCH "$branch"
923 #define VERSION "$version"
924 #define REVISION "$revision2"
925 #define SYSTEM "$incos"
929 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
931 open my $fh1, $file or $diff = 1;
932 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
936 if (defined($line1) != defined($line2)) {
938 } elsif (!defined $line1) {
941 $diff = ($line1 ne $line2);
946 rename "$file.tmp", $file;
953 # Write all .in files.
956 my $exe = "inspircd";
958 # Do this once here, and cache it in the .*.inc files,
959 # rather than attempting to read src/version.sh from
960 # compiled code -- we might not have the source to hand.
961 # Fix for bug#177 by Brain.
963 chomp($version = `sh ./src/version.sh`);
964 chomp(my $revision = getrevision());
965 $version = "$version(r$revision)";
967 # We can actually parse any file starting with . and ending with .inc,
968 # but right now we only parse .inspircd.inc to form './inspircd'
969 prepare_dynamic_makefile();
971 my @dotfiles = qw(main.mk inspircd);
972 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
974 foreach my $file (@dotfiles) {
975 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
976 $_ = join '', <FILEHANDLE>;
979 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
982 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
983 STARTSCRIPT DESTINATION SOCKETENGINE LOG_DIR
985 s/\@$var\@/$config{$var}/g;
987 s/\@EXECUTABLE\@/$exe/ if defined $exe;
988 s/\@VERSION\@/$version/ if defined $version;
990 if ($file eq 'main.mk') {
991 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
994 s/\@IFDEF (\S+)/ifdef $1/g;
995 s/\@IFNDEF (\S+)/ifndef $1/g;
996 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
997 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1000 s/ *\@BSD_ONLY .*\n//g;
1002 s/\@DO_EXPORT (.*)/export $1/g;
1003 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1007 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1009 s/\@IFDEF (\S+)/.if defined($1)/g;
1010 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1011 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1012 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1016 s/ *\@GNU_ONLY .*\n//g;
1018 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1019 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1023 print "Writing \e[1;32m$file\e[0m ...\n";
1024 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1025 print FILEHANDLE $_;
1030 chmod 0755, 'inspircd';
1036 for my $mod (@modlist) {
1037 getcompilerflags("src/modules/m_$mod.cpp");
1038 getlinkerflags("src/modules/m_$mod.cpp");
1042 sub prepare_dynamic_makefile
1048 $config{USE_EPOLL} = 0;
1052 $config{USE_KQUEUE} = 0;
1056 $config{USE_PORTS} = 0;
1060 # Routine to list out the extra/ modules that have been enabled.
1061 # Note: when getting any filenames out and comparing, it's important to lc it if the
1062 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1063 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1064 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1065 sub list_extras () {
1068 my $srcdir = File::Spec->catdir("src", "modules");
1069 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1072 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1073 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1076 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1077 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1080 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1082 EXTRA: for my $extra (@extras) {
1083 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1084 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1085 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1086 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1087 if (-l $abs_source) {
1088 # Symlink, is it in the right place?
1089 my $targ = readlink($abs_source);
1090 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1091 if ($abs_targ eq $abs_extra) {
1092 $extras{$extra} = "\e[32;1menabled\e[0m";
1094 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1096 } elsif (-e $abs_source) {
1097 my ($devext, $inoext) = stat($abs_extra);
1098 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1100 if ($devsrc == $devext && $inosrc == $inoext) {
1101 $extras{$extra} = "\e[32;1menabled\e[0m";
1103 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1106 open my $extfd, "<", $abs_extra;
1107 open my $srcfd, "<", $abs_source;
1109 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1110 $extras{$extra} = "\e[32;1menabled\e[0m";
1112 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1116 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1119 # Now let's add dependency info
1120 for my $extra (keys(%extras)) {
1121 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1122 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1123 my @deps = split / +/, getdependencies($abs_extra);
1124 for my $dep (@deps) {
1125 if (exists($extras{$dep})) {
1126 my $ref = \$extras{$dep}; # Take reference.
1127 if ($$ref !~ m/needed by/) {
1128 # First dependency found.
1129 if ($$ref =~ m/enabled/) {
1130 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1132 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1133 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1136 if ($$ref =~ m/enabled/) {
1137 $$ref .= ", \e[32;1m$extra\e[0m";
1139 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1145 for my $extra (sort {$a cmp $b} keys(%extras)) {
1146 my $text = $extras{$extra};
1147 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1148 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1150 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1153 return keys(%extras) if wantarray; # Can be used by manage_extras.
1156 sub enable_extras (@) {
1158 for my $extra (@extras) {
1159 my $extrapath = "src/modules/extra/$extra";
1160 if (!-e $extrapath) {
1161 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1164 my $source = "src/modules/$extra";
1166 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1169 # Get dependencies, and add them to be processed.
1170 my @deps = split / +/, getdependencies($extrapath);
1171 for my $dep (@deps) {
1172 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1173 if (!-e "src/modules/$dep") {
1174 if (-e "src/modules/extra/$dep") {
1175 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1178 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";
1182 print "Enabling $extra ... \n";
1183 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1187 sub disable_extras (@)
1189 opendir my $dd, "src/modules/extra/";
1190 my @files = readdir($dd);
1193 EXTRA: for my $extra (@extras) {
1194 my $extrapath = "src/modules/extra/$extra";
1195 my $source = "src/modules/$extra";
1196 if (!-e $extrapath) {
1197 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1200 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1201 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";
1204 # Check if anything needs this.
1205 for my $file (@files) {
1206 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1207 # File depends on this extra...
1208 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1209 # And is both enabled and not about to be disabled.
1210 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1211 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1217 print "Disabling $extra ... \n";
1218 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";