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
142 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
144 if (defined $opt_config_dir)
146 $config{CONFIG_DIR} = $opt_config_dir;
148 if (defined $opt_module_dir)
150 $config{MODULE_DIR} = $opt_module_dir;
152 if (defined $opt_binary_dir)
154 $config{BINARY_DIR} = $opt_binary_dir;
156 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
158 if (defined $opt_freebsd_port)
160 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
161 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
162 $config{USE_FREEBSD_BASE_SSL} = "n";
166 if ($^O eq "freebsd")
168 # default: use base ssl
169 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
170 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
174 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
175 $config{HAS_OPENSSL_PORT} = "";
179 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
180 chomp(our $openssl_ver = $config{HAS_OPENSSL});
181 $config{USE_GNUTLS} = "n";
182 if (defined $opt_use_gnutls)
184 $config{USE_GNUTLS} = "y"; # Use gnutls.
186 $config{USE_OPENSSL} = "n"; # Use openssl.
187 if (defined $opt_use_openssl)
189 $config{USE_OPENSSL} = "y";
192 # no, let's not change these.
193 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
194 if (!defined $opt_disable_debug)
196 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
200 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
203 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
204 $config{HAS_STDINT} = "false"; # stdint.h check
205 $config{USE_KQUEUE} = "y"; # kqueue enabled
206 if (defined $opt_kqueue)
208 $config{USE_KQUEUE} = "y";
210 if (defined $opt_nokqueue)
212 $config{USE_KQUEUE} = "n";
214 $config{USE_POLL} = "y"; # poll enabled
215 $config{USE_EPOLL} = "y"; # epoll enabled
216 if (defined $opt_epoll)
218 $config{USE_EPOLL} = "y";
220 if (defined $opt_noepoll)
222 $config{USE_EPOLL} = "n";
224 $config{USE_PORTS} = "y"; # epoll enabled
225 if (defined $opt_ports)
227 $config{USE_PORTS} = "y";
229 if (defined $opt_noports)
231 $config{USE_PORTS} = "n";
233 $config{IPV6} = "y"; # IPv6 support
234 if (defined $opt_noipv6)
238 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
239 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
240 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
241 $config{OSNAME} = $^O; # Operating System Name
242 $config{IS_DARWIN} = "NO"; # Is OSX?
243 $config{STARTSCRIPT} = "inspircd"; # start script?
244 $config{DESTINATION} = "BASE"; # Is target path.
245 $config{EXTRA_DIR} = ""; # Is empty.
246 if ($config{OSNAME} =~ /darwin/i)
248 $config{IS_DARWIN} = "YES";
249 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
250 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
251 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
253 $config{CC} = "g++"; # C++ compiler
256 $config{CC} = $opt_cc;
258 our $exec = $config{CC} . " -dumpversion | cut -c 1";
259 chomp($config{GCCVER} = `$exec`); # Major GCC Version
260 $exec = $config{CC} . " -dumpversion | cut -c 3";
261 chomp($config{GCCMINOR} = `$exec`);
262 $config{MAXBUF} = "512"; # Max buffer size
264 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
265 $config{HAS_OPENSSL} = $1;
267 $config{HAS_OPENSSL} = "";
270 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
271 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
275 # Get and Set some important vars..
280 unlink(".config.cache");
283 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
288 chomp($topdir = getcwd());
289 $this = resolve_directory($topdir); # PWD, Regardless.
291 # Does the cache file exist?
293 # No, No it doesn't.. *BASH*
294 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
297 # We've Loaded the cache file and all our variables..
298 print "Updating files...\n";
299 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
301 print "Disabling debug information (-g).\n";
302 $config{OPTIMISATI} = "";
304 $has_epoll = $config{HAS_EPOLL};
305 $has_ports = $config{HAS_PORTS};
306 $has_kqueue = $config{HAS_KQUEUE};
315 print "Configure update failed: $@\n";
323 open(FH,"<.svn/entries") or $fail = 1;
325 print "This is not an SVN copy of InspIRCd.\n";
332 open my $fd, "-|", "svn update";
333 my $configurechanged = 0; # Needs ./configure -update
334 my $rootincchanged = 0;
336 while (defined(my $line = <$fd>))
340 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
341 ($action, $file) = ($1, $2);
344 push @conflicted, $file;
345 if ($file eq "configure")
347 $configurechanged = 1;
349 elsif ($file =~ m/^\..*\.inc$/)
354 elsif ($action eq "U" || $action eq "G")
356 if ($file eq "configure")
358 $configurechanged = 1;
360 elsif ($file =~ m/^\..*\.inc$/)
366 unless (close $fd) # close() waits for exit and returns false if the command failed
370 print STDERR "Problem updating from SVN, please check above for errors\n";
374 print STDERR "Failed to run SVN: $!\n";
378 if (scalar(@conflicted) > 0)
380 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
381 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
382 print "Conflicted files: " . join ", ", @conflicted . "\n";
385 if ($configurechanged)
387 system("perl configure -update");
391 print "No need to update Makefiles.\n";
393 if (defined $opt_rebuild) {
394 system("make install");
402 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
403 $fail ||= system "./test_$feature";
404 unlink "test_$feature";
408 print "Running non-interactive configure...\n" unless $interactive;
409 print "Checking for cache from previous configure... ";
410 print ((!getcache()) ? "not found\n" : "found\n");
411 $config{SYSTEM} = lc $^O;
412 print "Checking operating system version... $config{SYSTEM}\n";
414 printf "Checking if stdint.h exists... ";
415 $config{HAS_STDINT} = "true";
417 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
418 if ($config{HAS_STDINT} eq "true") {
421 print "yes\n" if $config{HAS_STDINT} eq "true";
422 print "no\n" if $config{HAS_STDINT} eq "false";
424 printf "Checking if strlcpy exists... ";
425 # Perform the strlcpy() test..
426 $config{HAS_STRLCPY} = "false";
428 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
430 while (defined(my $line = <STRLCPY>)) {
432 # try and find the delcaration of:
433 # size_t strlcpy(...)
434 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
435 $config{HAS_STRLCPY} = "true";
440 print "yes\n" if $config{HAS_STRLCPY} eq "true";
441 print "no\n" if $config{HAS_STRLCPY} eq "false";
443 printf "Checking if kqueue exists... ";
446 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
448 while (defined(my $line = <KQUEUE>)) {
450 # try and find the delcaration of:
452 if ($line =~ /int(\0x9|\s)+kqueue/) {
458 print "yes\n" if $has_kqueue == 1;
459 print "no\n" if $has_kqueue == 0;
461 printf "Checking for epoll support... ";
462 $has_epoll = test_compile('epoll');
463 print $has_epoll ? "yes\n" : "no\n";
465 printf "Checking for eventfd support... ";
466 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
467 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
469 printf "Checking if Solaris I/O completion ports are available... ";
471 our $system = `uname -s`;
473 $has_ports = 1 if ($system eq "SunOS");
476 my $kernel = `uname -r`;
478 if (($kernel !~ /^5\.1./)) {
482 print "yes\n" if $has_ports == 1;
483 print "no\n" if $has_ports == 0;
485 $config{HAS_EPOLL} = $has_epoll;
486 $config{HAS_KQUEUE} = $has_kqueue;
488 printf "Checking for libgnutls... ";
489 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
490 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
492 $config{HAS_GNUTLS} = "y";
495 $config{HAS_GNUTLS} = "n";
499 $config{HAS_GNUTLS} = "n";
502 printf "Checking for openssl... ";
503 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
504 if (defined($openssl_ver) && ($openssl_ver ne "")) {
506 $config{HAS_OPENSSL} = "y";
509 $config{HAS_OPENSSL} = "n";
513 $config{HAS_OPENSSL} = "n";
516 printf "Checking if you are running an ancient, unsupported OS... ";
517 if ($config{OSNAME} =~ /FreeBSD/i)
519 my $version = `uname -r`;
520 if ($version =~ /^4\./)
523 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
524 print "To build, you will need to add the following to CXXFLAGS:\n";
525 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
529 print "no ($version)\n";
534 print "no ($config{OSNAME})\n";
537 print "Checking for upgrades to extra and third party modules... ";
538 system "./modulemanager upgrade";
540 ################################################################################
541 # BEGIN INTERACTIVE PART #
542 ################################################################################
547 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
550 my $rev = getrevision();
551 # Display Introduction Message..
553 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
554 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
556 *** If you are unsure of any of these values, leave it blank for ***
557 *** standard settings that will work, and your server will run ***
558 *** using them. Please consult your IRC network admin if in doubt. ***
560 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
561 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
562 dir, otherwise you won't have a config file!
564 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
565 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
568 print " (Non-SVN build)";
572 $config{CHANGE_COMPILER} = "n";
573 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";
575 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
576 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
577 should NOT be used. You should probably specify a newer compiler.\n\n";
578 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
579 if ($config{CHANGE_COMPILER} =~ /y/i) {
580 print "What command do you want to use to invoke your compiler?\n";
581 print "[\e[1;32m$config{CC}\e[0m] -> ";
582 chomp($config{CC} = <STDIN>);
583 if ($config{CC} eq "") {
586 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
588 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
589 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
590 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
591 if ($config{GCCVER} < 3) {
592 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
596 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
603 # Directory Settings..
604 my $tmpbase = $config{BASE_DIR};
605 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
606 if ($tmpbase ne $config{BASE_DIR}) {
607 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
608 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
609 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
612 dir_check("are the configuration files", "CONFIG_DIR");
613 dir_check("are the modules to be compiled to", "MODULE_DIR");
614 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
615 dir_check("do you want the build to take place", "BUILD_DIR");
617 my $chose_hiperf = 0;
619 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?");
621 if ($config{USE_KQUEUE} eq "y") {
626 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?");
628 if ($config{USE_EPOLL} eq "y") {
633 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?");
635 if ($config{USE_PORTS} eq "y") {
640 if (!$chose_hiperf) {
641 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?");
642 if ($config{USE_POLL} ne "y")
644 print "No high-performance socket engines are available, or you chose\n";
645 print "not to enable one. Defaulting to select() engine.\n\n";
649 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
652 $config{USE_FREEBSD_BASE_SSL} = "n";
653 $config{USE_FREEBSD_PORTS_SSL} = "n";
654 if ($config{HAS_OPENSSL_PORT} ne "")
656 $config{USE_FREEBSD_PORTS_SSL} = "y";
657 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
658 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";
659 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
661 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
663 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
665 # update to port version
666 $openssl_ver = $config{HAS_OPENSSL_PORT};
671 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
674 $config{USE_SSL} = "n";
676 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
678 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
679 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
681 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
682 if ($config{USE_SSL} eq "y")
684 if ($config{HAS_GNUTLS} eq "y")
686 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
687 if ($config{USE_GNUTLS} eq "y")
689 print "\nUsing GnuTLS SSL module.\n";
693 if ($config{HAS_OPENSSL} eq "y")
695 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
696 if ($config{USE_OPENSSL} eq "y")
698 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
705 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
706 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
712 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
714 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
717 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
719 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
724 $config{CERTGEN} ||= 'y';
725 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
727 if ($config{USE_GNUTLS} eq "y") {
728 unless (-r "src/modules/m_ssl_gnutls.cpp") {
729 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
730 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
732 if ($interactive && $config{CERTGEN} eq 'y')
734 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
735 print "SSL Certificates Not found, Generating.. \n\n
736 *************************************************************
737 * Generating the Private Key may take some time, go grab a *
738 * Coffee. Even better, to generate some more entropy if it *
739 * is taking a while, open another console and type du / a *
740 * few times and get that HD going :) Then answer the *
741 * Questions which follow. If you are unsure, just hit enter *
742 *************************************************************\n\n";
743 $failed = make_gnutls_cert();
745 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
747 print "\nCertificate generation complete, copying to config directory... ";
748 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
749 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
754 print "SSL Certificates found, skipping.\n\n";
759 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
763 if ($config{USE_OPENSSL} eq "y") {
764 unless (-r "src/modules/m_ssl_openssl.cpp") {
765 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
766 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
769 if ($interactive && $config{CERTGEN} eq 'y')
771 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
772 print "SSL Certificates Not found, Generating.. \n\n
773 *************************************************************
774 * Generating the certificates may take some time, go grab a *
775 * coffee, or something. *
776 *************************************************************\n\n";
778 print "\nCertificate generation complete, copying to config directory... ";
779 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
780 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
781 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
784 print "SSL Certificates found, skipping.\n\n"
789 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
792 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
793 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
801 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
802 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
803 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
804 print "modules in your config. This configure script has added those modules to the\n";
805 print "build process. For more info please refer to:\n";
806 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
808 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
809 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
810 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";
813 if ($config{GCCVER} < "3") {
815 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
816 GCC 2.x series compilers only had partial (read as broken) C++ support, and
817 your compile will most likely fail horribly! If you have any problems, do NOT
818 report them to the bugtracker or forums without first upgrading your compiler
819 to a newer 3.x or 4.x (or whatever is available currently) version.
823 ################################################################################
825 ################################################################################
827 # Retrieves the .config.cache file, and loads values into the main config hash.
828 open(CACHE, ".config.cache") or return 0;
831 # Ignore Blank lines, and comments..
834 my ($key, $value) = split("=", $_, 2);
835 $value =~ /^\"(.*)\"$/;
836 # Do something with data here!
844 # Dump the contents of %config
845 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
846 open(FILEHANDLE, ">.config.cache");
847 foreach my $key (keys %config) {
848 print FILEHANDLE "$key=\"$config{$key}\"\n";
854 my ($desc, $hash_key) = @_;
857 print "In what directory $desc?\n";
858 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
859 chomp(my $var = <STDIN>);
861 $var = $config{$hash_key};
863 if ($var =~ /^\~\/(.+)$/) {
864 # Convert it to a full path..
865 $var = resolve_directory($ENV{HOME} . "/" . $1);
867 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
869 # Assume relative Path was given.. fill in the rest.
870 $var = $this . "/$var";
873 $var = resolve_directory($var);
875 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
876 chomp(my $tmp = <STDIN>);
877 if (($tmp eq "") || ($tmp =~ /^y/i)) {
878 # Attempt to Create the Dir..
881 File::Path::mkpath($var, 0, 0777);
884 unless (defined($chk) && -d $var) {
885 print "Unable to create directory. ($var)\n\n";
890 # They said they don't want to create, and we can't install there.
896 # Target exists, but is not a directory.
897 print "File $var exists, but is not a directory.\n\n";
901 # Either Dir Exists, or was created fine.
902 $config{$hash_key} = $var;
910 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
913 my($writeheader) = @_;
914 # First File.. inspircd_config.h
915 chomp(my $incos = `uname -n -s -r`);
916 chomp(my $version = `sh src/version.sh`);
917 chomp(my $revision2 = getrevision());
918 if ($writeheader == 1)
920 print "Writing \e[1;32minspircd_config.h\e[0m\n";
921 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
922 print FILEHANDLE <<EOF;
923 /* Auto generated by configure, do not modify! */
924 #ifndef __CONFIGURATION_AUTO__
925 #define __CONFIGURATION_AUTO__
927 /* this is for windows support. */
928 #define CoreExport /**/
929 #define DllExport /**/
931 #define MOD_PATH "$config{MODULE_DIR}"
932 #define SOMAXCONN_S "$config{_SOMAXCONN}"
933 #define ENTRYPOINT int main(int argc, char** argv)
936 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
938 if ($config{OSNAME} =~ /SunOS/i) {
939 print FILEHANDLE "#define IS_SOLARIS\n";
941 if ($config{OSNAME} =~ /MINGW32/i) {
942 print FILEHANDLE "#define IS_MINGW\n";
944 if ($config{GCCVER} >= 3) {
945 print FILEHANDLE "#define GCC3\n";
948 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
950 ($config{GCCVER} > 4)
952 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
954 if ($config{HAS_STRLCPY} eq "true") {
955 print FILEHANDLE "#define HAS_STRLCPY\n";
957 if ($config{HAS_STDINT} eq "true") {
958 print FILEHANDLE "#define HAS_STDINT\n";
960 if ($config{IPV6} =~ /y/i) {
961 print FILEHANDLE "#define IPV6\n";
963 if ($config{HAS_EVENTFD} eq 'true') {
964 print FILEHANDLE "#define HAS_EVENTFD\n";
967 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
968 print FILEHANDLE "#define USE_KQUEUE\n";
969 $config{SOCKETENGINE} = "socketengine_kqueue";
972 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
973 print FILEHANDLE "#define USE_EPOLL\n";
974 $config{SOCKETENGINE} = "socketengine_epoll";
977 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
978 print FILEHANDLE "#define USE_PORTS\n";
979 $config{SOCKETENGINE} = "socketengine_ports";
982 # user didn't choose either epoll or select for their OS.
983 # default them to USE_SELECT (ewwy puke puke)
985 print "no hi-perf, " . $config{USE_POLL};
986 if ($config{USE_POLL} eq "y")
988 print FILEHANDLE "#define USE_POLL\n";
989 $config{SOCKETENGINE} = "socketengine_poll";
993 print FILEHANDLE "#define USE_SELECT\n";
994 $config{SOCKETENGINE} = "socketengine_select";
997 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1000 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1001 print FILEHANDLE <<EOF;
1002 #define VERSION "$version"
1003 #define REVISION "$revision2"
1004 #define SYSTEM "$incos"
1008 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
1010 open my $fh1, $file or $diff = 1;
1011 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1015 if (defined($line1) != defined($line2)) {
1017 } elsif (!defined $line1) {
1020 $diff = ($line1 ne $line2);
1025 rename "$file.tmp", $file;
1032 # Write all .in files.
1035 my $exe = "inspircd";
1037 # Do this once here, and cache it in the .*.inc files,
1038 # rather than attempting to read src/version.sh from
1039 # compiled code -- we might not have the source to hand.
1040 # Fix for bug#177 by Brain.
1042 chomp($version = `sh ./src/version.sh`);
1043 chomp(my $revision = getrevision());
1044 $version = "$version(r$revision)";
1046 # We can actually parse any file starting with . and ending with .inc,
1047 # but right now we only parse .inspircd.inc to form './inspircd'
1048 prepare_dynamic_makefile();
1050 print "Writing \e[1;32mMakefiles\e[0m\n";
1052 opendir(DIRHANDLE, $this);
1054 foreach my $name (sort readdir(DIRHANDLE)) {
1055 if ($name =~ /^\.(.+)\.inc$/) {
1058 # Bug #353, omit this on non-darwin
1059 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1061 # All .name.inc files need parsing!
1062 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1063 $_ = join '', <FILEHANDLE>;
1066 print "Writing \e[1;32m$file\e[0m ...\n";
1068 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1071 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR
1072 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1074 s/\@$var\@/$config{$var}/g;
1076 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1077 s/\@VERSION\@/$version/ if defined $version;
1079 if ($file eq 'Makefile') {
1081 s/\@IFDEF (\S+)/ifdef $1/g;
1082 s/\@IFNDEF (\S+)/ifndef $1/g;
1083 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1084 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1087 s/ *\@BSD_ONLY .*\n//g;
1089 s/\@DO_EXPORT (.*)/export $1/g;
1090 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1094 s/\@IFDEF (\S+)/.if defined($1)/g;
1095 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1096 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1097 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1101 s/ *\@GNU_ONLY .*\n//g;
1103 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1104 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1108 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1109 print FILEHANDLE $_;
1114 closedir(DIRHANDLE);
1116 # Make inspircd executable!
1117 chmod 0744, 'inspircd';
1123 for my $mod (@modlist) {
1124 getcompilerflags("src/modules/m_$mod.cpp");
1125 getlinkerflags("src/modules/m_$mod.cpp");
1129 sub prepare_dynamic_makefile
1135 $config{USE_EPOLL} = 0;
1139 $config{USE_KQUEUE} = 0;
1143 $config{USE_PORTS} = 0;
1147 # Routine to list out the extra/ modules that have been enabled.
1148 # Note: when getting any filenames out and comparing, it's important to lc it if the
1149 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1150 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1151 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1152 sub list_extras () {
1155 my $srcdir = File::Spec->catdir("src", "modules");
1156 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1159 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1160 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1163 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1164 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1167 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1169 EXTRA: for my $extra (@extras) {
1170 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1171 next if ($extra eq '.svn');
1172 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1173 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1174 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1175 if (-l $abs_source) {
1176 # Symlink, is it in the right place?
1177 my $targ = readlink($abs_source);
1178 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1179 if ($abs_targ eq $abs_extra) {
1180 $extras{$extra} = "\e[32;1menabled\e[0m";
1182 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1184 } elsif (-e $abs_source) {
1185 my ($devext, $inoext) = stat($abs_extra);
1186 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1188 if ($devsrc == $devext && $inosrc == $inoext) {
1189 $extras{$extra} = "\e[32;1menabled\e[0m";
1191 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1194 open my $extfd, "<", $abs_extra;
1195 open my $srcfd, "<", $abs_source;
1197 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1198 $extras{$extra} = "\e[32;1menabled\e[0m";
1200 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1204 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1207 # Now let's add dependency info
1208 for my $extra (keys(%extras)) {
1209 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1210 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1211 my @deps = split / +/, getdependencies($abs_extra);
1212 for my $dep (@deps) {
1213 if (exists($extras{$dep})) {
1214 my $ref = \$extras{$dep}; # Take reference.
1215 if ($$ref !~ m/needed by/) {
1216 # First dependency found.
1217 if ($$ref =~ m/enabled/) {
1218 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1220 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1221 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1224 if ($$ref =~ m/enabled/) {
1225 $$ref .= ", \e[32;1m$extra\e[0m";
1227 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1233 for my $extra (sort {$a cmp $b} keys(%extras)) {
1234 my $text = $extras{$extra};
1235 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1236 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1238 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1241 return keys(%extras) if wantarray; # Can be used by manage_extras.
1244 sub enable_extras (@) {
1246 for my $extra (@extras) {
1247 my $extrapath = "src/modules/extra/$extra";
1248 if (!-e $extrapath) {
1249 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1252 my $source = "src/modules/$extra";
1254 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1257 # Get dependencies, and add them to be processed.
1258 my @deps = split / +/, getdependencies($extrapath);
1259 for my $dep (@deps) {
1260 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1261 if (!-e "src/modules/$dep") {
1262 if (-e "src/modules/extra/$dep") {
1263 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1266 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";
1270 print "Enabling $extra ... \n";
1271 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1275 sub disable_extras (@)
1277 opendir my $dd, "src/modules/extra/";
1278 my @files = readdir($dd);
1281 EXTRA: for my $extra (@extras) {
1282 my $extrapath = "src/modules/extra/$extra";
1283 my $source = "src/modules/$extra";
1284 if (!-e $extrapath) {
1285 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1288 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1289 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";
1292 # Check if anything needs this.
1293 for my $file (@files) {
1294 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1295 # File depends on this extra...
1296 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1297 # And is both enabled and not about to be disabled.
1298 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1299 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1305 print "Disabling $extra ... \n";
1306 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";