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_ipv6, $opt_ipv6links, $opt_noipv6links, $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 'enable-ipv6' => \$opt_ipv6,
73 'enable-remote-ipv6' => \$opt_ipv6links,
74 'disable-remote-ipv6' => \$opt_noipv6links,
75 'with-cc=s' => \$opt_cc,
76 'with-maxbuf=i' => \$opt_maxbuf,
77 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
78 'prefix=s' => \$opt_base_dir,
79 'config-dir=s' => \$opt_config_dir,
80 'module-dir=s' => \$opt_module_dir,
81 'binary-dir=s' => \$opt_binary_dir,
82 'library-dir=s' => \$opt_library_dir,
83 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
84 'help' => sub { showhelp(); },
85 'update' => sub { update(); },
86 'svnupdate' => sub { svnupdate(); },
87 'clean' => sub { clean(); },
88 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
89 'enable-extras=s@' => \@opt_enableextras, # ^
90 'disable-extras=s@' => \@opt_disableextras, # ^
91 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
92 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
95 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
96 @opt_enableextras = split /,/, join(',', @opt_enableextras);
97 @opt_disableextras = split /,/, join(',', @opt_disableextras);
98 enable_extras(@opt_enableextras);
99 disable_extras(@opt_disableextras);
101 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
105 our $non_interactive = (
106 (defined $opt_library_dir) ||
107 (defined $opt_base_dir) ||
108 (defined $opt_config_dir) ||
109 (defined $opt_module_dir) ||
110 (defined $opt_base_dir) ||
111 (defined $opt_binary_dir) ||
112 (defined $opt_nointeractive) ||
114 (defined $opt_ipv6) ||
115 (defined $opt_ipv6links) ||
116 (defined $opt_noipv6links) ||
117 (defined $opt_kqueue) ||
118 (defined $opt_epoll) ||
119 (defined $opt_ports) ||
120 (defined $opt_use_openssl) ||
121 (defined $opt_nokqueue) ||
122 (defined $opt_noepoll) ||
123 (defined $opt_noports) ||
124 (defined $opt_maxbuf) ||
125 (defined $opt_use_gnutls) ||
126 (defined $opt_freebsd_port)
128 our $interactive = !$non_interactive;
130 chomp(our $topdir = getcwd());
131 our $this = resolve_directory($topdir); # PWD, Regardless.
132 our @modlist = (); # Declare for Module List..
133 our %config = (); # Initiate Configuration Hash..
134 $config{ME} = resolve_directory($topdir); # Present Working Directory
136 $config{BASE_DIR} = $config{ME};
138 if (defined $opt_base_dir)
140 $config{BASE_DIR} = $opt_base_dir;
143 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
144 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
145 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
146 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
148 if (defined $opt_config_dir)
150 $config{CONFIG_DIR} = $opt_config_dir;
152 if (defined $opt_module_dir)
154 $config{MODULE_DIR} = $opt_module_dir;
156 if (defined $opt_binary_dir)
158 $config{BINARY_DIR} = $opt_binary_dir;
160 if (defined $opt_library_dir)
162 $config{LIBRARY_DIR} = $opt_library_dir;
164 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
166 if (defined $opt_freebsd_port)
168 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
169 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
170 $config{USE_FREEBSD_BASE_SSL} = "n";
174 if ($^O eq "freebsd")
176 # default: use base ssl
177 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
178 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
182 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
183 $config{HAS_OPENSSL_PORT} = "";
187 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
188 chomp(our $openssl_ver = $config{HAS_OPENSSL});
189 $config{USE_GNUTLS} = "n";
190 if (defined $opt_use_gnutls)
192 $config{USE_GNUTLS} = "y"; # Use gnutls.
194 $config{USE_OPENSSL} = "n"; # Use openssl.
195 if (defined $opt_use_openssl)
197 $config{USE_OPENSSL} = "y";
200 # no, let's not change these.
201 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
202 if (!defined $opt_disable_debug)
204 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
208 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
211 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
212 $config{HAS_STDINT} = "false"; # stdint.h check
213 $config{USE_KQUEUE} = "y"; # kqueue enabled
214 if (defined $opt_kqueue)
216 $config{USE_KQUEUE} = "y";
218 if (defined $opt_nokqueue)
220 $config{USE_KQUEUE} = "n";
222 $config{USE_POLL} = "y"; # poll enabled
223 $config{USE_EPOLL} = "y"; # epoll enabled
224 if (defined $opt_epoll)
226 $config{USE_EPOLL} = "y";
228 if (defined $opt_noepoll)
230 $config{USE_EPOLL} = "n";
232 $config{USE_PORTS} = "y"; # epoll enabled
233 if (defined $opt_ports)
235 $config{USE_PORTS} = "y";
237 if (defined $opt_noports)
239 $config{USE_PORTS} = "n";
241 $config{IPV6} = "n"; # IPv6 support (experimental)
242 if (defined $opt_ipv6)
246 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
247 if (defined $opt_ipv6links)
249 $config{SUPPORT_IP6LINKS} = "y";
251 if (defined $opt_noipv6links)
253 $config{SUPPORT_IP6LINKS} = "n";
255 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
256 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
257 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
258 $config{OSNAME} = $^O; # Operating System Name
259 $config{IS_DARWIN} = "NO"; # Is OSX?
260 $config{STARTSCRIPT} = "inspircd"; # start script?
261 $config{DESTINATION} = "BASE"; # Is target path.
262 $config{EXTRA_DIR} = ""; # Is empty.
263 if ($config{OSNAME} =~ /darwin/i)
265 $config{IS_DARWIN} = "YES";
266 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
267 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
268 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
270 $config{CC} = "g++"; # C++ compiler
273 $config{CC} = $opt_cc;
275 our $exec = $config{CC} . " -dumpversion | cut -c 1";
276 chomp($config{GCCVER} = `$exec`); # Major GCC Version
277 $exec = $config{CC} . " -dumpversion | cut -c 3";
278 chomp($config{GCCMINOR} = `$exec`);
279 $config{MAXBUF} = "512"; # Max buffer size
281 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
282 $config{HAS_OPENSSL} = $1;
284 $config{HAS_OPENSSL} = "";
287 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
288 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
292 # Get and Set some important vars..
297 unlink(".config.cache");
300 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
305 chomp($topdir = getcwd());
306 $this = resolve_directory($topdir); # PWD, Regardless.
308 # Does the cache file exist?
310 # No, No it doesn't.. *BASH*
311 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
314 # We've Loaded the cache file and all our variables..
315 print "Updating files...\n";
316 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
318 print "Disabling debug information (-g).\n";
319 $config{OPTIMISATI} = "";
321 $has_epoll = $config{HAS_EPOLL};
322 $has_ports = $config{HAS_PORTS};
323 $has_kqueue = $config{HAS_KQUEUE};
332 print "Configure update failed: $@\n";
340 open(FH,"<.svn/entries") or $fail = 1;
342 print "This is not an SVN copy of InspIRCd.\n";
349 open my $fd, "-|", "svn update";
350 my $configurechanged = 0; # Needs ./configure -update
351 my $rootincchanged = 0;
353 while (defined(my $line = <$fd>))
357 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
358 ($action, $file) = ($1, $2);
361 push @conflicted, $file;
362 if ($file eq "configure")
364 $configurechanged = 1;
366 elsif ($file =~ m/^\..*\.inc$/)
371 elsif ($action eq "U" || $action eq "G")
373 if ($file eq "configure")
375 $configurechanged = 1;
377 elsif ($file =~ m/^\..*\.inc$/)
383 unless (close $fd) # close() waits for exit and returns false if the command failed
387 print STDERR "Problem updating from SVN, please check above for errors\n";
391 print STDERR "Failed to run SVN: $!\n";
395 if (scalar(@conflicted) > 0)
397 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
398 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
399 print "Conflicted files: " . join ", ", @conflicted . "\n";
402 if ($configurechanged)
404 system("perl configure -update");
408 print "No need to update Makefiles.\n";
410 if (defined $opt_rebuild) {
411 system("make install");
419 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
420 $fail ||= system "./test_$feature";
421 unlink "test_$feature";
425 print "Running non-interactive configure...\n" unless $interactive;
426 print "Checking for cache from previous configure... ";
427 print ((!getcache()) ? "not found\n" : "found\n");
428 $config{SYSTEM} = lc $^O;
429 print "Checking operating system version... $config{SYSTEM}\n";
431 printf "Checking if stdint.h exists... ";
432 $config{HAS_STDINT} = "true";
434 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
435 if ($config{HAS_STDINT} eq "true") {
438 print "yes\n" if $config{HAS_STDINT} eq "true";
439 print "no\n" if $config{HAS_STDINT} eq "false";
441 printf "Checking if strlcpy exists... ";
442 # Perform the strlcpy() test..
443 $config{HAS_STRLCPY} = "false";
445 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
447 while (defined(my $line = <STRLCPY>)) {
449 # try and find the delcaration of:
450 # size_t strlcpy(...)
451 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
452 $config{HAS_STRLCPY} = "true";
457 print "yes\n" if $config{HAS_STRLCPY} eq "true";
458 print "no\n" if $config{HAS_STRLCPY} eq "false";
460 printf "Checking if kqueue exists... ";
463 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
465 while (defined(my $line = <KQUEUE>)) {
467 # try and find the delcaration of:
469 if ($line =~ /int(\0x9|\s)+kqueue/) {
475 print "yes\n" if $has_kqueue == 1;
476 print "no\n" if $has_kqueue == 0;
478 printf "Checking for epoll support... ";
479 $has_epoll = test_compile('epoll');
480 print $has_epoll ? "yes\n" : "no\n";
482 printf "Checking for eventfd support... ";
483 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
484 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
486 printf "Checking if Solaris I/O completion ports are available... ";
488 our $system = `uname -s`;
490 $has_ports = 1 if ($system eq "SunOS");
493 my $kernel = `uname -r`;
495 if (($kernel !~ /^5\.1./)) {
499 print "yes\n" if $has_ports == 1;
500 print "no\n" if $has_ports == 0;
502 $config{HAS_EPOLL} = $has_epoll;
503 $config{HAS_KQUEUE} = $has_kqueue;
505 printf "Checking for libgnutls... ";
506 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
507 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
509 $config{HAS_GNUTLS} = "y";
512 $config{HAS_GNUTLS} = "n";
516 $config{HAS_GNUTLS} = "n";
519 printf "Checking for openssl... ";
520 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
521 if (defined($openssl_ver) && ($openssl_ver ne "")) {
523 $config{HAS_OPENSSL} = "y";
526 $config{HAS_OPENSSL} = "n";
530 $config{HAS_OPENSSL} = "n";
533 printf "Checking if you are running an ancient, unsupported OS... ";
534 if ($config{OSNAME} =~ /FreeBSD/i)
536 my $version = `uname -r`;
537 if ($version =~ /^4\./)
544 print "no ($version)\n";
549 print "no ($config{OSNAME})\n";
552 print "Checking for upgrades to extra and third party modules... ";
553 system "./modulemanager upgrade";
555 ################################################################################
556 # BEGIN INTERACTIVE PART #
557 ################################################################################
562 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
565 my $rev = getrevision();
566 # Display Introduction Message..
568 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
569 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
571 *** If you are unsure of any of these values, leave it blank for ***
572 *** standard settings that will work, and your server will run ***
573 *** using them. Please consult your IRC network admin if in doubt. ***
575 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
576 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
577 dir, otherwise you won't have a config file!
579 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
580 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
583 print " (Non-SVN build)";
587 $config{CHANGE_COMPILER} = "n";
588 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";
590 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
591 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
592 should NOT be used. You should probably specify a newer compiler.\n\n";
593 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
594 if ($config{CHANGE_COMPILER} =~ /y/i) {
595 print "What command do you want to use to invoke your compiler?\n";
596 print "[\e[1;32m$config{CC}\e[0m] -> ";
597 chomp($config{CC} = <STDIN>);
598 if ($config{CC} eq "") {
601 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
603 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
604 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
605 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
606 if ($config{GCCVER} < 3) {
607 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
611 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
618 # Directory Settings..
619 my $tmpbase = $config{BASE_DIR};
620 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
621 if ($tmpbase ne $config{BASE_DIR}) {
622 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
623 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
624 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
625 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
628 dir_check("are the configuration files", "CONFIG_DIR");
629 dir_check("are the modules to be compiled to", "MODULE_DIR");
630 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
631 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
633 my $chose_hiperf = 0;
635 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?");
637 if ($config{USE_KQUEUE} eq "y") {
642 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?");
644 if ($config{USE_EPOLL} eq "y") {
649 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?");
651 if ($config{USE_PORTS} eq "y") {
656 if (!$chose_hiperf) {
657 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?\n");
658 if ($config{USE_POLL} ne "y")
660 print "No high-performance socket engines are available, or you chose\n";
661 print "not to enable one. Defaulting to select() engine.\n\n";
665 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
668 if ($config{IPV6} eq "y") {
669 print "You have chosen to build an \e[1;32mIPV6-enabled\e[0m server.\nTo accept IPV4 users, you can still use IPV4 addresses\nin your port bindings..\n\n";
670 $config{SUPPORT_IP6LINKS} = "y";
672 yesno('SUPPORT_IP6LINKS',"You have chosen to build an \e[1;32mIPV4-only\e[0m server.\nWould you like to enable support for linking to IPV6-enabled\nInspIRCd servers? If you are using a recent operating system and are\nunsure, answer yes. If you answer 'no' here, your InspIRCd server will\nbe unable to parse IPV6 addresses (e.g. for CIDR bans)\n\nEnable linking to servers which have IPV6 enabled?");
676 $config{USE_FREEBSD_BASE_SSL} = "n";
677 $config{USE_FREEBSD_PORTS_SSL} = "n";
678 if ($config{HAS_OPENSSL_PORT} ne "")
680 $config{USE_FREEBSD_PORTS_SSL} = "y";
681 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
682 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";
683 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
685 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
687 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
689 # update to port version
690 $openssl_ver = $config{HAS_OPENSSL_PORT};
695 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
698 $config{USE_SSL} = "n";
700 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
702 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
703 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
705 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
706 if ($config{USE_SSL} eq "y")
708 if ($config{HAS_GNUTLS} eq "y")
710 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
711 if ($config{USE_GNUTLS} eq "y")
713 print "\nUsing GnuTLS SSL module.\n";
717 if ($config{HAS_OPENSSL} eq "y")
719 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
720 if ($config{USE_OPENSSL} eq "y")
722 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
729 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
730 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
736 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
738 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
741 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
743 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
748 $config{CERTGEN} ||= 'y';
749 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
751 if ($config{USE_GNUTLS} eq "y") {
752 unless (-r "src/modules/m_ssl_gnutls.cpp") {
753 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
754 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
756 if ($interactive && $config{CERTGEN} eq 'y')
758 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
759 print "SSL Certificates Not found, Generating.. \n\n
760 *************************************************************
761 * Generating the Private Key may take some time, go grab a *
762 * Coffee. Even better, to generate some more entropy if it *
763 * is taking a while, open another console and type du / a *
764 * few times and get that HD going :) Then answer the *
765 * Questions which follow. If you are unsure, just hit enter *
766 *************************************************************\n\n";
767 $failed = make_gnutls_cert();
769 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
771 print "\nCertificate generation complete, copying to config directory... ";
772 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
773 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
778 print "SSL Certificates found, skipping.\n\n";
783 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
787 if ($config{USE_OPENSSL} eq "y") {
788 unless (-r "src/modules/m_ssl_openssl.cpp") {
789 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
790 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
793 if ($interactive && $config{CERTGEN} eq 'y')
795 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
796 print "SSL Certificates Not found, Generating.. \n\n
797 *************************************************************
798 * Generating the certificates may take some time, go grab a *
799 * coffee, or something. *
800 *************************************************************\n\n";
802 print "\nCertificate generation complete, copying to config directory... ";
803 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
804 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
805 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
808 print "SSL Certificates found, skipping.\n\n"
813 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
816 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
817 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
824 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
825 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
826 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
827 print "modules in your config. This configure script has added those modules to the\n";
828 print "build process. For more info please refer to:\n";
829 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
831 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
832 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
833 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";
836 if ($config{GCCVER} < "3") {
838 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
839 GCC 2.x series compilers only had partial (read as broken) C++ support, and
840 your compile will most likely fail horribly! If you have any problems, do NOT
841 report them to the bugtracker or forums without first upgrading your compiler
842 to a newer 3.x or 4.x (or whatever is available currently) version.
846 ################################################################################
848 ################################################################################
850 # Retrieves the .config.cache file, and loads values into the main config hash.
851 open(CACHE, ".config.cache") or return 0;
854 # Ignore Blank lines, and comments..
857 my ($key, $value) = split("=", $_, 2);
858 $value =~ /^\"(.*)\"$/;
859 # Do something with data here!
867 # Dump the contents of %config
868 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
869 open(FILEHANDLE, ">.config.cache");
870 foreach my $key (keys %config) {
871 print FILEHANDLE "$key=\"$config{$key}\"\n";
877 my ($desc, $hash_key) = @_;
880 print "In what directory $desc?\n";
881 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
882 chomp(my $var = <STDIN>);
884 $var = $config{$hash_key};
886 if ($var =~ /^\~\/(.+)$/) {
887 # Convert it to a full path..
888 $var = resolve_directory($ENV{HOME} . "/" . $1);
890 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
892 # Assume relative Path was given.. fill in the rest.
893 $var = $this . "/$var";
896 $var = resolve_directory($var);
898 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
899 chomp(my $tmp = <STDIN>);
900 if (($tmp eq "") || ($tmp =~ /^y/i)) {
901 # Attempt to Create the Dir..
904 File::Path::mkpath($var, 0, 0777);
907 unless (defined($chk) && -d $var) {
908 print "Unable to create directory. ($var)\n\n";
913 # They said they don't want to create, and we can't install there.
919 # Target exists, but is not a directory.
920 print "File $var exists, but is not a directory.\n\n";
924 # Either Dir Exists, or was created fine.
925 $config{$hash_key} = $var;
933 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
936 my($writeheader) = @_;
937 # First File.. inspircd_config.h
938 chomp(my $incos = `uname -n -s -r`);
939 chomp(my $version = `sh src/version.sh`);
940 chomp(my $revision2 = getrevision());
941 if ($writeheader == 1)
943 print "Writing \e[1;32minspircd_config.h\e[0m\n";
944 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
945 print FILEHANDLE <<EOF;
946 /* Auto generated by configure, do not modify! */
947 #ifndef __CONFIGURATION_AUTO__
948 #define __CONFIGURATION_AUTO__
950 /* this is for windows support. */
951 #define CoreExport /**/
952 #define DllExport /**/
954 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
955 #define MOD_PATH "$config{MODULE_DIR}"
956 #define SOMAXCONN_S "$config{_SOMAXCONN}"
957 #define OPTIMISATION $config{OPTIMITEMP}
958 #define LIBRARYDIR "$config{LIBRARY_DIR}"
959 #define ENTRYPOINT int main(int argc, char** argv)
962 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
964 if ($config{OSNAME} =~ /SunOS/i) {
965 print FILEHANDLE "#define IS_SOLARIS\n";
967 if ($config{OSNAME} =~ /MINGW32/i) {
968 print FILEHANDLE "#define IS_MINGW\n";
970 if ($config{GCCVER} >= 3) {
971 print FILEHANDLE "#define GCC3\n";
974 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
976 ($config{GCCVER} > 4)
978 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
980 if ($config{HAS_STRLCPY} eq "true") {
981 print FILEHANDLE "#define HAS_STRLCPY\n";
983 if ($config{HAS_STDINT} eq "true") {
984 print FILEHANDLE "#define HAS_STDINT\n";
986 if ($config{IPV6} =~ /y/i) {
987 print FILEHANDLE "#define IPV6\n";
989 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
990 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
992 if ($config{HAS_EVENTFD} eq 'true') {
993 print FILEHANDLE "#define HAS_EVENTFD\n";
996 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
997 print FILEHANDLE "#define USE_KQUEUE\n";
998 $config{SOCKETENGINE} = "socketengine_kqueue";
1001 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1002 print FILEHANDLE "#define USE_EPOLL\n";
1003 $config{SOCKETENGINE} = "socketengine_epoll";
1006 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1007 print FILEHANDLE "#define USE_PORTS\n";
1008 $config{SOCKETENGINE} = "socketengine_ports";
1011 # user didn't choose either epoll or select for their OS.
1012 # default them to USE_SELECT (ewwy puke puke)
1014 print "no hi-perf, " . $config{USE_POLL};
1015 if ($config{USE_POLL} eq "y")
1017 print FILEHANDLE "#define USE_POLL\n";
1018 $config{SOCKETENGINE} = "socketengine_poll";
1022 print FILEHANDLE "#define USE_SELECT\n";
1023 $config{SOCKETENGINE} = "socketengine_select";
1026 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1029 open(FILEHANDLE, ">include/inspircd_se_config.h.tmp");
1030 print FILEHANDLE <<EOF;
1031 /* Auto generated by configure, do not modify or commit to svn! */
1032 #ifndef __CONFIGURATION_SOCKETENGINE__
1033 #define __CONFIGURATION_SOCKETENGINE__
1035 #include "socketengines/$config{SOCKETENGINE}.h"
1041 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1042 print FILEHANDLE <<EOF;
1043 #define VERSION "$version"
1044 #define REVISION "$revision2"
1045 #define SYSTEM "$incos"
1049 for my $file (qw(include/inspircd_config.h include/inspircd_se_config.h include/inspircd_version.h)) {
1051 open my $fh1, $file or $diff = 1;
1052 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1056 if (defined($line1) != defined($line2)) {
1058 } elsif (!defined $line1) {
1061 $diff = ($line1 ne $line2);
1066 rename "$file.tmp", $file;
1073 # Write all .in files.
1076 my $exe = "inspircd";
1078 # Do this once here, and cache it in the .*.inc files,
1079 # rather than attempting to read src/version.sh from
1080 # compiled code -- we might not have the source to hand.
1081 # Fix for bug#177 by Brain.
1083 chomp($version = `sh ./src/version.sh`);
1084 chomp(my $revision = getrevision());
1085 $version = "$version(r$revision)";
1087 # We can actually parse any file starting with . and ending with .inc,
1088 # but right now we only parse .inspircd.inc to form './inspircd'
1089 prepare_dynamic_makefile();
1091 print "Writing \e[1;32mMakefiles\e[0m\n";
1093 opendir(DIRHANDLE, $this);
1095 foreach my $name (sort readdir(DIRHANDLE)) {
1096 if ($name =~ /^\.(.+)\.inc$/) {
1099 # Bug #353, omit this on non-darwin
1100 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1102 # All .name.inc files need parsing!
1103 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1104 $_ = join '', <FILEHANDLE>;
1107 print "Writing \e[1;32m$file\e[0m ...\n";
1109 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR LIBRARY_DIR
1110 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE CORE_FLAGS
1112 s/\@$var\@/$config{$var}/g;
1114 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1115 s/\@VERSION\@/$version/ if defined $version;
1117 if ($file eq 'Makefile') {
1119 s/\@IFDEF (\S+)/ifdef $1/g;
1120 s/\@IFNDEF (\S+)/ifndef $1/g;
1121 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1122 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1125 s/ *\@BSD_ONLY .*\n//g;
1127 s/\@DO_EXPORT (.*)/export $1/g;
1128 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1132 s/\@IFDEF (\S+)/.if defined($1)/g;
1133 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1134 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1135 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1139 s/ *\@GNU_ONLY .*\n//g;
1141 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1142 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1146 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1147 print FILEHANDLE $_;
1152 closedir(DIRHANDLE);
1154 # Make inspircd executable!
1155 chmod 0744, 'inspircd';
1158 sub prepare_dynamic_makefile
1164 $config{USE_EPOLL} = 0;
1168 $config{USE_KQUEUE} = 0;
1172 $config{USE_PORTS} = 0;
1176 # Routine to list out the extra/ modules that have been enabled.
1177 # Note: when getting any filenames out and comparing, it's important to lc it if the
1178 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1179 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1180 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1181 sub list_extras () {
1184 my $srcdir = File::Spec->catdir("src", "modules");
1185 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1188 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1189 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1192 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1193 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1196 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1198 EXTRA: for my $extra (@extras) {
1199 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1200 next if ($extra eq '.svn');
1201 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1202 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1203 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1204 if (-l $abs_source) {
1205 # Symlink, is it in the right place?
1206 my $targ = readlink($abs_source);
1207 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1208 if ($abs_targ eq $abs_extra) {
1209 $extras{$extra} = "\e[32;1menabled\e[0m";
1211 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1213 } elsif (-e $abs_source) {
1214 my ($devext, $inoext) = stat($abs_extra);
1215 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1217 if ($devsrc == $devext && $inosrc == $inoext) {
1218 $extras{$extra} = "\e[32;1menabled\e[0m";
1220 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1223 open my $extfd, "<", $abs_extra;
1224 open my $srcfd, "<", $abs_source;
1226 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1227 $extras{$extra} = "\e[32;1menabled\e[0m";
1229 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1233 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1236 # Now let's add dependency info
1237 for my $extra (keys(%extras)) {
1238 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1239 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1240 my @deps = split / +/, getdependencies($abs_extra);
1241 for my $dep (@deps) {
1242 if (exists($extras{$dep})) {
1243 my $ref = \$extras{$dep}; # Take reference.
1244 if ($$ref !~ m/needed by/) {
1245 # First dependency found.
1246 if ($$ref =~ m/enabled/) {
1247 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1249 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1250 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1253 if ($$ref =~ m/enabled/) {
1254 $$ref .= ", \e[32;1m$extra\e[0m";
1256 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1262 for my $extra (sort {$a cmp $b} keys(%extras)) {
1263 my $text = $extras{$extra};
1264 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1265 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1267 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1270 return keys(%extras) if wantarray; # Can be used by manage_extras.
1273 sub enable_extras (@) {
1275 for my $extra (@extras) {
1276 my $extrapath = "src/modules/extra/$extra";
1277 if (!-e $extrapath) {
1278 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1281 my $source = "src/modules/$extra";
1283 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1286 # Get dependencies, and add them to be processed.
1287 my @deps = split / +/, getdependencies($extrapath);
1288 for my $dep (@deps) {
1289 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1290 if (!-e "src/modules/$dep") {
1291 if (-e "src/modules/extra/$dep") {
1292 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1295 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";
1299 print "Enabling $extra ... \n";
1300 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1304 sub disable_extras (@)
1306 opendir my $dd, "src/modules/extra/";
1307 my @files = readdir($dd);
1310 EXTRA: for my $extra (@extras) {
1311 my $extrapath = "src/modules/extra/$extra";
1312 my $source = "src/modules/$extra";
1313 if (!-e $extrapath) {
1314 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1317 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1318 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";
1321 # Check if anything needs this.
1322 for my $file (@files) {
1323 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1324 # File depends on this extra...
1325 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1326 # And is both enabled and not about to be disabled.
1327 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1328 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1334 print "Disabling $extra ... \n";
1335 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";