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");
615 my $chose_hiperf = 0;
617 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?");
619 if ($config{USE_KQUEUE} eq "y") {
624 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?");
626 if ($config{USE_EPOLL} eq "y") {
631 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?");
633 if ($config{USE_PORTS} eq "y") {
638 if (!$chose_hiperf) {
639 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?");
640 if ($config{USE_POLL} ne "y")
642 print "No high-performance socket engines are available, or you chose\n";
643 print "not to enable one. Defaulting to select() engine.\n\n";
647 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
650 $config{USE_FREEBSD_BASE_SSL} = "n";
651 $config{USE_FREEBSD_PORTS_SSL} = "n";
652 if ($config{HAS_OPENSSL_PORT} ne "")
654 $config{USE_FREEBSD_PORTS_SSL} = "y";
655 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
656 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";
657 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
659 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
661 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
663 # update to port version
664 $openssl_ver = $config{HAS_OPENSSL_PORT};
669 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
672 $config{USE_SSL} = "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";
710 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
712 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
715 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
717 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
722 $config{CERTGEN} ||= 'y';
723 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
725 if ($config{USE_GNUTLS} eq "y") {
726 unless (-r "src/modules/m_ssl_gnutls.cpp") {
727 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
728 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
730 if ($interactive && $config{CERTGEN} eq 'y')
732 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
733 print "SSL Certificates Not found, Generating.. \n\n
734 *************************************************************
735 * Generating the Private Key may take some time, go grab a *
736 * Coffee. Even better, to generate some more entropy if it *
737 * is taking a while, open another console and type du / a *
738 * few times and get that HD going :) Then answer the *
739 * Questions which follow. If you are unsure, just hit enter *
740 *************************************************************\n\n";
741 $failed = make_gnutls_cert();
743 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
745 print "\nCertificate generation complete, copying to config directory... ";
746 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
747 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
752 print "SSL Certificates found, skipping.\n\n";
757 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
761 if ($config{USE_OPENSSL} eq "y") {
762 unless (-r "src/modules/m_ssl_openssl.cpp") {
763 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
764 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
767 if ($interactive && $config{CERTGEN} eq 'y')
769 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
770 print "SSL Certificates Not found, Generating.. \n\n
771 *************************************************************
772 * Generating the certificates may take some time, go grab a *
773 * coffee, or something. *
774 *************************************************************\n\n";
776 print "\nCertificate generation complete, copying to config directory... ";
777 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
778 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
779 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
782 print "SSL Certificates found, skipping.\n\n"
787 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
790 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
791 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
799 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
800 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
801 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
802 print "modules in your config. This configure script has added those modules to the\n";
803 print "build process. For more info please refer to:\n";
804 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
806 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
807 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
808 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";
811 if ($config{GCCVER} < "3") {
813 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
814 GCC 2.x series compilers only had partial (read as broken) C++ support, and
815 your compile will most likely fail horribly! If you have any problems, do NOT
816 report them to the bugtracker or forums without first upgrading your compiler
817 to a newer 3.x or 4.x (or whatever is available currently) version.
821 ################################################################################
823 ################################################################################
825 # Retrieves the .config.cache file, and loads values into the main config hash.
826 open(CACHE, ".config.cache") or return 0;
829 # Ignore Blank lines, and comments..
832 my ($key, $value) = split("=", $_, 2);
833 $value =~ /^\"(.*)\"$/;
834 # Do something with data here!
842 # Dump the contents of %config
843 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
844 open(FILEHANDLE, ">.config.cache");
845 foreach my $key (keys %config) {
846 print FILEHANDLE "$key=\"$config{$key}\"\n";
852 my ($desc, $hash_key) = @_;
855 print "In what directory $desc?\n";
856 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
857 chomp(my $var = <STDIN>);
859 $var = $config{$hash_key};
861 if ($var =~ /^\~\/(.+)$/) {
862 # Convert it to a full path..
863 $var = resolve_directory($ENV{HOME} . "/" . $1);
865 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
867 # Assume relative Path was given.. fill in the rest.
868 $var = $this . "/$var";
871 $var = resolve_directory($var);
873 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
874 chomp(my $tmp = <STDIN>);
875 if (($tmp eq "") || ($tmp =~ /^y/i)) {
876 # Attempt to Create the Dir..
879 File::Path::mkpath($var, 0, 0777);
882 unless (defined($chk) && -d $var) {
883 print "Unable to create directory. ($var)\n\n";
888 # They said they don't want to create, and we can't install there.
894 # Target exists, but is not a directory.
895 print "File $var exists, but is not a directory.\n\n";
899 # Either Dir Exists, or was created fine.
900 $config{$hash_key} = $var;
908 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
911 my($writeheader) = @_;
912 # First File.. inspircd_config.h
913 chomp(my $incos = `uname -n -s -r`);
914 chomp(my $version = `sh src/version.sh`);
915 chomp(my $revision2 = getrevision());
916 if ($writeheader == 1)
918 print "Writing \e[1;32minspircd_config.h\e[0m\n";
919 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
920 print FILEHANDLE <<EOF;
921 /* Auto generated by configure, do not modify! */
922 #ifndef __CONFIGURATION_AUTO__
923 #define __CONFIGURATION_AUTO__
925 /* this is for windows support. */
926 #define CoreExport /**/
927 #define DllExport /**/
929 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
930 #define MOD_PATH "$config{MODULE_DIR}"
931 #define SOMAXCONN_S "$config{_SOMAXCONN}"
932 #define ENTRYPOINT int main(int argc, char** argv)
935 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
937 if ($config{OSNAME} =~ /SunOS/i) {
938 print FILEHANDLE "#define IS_SOLARIS\n";
940 if ($config{OSNAME} =~ /MINGW32/i) {
941 print FILEHANDLE "#define IS_MINGW\n";
943 if ($config{GCCVER} >= 3) {
944 print FILEHANDLE "#define GCC3\n";
947 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
949 ($config{GCCVER} > 4)
951 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
953 if ($config{HAS_STRLCPY} eq "true") {
954 print FILEHANDLE "#define HAS_STRLCPY\n";
956 if ($config{HAS_STDINT} eq "true") {
957 print FILEHANDLE "#define HAS_STDINT\n";
959 if ($config{IPV6} =~ /y/i) {
960 print FILEHANDLE "#define IPV6\n";
962 if ($config{HAS_EVENTFD} eq 'true') {
963 print FILEHANDLE "#define HAS_EVENTFD\n";
966 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
967 print FILEHANDLE "#define USE_KQUEUE\n";
968 $config{SOCKETENGINE} = "socketengine_kqueue";
971 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
972 print FILEHANDLE "#define USE_EPOLL\n";
973 $config{SOCKETENGINE} = "socketengine_epoll";
976 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
977 print FILEHANDLE "#define USE_PORTS\n";
978 $config{SOCKETENGINE} = "socketengine_ports";
981 # user didn't choose either epoll or select for their OS.
982 # default them to USE_SELECT (ewwy puke puke)
984 print "no hi-perf, " . $config{USE_POLL};
985 if ($config{USE_POLL} eq "y")
987 print FILEHANDLE "#define USE_POLL\n";
988 $config{SOCKETENGINE} = "socketengine_poll";
992 print FILEHANDLE "#define USE_SELECT\n";
993 $config{SOCKETENGINE} = "socketengine_select";
996 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
999 open(FILEHANDLE, ">include/inspircd_se_config.h.tmp");
1000 print FILEHANDLE <<EOF;
1001 /* Auto generated by configure, do not modify or commit to svn! */
1002 #ifndef __CONFIGURATION_SOCKETENGINE__
1003 #define __CONFIGURATION_SOCKETENGINE__
1005 #include "socketengines/$config{SOCKETENGINE}.h"
1011 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1012 print FILEHANDLE <<EOF;
1013 #define VERSION "$version"
1014 #define REVISION "$revision2"
1015 #define SYSTEM "$incos"
1019 for my $file (qw(include/inspircd_config.h include/inspircd_se_config.h include/inspircd_version.h)) {
1021 open my $fh1, $file or $diff = 1;
1022 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1026 if (defined($line1) != defined($line2)) {
1028 } elsif (!defined $line1) {
1031 $diff = ($line1 ne $line2);
1036 rename "$file.tmp", $file;
1043 # Write all .in files.
1046 my $exe = "inspircd";
1048 # Do this once here, and cache it in the .*.inc files,
1049 # rather than attempting to read src/version.sh from
1050 # compiled code -- we might not have the source to hand.
1051 # Fix for bug#177 by Brain.
1053 chomp($version = `sh ./src/version.sh`);
1054 chomp(my $revision = getrevision());
1055 $version = "$version(r$revision)";
1057 # We can actually parse any file starting with . and ending with .inc,
1058 # but right now we only parse .inspircd.inc to form './inspircd'
1059 prepare_dynamic_makefile();
1061 print "Writing \e[1;32mMakefiles\e[0m\n";
1063 opendir(DIRHANDLE, $this);
1065 foreach my $name (sort readdir(DIRHANDLE)) {
1066 if ($name =~ /^\.(.+)\.inc$/) {
1069 # Bug #353, omit this on non-darwin
1070 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1072 # All .name.inc files need parsing!
1073 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1074 $_ = join '', <FILEHANDLE>;
1077 print "Writing \e[1;32m$file\e[0m ...\n";
1079 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR
1080 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE CORE_FLAGS
1082 s/\@$var\@/$config{$var}/g;
1084 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1085 s/\@VERSION\@/$version/ if defined $version;
1087 if ($file eq 'Makefile') {
1089 s/\@IFDEF (\S+)/ifdef $1/g;
1090 s/\@IFNDEF (\S+)/ifndef $1/g;
1091 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1092 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1095 s/ *\@BSD_ONLY .*\n//g;
1097 s/\@DO_EXPORT (.*)/export $1/g;
1098 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1102 s/\@IFDEF (\S+)/.if defined($1)/g;
1103 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1104 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1105 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1109 s/ *\@GNU_ONLY .*\n//g;
1111 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1112 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1116 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1117 print FILEHANDLE $_;
1122 closedir(DIRHANDLE);
1124 # Make inspircd executable!
1125 chmod 0744, 'inspircd';
1131 for my $mod (@modlist) {
1132 getcompilerflags("src/modules/m_$mod.cpp");
1133 getlinkerflags("src/modules/m_$mod.cpp");
1137 sub prepare_dynamic_makefile
1143 $config{USE_EPOLL} = 0;
1147 $config{USE_KQUEUE} = 0;
1151 $config{USE_PORTS} = 0;
1155 # Routine to list out the extra/ modules that have been enabled.
1156 # Note: when getting any filenames out and comparing, it's important to lc it if the
1157 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1158 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1159 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1160 sub list_extras () {
1163 my $srcdir = File::Spec->catdir("src", "modules");
1164 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1167 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1168 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1171 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1172 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1175 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1177 EXTRA: for my $extra (@extras) {
1178 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1179 next if ($extra eq '.svn');
1180 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1181 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1182 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1183 if (-l $abs_source) {
1184 # Symlink, is it in the right place?
1185 my $targ = readlink($abs_source);
1186 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1187 if ($abs_targ eq $abs_extra) {
1188 $extras{$extra} = "\e[32;1menabled\e[0m";
1190 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1192 } elsif (-e $abs_source) {
1193 my ($devext, $inoext) = stat($abs_extra);
1194 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1196 if ($devsrc == $devext && $inosrc == $inoext) {
1197 $extras{$extra} = "\e[32;1menabled\e[0m";
1199 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1202 open my $extfd, "<", $abs_extra;
1203 open my $srcfd, "<", $abs_source;
1205 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1206 $extras{$extra} = "\e[32;1menabled\e[0m";
1208 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1212 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1215 # Now let's add dependency info
1216 for my $extra (keys(%extras)) {
1217 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1218 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1219 my @deps = split / +/, getdependencies($abs_extra);
1220 for my $dep (@deps) {
1221 if (exists($extras{$dep})) {
1222 my $ref = \$extras{$dep}; # Take reference.
1223 if ($$ref !~ m/needed by/) {
1224 # First dependency found.
1225 if ($$ref =~ m/enabled/) {
1226 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1228 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1229 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1232 if ($$ref =~ m/enabled/) {
1233 $$ref .= ", \e[32;1m$extra\e[0m";
1235 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1241 for my $extra (sort {$a cmp $b} keys(%extras)) {
1242 my $text = $extras{$extra};
1243 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1244 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1246 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1249 return keys(%extras) if wantarray; # Can be used by manage_extras.
1252 sub enable_extras (@) {
1254 for my $extra (@extras) {
1255 my $extrapath = "src/modules/extra/$extra";
1256 if (!-e $extrapath) {
1257 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1260 my $source = "src/modules/$extra";
1262 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1265 # Get dependencies, and add them to be processed.
1266 my @deps = split / +/, getdependencies($extrapath);
1267 for my $dep (@deps) {
1268 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1269 if (!-e "src/modules/$dep") {
1270 if (-e "src/modules/extra/$dep") {
1271 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1274 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";
1278 print "Enabling $extra ... \n";
1279 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1283 sub disable_extras (@)
1285 opendir my $dd, "src/modules/extra/";
1286 my @files = readdir($dd);
1289 EXTRA: for my $extra (@extras) {
1290 my $extrapath = "src/modules/extra/$extra";
1291 my $source = "src/modules/$extra";
1292 if (!-e $extrapath) {
1293 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1296 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1297 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";
1300 # Check if anything needs this.
1301 for my $file (@files) {
1302 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1303 # File depends on this extra...
1304 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1305 # And is both enabled and not about to be disabled.
1306 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1307 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1313 print "Disabling $extra ... \n";
1314 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";