2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2009 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,
54 sub enable_extras (@);
56 sub disable_extras (@);
59 my @opt_disableextras;
62 'enable-gnutls' => \$opt_use_gnutls,
63 'rebuild' => \$opt_rebuild,
64 'enable-openssl' => \$opt_use_openssl,
65 'disable-interactive' => \$opt_nointeractive,
66 'enable-ports' => \$opt_ports,
67 'enable-epoll' => \$opt_epoll,
68 'enable-kqueue' => \$opt_kqueue,
69 'disable-ports' => \$opt_noports,
70 'disable-epoll' => \$opt_noepoll,
71 'disable-kqueue' => \$opt_nokqueue,
72 'disable-ipv6' => \$opt_noipv6,
73 'with-cc=s' => \$opt_cc,
74 'with-maxbuf=i' => \$opt_maxbuf,
75 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
76 'prefix=s' => \$opt_base_dir,
77 'config-dir=s' => \$opt_config_dir,
78 'module-dir=s' => \$opt_module_dir,
79 'binary-dir=s' => \$opt_binary_dir,
80 'library-dir=s' => \$opt_library_dir,
81 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
82 'help' => sub { showhelp(); },
83 'update' => sub { update(); },
84 'svnupdate' => sub { svnupdate(); },
85 'clean' => sub { clean(); },
86 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
87 'enable-extras=s@' => \@opt_enableextras, # ^
88 'disable-extras=s@' => \@opt_disableextras, # ^
89 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
90 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
93 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
94 @opt_enableextras = split /,/, join(',', @opt_enableextras);
95 @opt_disableextras = split /,/, join(',', @opt_disableextras);
96 enable_extras(@opt_enableextras);
97 disable_extras(@opt_disableextras);
99 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
103 our $non_interactive = (
104 (defined $opt_library_dir) ||
105 (defined $opt_base_dir) ||
106 (defined $opt_config_dir) ||
107 (defined $opt_module_dir) ||
108 (defined $opt_base_dir) ||
109 (defined $opt_binary_dir) ||
110 (defined $opt_nointeractive) ||
112 (defined $opt_noipv6) ||
113 (defined $opt_kqueue) ||
114 (defined $opt_epoll) ||
115 (defined $opt_ports) ||
116 (defined $opt_use_openssl) ||
117 (defined $opt_nokqueue) ||
118 (defined $opt_noepoll) ||
119 (defined $opt_noports) ||
120 (defined $opt_maxbuf) ||
121 (defined $opt_use_gnutls) ||
122 (defined $opt_freebsd_port)
124 our $interactive = !$non_interactive;
126 chomp(our $topdir = getcwd());
127 our $this = resolve_directory($topdir); # PWD, Regardless.
128 our @modlist = (); # Declare for Module List..
129 our %config = (); # Initiate Configuration Hash..
130 $config{ME} = resolve_directory($topdir); # Present Working Directory
132 $config{BASE_DIR} = $config{ME};
134 if (defined $opt_base_dir)
136 $config{BASE_DIR} = $opt_base_dir;
139 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
140 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
141 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
143 if (defined $opt_config_dir)
145 $config{CONFIG_DIR} = $opt_config_dir;
147 if (defined $opt_module_dir)
149 $config{MODULE_DIR} = $opt_module_dir;
151 if (defined $opt_binary_dir)
153 $config{BINARY_DIR} = $opt_binary_dir;
155 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
157 if (defined $opt_freebsd_port)
159 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
160 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
161 $config{USE_FREEBSD_BASE_SSL} = "n";
165 if ($^O eq "freebsd")
167 # default: use base ssl
168 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
169 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
173 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
174 $config{HAS_OPENSSL_PORT} = "";
178 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
179 chomp(our $openssl_ver = $config{HAS_OPENSSL});
180 $config{USE_GNUTLS} = "n";
181 if (defined $opt_use_gnutls)
183 $config{USE_GNUTLS} = "y"; # Use gnutls.
185 $config{USE_OPENSSL} = "n"; # Use openssl.
186 if (defined $opt_use_openssl)
188 $config{USE_OPENSSL} = "y";
191 # no, let's not change these.
192 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
193 if (!defined $opt_disable_debug)
195 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
199 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
202 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
203 $config{HAS_STDINT} = "false"; # stdint.h check
204 $config{USE_KQUEUE} = "y"; # kqueue enabled
205 if (defined $opt_kqueue)
207 $config{USE_KQUEUE} = "y";
209 if (defined $opt_nokqueue)
211 $config{USE_KQUEUE} = "n";
213 $config{USE_POLL} = "y"; # poll enabled
214 $config{USE_EPOLL} = "y"; # epoll enabled
215 if (defined $opt_epoll)
217 $config{USE_EPOLL} = "y";
219 if (defined $opt_noepoll)
221 $config{USE_EPOLL} = "n";
223 $config{USE_PORTS} = "y"; # epoll enabled
224 if (defined $opt_ports)
226 $config{USE_PORTS} = "y";
228 if (defined $opt_noports)
230 $config{USE_PORTS} = "n";
232 $config{IPV6} = "y"; # IPv6 support
233 if (defined $opt_noipv6)
237 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
238 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
239 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
240 $config{OSNAME} = $^O; # Operating System Name
241 $config{IS_DARWIN} = "NO"; # Is OSX?
242 $config{STARTSCRIPT} = "inspircd"; # start script?
243 $config{DESTINATION} = "BASE"; # Is target path.
244 $config{EXTRA_DIR} = ""; # Is empty.
245 if ($config{OSNAME} =~ /darwin/i)
247 $config{IS_DARWIN} = "YES";
248 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
249 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
250 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
252 $config{CC} = "g++"; # C++ compiler
255 $config{CC} = $opt_cc;
257 our $exec = $config{CC} . " -dumpversion | cut -c 1";
258 chomp($config{GCCVER} = `$exec`); # Major GCC Version
259 $exec = $config{CC} . " -dumpversion | cut -c 3";
260 chomp($config{GCCMINOR} = `$exec`);
261 $config{MAXBUF} = "512"; # Max buffer size
263 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
264 $config{HAS_OPENSSL} = $1;
266 $config{HAS_OPENSSL} = "";
269 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
270 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
274 # Get and Set some important vars..
279 unlink(".config.cache");
282 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
287 chomp($topdir = getcwd());
288 $this = resolve_directory($topdir); # PWD, Regardless.
290 # Does the cache file exist?
292 # No, No it doesn't.. *BASH*
293 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
296 # We've Loaded the cache file and all our variables..
297 print "Updating files...\n";
298 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
300 print "Disabling debug information (-g).\n";
301 $config{OPTIMISATI} = "";
303 $has_epoll = $config{HAS_EPOLL};
304 $has_ports = $config{HAS_PORTS};
305 $has_kqueue = $config{HAS_KQUEUE};
314 print "Configure update failed: $@\n";
322 open(FH,"<.svn/entries") or $fail = 1;
324 print "This is not an SVN copy of InspIRCd.\n";
331 open my $fd, "-|", "svn update";
332 my $configurechanged = 0; # Needs ./configure -update
333 my $rootincchanged = 0;
335 while (defined(my $line = <$fd>))
339 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
340 ($action, $file) = ($1, $2);
343 push @conflicted, $file;
344 if ($file eq "configure")
346 $configurechanged = 1;
348 elsif ($file =~ m/^\..*\.inc$/)
353 elsif ($action eq "U" || $action eq "G")
355 if ($file eq "configure")
357 $configurechanged = 1;
359 elsif ($file =~ m/^\..*\.inc$/)
365 unless (close $fd) # close() waits for exit and returns false if the command failed
369 print STDERR "Problem updating from SVN, please check above for errors\n";
373 print STDERR "Failed to run SVN: $!\n";
377 if (scalar(@conflicted) > 0)
379 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
380 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
381 print "Conflicted files: " . join ", ", @conflicted . "\n";
384 if ($configurechanged)
386 system("perl configure -update");
390 print "No need to update Makefiles.\n";
392 if (defined $opt_rebuild) {
393 system("make install");
401 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
402 $fail ||= system "./test_$feature";
403 unlink "test_$feature";
407 print "Running non-interactive configure...\n" unless $interactive;
408 print "Checking for cache from previous configure... ";
409 print ((!getcache()) ? "not found\n" : "found\n");
410 $config{SYSTEM} = lc $^O;
411 print "Checking operating system version... $config{SYSTEM}\n";
413 printf "Checking if stdint.h exists... ";
414 $config{HAS_STDINT} = "true";
416 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
417 if ($config{HAS_STDINT} eq "true") {
420 print "yes\n" if $config{HAS_STDINT} eq "true";
421 print "no\n" if $config{HAS_STDINT} eq "false";
423 printf "Checking if strlcpy exists... ";
424 # Perform the strlcpy() test..
425 $config{HAS_STRLCPY} = "false";
427 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
429 while (defined(my $line = <STRLCPY>)) {
431 # try and find the delcaration of:
432 # size_t strlcpy(...)
433 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
434 $config{HAS_STRLCPY} = "true";
439 print "yes\n" if $config{HAS_STRLCPY} eq "true";
440 print "no\n" if $config{HAS_STRLCPY} eq "false";
442 printf "Checking if kqueue exists... ";
445 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
447 while (defined(my $line = <KQUEUE>)) {
449 # try and find the delcaration of:
451 if ($line =~ /int(\0x9|\s)+kqueue/) {
457 print "yes\n" if $has_kqueue == 1;
458 print "no\n" if $has_kqueue == 0;
460 printf "Checking for epoll support... ";
461 $has_epoll = test_compile('epoll');
462 print $has_epoll ? "yes\n" : "no\n";
464 printf "Checking for eventfd support... ";
465 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
466 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
468 printf "Checking if Solaris I/O completion ports are available... ";
470 our $system = `uname -s`;
472 $has_ports = 1 if ($system eq "SunOS");
475 my $kernel = `uname -r`;
477 if (($kernel !~ /^5\.1./)) {
481 print "yes\n" if $has_ports == 1;
482 print "no\n" if $has_ports == 0;
484 $config{HAS_EPOLL} = $has_epoll;
485 $config{HAS_KQUEUE} = $has_kqueue;
487 printf "Checking for libgnutls... ";
488 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
489 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
491 $config{HAS_GNUTLS} = "y";
494 $config{HAS_GNUTLS} = "n";
498 $config{HAS_GNUTLS} = "n";
501 printf "Checking for openssl... ";
502 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
503 if (defined($openssl_ver) && ($openssl_ver ne "")) {
505 $config{HAS_OPENSSL} = "y";
508 $config{HAS_OPENSSL} = "n";
512 $config{HAS_OPENSSL} = "n";
515 printf "Checking if you are running an ancient, unsupported OS... ";
516 if ($config{OSNAME} =~ /FreeBSD/i)
518 my $version = `uname -r`;
519 if ($version =~ /^4\./)
522 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
523 print "To build, you will need to add the following to CXXFLAGS:\n";
524 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
528 print "no ($version)\n";
533 print "no ($config{OSNAME})\n";
536 print "Checking for upgrades to extra and third party modules... ";
537 system "./modulemanager upgrade";
539 ################################################################################
540 # BEGIN INTERACTIVE PART #
541 ################################################################################
546 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
549 my $rev = getrevision();
550 # Display Introduction Message..
552 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
553 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
555 *** If you are unsure of any of these values, leave it blank for ***
556 *** standard settings that will work, and your server will run ***
557 *** using them. Please consult your IRC network admin if in doubt. ***
559 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
560 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
561 dir, otherwise you won't have a config file!
563 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
564 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
567 print " (Non-SVN build)";
571 $config{CHANGE_COMPILER} = "n";
572 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";
574 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
575 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
576 should NOT be used. You should probably specify a newer compiler.\n\n";
577 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
578 if ($config{CHANGE_COMPILER} =~ /y/i) {
579 print "What command do you want to use to invoke your compiler?\n";
580 print "[\e[1;32m$config{CC}\e[0m] -> ";
581 chomp($config{CC} = <STDIN>);
582 if ($config{CC} eq "") {
585 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
587 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
588 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
589 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
590 if ($config{GCCVER} < 3) {
591 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
595 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
602 # Directory Settings..
603 my $tmpbase = $config{BASE_DIR};
604 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
605 if ($tmpbase ne $config{BASE_DIR}) {
606 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
607 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
608 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
611 dir_check("are the configuration files", "CONFIG_DIR");
612 dir_check("are the modules to be compiled to", "MODULE_DIR");
613 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
614 dir_check("do you want the build to take place", "BUILD_DIR");
616 my $chose_hiperf = 0;
618 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?");
620 if ($config{USE_KQUEUE} eq "y") {
625 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?");
627 if ($config{USE_EPOLL} eq "y") {
632 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?");
634 if ($config{USE_PORTS} eq "y") {
639 if (!$chose_hiperf) {
640 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?");
641 if ($config{USE_POLL} ne "y")
643 print "No high-performance socket engines are available, or you chose\n";
644 print "not to enable one. Defaulting to select() engine.\n\n";
648 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
651 $config{USE_FREEBSD_BASE_SSL} = "n";
652 $config{USE_FREEBSD_PORTS_SSL} = "n";
653 if ($config{HAS_OPENSSL_PORT} ne "")
655 $config{USE_FREEBSD_PORTS_SSL} = "y";
656 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
657 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";
658 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
660 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
662 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
664 # update to port version
665 $openssl_ver = $config{HAS_OPENSSL_PORT};
670 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
673 $config{USE_SSL} = "n";
675 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
677 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
678 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
680 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
681 if ($config{USE_SSL} eq "y")
683 if ($config{HAS_GNUTLS} eq "y")
685 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
686 if ($config{USE_GNUTLS} eq "y")
688 print "\nUsing GnuTLS SSL module.\n";
692 if ($config{HAS_OPENSSL} eq "y")
694 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
695 if ($config{USE_OPENSSL} eq "y")
697 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
704 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
705 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
711 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
713 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
716 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
718 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
723 $config{CERTGEN} ||= 'y';
724 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
726 if ($config{USE_GNUTLS} eq "y") {
727 unless (-r "src/modules/m_ssl_gnutls.cpp") {
728 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
729 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
731 if ($interactive && $config{CERTGEN} eq 'y')
733 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
734 print "SSL Certificates Not found, Generating.. \n\n
735 *************************************************************
736 * Generating the Private Key may take some time, go grab a *
737 * Coffee. Even better, to generate some more entropy if it *
738 * is taking a while, open another console and type du / a *
739 * few times and get that HD going :) Then answer the *
740 * Questions which follow. If you are unsure, just hit enter *
741 *************************************************************\n\n";
742 $failed = make_gnutls_cert();
744 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
746 print "\nCertificate generation complete, copying to config directory... ";
747 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
748 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
753 print "SSL Certificates found, skipping.\n\n";
758 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
762 if ($config{USE_OPENSSL} eq "y") {
763 unless (-r "src/modules/m_ssl_openssl.cpp") {
764 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
765 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
768 if ($interactive && $config{CERTGEN} eq 'y')
770 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
771 print "SSL Certificates Not found, Generating.. \n\n
772 *************************************************************
773 * Generating the certificates may take some time, go grab a *
774 * coffee, or something. *
775 *************************************************************\n\n";
777 print "\nCertificate generation complete, copying to config directory... ";
778 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
779 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
780 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
783 print "SSL Certificates found, skipping.\n\n"
788 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
791 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
792 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
800 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
801 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
802 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
803 print "modules in your config. This configure script has added those modules to the\n";
804 print "build process. For more info please refer to:\n";
805 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
807 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
808 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
809 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";
812 if ($config{GCCVER} < "3") {
814 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
815 GCC 2.x series compilers only had partial (read as broken) C++ support, and
816 your compile will most likely fail horribly! If you have any problems, do NOT
817 report them to the bugtracker or forums without first upgrading your compiler
818 to a newer 3.x or 4.x (or whatever is available currently) version.
822 ################################################################################
824 ################################################################################
826 # Retrieves the .config.cache file, and loads values into the main config hash.
827 open(CACHE, ".config.cache") or return 0;
830 # Ignore Blank lines, and comments..
833 my ($key, $value) = split("=", $_, 2);
834 $value =~ /^\"(.*)\"$/;
835 # Do something with data here!
843 # Dump the contents of %config
844 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
845 open(FILEHANDLE, ">.config.cache");
846 foreach my $key (keys %config) {
847 print FILEHANDLE "$key=\"$config{$key}\"\n";
853 my ($desc, $hash_key) = @_;
856 print "In what directory $desc?\n";
857 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
858 chomp(my $var = <STDIN>);
860 $var = $config{$hash_key};
862 if ($var =~ /^\~\/(.+)$/) {
863 # Convert it to a full path..
864 $var = resolve_directory($ENV{HOME} . "/" . $1);
866 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
868 # Assume relative Path was given.. fill in the rest.
869 $var = $this . "/$var";
872 $var = resolve_directory($var);
874 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
875 chomp(my $tmp = <STDIN>);
876 if (($tmp eq "") || ($tmp =~ /^y/i)) {
877 # Attempt to Create the Dir..
880 File::Path::mkpath($var, 0, 0777);
883 unless (defined($chk) && -d $var) {
884 print "Unable to create directory. ($var)\n\n";
889 # They said they don't want to create, and we can't install there.
895 # Target exists, but is not a directory.
896 print "File $var exists, but is not a directory.\n\n";
900 # Either Dir Exists, or was created fine.
901 $config{$hash_key} = $var;
909 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
912 my($writeheader) = @_;
913 # First File.. inspircd_config.h
914 chomp(my $incos = `uname -n -s -r`);
915 chomp(my $version = `sh src/version.sh`);
916 chomp(my $revision2 = getrevision());
917 if ($writeheader == 1)
919 print "Writing \e[1;32minspircd_config.h\e[0m\n";
920 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
921 print FILEHANDLE <<EOF;
922 /* Auto generated by configure, do not modify! */
923 #ifndef __CONFIGURATION_AUTO__
924 #define __CONFIGURATION_AUTO__
926 /* this is for windows support. */
927 #define CoreExport /**/
928 #define DllExport /**/
930 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
931 #define MOD_PATH "$config{MODULE_DIR}"
932 #define SOMAXCONN_S "$config{_SOMAXCONN}"
933 #define ENTRYPOINT int main(int argc, char** argv)
936 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
938 if ($config{OSNAME} =~ /SunOS/i) {
939 print FILEHANDLE "#define IS_SOLARIS\n";
941 if ($config{OSNAME} =~ /MINGW32/i) {
942 print FILEHANDLE "#define IS_MINGW\n";
944 if ($config{GCCVER} >= 3) {
945 print FILEHANDLE "#define GCC3\n";
948 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
950 ($config{GCCVER} > 4)
952 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
954 if ($config{HAS_STRLCPY} eq "true") {
955 print FILEHANDLE "#define HAS_STRLCPY\n";
957 if ($config{HAS_STDINT} eq "true") {
958 print FILEHANDLE "#define HAS_STDINT\n";
960 if ($config{IPV6} =~ /y/i) {
961 print FILEHANDLE "#define IPV6\n";
963 if ($config{HAS_EVENTFD} eq 'true') {
964 print FILEHANDLE "#define HAS_EVENTFD\n";
967 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
968 print FILEHANDLE "#define USE_KQUEUE\n";
969 $config{SOCKETENGINE} = "socketengine_kqueue";
972 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
973 print FILEHANDLE "#define USE_EPOLL\n";
974 $config{SOCKETENGINE} = "socketengine_epoll";
977 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
978 print FILEHANDLE "#define USE_PORTS\n";
979 $config{SOCKETENGINE} = "socketengine_ports";
982 # user didn't choose either epoll or select for their OS.
983 # default them to USE_SELECT (ewwy puke puke)
985 print "no hi-perf, " . $config{USE_POLL};
986 if ($config{USE_POLL} eq "y")
988 print FILEHANDLE "#define USE_POLL\n";
989 $config{SOCKETENGINE} = "socketengine_poll";
993 print FILEHANDLE "#define USE_SELECT\n";
994 $config{SOCKETENGINE} = "socketengine_select";
997 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1000 open(FILEHANDLE, ">include/inspircd_se_config.h.tmp");
1001 print FILEHANDLE <<EOF;
1002 /* Auto generated by configure, do not modify or commit to svn! */
1003 #ifndef __CONFIGURATION_SOCKETENGINE__
1004 #define __CONFIGURATION_SOCKETENGINE__
1006 #include "socketengines/$config{SOCKETENGINE}.h"
1012 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1013 print FILEHANDLE <<EOF;
1014 #define VERSION "$version"
1015 #define REVISION "$revision2"
1016 #define SYSTEM "$incos"
1020 for my $file (qw(include/inspircd_config.h include/inspircd_se_config.h include/inspircd_version.h)) {
1022 open my $fh1, $file or $diff = 1;
1023 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1027 if (defined($line1) != defined($line2)) {
1029 } elsif (!defined $line1) {
1032 $diff = ($line1 ne $line2);
1037 rename "$file.tmp", $file;
1044 # Write all .in files.
1047 my $exe = "inspircd";
1049 # Do this once here, and cache it in the .*.inc files,
1050 # rather than attempting to read src/version.sh from
1051 # compiled code -- we might not have the source to hand.
1052 # Fix for bug#177 by Brain.
1054 chomp($version = `sh ./src/version.sh`);
1055 chomp(my $revision = getrevision());
1056 $version = "$version(r$revision)";
1058 # We can actually parse any file starting with . and ending with .inc,
1059 # but right now we only parse .inspircd.inc to form './inspircd'
1060 prepare_dynamic_makefile();
1062 print "Writing \e[1;32mMakefiles\e[0m\n";
1064 opendir(DIRHANDLE, $this);
1066 foreach my $name (sort readdir(DIRHANDLE)) {
1067 if ($name =~ /^\.(.+)\.inc$/) {
1070 # Bug #353, omit this on non-darwin
1071 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1073 # All .name.inc files need parsing!
1074 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1075 $_ = join '', <FILEHANDLE>;
1078 print "Writing \e[1;32m$file\e[0m ...\n";
1080 $config{BUILD_DIR} ||= 'build';
1083 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR
1084 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1086 s/\@$var\@/$config{$var}/g;
1088 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1089 s/\@VERSION\@/$version/ if defined $version;
1091 if ($file eq 'Makefile') {
1093 s/\@IFDEF (\S+)/ifdef $1/g;
1094 s/\@IFNDEF (\S+)/ifndef $1/g;
1095 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1096 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1099 s/ *\@BSD_ONLY .*\n//g;
1101 s/\@DO_EXPORT (.*)/export $1/g;
1102 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1106 s/\@IFDEF (\S+)/.if defined($1)/g;
1107 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1108 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1109 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1113 s/ *\@GNU_ONLY .*\n//g;
1115 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1116 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1120 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1121 print FILEHANDLE $_;
1126 closedir(DIRHANDLE);
1128 # Make inspircd executable!
1129 chmod 0744, 'inspircd';
1135 for my $mod (@modlist) {
1136 getcompilerflags("src/modules/m_$mod.cpp");
1137 getlinkerflags("src/modules/m_$mod.cpp");
1141 sub prepare_dynamic_makefile
1147 $config{USE_EPOLL} = 0;
1151 $config{USE_KQUEUE} = 0;
1155 $config{USE_PORTS} = 0;
1159 # Routine to list out the extra/ modules that have been enabled.
1160 # Note: when getting any filenames out and comparing, it's important to lc it if the
1161 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1162 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1163 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1164 sub list_extras () {
1167 my $srcdir = File::Spec->catdir("src", "modules");
1168 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1171 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1172 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1175 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1176 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1179 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1181 EXTRA: for my $extra (@extras) {
1182 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1183 next if ($extra eq '.svn');
1184 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1185 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1186 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1187 if (-l $abs_source) {
1188 # Symlink, is it in the right place?
1189 my $targ = readlink($abs_source);
1190 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1191 if ($abs_targ eq $abs_extra) {
1192 $extras{$extra} = "\e[32;1menabled\e[0m";
1194 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1196 } elsif (-e $abs_source) {
1197 my ($devext, $inoext) = stat($abs_extra);
1198 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1200 if ($devsrc == $devext && $inosrc == $inoext) {
1201 $extras{$extra} = "\e[32;1menabled\e[0m";
1203 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1206 open my $extfd, "<", $abs_extra;
1207 open my $srcfd, "<", $abs_source;
1209 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1210 $extras{$extra} = "\e[32;1menabled\e[0m";
1212 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1216 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1219 # Now let's add dependency info
1220 for my $extra (keys(%extras)) {
1221 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1222 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1223 my @deps = split / +/, getdependencies($abs_extra);
1224 for my $dep (@deps) {
1225 if (exists($extras{$dep})) {
1226 my $ref = \$extras{$dep}; # Take reference.
1227 if ($$ref !~ m/needed by/) {
1228 # First dependency found.
1229 if ($$ref =~ m/enabled/) {
1230 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1232 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1233 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1236 if ($$ref =~ m/enabled/) {
1237 $$ref .= ", \e[32;1m$extra\e[0m";
1239 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1245 for my $extra (sort {$a cmp $b} keys(%extras)) {
1246 my $text = $extras{$extra};
1247 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1248 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1250 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1253 return keys(%extras) if wantarray; # Can be used by manage_extras.
1256 sub enable_extras (@) {
1258 for my $extra (@extras) {
1259 my $extrapath = "src/modules/extra/$extra";
1260 if (!-e $extrapath) {
1261 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1264 my $source = "src/modules/$extra";
1266 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1269 # Get dependencies, and add them to be processed.
1270 my @deps = split / +/, getdependencies($extrapath);
1271 for my $dep (@deps) {
1272 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1273 if (!-e "src/modules/$dep") {
1274 if (-e "src/modules/extra/$dep") {
1275 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1278 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";
1282 print "Enabling $extra ... \n";
1283 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1287 sub disable_extras (@)
1289 opendir my $dd, "src/modules/extra/";
1290 my @files = readdir($dd);
1293 EXTRA: for my $extra (@extras) {
1294 my $extrapath = "src/modules/extra/$extra";
1295 my $source = "src/modules/$extra";
1296 if (!-e $extrapath) {
1297 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1300 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1301 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";
1304 # Check if anything needs this.
1305 for my $file (@files) {
1306 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1307 # File depends on this extra...
1308 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1309 # And is both enabled and not about to be disabled.
1310 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1311 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1317 print "Disabling $extra ... \n";
1318 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";