4 # InspIRCd -- Internet Relay Chat Daemon
6 # Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
7 # Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
8 # Copyright (C) 2003, 2006-2008 Craig Edwards <craigedwards@brainbox.cc>
9 # Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
10 # Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
11 # Copyright (C) 2007 John Brooks <john.brooks@dereferenced.net>
12 # Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
13 # Copyright (C) 2003-2006 Craig McLure <craig@chatspike.net>
15 # This file is part of InspIRCd. InspIRCd is free software: you can
16 # redistribute it and/or modify it under the terms of the GNU General Public
17 # License as published by the Free Software Foundation, version 2.
19 # This program is distributed in the hope that it will be useful, but WITHOUT
20 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
34 use warnings FATAL => qw(all);
38 $Data::Dumper::Sortkeys = 1;
39 $Data::Dumper::Useqq = 1;
47 # Utility functions for our buildsystem
51 ###############################################################################################
53 # NON-EDITABLE VARIABLES
55 ###############################################################################################
57 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
58 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
59 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
60 $opt_system, $opt_uid);
62 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_data_dir, $opt_log_dir);
66 sub enable_extras (@);
68 sub disable_extras (@);
71 my @opt_disableextras;
74 'enable-gnutls' => \$opt_use_gnutls,
75 'rebuild' => \$opt_rebuild,
76 'system' => \$opt_system,
78 'enable-openssl' => \$opt_use_openssl,
79 'disable-interactive' => \$opt_nointeractive,
80 'enable-ports' => \$opt_ports,
81 'enable-epoll' => \$opt_epoll,
82 'enable-kqueue' => \$opt_kqueue,
83 'disable-ports' => \$opt_noports,
84 'disable-epoll' => \$opt_noepoll,
85 'disable-kqueue' => \$opt_nokqueue,
86 'disable-ipv6' => \$opt_noipv6,
87 'with-cc=s' => \$opt_cc,
88 'with-maxbuf=i' => \$opt_maxbuf,
89 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
90 'prefix=s' => \$opt_base_dir,
91 'config-dir=s' => \$opt_config_dir,
92 'module-dir=s' => \$opt_module_dir,
93 'binary-dir=s' => \$opt_binary_dir,
94 'data-dir=s' => \$opt_data_dir,
95 'log-dir=s' => \$opt_log_dir,
96 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
97 'help' => sub { showhelp(); },
98 'update' => sub { update(); },
99 'clean' => sub { clean(); },
100 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
101 'enable-extras=s@' => \@opt_enableextras, # ^
102 'disable-extras=s@' => \@opt_disableextras, # ^
103 'generate-openssl-cert' => sub { exec './tools/genssl openssl'; },
104 'generate-gnutls-cert' => sub { exec './tools/genssl gnutls'; }
107 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
108 @opt_enableextras = split /,/, join(',', @opt_enableextras);
109 @opt_disableextras = split /,/, join(',', @opt_disableextras);
110 enable_extras(@opt_enableextras);
111 disable_extras(@opt_disableextras);
113 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
117 our $interactive = !(
118 (defined $opt_base_dir) ||
119 (defined $opt_config_dir) ||
120 (defined $opt_module_dir) ||
121 (defined $opt_base_dir) ||
122 (defined $opt_binary_dir) ||
123 (defined $opt_data_dir) ||
124 (defined $opt_log_dir) ||
125 (defined $opt_nointeractive) ||
127 (defined $opt_noipv6) ||
128 (defined $opt_kqueue) ||
129 (defined $opt_epoll) ||
130 (defined $opt_ports) ||
131 (defined $opt_use_openssl) ||
132 (defined $opt_nokqueue) ||
133 (defined $opt_noepoll) ||
134 (defined $opt_noports) ||
135 (defined $opt_maxbuf) ||
136 (defined $opt_system) ||
137 (defined $opt_uid) ||
138 (defined $opt_use_gnutls) ||
139 (defined $opt_freebsd_port)
142 chomp(our $topdir = getcwd());
143 our $this = resolve_directory($topdir); # PWD, Regardless.
144 our @modlist = (); # Declare for Module List..
145 our %config = (); # Initiate Configuration Hash..
146 our $cache_loaded = getcache();
147 $config{ME} = resolve_directory($topdir); # Present Working Directory
149 $config{BASE_DIR} = $config{ME}."/run";
151 if (defined $opt_base_dir) {
152 $config{BASE_DIR} = $opt_base_dir;
153 } elsif (defined $opt_system) {
154 $config{BASE_DIR} = '/var/lib/inspircd';
157 if (defined $opt_system) {
158 $config{UID} = $opt_uid || 'ircd';
159 $config{CONFIG_DIR} = '/etc/inspircd';
160 $config{MODULE_DIR} = '/usr/lib/inspircd';
161 $config{BINARY_DIR} = '/usr/sbin/';
162 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
163 $config{DATA_DIR} = '/var/inspircd';
164 $config{LOG_DIR} = '/var/log/inspircd';
166 $config{UID} = $opt_uid || $<;
167 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
168 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
169 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
170 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
171 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data directory
172 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log directory
175 if (defined $opt_config_dir) {
176 $config{CONFIG_DIR} = $opt_config_dir;
178 if (defined $opt_module_dir) {
179 $config{MODULE_DIR} = $opt_module_dir;
181 if (defined $opt_binary_dir) {
182 $config{BINARY_DIR} = $opt_binary_dir;
184 if (defined $opt_data_dir) {
185 $config{DATA_DIR} = $opt_data_dir;
187 if (defined $opt_log_dir) {
188 $config{LOG_DIR} = $opt_log_dir;
190 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
192 if (defined $opt_freebsd_port)
194 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
195 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
196 $config{USE_FREEBSD_BASE_SSL} = "n";
200 if ($^O eq "freebsd")
202 # default: use base ssl
203 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
204 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
208 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
209 $config{HAS_OPENSSL_PORT} = "";
213 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
214 chomp(our $openssl_ver = $config{HAS_OPENSSL});
215 $config{USE_GNUTLS} = "n";
216 if (defined $opt_use_gnutls)
218 $config{USE_GNUTLS} = "y"; # Use gnutls.
220 $config{USE_OPENSSL} = "n"; # Use openssl.
221 if (defined $opt_use_openssl)
223 $config{USE_OPENSSL} = "y";
226 if (!defined $opt_disable_debug) {
227 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
229 $config{OPTIMISATI} = "-O2";
232 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
233 $config{HAS_STDINT} = "false"; # stdint.h check
234 $config{USE_KQUEUE} = "y"; # kqueue enabled
235 if (defined $opt_nokqueue) {
236 $config{USE_KQUEUE} = "n";
238 $config{USE_POLL} = "y"; # poll enabled
239 $config{USE_EPOLL} = "y"; # epoll enabled
240 if (defined $opt_noepoll)
242 $config{USE_EPOLL} = "n";
244 $config{USE_PORTS} = "y"; # epoll enabled
245 if (defined $opt_noports)
247 $config{USE_PORTS} = "n";
249 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
250 $config{OSNAME} = $^O; # Operating System Name
251 $config{IS_DARWIN} = "NO"; # Is OSX?
252 $config{STARTSCRIPT} = "inspircd"; # start script?
253 $config{DESTINATION} = "BASE"; # Is target path.
254 if ($config{OSNAME} =~ /darwin/i)
256 $config{IS_DARWIN} = "YES";
257 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
258 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
262 $config{CC} = "g++"; # C++ compiler
266 $config{CC} = $opt_cc;
268 our $exec = $config{CC} . " -dumpversion | cut -c 1";
269 chomp($config{GCCVER} = `$exec`); # Major GCC Version
270 $exec = $config{CC} . " -dumpversion | cut -c 3";
271 chomp($config{GCCMINOR} = `$exec`);
272 $config{MAXBUF} = "512"; # Max buffer size
274 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) {
275 $config{HAS_OPENSSL} = $1;
277 $config{HAS_OPENSSL} = "";
280 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
281 if ($config{IS_DARWIN} eq "YES") {
282 print $config{CC} . " was not found! You require clang++ (the LLVM C++ compiler, part of the OSX developer tools) to build InspIRCd!\n";
284 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\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 # Perform the strlcpy() test..
367 $config{HAS_STRLCPY} = "false";
369 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
371 while (defined(my $line = <STRLCPY>)) {
373 # try and find the delcaration of:
374 # size_t strlcpy(...)
375 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
376 $config{HAS_STRLCPY} = "true";
381 print "yes\n" if $config{HAS_STRLCPY} eq "true";
382 print "no\n" if $config{HAS_STRLCPY} eq "false";
384 printf "Checking if kqueue exists... ";
387 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
389 while (defined(my $line = <KQUEUE>)) {
391 # try and find the delcaration of:
393 if ($line =~ /int(\0x9|\s)+kqueue/) {
399 print "yes\n" if $has_kqueue == 1;
400 print "no\n" if $has_kqueue == 0;
402 printf "Checking for epoll support... ";
403 $has_epoll = test_compile('epoll');
404 print $has_epoll ? "yes\n" : "no\n";
406 printf "Checking for eventfd support... ";
407 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
408 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
410 printf "Checking if Solaris I/O completion ports are available... ";
412 our $system = `uname -s`;
414 $has_ports = 1 if ($system eq "SunOS");
417 my $kernel = `uname -r`;
419 if (($kernel !~ /^5\.1./)) {
423 print "yes\n" if $has_ports == 1;
424 print "no\n" if $has_ports == 0;
426 $config{HAS_EPOLL} = $has_epoll;
427 $config{HAS_KQUEUE} = $has_kqueue;
429 printf "Checking for libgnutls... ";
430 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
431 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
433 $config{HAS_GNUTLS} = "y";
436 $config{HAS_GNUTLS} = "n";
440 $config{HAS_GNUTLS} = "n";
443 printf "Checking for openssl... ";
444 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
445 if (defined($openssl_ver) && ($openssl_ver ne "")) {
447 $config{HAS_OPENSSL} = "y";
450 $config{HAS_OPENSSL} = "n";
454 $config{HAS_OPENSSL} = "n";
457 printf "Checking if you are running an ancient, unsupported OS... ";
458 if ($config{OSNAME} =~ /FreeBSD/i)
460 my $version = `uname -r`;
461 if ($version =~ /^4\./)
464 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
465 print "To build, you will need to add the following to CXXFLAGS:\n";
466 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
470 print "no ($version)\n";
475 print "no ($config{OSNAME})\n";
478 ################################################################################
479 # BEGIN INTERACTIVE PART #
480 ################################################################################
485 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
488 my $rev = getrevision();
489 # Display Introduction Message..
491 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
492 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
494 *** If you are unsure of any of these values, leave it blank for ***
495 *** standard settings that will work, and your server will run ***
496 *** using them. Please consult your IRC network admin if in doubt. ***
498 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
499 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
500 dir, otherwise you won't have a config file!
502 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
503 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
506 print " (Non-SVN build)";
510 $config{CHANGE_COMPILER} = "n";
511 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";
513 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
514 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
515 should NOT be used. You should probably specify a newer compiler.\n\n";
516 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
517 if ($config{CHANGE_COMPILER} =~ /y/i) {
518 print "What command do you want to use to invoke your compiler?\n";
519 print "[\e[1;32m$config{CC}\e[0m] -> ";
520 chomp($config{CC} = <STDIN>);
521 if ($config{CC} eq "") {
524 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
526 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
527 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
528 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
529 if ($config{GCCVER} < 3) {
530 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
534 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
541 # Directory Settings..
542 my $tmpbase = $config{BASE_DIR};
543 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
544 if ($tmpbase ne $config{BASE_DIR}) {
545 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
546 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
547 $config{DATA_DIR} = resolve_directory($config{BASE_DIR}."/data"); # Data Directory
548 $config{LOG_DIR} = resolve_directory($config{BASE_DIR}."/logs"); # Log Directory
549 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
552 dir_check("are the configuration files", "CONFIG_DIR");
553 dir_check("are the modules to be compiled to", "MODULE_DIR");
554 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
555 dir_check("are variable data files to be located in", "DATA_DIR");
556 dir_check("are the logs to be stored in", "LOG_DIR");
557 dir_check("do you want the build to take place", "BUILD_DIR");
559 my $chose_hiperf = 0;
561 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?");
563 if ($config{USE_KQUEUE} eq "y") {
568 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?");
570 if ($config{USE_EPOLL} eq "y") {
575 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?");
577 if ($config{USE_PORTS} eq "y") {
582 if (!$chose_hiperf) {
583 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?");
584 if ($config{USE_POLL} ne "y")
586 print "No high-performance socket engines are available, or you chose\n";
587 print "not to enable one. Defaulting to select() engine.\n\n";
591 $config{USE_FREEBSD_BASE_SSL} = "n";
592 $config{USE_FREEBSD_PORTS_SSL} = "n";
593 if ($config{HAS_OPENSSL_PORT} ne "")
595 $config{USE_FREEBSD_PORTS_SSL} = "y";
596 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
597 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";
598 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
600 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
602 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
604 # update to port version
605 $openssl_ver = $config{HAS_OPENSSL_PORT};
610 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
613 $config{USE_SSL} = "n";
614 $config{MODUPDATE} = 'n';
616 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
618 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
619 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
621 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
622 if ($config{USE_SSL} eq "y")
624 if ($config{HAS_GNUTLS} eq "y")
626 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
627 if ($config{USE_GNUTLS} eq "y")
629 print "\nUsing GnuTLS SSL module.\n";
633 if ($config{HAS_OPENSSL} eq "y")
635 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
636 if ($config{USE_OPENSSL} eq "y")
638 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
645 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed and\n";
646 print "is in your path.\n\n";
649 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
651 if ($config{MODUPDATE} eq "y") {
652 print "Checking for upgrades to extra and third party modules... ";
653 system "./modulemanager upgrade";
657 # We are on a POSIX system, we can enable POSIX extras without asking
658 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
662 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
664 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
667 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
669 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
674 $config{CERTGEN} ||= 'y';
675 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
677 if ($config{USE_GNUTLS} eq "y") {
678 unless (-r "src/modules/m_ssl_gnutls.cpp") {
679 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
680 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.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 Private Key may take some time, go grab a *
688 * Coffee. Even better, to generate some more entropy if it *
689 * is taking a while, open another console and type du / a *
690 * few times and get that HD going :) Then answer the *
691 * Questions which follow. If you are unsure, just hit enter *
692 *************************************************************\n\n";
693 $failed = system "./tools/genssl gnutls";
695 print "\n\e[1;32mCertificate generation failed!\e[0m\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";
704 print "SSL Certificates found, skipping.\n\n";
709 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
713 if ($config{USE_OPENSSL} eq "y") {
714 unless (-r "src/modules/m_ssl_openssl.cpp") {
715 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
716 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
719 if ($interactive && $config{CERTGEN} eq 'y')
721 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
722 print "SSL Certificates Not found, Generating.. \n\n
723 *************************************************************
724 * Generating the certificates may take some time, go grab a *
725 * coffee, or something. *
726 *************************************************************\n\n";
727 system "./tools/genssl openssl";
728 print "\nCertificate generation complete, copying to config directory... ";
729 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
730 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
731 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
734 print "SSL Certificates found, skipping.\n\n"
739 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
742 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
743 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
751 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
752 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
753 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
754 print "modules in your config. This configure script has added those modules to the\n";
755 print "build process. For more info please refer to:\n";
756 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
758 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
759 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
760 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";
763 if ($config{GCCVER} < "3") {
765 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
766 GCC 2.x series compilers only had partial (read as broken) C++ support, and
767 your compile will most likely fail horribly! If you have any problems, do NOT
768 report them to the bugtracker or forums without first upgrading your compiler
769 to a newer 3.x or 4.x (or whatever is available currently) version.
773 ################################################################################
775 ################################################################################
777 # Retrieves the .config.cache file, and loads values into the main config hash.
778 open(CACHE, ".config.cache") or return 0;
781 # Ignore Blank lines, and comments..
784 my ($key, $value) = split("=", $_, 2);
785 $value =~ /^\"(.*)\"$/;
786 # Do something with data here!
794 # Dump the contents of %config
795 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
796 open(FILEHANDLE, ">.config.cache");
797 foreach my $key (keys %config) {
798 print FILEHANDLE "$key=\"$config{$key}\"\n";
804 my ($desc, $hash_key) = @_;
807 print "In what directory $desc?\n";
808 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
809 chomp(my $var = <STDIN>);
811 $var = $config{$hash_key};
813 if ($var =~ /^\~\/(.+)$/) {
814 # Convert it to a full path..
815 $var = resolve_directory($ENV{HOME} . "/" . $1);
817 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
819 # Assume relative Path was given.. fill in the rest.
820 $var = $this . "/$var";
823 $var = resolve_directory($var);
825 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
826 chomp(my $tmp = <STDIN>);
827 if (($tmp eq "") || ($tmp =~ /^y/i)) {
828 # Attempt to Create the Dir..
831 File::Path::mkpath($var, 0, 0777);
834 unless (defined($chk) && -d $var) {
835 print "Unable to create directory. ($var)\n\n";
840 # They said they don't want to create, and we can't install there.
846 # Target exists, but is not a directory.
847 print "File $var exists, but is not a directory.\n\n";
851 # Either Dir Exists, or was created fine.
852 $config{$hash_key} = $var;
860 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
863 my($writeheader) = @_;
864 # First File.. inspircd_config.h
865 chomp(my $incos = `uname -n -s -r`);
866 chomp(my $version = `sh src/version.sh`);
867 chomp(my $revision2 = getrevision());
868 my $branch = "InspIRCd-0.0";
869 if ($version =~ /^(InspIRCd-[0-9]+\.[0-9]+)\.[0-9]+/)
873 if ($writeheader == 1)
875 print "Writing \e[1;32minspircd_config.h\e[0m\n";
876 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
877 print FILEHANDLE <<EOF;
878 /* Auto generated by configure, do not modify! */
879 #ifndef __CONFIGURATION_AUTO__
880 #define __CONFIGURATION_AUTO__
882 /* this is for windows support. */
883 #define CoreExport /**/
884 #define DllExport /**/
886 #define CONFIG_PATH "$config{CONFIG_DIR}"
887 #define DATA_PATH "$config{DATA_DIR}"
888 #define LOG_PATH "$config{LOG_DIR}"
889 #define MOD_PATH "$config{MODULE_DIR}"
890 #define SOMAXCONN_S "$config{_SOMAXCONN}"
891 #define ENTRYPOINT int main(int argc, char** argv)
894 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
896 if ($config{OSNAME} =~ /SunOS/i) {
897 print FILEHANDLE "#define IS_SOLARIS\n";
899 if ($config{OSNAME} =~ /MINGW32/i) {
900 print FILEHANDLE "#define IS_MINGW\n";
902 if ($config{GCCVER} >= 3) {
903 print FILEHANDLE "#define GCC3\n";
905 if ($config{HAS_STRLCPY} eq "true") {
906 print FILEHANDLE "#define HAS_STRLCPY\n";
908 if ($config{HAS_STDINT} eq "true") {
909 print FILEHANDLE "#define HAS_STDINT\n";
911 if ($config{HAS_EVENTFD} eq 'true') {
912 print FILEHANDLE "#define HAS_EVENTFD\n";
914 if ($config{OSNAME} !~ /DARWIN/i) {
915 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
918 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
919 print FILEHANDLE "#define USE_KQUEUE\n";
920 $config{SOCKETENGINE} = "socketengine_kqueue";
923 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
924 print FILEHANDLE "#define USE_EPOLL\n";
925 $config{SOCKETENGINE} = "socketengine_epoll";
928 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
929 print FILEHANDLE "#define USE_PORTS\n";
930 $config{SOCKETENGINE} = "socketengine_ports";
933 # user didn't choose either epoll or select for their OS.
934 # default them to USE_SELECT (ewwy puke puke)
936 print "no hi-perf, " . $config{USE_POLL};
937 if ($config{USE_POLL} eq "y")
939 print FILEHANDLE "#define USE_POLL\n";
940 $config{SOCKETENGINE} = "socketengine_poll";
944 print FILEHANDLE "#define USE_SELECT\n";
945 $config{SOCKETENGINE} = "socketengine_select";
948 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
951 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
952 print FILEHANDLE <<EOF;
953 #define BRANCH "$branch"
954 #define VERSION "$version"
955 #define REVISION "$revision2"
956 #define SYSTEM "$incos"
960 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
962 open my $fh1, $file or $diff = 1;
963 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
967 if (defined($line1) != defined($line2)) {
969 } elsif (!defined $line1) {
972 $diff = ($line1 ne $line2);
977 rename "$file.tmp", $file;
984 # Write all .in files.
987 my $exe = "inspircd";
989 # Do this once here, and cache it in the .*.inc files,
990 # rather than attempting to read src/version.sh from
991 # compiled code -- we might not have the source to hand.
992 # Fix for bug#177 by Brain.
994 chomp($version = `sh ./src/version.sh`);
995 chomp(my $revision = getrevision());
996 $version = "$version(r$revision)";
998 # We can actually parse any file starting with . and ending with .inc,
999 # but right now we only parse .inspircd.inc to form './inspircd'
1000 prepare_dynamic_makefile();
1002 my @dotfiles = qw(main.mk inspircd);
1003 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1005 foreach my $file (@dotfiles) {
1006 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1007 $_ = join '', <FILEHANDLE>;
1010 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1013 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR DATA_DIR UID
1014 STARTSCRIPT DESTINATION SOCKETENGINE
1016 s/\@$var\@/$config{$var}/g;
1018 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1019 s/\@VERSION\@/$version/ if defined $version;
1021 if ($file eq 'main.mk') {
1022 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1025 s/\@IFDEF (\S+)/ifdef $1/g;
1026 s/\@IFNDEF (\S+)/ifndef $1/g;
1027 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1028 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1031 s/ *\@BSD_ONLY .*\n//g;
1033 s/\@DO_EXPORT (.*)/export $1/g;
1034 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1038 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1040 s/\@IFDEF (\S+)/.if defined($1)/g;
1041 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1042 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1043 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1047 s/ *\@GNU_ONLY .*\n//g;
1049 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1050 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1054 print "Writing \e[1;32m$file\e[0m ...\n";
1055 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1056 print FILEHANDLE $_;
1061 chmod 0755, 'inspircd';
1067 for my $mod (@modlist) {
1068 getcompilerflags("src/modules/m_$mod.cpp");
1069 getlinkerflags("src/modules/m_$mod.cpp");
1073 sub prepare_dynamic_makefile
1079 $config{USE_EPOLL} = 0;
1083 $config{USE_KQUEUE} = 0;
1087 $config{USE_PORTS} = 0;
1091 # Routine to list out the extra/ modules that have been enabled.
1092 # Note: when getting any filenames out and comparing, it's important to lc it if the
1093 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1094 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1095 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1096 sub list_extras () {
1099 my $srcdir = File::Spec->catdir("src", "modules");
1100 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1103 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1104 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1107 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1108 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1111 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1113 EXTRA: for my $extra (@extras) {
1114 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1115 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1116 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1117 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1118 if (-l $abs_source) {
1119 # Symlink, is it in the right place?
1120 my $targ = readlink($abs_source);
1121 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1122 if ($abs_targ eq $abs_extra) {
1123 $extras{$extra} = "\e[32;1menabled\e[0m";
1125 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1127 } elsif (-e $abs_source) {
1128 my ($devext, $inoext) = stat($abs_extra);
1129 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1131 if ($devsrc == $devext && $inosrc == $inoext) {
1132 $extras{$extra} = "\e[32;1menabled\e[0m";
1134 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1137 open my $extfd, "<", $abs_extra;
1138 open my $srcfd, "<", $abs_source;
1140 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1141 $extras{$extra} = "\e[32;1menabled\e[0m";
1143 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1147 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1150 # Now let's add dependency info
1151 for my $extra (keys(%extras)) {
1152 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1153 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1154 my @deps = split / +/, getdependencies($abs_extra);
1155 for my $dep (@deps) {
1156 if (exists($extras{$dep})) {
1157 my $ref = \$extras{$dep}; # Take reference.
1158 if ($$ref !~ m/needed by/) {
1159 # First dependency found.
1160 if ($$ref =~ m/enabled/) {
1161 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1163 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1164 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1167 if ($$ref =~ m/enabled/) {
1168 $$ref .= ", \e[32;1m$extra\e[0m";
1170 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1176 for my $extra (sort {$a cmp $b} keys(%extras)) {
1177 my $text = $extras{$extra};
1178 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1179 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1181 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1184 return keys(%extras) if wantarray; # Can be used by manage_extras.
1187 sub enable_extras (@) {
1189 for my $extra (@extras) {
1190 my $extrapath = "src/modules/extra/$extra";
1191 if (!-e $extrapath) {
1192 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1195 my $source = "src/modules/$extra";
1197 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1200 # Get dependencies, and add them to be processed.
1201 my @deps = split / +/, getdependencies($extrapath);
1202 for my $dep (@deps) {
1203 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1204 if (!-e "src/modules/$dep") {
1205 if (-e "src/modules/extra/$dep") {
1206 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1209 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";
1213 print "Enabling $extra ... \n";
1214 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1218 sub disable_extras (@)
1220 opendir my $dd, "src/modules/extra/";
1221 my @files = readdir($dd);
1224 EXTRA: for my $extra (@extras) {
1225 my $extrapath = "src/modules/extra/$extra";
1226 my $source = "src/modules/$extra";
1227 if (!-e $extrapath) {
1228 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1231 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1232 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";
1235 # Check if anything needs this.
1236 for my $file (@files) {
1237 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1238 # File depends on this extra...
1239 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1240 # And is both enabled and not about to be disabled.
1241 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1242 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1248 print "Disabling $extra ... \n";
1249 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";