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);
53 sub enable_extras (@);
55 sub disable_extras (@);
58 my @opt_disableextras;
61 'enable-gnutls' => \$opt_use_gnutls,
62 'rebuild' => \$opt_rebuild,
63 'enable-openssl' => \$opt_use_openssl,
64 'disable-interactive' => \$opt_nointeractive,
65 'enable-ports' => \$opt_ports,
66 'enable-epoll' => \$opt_epoll,
67 'enable-kqueue' => \$opt_kqueue,
68 'disable-ports' => \$opt_noports,
69 'disable-epoll' => \$opt_noepoll,
70 'disable-kqueue' => \$opt_nokqueue,
71 'disable-ipv6' => \$opt_noipv6,
72 'with-cc=s' => \$opt_cc,
73 'with-maxbuf=i' => \$opt_maxbuf,
74 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
75 'prefix=s' => \$opt_base_dir,
76 'config-dir=s' => \$opt_config_dir,
77 'module-dir=s' => \$opt_module_dir,
78 'binary-dir=s' => \$opt_binary_dir,
79 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
80 'help' => sub { showhelp(); },
81 'update' => sub { update(); },
82 'svnupdate' => sub { svnupdate(); },
83 'clean' => sub { clean(); },
84 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
85 'enable-extras=s@' => \@opt_enableextras, # ^
86 'disable-extras=s@' => \@opt_disableextras, # ^
87 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
88 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
91 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
92 @opt_enableextras = split /,/, join(',', @opt_enableextras);
93 @opt_disableextras = split /,/, join(',', @opt_disableextras);
94 enable_extras(@opt_enableextras);
95 disable_extras(@opt_disableextras);
97 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
101 our $non_interactive = (
102 (defined $opt_base_dir) ||
103 (defined $opt_config_dir) ||
104 (defined $opt_module_dir) ||
105 (defined $opt_base_dir) ||
106 (defined $opt_binary_dir) ||
107 (defined $opt_nointeractive) ||
109 (defined $opt_noipv6) ||
110 (defined $opt_kqueue) ||
111 (defined $opt_epoll) ||
112 (defined $opt_ports) ||
113 (defined $opt_use_openssl) ||
114 (defined $opt_nokqueue) ||
115 (defined $opt_noepoll) ||
116 (defined $opt_noports) ||
117 (defined $opt_maxbuf) ||
118 (defined $opt_use_gnutls) ||
119 (defined $opt_freebsd_port)
121 our $interactive = !$non_interactive;
123 chomp(our $topdir = getcwd());
124 our $this = resolve_directory($topdir); # PWD, Regardless.
125 our @modlist = (); # Declare for Module List..
126 our %config = (); # Initiate Configuration Hash..
127 $config{ME} = resolve_directory($topdir); # Present Working Directory
129 $config{BASE_DIR} = $config{ME}."/run";
131 if (defined $opt_base_dir)
133 $config{BASE_DIR} = $opt_base_dir;
136 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
137 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
138 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
139 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
141 if (defined $opt_config_dir)
143 $config{CONFIG_DIR} = $opt_config_dir;
145 if (defined $opt_module_dir)
147 $config{MODULE_DIR} = $opt_module_dir;
149 if (defined $opt_binary_dir)
151 $config{BINARY_DIR} = $opt_binary_dir;
153 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
155 if (defined $opt_freebsd_port)
157 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
158 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
159 $config{USE_FREEBSD_BASE_SSL} = "n";
163 if ($^O eq "freebsd")
165 # default: use base ssl
166 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
167 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
171 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
172 $config{HAS_OPENSSL_PORT} = "";
176 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
177 chomp(our $openssl_ver = $config{HAS_OPENSSL});
178 $config{USE_GNUTLS} = "n";
179 if (defined $opt_use_gnutls)
181 $config{USE_GNUTLS} = "y"; # Use gnutls.
183 $config{USE_OPENSSL} = "n"; # Use openssl.
184 if (defined $opt_use_openssl)
186 $config{USE_OPENSSL} = "y";
189 # no, let's not change these.
190 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
191 if (!defined $opt_disable_debug)
193 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
197 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
200 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
201 $config{HAS_STDINT} = "false"; # stdint.h check
202 $config{USE_KQUEUE} = "y"; # kqueue enabled
203 if (defined $opt_kqueue)
205 $config{USE_KQUEUE} = "y";
207 if (defined $opt_nokqueue)
209 $config{USE_KQUEUE} = "n";
211 $config{USE_POLL} = "y"; # poll enabled
212 $config{USE_EPOLL} = "y"; # epoll enabled
213 if (defined $opt_epoll)
215 $config{USE_EPOLL} = "y";
217 if (defined $opt_noepoll)
219 $config{USE_EPOLL} = "n";
221 $config{USE_PORTS} = "y"; # epoll enabled
222 if (defined $opt_ports)
224 $config{USE_PORTS} = "y";
226 if (defined $opt_noports)
228 $config{USE_PORTS} = "n";
230 $config{IPV6} = "y"; # IPv6 support
231 if (defined $opt_noipv6)
235 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
236 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
237 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
238 $config{OSNAME} = $^O; # Operating System Name
239 $config{IS_DARWIN} = "NO"; # Is OSX?
240 $config{STARTSCRIPT} = "inspircd"; # start script?
241 $config{DESTINATION} = "BASE"; # Is target path.
242 $config{EXTRA_DIR} = ""; # Is empty.
243 if ($config{OSNAME} =~ /darwin/i)
245 $config{IS_DARWIN} = "YES";
246 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
247 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
248 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
250 $config{CC} = "g++"; # C++ compiler
253 $config{CC} = $opt_cc;
255 our $exec = $config{CC} . " -dumpversion | cut -c 1";
256 chomp($config{GCCVER} = `$exec`); # Major GCC Version
257 $exec = $config{CC} . " -dumpversion | cut -c 3";
258 chomp($config{GCCMINOR} = `$exec`);
259 $config{MAXBUF} = "512"; # Max buffer size
261 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
262 $config{HAS_OPENSSL} = $1;
264 $config{HAS_OPENSSL} = "";
267 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
268 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
272 # Get and Set some important vars..
277 unlink(".config.cache");
280 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
285 chomp($topdir = getcwd());
286 $this = resolve_directory($topdir); # PWD, Regardless.
288 # Does the cache file exist?
290 # No, No it doesn't.. *BASH*
291 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
294 # We've Loaded the cache file and all our variables..
295 print "Updating files...\n";
296 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
298 print "Disabling debug information (-g).\n";
299 $config{OPTIMISATI} = "";
301 $has_epoll = $config{HAS_EPOLL};
302 $has_ports = $config{HAS_PORTS};
303 $has_kqueue = $config{HAS_KQUEUE};
312 print "Configure update failed: $@\n";
320 open(FH,"<.svn/entries") or $fail = 1;
322 print "This is not an SVN copy of InspIRCd.\n";
329 open my $fd, "-|", "svn update";
330 my $configurechanged = 0; # Needs ./configure -update
331 my $rootincchanged = 0;
333 while (defined(my $line = <$fd>))
337 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
338 ($action, $file) = ($1, $2);
341 push @conflicted, $file;
342 if ($file eq "configure")
344 $configurechanged = 1;
346 elsif ($file =~ m/^\..*\.inc$/)
351 elsif ($action eq "U" || $action eq "G")
353 if ($file eq "configure")
355 $configurechanged = 1;
357 elsif ($file =~ m/^\..*\.inc$/)
363 unless (close $fd) # close() waits for exit and returns false if the command failed
367 print STDERR "Problem updating from SVN, please check above for errors\n";
371 print STDERR "Failed to run SVN: $!\n";
375 if (scalar(@conflicted) > 0)
377 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
378 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
379 print "Conflicted files: " . join ", ", @conflicted . "\n";
382 if ($configurechanged)
384 system("perl configure -update");
388 print "No need to update Makefiles.\n";
390 if (defined $opt_rebuild) {
391 system("make install");
399 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
400 $fail ||= system "./test_$feature";
401 unlink "test_$feature";
405 print "Running non-interactive configure...\n" unless $interactive;
406 print "Checking for cache from previous configure... ";
407 print ((!getcache()) ? "not found\n" : "found\n");
408 $config{SYSTEM} = lc $^O;
409 print "Checking operating system version... $config{SYSTEM}\n";
411 printf "Checking if stdint.h exists... ";
412 $config{HAS_STDINT} = "true";
414 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
415 if ($config{HAS_STDINT} eq "true") {
418 print "yes\n" if $config{HAS_STDINT} eq "true";
419 print "no\n" if $config{HAS_STDINT} eq "false";
421 printf "Checking if strlcpy exists... ";
422 # Perform the strlcpy() test..
423 $config{HAS_STRLCPY} = "false";
425 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
427 while (defined(my $line = <STRLCPY>)) {
429 # try and find the delcaration of:
430 # size_t strlcpy(...)
431 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
432 $config{HAS_STRLCPY} = "true";
437 print "yes\n" if $config{HAS_STRLCPY} eq "true";
438 print "no\n" if $config{HAS_STRLCPY} eq "false";
440 printf "Checking if kqueue exists... ";
443 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
445 while (defined(my $line = <KQUEUE>)) {
447 # try and find the delcaration of:
449 if ($line =~ /int(\0x9|\s)+kqueue/) {
455 print "yes\n" if $has_kqueue == 1;
456 print "no\n" if $has_kqueue == 0;
458 printf "Checking for epoll support... ";
459 $has_epoll = test_compile('epoll');
460 print $has_epoll ? "yes\n" : "no\n";
462 printf "Checking for eventfd support... ";
463 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
464 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
466 printf "Checking if Solaris I/O completion ports are available... ";
468 our $system = `uname -s`;
470 $has_ports = 1 if ($system eq "SunOS");
473 my $kernel = `uname -r`;
475 if (($kernel !~ /^5\.1./)) {
479 print "yes\n" if $has_ports == 1;
480 print "no\n" if $has_ports == 0;
482 $config{HAS_EPOLL} = $has_epoll;
483 $config{HAS_KQUEUE} = $has_kqueue;
485 printf "Checking for libgnutls... ";
486 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
487 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
489 $config{HAS_GNUTLS} = "y";
492 $config{HAS_GNUTLS} = "n";
496 $config{HAS_GNUTLS} = "n";
499 printf "Checking for openssl... ";
500 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
501 if (defined($openssl_ver) && ($openssl_ver ne "")) {
503 $config{HAS_OPENSSL} = "y";
506 $config{HAS_OPENSSL} = "n";
510 $config{HAS_OPENSSL} = "n";
513 printf "Checking if you are running an ancient, unsupported OS... ";
514 if ($config{OSNAME} =~ /FreeBSD/i)
516 my $version = `uname -r`;
517 if ($version =~ /^4\./)
520 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
521 print "To build, you will need to add the following to CXXFLAGS:\n";
522 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
526 print "no ($version)\n";
531 print "no ($config{OSNAME})\n";
534 ################################################################################
535 # BEGIN INTERACTIVE PART #
536 ################################################################################
541 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
544 my $rev = getrevision();
545 # Display Introduction Message..
547 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
548 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
550 *** If you are unsure of any of these values, leave it blank for ***
551 *** standard settings that will work, and your server will run ***
552 *** using them. Please consult your IRC network admin if in doubt. ***
554 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
555 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
556 dir, otherwise you won't have a config file!
558 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
559 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
562 print " (Non-SVN build)";
566 $config{CHANGE_COMPILER} = "n";
567 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";
569 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
570 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
571 should NOT be used. You should probably specify a newer compiler.\n\n";
572 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
573 if ($config{CHANGE_COMPILER} =~ /y/i) {
574 print "What command do you want to use to invoke your compiler?\n";
575 print "[\e[1;32m$config{CC}\e[0m] -> ";
576 chomp($config{CC} = <STDIN>);
577 if ($config{CC} eq "") {
580 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
582 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
583 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
584 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
585 if ($config{GCCVER} < 3) {
586 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
590 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
597 # Directory Settings..
598 my $tmpbase = $config{BASE_DIR};
599 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
600 if ($tmpbase ne $config{BASE_DIR}) {
601 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
602 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
603 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
606 dir_check("are the configuration files", "CONFIG_DIR");
607 dir_check("are the modules to be compiled to", "MODULE_DIR");
608 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
609 dir_check("do you want the build to take place", "BUILD_DIR");
611 my $chose_hiperf = 0;
613 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?");
615 if ($config{USE_KQUEUE} eq "y") {
620 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?");
622 if ($config{USE_EPOLL} eq "y") {
627 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?");
629 if ($config{USE_PORTS} eq "y") {
634 if (!$chose_hiperf) {
635 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?");
636 if ($config{USE_POLL} ne "y")
638 print "No high-performance socket engines are available, or you chose\n";
639 print "not to enable one. Defaulting to select() engine.\n\n";
643 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
646 $config{USE_FREEBSD_BASE_SSL} = "n";
647 $config{USE_FREEBSD_PORTS_SSL} = "n";
648 if ($config{HAS_OPENSSL_PORT} ne "")
650 $config{USE_FREEBSD_PORTS_SSL} = "y";
651 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
652 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";
653 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
655 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
657 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
659 # update to port version
660 $openssl_ver = $config{HAS_OPENSSL_PORT};
665 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
668 $config{USE_SSL} = "n";
669 $config{MODUPDATE} = 'n';
671 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
673 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
674 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
676 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
677 if ($config{USE_SSL} eq "y")
679 if ($config{HAS_GNUTLS} eq "y")
681 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
682 if ($config{USE_GNUTLS} eq "y")
684 print "\nUsing GnuTLS SSL module.\n";
688 if ($config{HAS_OPENSSL} eq "y")
690 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
691 if ($config{USE_OPENSSL} eq "y")
693 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
700 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
701 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
704 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
706 if ($config{MODUPDATE} eq "y") {
707 print "Checking for upgrades to extra and third party modules... ";
708 system "./modulemanager upgrade";
714 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
716 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
719 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
721 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
726 $config{CERTGEN} ||= 'y';
727 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
729 if ($config{USE_GNUTLS} eq "y") {
730 unless (-r "src/modules/m_ssl_gnutls.cpp") {
731 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
732 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
734 if ($interactive && $config{CERTGEN} eq 'y')
736 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
737 print "SSL Certificates Not found, Generating.. \n\n
738 *************************************************************
739 * Generating the Private Key may take some time, go grab a *
740 * Coffee. Even better, to generate some more entropy if it *
741 * is taking a while, open another console and type du / a *
742 * few times and get that HD going :) Then answer the *
743 * Questions which follow. If you are unsure, just hit enter *
744 *************************************************************\n\n";
745 $failed = make_gnutls_cert();
747 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
749 print "\nCertificate generation complete, copying to config directory... ";
750 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
751 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
756 print "SSL Certificates found, skipping.\n\n";
761 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
765 if ($config{USE_OPENSSL} eq "y") {
766 unless (-r "src/modules/m_ssl_openssl.cpp") {
767 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
768 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
771 if ($interactive && $config{CERTGEN} eq 'y')
773 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
774 print "SSL Certificates Not found, Generating.. \n\n
775 *************************************************************
776 * Generating the certificates may take some time, go grab a *
777 * coffee, or something. *
778 *************************************************************\n\n";
780 print "\nCertificate generation complete, copying to config directory... ";
781 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
782 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
783 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
786 print "SSL Certificates found, skipping.\n\n"
791 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
794 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
795 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
803 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
804 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
805 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
806 print "modules in your config. This configure script has added those modules to the\n";
807 print "build process. For more info please refer to:\n";
808 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
810 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
811 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
812 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";
815 if ($config{GCCVER} < "3") {
817 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
818 GCC 2.x series compilers only had partial (read as broken) C++ support, and
819 your compile will most likely fail horribly! If you have any problems, do NOT
820 report them to the bugtracker or forums without first upgrading your compiler
821 to a newer 3.x or 4.x (or whatever is available currently) version.
825 ################################################################################
827 ################################################################################
829 # Retrieves the .config.cache file, and loads values into the main config hash.
830 open(CACHE, ".config.cache") or return 0;
833 # Ignore Blank lines, and comments..
836 my ($key, $value) = split("=", $_, 2);
837 $value =~ /^\"(.*)\"$/;
838 # Do something with data here!
846 # Dump the contents of %config
847 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
848 open(FILEHANDLE, ">.config.cache");
849 foreach my $key (keys %config) {
850 print FILEHANDLE "$key=\"$config{$key}\"\n";
856 my ($desc, $hash_key) = @_;
859 print "In what directory $desc?\n";
860 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
861 chomp(my $var = <STDIN>);
863 $var = $config{$hash_key};
865 if ($var =~ /^\~\/(.+)$/) {
866 # Convert it to a full path..
867 $var = resolve_directory($ENV{HOME} . "/" . $1);
869 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
871 # Assume relative Path was given.. fill in the rest.
872 $var = $this . "/$var";
875 $var = resolve_directory($var);
877 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
878 chomp(my $tmp = <STDIN>);
879 if (($tmp eq "") || ($tmp =~ /^y/i)) {
880 # Attempt to Create the Dir..
883 File::Path::mkpath($var, 0, 0777);
886 unless (defined($chk) && -d $var) {
887 print "Unable to create directory. ($var)\n\n";
892 # They said they don't want to create, and we can't install there.
898 # Target exists, but is not a directory.
899 print "File $var exists, but is not a directory.\n\n";
903 # Either Dir Exists, or was created fine.
904 $config{$hash_key} = $var;
912 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
915 my($writeheader) = @_;
916 # First File.. inspircd_config.h
917 chomp(my $incos = `uname -n -s -r`);
918 chomp(my $version = `sh src/version.sh`);
919 chomp(my $revision2 = getrevision());
920 if ($writeheader == 1)
922 print "Writing \e[1;32minspircd_config.h\e[0m\n";
923 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
924 print FILEHANDLE <<EOF;
925 /* Auto generated by configure, do not modify! */
926 #ifndef __CONFIGURATION_AUTO__
927 #define __CONFIGURATION_AUTO__
929 /* this is for windows support. */
930 #define CoreExport /**/
931 #define DllExport /**/
933 #define MOD_PATH "$config{MODULE_DIR}"
934 #define SOMAXCONN_S "$config{_SOMAXCONN}"
935 #define ENTRYPOINT int main(int argc, char** argv)
938 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
940 if ($config{OSNAME} =~ /SunOS/i) {
941 print FILEHANDLE "#define IS_SOLARIS\n";
943 if ($config{OSNAME} =~ /MINGW32/i) {
944 print FILEHANDLE "#define IS_MINGW\n";
946 if ($config{GCCVER} >= 3) {
947 print FILEHANDLE "#define GCC3\n";
950 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
952 ($config{GCCVER} > 4)
954 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
956 if ($config{HAS_STRLCPY} eq "true") {
957 print FILEHANDLE "#define HAS_STRLCPY\n";
959 if ($config{HAS_STDINT} eq "true") {
960 print FILEHANDLE "#define HAS_STDINT\n";
962 if ($config{IPV6} =~ /y/i) {
963 print FILEHANDLE "#define IPV6\n";
965 if ($config{HAS_EVENTFD} eq 'true') {
966 print FILEHANDLE "#define HAS_EVENTFD\n";
969 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
970 print FILEHANDLE "#define USE_KQUEUE\n";
971 $config{SOCKETENGINE} = "socketengine_kqueue";
974 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
975 print FILEHANDLE "#define USE_EPOLL\n";
976 $config{SOCKETENGINE} = "socketengine_epoll";
979 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
980 print FILEHANDLE "#define USE_PORTS\n";
981 $config{SOCKETENGINE} = "socketengine_ports";
984 # user didn't choose either epoll or select for their OS.
985 # default them to USE_SELECT (ewwy puke puke)
987 print "no hi-perf, " . $config{USE_POLL};
988 if ($config{USE_POLL} eq "y")
990 print FILEHANDLE "#define USE_POLL\n";
991 $config{SOCKETENGINE} = "socketengine_poll";
995 print FILEHANDLE "#define USE_SELECT\n";
996 $config{SOCKETENGINE} = "socketengine_select";
999 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1002 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1003 print FILEHANDLE <<EOF;
1004 #define VERSION "$version"
1005 #define REVISION "$revision2"
1006 #define SYSTEM "$incos"
1010 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
1012 open my $fh1, $file or $diff = 1;
1013 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1017 if (defined($line1) != defined($line2)) {
1019 } elsif (!defined $line1) {
1022 $diff = ($line1 ne $line2);
1027 rename "$file.tmp", $file;
1034 # Write all .in files.
1037 my $exe = "inspircd";
1039 # Do this once here, and cache it in the .*.inc files,
1040 # rather than attempting to read src/version.sh from
1041 # compiled code -- we might not have the source to hand.
1042 # Fix for bug#177 by Brain.
1044 chomp($version = `sh ./src/version.sh`);
1045 chomp(my $revision = getrevision());
1046 $version = "$version(r$revision)";
1048 # We can actually parse any file starting with . and ending with .inc,
1049 # but right now we only parse .inspircd.inc to form './inspircd'
1050 prepare_dynamic_makefile();
1052 my @dotfiles = qw(main.mk inspircd);
1053 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1055 foreach my $file (@dotfiles) {
1056 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1057 $_ = join '', <FILEHANDLE>;
1060 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1063 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR
1064 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1066 s/\@$var\@/$config{$var}/g;
1068 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1069 s/\@VERSION\@/$version/ if defined $version;
1071 if ($file eq 'main.mk') {
1072 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1075 s/\@IFDEF (\S+)/ifdef $1/g;
1076 s/\@IFNDEF (\S+)/ifndef $1/g;
1077 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1078 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1081 s/ *\@BSD_ONLY .*\n//g;
1083 s/\@DO_EXPORT (.*)/export $1/g;
1084 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1088 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1090 s/\@IFDEF (\S+)/.if defined($1)/g;
1091 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1092 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1093 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1097 s/ *\@GNU_ONLY .*\n//g;
1099 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1100 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1104 print "Writing \e[1;32m$file\e[0m ...\n";
1105 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1106 print FILEHANDLE $_;
1111 chmod 0755, 'inspircd';
1117 for my $mod (@modlist) {
1118 getcompilerflags("src/modules/m_$mod.cpp");
1119 getlinkerflags("src/modules/m_$mod.cpp");
1123 sub prepare_dynamic_makefile
1129 $config{USE_EPOLL} = 0;
1133 $config{USE_KQUEUE} = 0;
1137 $config{USE_PORTS} = 0;
1141 # Routine to list out the extra/ modules that have been enabled.
1142 # Note: when getting any filenames out and comparing, it's important to lc it if the
1143 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1144 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1145 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1146 sub list_extras () {
1149 my $srcdir = File::Spec->catdir("src", "modules");
1150 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1153 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1154 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1157 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1158 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1161 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1163 EXTRA: for my $extra (@extras) {
1164 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1165 next if ($extra eq '.svn');
1166 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1167 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1168 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1169 if (-l $abs_source) {
1170 # Symlink, is it in the right place?
1171 my $targ = readlink($abs_source);
1172 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1173 if ($abs_targ eq $abs_extra) {
1174 $extras{$extra} = "\e[32;1menabled\e[0m";
1176 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1178 } elsif (-e $abs_source) {
1179 my ($devext, $inoext) = stat($abs_extra);
1180 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1182 if ($devsrc == $devext && $inosrc == $inoext) {
1183 $extras{$extra} = "\e[32;1menabled\e[0m";
1185 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1188 open my $extfd, "<", $abs_extra;
1189 open my $srcfd, "<", $abs_source;
1191 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1192 $extras{$extra} = "\e[32;1menabled\e[0m";
1194 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1198 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1201 # Now let's add dependency info
1202 for my $extra (keys(%extras)) {
1203 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1204 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1205 my @deps = split / +/, getdependencies($abs_extra);
1206 for my $dep (@deps) {
1207 if (exists($extras{$dep})) {
1208 my $ref = \$extras{$dep}; # Take reference.
1209 if ($$ref !~ m/needed by/) {
1210 # First dependency found.
1211 if ($$ref =~ m/enabled/) {
1212 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1214 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1215 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1218 if ($$ref =~ m/enabled/) {
1219 $$ref .= ", \e[32;1m$extra\e[0m";
1221 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1227 for my $extra (sort {$a cmp $b} keys(%extras)) {
1228 my $text = $extras{$extra};
1229 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1230 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1232 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1235 return keys(%extras) if wantarray; # Can be used by manage_extras.
1238 sub enable_extras (@) {
1240 for my $extra (@extras) {
1241 my $extrapath = "src/modules/extra/$extra";
1242 if (!-e $extrapath) {
1243 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1246 my $source = "src/modules/$extra";
1248 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1251 # Get dependencies, and add them to be processed.
1252 my @deps = split / +/, getdependencies($extrapath);
1253 for my $dep (@deps) {
1254 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1255 if (!-e "src/modules/$dep") {
1256 if (-e "src/modules/extra/$dep") {
1257 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1260 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";
1264 print "Enabling $extra ... \n";
1265 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1269 sub disable_extras (@)
1271 opendir my $dd, "src/modules/extra/";
1272 my @files = readdir($dd);
1275 EXTRA: for my $extra (@extras) {
1276 my $extrapath = "src/modules/extra/$extra";
1277 my $source = "src/modules/$extra";
1278 if (!-e $extrapath) {
1279 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1282 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1283 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";
1286 # Check if anything needs this.
1287 for my $file (@files) {
1288 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1289 # File depends on this extra...
1290 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1291 # And is both enabled and not about to be disabled.
1292 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1293 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1299 print "Disabling $extra ... \n";
1300 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";