2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2010 The InspIRCd Development Team
6 # http://wiki.inspircd.org/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
41 # NON-EDITABLE VARIABLES
43 ###############################################################################################
45 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
46 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
47 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port);
49 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir);
53 sub enable_extras (@);
55 sub disable_extras (@);
58 my @opt_disableextras;
61 'enable-gnutls' => \$opt_use_gnutls,
62 'rebuild' => \$opt_rebuild,
63 'enable-openssl' => \$opt_use_openssl,
64 'disable-interactive' => \$opt_nointeractive,
65 'enable-ports' => \$opt_ports,
66 'enable-epoll' => \$opt_epoll,
67 'enable-kqueue' => \$opt_kqueue,
68 'disable-ports' => \$opt_noports,
69 'disable-epoll' => \$opt_noepoll,
70 'disable-kqueue' => \$opt_nokqueue,
71 'disable-ipv6' => \$opt_noipv6,
72 'with-cc=s' => \$opt_cc,
73 'with-maxbuf=i' => \$opt_maxbuf,
74 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
75 'prefix=s' => \$opt_base_dir,
76 'config-dir=s' => \$opt_config_dir,
77 'module-dir=s' => \$opt_module_dir,
78 'binary-dir=s' => \$opt_binary_dir,
79 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
80 'help' => sub { showhelp(); },
81 'update' => sub { update(); },
82 'svnupdate' => sub { svnupdate(); },
83 'clean' => sub { clean(); },
84 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
85 'enable-extras=s@' => \@opt_enableextras, # ^
86 'disable-extras=s@' => \@opt_disableextras, # ^
87 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
88 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
91 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
92 @opt_enableextras = split /,/, join(',', @opt_enableextras);
93 @opt_disableextras = split /,/, join(',', @opt_disableextras);
94 enable_extras(@opt_enableextras);
95 disable_extras(@opt_disableextras);
97 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
101 our $non_interactive = (
102 (defined $opt_base_dir) ||
103 (defined $opt_config_dir) ||
104 (defined $opt_module_dir) ||
105 (defined $opt_base_dir) ||
106 (defined $opt_binary_dir) ||
107 (defined $opt_nointeractive) ||
109 (defined $opt_noipv6) ||
110 (defined $opt_kqueue) ||
111 (defined $opt_epoll) ||
112 (defined $opt_ports) ||
113 (defined $opt_use_openssl) ||
114 (defined $opt_nokqueue) ||
115 (defined $opt_noepoll) ||
116 (defined $opt_noports) ||
117 (defined $opt_maxbuf) ||
118 (defined $opt_use_gnutls) ||
119 (defined $opt_freebsd_port)
121 our $interactive = !$non_interactive;
123 chomp(our $topdir = getcwd());
124 our $this = resolve_directory($topdir); # PWD, Regardless.
125 our @modlist = (); # Declare for Module List..
126 our %config = (); # Initiate Configuration Hash..
127 $config{ME} = resolve_directory($topdir); # Present Working Directory
129 $config{BASE_DIR} = $config{ME}."/run";
131 if (defined $opt_base_dir)
133 $config{BASE_DIR} = $opt_base_dir;
136 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
137 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
138 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
139 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
141 if (defined $opt_config_dir)
143 $config{CONFIG_DIR} = $opt_config_dir;
145 if (defined $opt_module_dir)
147 $config{MODULE_DIR} = $opt_module_dir;
149 if (defined $opt_binary_dir)
151 $config{BINARY_DIR} = $opt_binary_dir;
153 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
155 if (defined $opt_freebsd_port)
157 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
158 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
159 $config{USE_FREEBSD_BASE_SSL} = "n";
163 if ($^O eq "freebsd")
165 # default: use base ssl
166 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
167 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
171 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
172 $config{HAS_OPENSSL_PORT} = "";
176 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
177 chomp(our $openssl_ver = $config{HAS_OPENSSL});
178 $config{USE_GNUTLS} = "n";
179 if (defined $opt_use_gnutls)
181 $config{USE_GNUTLS} = "y"; # Use gnutls.
183 $config{USE_OPENSSL} = "n"; # Use openssl.
184 if (defined $opt_use_openssl)
186 $config{USE_OPENSSL} = "y";
189 # no, let's not change these.
190 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
191 if (!defined $opt_disable_debug)
193 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
197 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
200 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
201 $config{HAS_STDINT} = "false"; # stdint.h check
202 $config{USE_KQUEUE} = "y"; # kqueue enabled
203 if (defined $opt_kqueue)
205 $config{USE_KQUEUE} = "y";
207 if (defined $opt_nokqueue)
209 $config{USE_KQUEUE} = "n";
211 $config{USE_POLL} = "y"; # poll enabled
212 $config{USE_EPOLL} = "y"; # epoll enabled
213 if (defined $opt_epoll)
215 $config{USE_EPOLL} = "y";
217 if (defined $opt_noepoll)
219 $config{USE_EPOLL} = "n";
221 $config{USE_PORTS} = "y"; # epoll enabled
222 if (defined $opt_ports)
224 $config{USE_PORTS} = "y";
226 if (defined $opt_noports)
228 $config{USE_PORTS} = "n";
230 $config{IPV6} = "y"; # IPv6 support
231 if (defined $opt_noipv6)
235 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
236 $config{OSNAME} = $^O; # Operating System Name
237 $config{IS_DARWIN} = "NO"; # Is OSX?
238 $config{STARTSCRIPT} = "inspircd"; # start script?
239 $config{DESTINATION} = "BASE"; # Is target path.
240 $config{EXTRA_DIR} = ""; # Is empty.
241 if ($config{OSNAME} =~ /darwin/i)
243 $config{IS_DARWIN} = "YES";
244 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
245 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
246 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
248 $config{CC} = "g++"; # C++ compiler
251 $config{CC} = $opt_cc;
253 our $exec = $config{CC} . " -dumpversion | cut -c 1";
254 chomp($config{GCCVER} = `$exec`); # Major GCC Version
255 $exec = $config{CC} . " -dumpversion | cut -c 3";
256 chomp($config{GCCMINOR} = `$exec`);
257 $config{MAXBUF} = "512"; # Max buffer size
259 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
260 $config{HAS_OPENSSL} = $1;
262 $config{HAS_OPENSSL} = "";
265 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
266 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
270 # Get and Set some important vars..
275 unlink(".config.cache");
278 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
283 chomp($topdir = getcwd());
284 $this = resolve_directory($topdir); # PWD, Regardless.
286 # Does the cache file exist?
288 # No, No it doesn't.. *BASH*
289 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
292 # We've Loaded the cache file and all our variables..
293 print "Updating files...\n";
294 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
296 print "Disabling debug information (-g).\n";
297 $config{OPTIMISATI} = "";
299 $has_epoll = $config{HAS_EPOLL};
300 $has_ports = $config{HAS_PORTS};
301 $has_kqueue = $config{HAS_KQUEUE};
310 print "Configure update failed: $@\n";
318 open(FH,"<.svn/entries") or $fail = 1;
320 print "This is not an SVN copy of InspIRCd.\n";
327 open my $fd, "-|", "svn update";
328 my $configurechanged = 0; # Needs ./configure -update
329 my $rootincchanged = 0;
331 while (defined(my $line = <$fd>))
335 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
336 ($action, $file) = ($1, $2);
339 push @conflicted, $file;
340 if ($file eq "configure")
342 $configurechanged = 1;
344 elsif ($file =~ m/^\..*\.inc$/)
349 elsif ($action eq "U" || $action eq "G")
351 if ($file eq "configure")
353 $configurechanged = 1;
355 elsif ($file =~ m/^\..*\.inc$/)
361 unless (close $fd) # close() waits for exit and returns false if the command failed
365 print STDERR "Problem updating from SVN, please check above for errors\n";
369 print STDERR "Failed to run SVN: $!\n";
373 if (scalar(@conflicted) > 0)
375 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
376 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
377 print "Conflicted files: " . join ", ", @conflicted . "\n";
380 if ($configurechanged)
382 system("perl configure -update");
386 print "No need to update Makefiles.\n";
388 if (defined $opt_rebuild) {
389 system("make install");
397 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
398 $fail ||= system "./test_$feature";
399 unlink "test_$feature";
403 print "Running non-interactive configure...\n" unless $interactive;
404 print "Checking for cache from previous configure... ";
405 print ((!getcache()) ? "not found\n" : "found\n");
406 $config{SYSTEM} = lc $^O;
407 print "Checking operating system version... $config{SYSTEM}\n";
409 $exec = $config{CC} . " -dumpversion | cut -c 1";
410 chomp($config{GCCVER} = `$exec`); # Major GCC Version
411 $exec = $config{CC} . " -dumpversion | cut -c 3";
412 chomp($config{GCCMINOR} = `$exec`);
414 printf "Checking if stdint.h exists... ";
415 $config{HAS_STDINT} = "true";
417 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
418 if ($config{HAS_STDINT} eq "true") {
421 print "yes\n" if $config{HAS_STDINT} eq "true";
422 print "no\n" if $config{HAS_STDINT} eq "false";
424 printf "Checking if strlcpy exists... ";
425 # Perform the strlcpy() test..
426 $config{HAS_STRLCPY} = "false";
428 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
430 while (defined(my $line = <STRLCPY>)) {
432 # try and find the delcaration of:
433 # size_t strlcpy(...)
434 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
435 $config{HAS_STRLCPY} = "true";
440 print "yes\n" if $config{HAS_STRLCPY} eq "true";
441 print "no\n" if $config{HAS_STRLCPY} eq "false";
443 printf "Checking if kqueue exists... ";
446 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
448 while (defined(my $line = <KQUEUE>)) {
450 # try and find the delcaration of:
452 if ($line =~ /int(\0x9|\s)+kqueue/) {
458 print "yes\n" if $has_kqueue == 1;
459 print "no\n" if $has_kqueue == 0;
461 printf "Checking for epoll support... ";
462 $has_epoll = test_compile('epoll');
463 print $has_epoll ? "yes\n" : "no\n";
465 printf "Checking for eventfd support... ";
466 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
467 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
469 printf "Checking if Solaris I/O completion ports are available... ";
471 our $system = `uname -s`;
473 $has_ports = 1 if ($system eq "SunOS");
476 my $kernel = `uname -r`;
478 if (($kernel !~ /^5\.1./)) {
482 print "yes\n" if $has_ports == 1;
483 print "no\n" if $has_ports == 0;
485 $config{HAS_EPOLL} = $has_epoll;
486 $config{HAS_KQUEUE} = $has_kqueue;
488 printf "Checking for libgnutls... ";
489 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
490 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
492 $config{HAS_GNUTLS} = "y";
495 $config{HAS_GNUTLS} = "n";
499 $config{HAS_GNUTLS} = "n";
502 printf "Checking for openssl... ";
503 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
504 if (defined($openssl_ver) && ($openssl_ver ne "")) {
506 $config{HAS_OPENSSL} = "y";
509 $config{HAS_OPENSSL} = "n";
513 $config{HAS_OPENSSL} = "n";
516 printf "Checking if you are running an ancient, unsupported OS... ";
517 if ($config{OSNAME} =~ /FreeBSD/i)
519 my $version = `uname -r`;
520 if ($version =~ /^4\./)
523 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
524 print "To build, you will need to add the following to CXXFLAGS:\n";
525 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
529 print "no ($version)\n";
534 print "no ($config{OSNAME})\n";
537 ################################################################################
538 # BEGIN INTERACTIVE PART #
539 ################################################################################
544 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
547 my $rev = getrevision();
548 # Display Introduction Message..
550 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
551 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
553 *** If you are unsure of any of these values, leave it blank for ***
554 *** standard settings that will work, and your server will run ***
555 *** using them. Please consult your IRC network admin if in doubt. ***
557 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
558 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
559 dir, otherwise you won't have a config file!
561 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
562 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
565 print " (Non-SVN build)";
569 $config{CHANGE_COMPILER} = "n";
570 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";
572 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
573 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
574 should NOT be used. You should probably specify a newer compiler.\n\n";
575 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
576 if ($config{CHANGE_COMPILER} =~ /y/i) {
577 print "What command do you want to use to invoke your compiler?\n";
578 print "[\e[1;32m$config{CC}\e[0m] -> ";
579 chomp($config{CC} = <STDIN>);
580 if ($config{CC} eq "") {
583 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
585 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
586 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
587 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
588 if ($config{GCCVER} < 3) {
589 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
593 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
600 # Directory Settings..
601 my $tmpbase = $config{BASE_DIR};
602 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
603 if ($tmpbase ne $config{BASE_DIR}) {
604 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
605 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
606 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
609 dir_check("are the configuration files", "CONFIG_DIR");
610 dir_check("are the modules to be compiled to", "MODULE_DIR");
611 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
612 dir_check("do you want the build to take place", "BUILD_DIR");
614 my $chose_hiperf = 0;
616 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?");
618 if ($config{USE_KQUEUE} eq "y") {
623 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?");
625 if ($config{USE_EPOLL} eq "y") {
630 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?");
632 if ($config{USE_PORTS} eq "y") {
637 if (!$chose_hiperf) {
638 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?");
639 if ($config{USE_POLL} ne "y")
641 print "No high-performance socket engines are available, or you chose\n";
642 print "not to enable one. Defaulting to select() engine.\n\n";
646 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
649 $config{USE_FREEBSD_BASE_SSL} = "n";
650 $config{USE_FREEBSD_PORTS_SSL} = "n";
651 if ($config{HAS_OPENSSL_PORT} ne "")
653 $config{USE_FREEBSD_PORTS_SSL} = "y";
654 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
655 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";
656 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
658 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
660 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
662 # update to port version
663 $openssl_ver = $config{HAS_OPENSSL_PORT};
668 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
671 $config{USE_SSL} = "n";
672 $config{MODUPDATE} = 'n';
674 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
676 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
677 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
679 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
680 if ($config{USE_SSL} eq "y")
682 if ($config{HAS_GNUTLS} eq "y")
684 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
685 if ($config{USE_GNUTLS} eq "y")
687 print "\nUsing GnuTLS SSL module.\n";
691 if ($config{HAS_OPENSSL} eq "y")
693 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
694 if ($config{USE_OPENSSL} eq "y")
696 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
703 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
704 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
707 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
709 if ($config{MODUPDATE} eq "y") {
710 print "Checking for upgrades to extra and third party modules... ";
711 system "./modulemanager upgrade";
717 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
719 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
722 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
724 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
729 $config{CERTGEN} ||= 'y';
730 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
732 if ($config{USE_GNUTLS} eq "y") {
733 unless (-r "src/modules/m_ssl_gnutls.cpp") {
734 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
735 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
737 if ($interactive && $config{CERTGEN} eq 'y')
739 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
740 print "SSL Certificates Not found, Generating.. \n\n
741 *************************************************************
742 * Generating the Private Key may take some time, go grab a *
743 * Coffee. Even better, to generate some more entropy if it *
744 * is taking a while, open another console and type du / a *
745 * few times and get that HD going :) Then answer the *
746 * Questions which follow. If you are unsure, just hit enter *
747 *************************************************************\n\n";
748 $failed = make_gnutls_cert();
750 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
752 print "\nCertificate generation complete, copying to config directory... ";
753 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
754 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
759 print "SSL Certificates found, skipping.\n\n";
764 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
768 if ($config{USE_OPENSSL} eq "y") {
769 unless (-r "src/modules/m_ssl_openssl.cpp") {
770 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
771 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
774 if ($interactive && $config{CERTGEN} eq 'y')
776 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
777 print "SSL Certificates Not found, Generating.. \n\n
778 *************************************************************
779 * Generating the certificates may take some time, go grab a *
780 * coffee, or something. *
781 *************************************************************\n\n";
783 print "\nCertificate generation complete, copying to config directory... ";
784 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
785 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
786 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
789 print "SSL Certificates found, skipping.\n\n"
794 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
797 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
798 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
806 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
807 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
808 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
809 print "modules in your config. This configure script has added those modules to the\n";
810 print "build process. For more info please refer to:\n";
811 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
813 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
814 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
815 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";
818 if ($config{GCCVER} < "3") {
820 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
821 GCC 2.x series compilers only had partial (read as broken) C++ support, and
822 your compile will most likely fail horribly! If you have any problems, do NOT
823 report them to the bugtracker or forums without first upgrading your compiler
824 to a newer 3.x or 4.x (or whatever is available currently) version.
828 ################################################################################
830 ################################################################################
832 # Retrieves the .config.cache file, and loads values into the main config hash.
833 open(CACHE, ".config.cache") or return 0;
836 # Ignore Blank lines, and comments..
839 my ($key, $value) = split("=", $_, 2);
840 $value =~ /^\"(.*)\"$/;
841 # Do something with data here!
849 # Dump the contents of %config
850 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
851 open(FILEHANDLE, ">.config.cache");
852 foreach my $key (keys %config) {
853 print FILEHANDLE "$key=\"$config{$key}\"\n";
859 my ($desc, $hash_key) = @_;
862 print "In what directory $desc?\n";
863 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
864 chomp(my $var = <STDIN>);
866 $var = $config{$hash_key};
868 if ($var =~ /^\~\/(.+)$/) {
869 # Convert it to a full path..
870 $var = resolve_directory($ENV{HOME} . "/" . $1);
872 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
874 # Assume relative Path was given.. fill in the rest.
875 $var = $this . "/$var";
878 $var = resolve_directory($var);
880 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
881 chomp(my $tmp = <STDIN>);
882 if (($tmp eq "") || ($tmp =~ /^y/i)) {
883 # Attempt to Create the Dir..
886 File::Path::mkpath($var, 0, 0777);
889 unless (defined($chk) && -d $var) {
890 print "Unable to create directory. ($var)\n\n";
895 # They said they don't want to create, and we can't install there.
901 # Target exists, but is not a directory.
902 print "File $var exists, but is not a directory.\n\n";
906 # Either Dir Exists, or was created fine.
907 $config{$hash_key} = $var;
915 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
918 my($writeheader) = @_;
919 # First File.. inspircd_config.h
920 chomp(my $incos = `uname -n -s -r`);
921 chomp(my $version = `sh src/version.sh`);
922 chomp(my $revision2 = getrevision());
923 if ($writeheader == 1)
925 print "Writing \e[1;32minspircd_config.h\e[0m\n";
926 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
927 print FILEHANDLE <<EOF;
928 /* Auto generated by configure, do not modify! */
929 #ifndef __CONFIGURATION_AUTO__
930 #define __CONFIGURATION_AUTO__
932 /* this is for windows support. */
933 #define CoreExport /**/
934 #define DllExport /**/
936 #define MOD_PATH "$config{MODULE_DIR}"
937 #define SOMAXCONN_S "$config{_SOMAXCONN}"
938 #define ENTRYPOINT int main(int argc, char** argv)
941 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
943 if ($config{OSNAME} =~ /SunOS/i) {
944 print FILEHANDLE "#define IS_SOLARIS\n";
946 if ($config{OSNAME} =~ /MINGW32/i) {
947 print FILEHANDLE "#define IS_MINGW\n";
949 if ($config{GCCVER} >= 3) {
950 print FILEHANDLE "#define GCC3\n";
953 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
955 ($config{GCCVER} > 4)
957 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
959 if ($config{HAS_STRLCPY} eq "true") {
960 print FILEHANDLE "#define HAS_STRLCPY\n";
962 if ($config{HAS_STDINT} eq "true") {
963 print FILEHANDLE "#define HAS_STDINT\n";
965 if ($config{IPV6} =~ /y/i) {
966 print FILEHANDLE "#define IPV6\n";
968 if ($config{HAS_EVENTFD} eq 'true') {
969 print FILEHANDLE "#define HAS_EVENTFD\n";
972 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
973 print FILEHANDLE "#define USE_KQUEUE\n";
974 $config{SOCKETENGINE} = "socketengine_kqueue";
977 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
978 print FILEHANDLE "#define USE_EPOLL\n";
979 $config{SOCKETENGINE} = "socketengine_epoll";
982 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
983 print FILEHANDLE "#define USE_PORTS\n";
984 $config{SOCKETENGINE} = "socketengine_ports";
987 # user didn't choose either epoll or select for their OS.
988 # default them to USE_SELECT (ewwy puke puke)
990 print "no hi-perf, " . $config{USE_POLL};
991 if ($config{USE_POLL} eq "y")
993 print FILEHANDLE "#define USE_POLL\n";
994 $config{SOCKETENGINE} = "socketengine_poll";
998 print FILEHANDLE "#define USE_SELECT\n";
999 $config{SOCKETENGINE} = "socketengine_select";
1002 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1005 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1006 print FILEHANDLE <<EOF;
1007 #define VERSION "$version"
1008 #define REVISION "$revision2"
1009 #define SYSTEM "$incos"
1013 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
1015 open my $fh1, $file or $diff = 1;
1016 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1020 if (defined($line1) != defined($line2)) {
1022 } elsif (!defined $line1) {
1025 $diff = ($line1 ne $line2);
1030 rename "$file.tmp", $file;
1037 # Write all .in files.
1040 my $exe = "inspircd";
1042 # Do this once here, and cache it in the .*.inc files,
1043 # rather than attempting to read src/version.sh from
1044 # compiled code -- we might not have the source to hand.
1045 # Fix for bug#177 by Brain.
1047 chomp($version = `sh ./src/version.sh`);
1048 chomp(my $revision = getrevision());
1049 $version = "$version(r$revision)";
1051 # We can actually parse any file starting with . and ending with .inc,
1052 # but right now we only parse .inspircd.inc to form './inspircd'
1053 prepare_dynamic_makefile();
1055 my @dotfiles = qw(main.mk inspircd);
1056 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1058 foreach my $file (@dotfiles) {
1059 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1060 $_ = join '', <FILEHANDLE>;
1063 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1066 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR
1067 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1069 s/\@$var\@/$config{$var}/g;
1071 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1072 s/\@VERSION\@/$version/ if defined $version;
1074 if ($file eq 'main.mk') {
1075 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1078 s/\@IFDEF (\S+)/ifdef $1/g;
1079 s/\@IFNDEF (\S+)/ifndef $1/g;
1080 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1081 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1084 s/ *\@BSD_ONLY .*\n//g;
1086 s/\@DO_EXPORT (.*)/export $1/g;
1087 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1091 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1093 s/\@IFDEF (\S+)/.if defined($1)/g;
1094 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1095 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1096 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1100 s/ *\@GNU_ONLY .*\n//g;
1102 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1103 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1107 print "Writing \e[1;32m$file\e[0m ...\n";
1108 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1109 print FILEHANDLE $_;
1114 chmod 0755, 'inspircd';
1120 for my $mod (@modlist) {
1121 getcompilerflags("src/modules/m_$mod.cpp");
1122 getlinkerflags("src/modules/m_$mod.cpp");
1126 sub prepare_dynamic_makefile
1132 $config{USE_EPOLL} = 0;
1136 $config{USE_KQUEUE} = 0;
1140 $config{USE_PORTS} = 0;
1144 # Routine to list out the extra/ modules that have been enabled.
1145 # Note: when getting any filenames out and comparing, it's important to lc it if the
1146 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1147 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1148 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1149 sub list_extras () {
1152 my $srcdir = File::Spec->catdir("src", "modules");
1153 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1156 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1157 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1160 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1161 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1164 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1166 EXTRA: for my $extra (@extras) {
1167 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1168 next if ($extra eq '.svn');
1169 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1170 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1171 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1172 if (-l $abs_source) {
1173 # Symlink, is it in the right place?
1174 my $targ = readlink($abs_source);
1175 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1176 if ($abs_targ eq $abs_extra) {
1177 $extras{$extra} = "\e[32;1menabled\e[0m";
1179 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1181 } elsif (-e $abs_source) {
1182 my ($devext, $inoext) = stat($abs_extra);
1183 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1185 if ($devsrc == $devext && $inosrc == $inoext) {
1186 $extras{$extra} = "\e[32;1menabled\e[0m";
1188 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1191 open my $extfd, "<", $abs_extra;
1192 open my $srcfd, "<", $abs_source;
1194 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1195 $extras{$extra} = "\e[32;1menabled\e[0m";
1197 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1201 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1204 # Now let's add dependency info
1205 for my $extra (keys(%extras)) {
1206 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1207 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1208 my @deps = split / +/, getdependencies($abs_extra);
1209 for my $dep (@deps) {
1210 if (exists($extras{$dep})) {
1211 my $ref = \$extras{$dep}; # Take reference.
1212 if ($$ref !~ m/needed by/) {
1213 # First dependency found.
1214 if ($$ref =~ m/enabled/) {
1215 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1217 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1218 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1221 if ($$ref =~ m/enabled/) {
1222 $$ref .= ", \e[32;1m$extra\e[0m";
1224 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1230 for my $extra (sort {$a cmp $b} keys(%extras)) {
1231 my $text = $extras{$extra};
1232 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1233 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1235 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1238 return keys(%extras) if wantarray; # Can be used by manage_extras.
1241 sub enable_extras (@) {
1243 for my $extra (@extras) {
1244 my $extrapath = "src/modules/extra/$extra";
1245 if (!-e $extrapath) {
1246 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1249 my $source = "src/modules/$extra";
1251 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1254 # Get dependencies, and add them to be processed.
1255 my @deps = split / +/, getdependencies($extrapath);
1256 for my $dep (@deps) {
1257 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1258 if (!-e "src/modules/$dep") {
1259 if (-e "src/modules/extra/$dep") {
1260 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1263 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";
1267 print "Enabling $extra ... \n";
1268 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1272 sub disable_extras (@)
1274 opendir my $dd, "src/modules/extra/";
1275 my @files = readdir($dd);
1278 EXTRA: for my $extra (@extras) {
1279 my $extrapath = "src/modules/extra/$extra";
1280 my $source = "src/modules/$extra";
1281 if (!-e $extrapath) {
1282 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1285 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1286 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";
1289 # Check if anything needs this.
1290 for my $file (@files) {
1291 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1292 # File depends on this extra...
1293 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1294 # And is both enabled and not about to be disabled.
1295 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1296 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1302 print "Disabling $extra ... \n";
1303 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";