2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2010 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 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
236 $config{OSNAME} = $^O; # Operating System Name
237 $config{IS_DARWIN} = "NO"; # Is OSX?
238 $config{STARTSCRIPT} = "inspircd"; # start script?
239 $config{DESTINATION} = "BASE"; # Is target path.
240 $config{EXTRA_DIR} = ""; # Is empty.
241 if ($config{OSNAME} =~ /darwin/i)
243 $config{IS_DARWIN} = "YES";
244 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
246 $config{CC} = "g++"; # C++ compiler
249 $config{CC} = $opt_cc;
251 our $exec = $config{CC} . " -dumpversion | cut -c 1";
252 chomp($config{GCCVER} = `$exec`); # Major GCC Version
253 $exec = $config{CC} . " -dumpversion | cut -c 3";
254 chomp($config{GCCMINOR} = `$exec`);
255 $config{MAXBUF} = "512"; # Max buffer size
257 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
258 $config{HAS_OPENSSL} = $1;
260 $config{HAS_OPENSSL} = "";
263 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
264 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
268 # Get and Set some important vars..
273 unlink(".config.cache");
276 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
281 chomp($topdir = getcwd());
282 $this = resolve_directory($topdir); # PWD, Regardless.
284 # Does the cache file exist?
286 # No, No it doesn't.. *BASH*
287 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
290 # We've Loaded the cache file and all our variables..
291 print "Updating files...\n";
292 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
294 print "Disabling debug information (-g).\n";
295 $config{OPTIMISATI} = "";
297 $has_epoll = $config{HAS_EPOLL};
298 $has_ports = $config{HAS_PORTS};
299 $has_kqueue = $config{HAS_KQUEUE};
308 print "Configure update failed: $@\n";
316 open(FH,"<.svn/entries") or $fail = 1;
318 print "This is not an SVN copy of InspIRCd.\n";
325 open my $fd, "-|", "svn update";
326 my $configurechanged = 0; # Needs ./configure -update
327 my $rootincchanged = 0;
329 while (defined(my $line = <$fd>))
333 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
334 ($action, $file) = ($1, $2);
337 push @conflicted, $file;
338 if ($file eq "configure")
340 $configurechanged = 1;
342 elsif ($file =~ m/^\..*\.inc$/)
347 elsif ($action eq "U" || $action eq "G")
349 if ($file eq "configure")
351 $configurechanged = 1;
353 elsif ($file =~ m/^\..*\.inc$/)
359 unless (close $fd) # close() waits for exit and returns false if the command failed
363 print STDERR "Problem updating from SVN, please check above for errors\n";
367 print STDERR "Failed to run SVN: $!\n";
371 if (scalar(@conflicted) > 0)
373 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
374 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
375 print "Conflicted files: " . join ", ", @conflicted . "\n";
378 if ($configurechanged)
380 system("perl configure -update");
384 print "No need to update Makefiles.\n";
386 if (defined $opt_rebuild) {
387 system("make install");
395 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
396 $fail ||= system "./test_$feature";
397 unlink "test_$feature";
401 print "Running non-interactive configure...\n" unless $interactive;
402 print "Checking for cache from previous configure... ";
403 print ((!getcache()) ? "not found\n" : "found\n");
404 $config{SYSTEM} = lc $^O;
405 print "Checking operating system version... $config{SYSTEM}\n";
407 $exec = $config{CC} . " -dumpversion | cut -c 1";
408 chomp($config{GCCVER} = `$exec`); # Major GCC Version
409 $exec = $config{CC} . " -dumpversion | cut -c 3";
410 chomp($config{GCCMINOR} = `$exec`);
412 printf "Checking if stdint.h exists... ";
413 $config{HAS_STDINT} = "true";
415 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
416 if ($config{HAS_STDINT} eq "true") {
419 print "yes\n" if $config{HAS_STDINT} eq "true";
420 print "no\n" if $config{HAS_STDINT} eq "false";
422 printf "Checking if strlcpy exists... ";
423 # Perform the strlcpy() test..
424 $config{HAS_STRLCPY} = "false";
426 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
428 while (defined(my $line = <STRLCPY>)) {
430 # try and find the delcaration of:
431 # size_t strlcpy(...)
432 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
433 $config{HAS_STRLCPY} = "true";
438 print "yes\n" if $config{HAS_STRLCPY} eq "true";
439 print "no\n" if $config{HAS_STRLCPY} eq "false";
441 printf "Checking if kqueue exists... ";
444 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
446 while (defined(my $line = <KQUEUE>)) {
448 # try and find the delcaration of:
450 if ($line =~ /int(\0x9|\s)+kqueue/) {
456 print "yes\n" if $has_kqueue == 1;
457 print "no\n" if $has_kqueue == 0;
459 printf "Checking for epoll support... ";
460 $has_epoll = test_compile('epoll');
461 print $has_epoll ? "yes\n" : "no\n";
463 printf "Checking for eventfd support... ";
464 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
465 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
467 printf "Checking if Solaris I/O completion ports are available... ";
469 our $system = `uname -s`;
471 $has_ports = 1 if ($system eq "SunOS");
474 my $kernel = `uname -r`;
476 if (($kernel !~ /^5\.1./)) {
480 print "yes\n" if $has_ports == 1;
481 print "no\n" if $has_ports == 0;
483 $config{HAS_EPOLL} = $has_epoll;
484 $config{HAS_KQUEUE} = $has_kqueue;
486 printf "Checking for libgnutls... ";
487 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
488 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
490 $config{HAS_GNUTLS} = "y";
493 $config{HAS_GNUTLS} = "n";
497 $config{HAS_GNUTLS} = "n";
500 printf "Checking for openssl... ";
501 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
502 if (defined($openssl_ver) && ($openssl_ver ne "")) {
504 $config{HAS_OPENSSL} = "y";
507 $config{HAS_OPENSSL} = "n";
511 $config{HAS_OPENSSL} = "n";
514 printf "Checking if you are running an ancient, unsupported OS... ";
515 if ($config{OSNAME} =~ /FreeBSD/i)
517 my $version = `uname -r`;
518 if ($version =~ /^4\./)
521 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
522 print "To build, you will need to add the following to CXXFLAGS:\n";
523 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
527 print "no ($version)\n";
532 print "no ($config{OSNAME})\n";
535 ################################################################################
536 # BEGIN INTERACTIVE PART #
537 ################################################################################
542 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
545 my $rev = getrevision();
546 # Display Introduction Message..
548 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
549 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
551 *** If you are unsure of any of these values, leave it blank for ***
552 *** standard settings that will work, and your server will run ***
553 *** using them. Please consult your IRC network admin if in doubt. ***
555 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
556 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
557 dir, otherwise you won't have a config file!
559 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
560 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
563 print " (Non-SVN build)";
567 $config{CHANGE_COMPILER} = "n";
568 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";
570 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
571 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
572 should NOT be used. You should probably specify a newer compiler.\n\n";
573 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
574 if ($config{CHANGE_COMPILER} =~ /y/i) {
575 print "What command do you want to use to invoke your compiler?\n";
576 print "[\e[1;32m$config{CC}\e[0m] -> ";
577 chomp($config{CC} = <STDIN>);
578 if ($config{CC} eq "") {
581 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
583 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
584 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
585 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
586 if ($config{GCCVER} < 3) {
587 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
591 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
598 # Directory Settings..
599 my $tmpbase = $config{BASE_DIR};
600 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
601 if ($tmpbase ne $config{BASE_DIR}) {
602 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
603 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
604 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
607 dir_check("are the configuration files", "CONFIG_DIR");
608 dir_check("are the modules to be compiled to", "MODULE_DIR");
609 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
610 dir_check("do you want the build to take place", "BUILD_DIR");
612 my $chose_hiperf = 0;
614 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?");
616 if ($config{USE_KQUEUE} eq "y") {
621 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?");
623 if ($config{USE_EPOLL} eq "y") {
628 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?");
630 if ($config{USE_PORTS} eq "y") {
635 if (!$chose_hiperf) {
636 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?");
637 if ($config{USE_POLL} ne "y")
639 print "No high-performance socket engines are available, or you chose\n";
640 print "not to enable one. Defaulting to select() engine.\n\n";
644 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
647 $config{USE_FREEBSD_BASE_SSL} = "n";
648 $config{USE_FREEBSD_PORTS_SSL} = "n";
649 if ($config{HAS_OPENSSL_PORT} ne "")
651 $config{USE_FREEBSD_PORTS_SSL} = "y";
652 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
653 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";
654 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
656 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
658 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
660 # update to port version
661 $openssl_ver = $config{HAS_OPENSSL_PORT};
666 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
669 $config{USE_SSL} = "n";
670 $config{MODUPDATE} = 'n';
672 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
674 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
675 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
677 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
678 if ($config{USE_SSL} eq "y")
680 if ($config{HAS_GNUTLS} eq "y")
682 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
683 if ($config{USE_GNUTLS} eq "y")
685 print "\nUsing GnuTLS SSL module.\n";
689 if ($config{HAS_OPENSSL} eq "y")
691 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
692 if ($config{USE_OPENSSL} eq "y")
694 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
701 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
702 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
705 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
707 if ($config{MODUPDATE} eq "y") {
708 print "Checking for upgrades to extra and third party modules... ";
709 system "./modulemanager upgrade";
715 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
717 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
720 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
722 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
727 $config{CERTGEN} ||= 'y';
728 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
730 if ($config{USE_GNUTLS} eq "y") {
731 unless (-r "src/modules/m_ssl_gnutls.cpp") {
732 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
733 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
735 if ($interactive && $config{CERTGEN} eq 'y')
737 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
738 print "SSL Certificates Not found, Generating.. \n\n
739 *************************************************************
740 * Generating the Private Key may take some time, go grab a *
741 * Coffee. Even better, to generate some more entropy if it *
742 * is taking a while, open another console and type du / a *
743 * few times and get that HD going :) Then answer the *
744 * Questions which follow. If you are unsure, just hit enter *
745 *************************************************************\n\n";
746 $failed = make_gnutls_cert();
748 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
750 print "\nCertificate generation complete, copying to config directory... ";
751 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
752 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
757 print "SSL Certificates found, skipping.\n\n";
762 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
766 if ($config{USE_OPENSSL} eq "y") {
767 unless (-r "src/modules/m_ssl_openssl.cpp") {
768 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
769 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
772 if ($interactive && $config{CERTGEN} eq 'y')
774 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
775 print "SSL Certificates Not found, Generating.. \n\n
776 *************************************************************
777 * Generating the certificates may take some time, go grab a *
778 * coffee, or something. *
779 *************************************************************\n\n";
781 print "\nCertificate generation complete, copying to config directory... ";
782 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
783 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
784 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
787 print "SSL Certificates found, skipping.\n\n"
792 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
795 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
796 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
804 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
805 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
806 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
807 print "modules in your config. This configure script has added those modules to the\n";
808 print "build process. For more info please refer to:\n";
809 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
811 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
812 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
813 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";
816 if ($config{GCCVER} < "3") {
818 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
819 GCC 2.x series compilers only had partial (read as broken) C++ support, and
820 your compile will most likely fail horribly! If you have any problems, do NOT
821 report them to the bugtracker or forums without first upgrading your compiler
822 to a newer 3.x or 4.x (or whatever is available currently) version.
826 ################################################################################
828 ################################################################################
830 # Retrieves the .config.cache file, and loads values into the main config hash.
831 open(CACHE, ".config.cache") or return 0;
834 # Ignore Blank lines, and comments..
837 my ($key, $value) = split("=", $_, 2);
838 $value =~ /^\"(.*)\"$/;
839 # Do something with data here!
847 # Dump the contents of %config
848 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
849 open(FILEHANDLE, ">.config.cache");
850 foreach my $key (keys %config) {
851 print FILEHANDLE "$key=\"$config{$key}\"\n";
857 my ($desc, $hash_key) = @_;
860 print "In what directory $desc?\n";
861 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
862 chomp(my $var = <STDIN>);
864 $var = $config{$hash_key};
866 if ($var =~ /^\~\/(.+)$/) {
867 # Convert it to a full path..
868 $var = resolve_directory($ENV{HOME} . "/" . $1);
870 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
872 # Assume relative Path was given.. fill in the rest.
873 $var = $this . "/$var";
876 $var = resolve_directory($var);
878 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
879 chomp(my $tmp = <STDIN>);
880 if (($tmp eq "") || ($tmp =~ /^y/i)) {
881 # Attempt to Create the Dir..
884 File::Path::mkpath($var, 0, 0777);
887 unless (defined($chk) && -d $var) {
888 print "Unable to create directory. ($var)\n\n";
893 # They said they don't want to create, and we can't install there.
899 # Target exists, but is not a directory.
900 print "File $var exists, but is not a directory.\n\n";
904 # Either Dir Exists, or was created fine.
905 $config{$hash_key} = $var;
913 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
916 my($writeheader) = @_;
917 # First File.. inspircd_config.h
918 chomp(my $incos = `uname -n -s -r`);
919 chomp(my $version = `sh src/version.sh`);
920 chomp(my $revision2 = getrevision());
921 if ($writeheader == 1)
923 print "Writing \e[1;32minspircd_config.h\e[0m\n";
924 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
925 print FILEHANDLE <<EOF;
926 /* Auto generated by configure, do not modify! */
927 #ifndef __CONFIGURATION_AUTO__
928 #define __CONFIGURATION_AUTO__
930 /* this is for windows support. */
931 #define CoreExport /**/
932 #define DllExport /**/
934 #define MOD_PATH "$config{MODULE_DIR}"
935 #define SOMAXCONN_S "$config{_SOMAXCONN}"
936 #define ENTRYPOINT int main(int argc, char** argv)
939 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
941 if ($config{OSNAME} =~ /SunOS/i) {
942 print FILEHANDLE "#define IS_SOLARIS\n";
944 if ($config{OSNAME} =~ /MINGW32/i) {
945 print FILEHANDLE "#define IS_MINGW\n";
947 if ($config{GCCVER} >= 3) {
948 print FILEHANDLE "#define GCC3\n";
951 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
953 ($config{GCCVER} > 4)
955 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
957 if ($config{HAS_STRLCPY} eq "true") {
958 print FILEHANDLE "#define HAS_STRLCPY\n";
960 if ($config{HAS_STDINT} eq "true") {
961 print FILEHANDLE "#define HAS_STDINT\n";
963 if ($config{IPV6} =~ /y/i) {
964 print FILEHANDLE "#define IPV6\n";
966 if ($config{HAS_EVENTFD} eq 'true') {
967 print FILEHANDLE "#define HAS_EVENTFD\n";
970 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
971 print FILEHANDLE "#define USE_KQUEUE\n";
972 $config{SOCKETENGINE} = "socketengine_kqueue";
975 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
976 print FILEHANDLE "#define USE_EPOLL\n";
977 $config{SOCKETENGINE} = "socketengine_epoll";
980 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
981 print FILEHANDLE "#define USE_PORTS\n";
982 $config{SOCKETENGINE} = "socketengine_ports";
985 # user didn't choose either epoll or select for their OS.
986 # default them to USE_SELECT (ewwy puke puke)
988 print "no hi-perf, " . $config{USE_POLL};
989 if ($config{USE_POLL} eq "y")
991 print FILEHANDLE "#define USE_POLL\n";
992 $config{SOCKETENGINE} = "socketengine_poll";
996 print FILEHANDLE "#define USE_SELECT\n";
997 $config{SOCKETENGINE} = "socketengine_select";
1000 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1003 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1004 print FILEHANDLE <<EOF;
1005 #define VERSION "$version"
1006 #define REVISION "$revision2"
1007 #define SYSTEM "$incos"
1011 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
1013 open my $fh1, $file or $diff = 1;
1014 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1018 if (defined($line1) != defined($line2)) {
1020 } elsif (!defined $line1) {
1023 $diff = ($line1 ne $line2);
1028 rename "$file.tmp", $file;
1035 # Write all .in files.
1038 my $exe = "inspircd";
1040 # Do this once here, and cache it in the .*.inc files,
1041 # rather than attempting to read src/version.sh from
1042 # compiled code -- we might not have the source to hand.
1043 # Fix for bug#177 by Brain.
1045 chomp($version = `sh ./src/version.sh`);
1046 chomp(my $revision = getrevision());
1047 $version = "$version(r$revision)";
1049 # We can actually parse any file starting with . and ending with .inc,
1050 # but right now we only parse .inspircd.inc to form './inspircd'
1051 prepare_dynamic_makefile();
1053 my @dotfiles = qw(main.mk inspircd);
1054 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1056 foreach my $file (@dotfiles) {
1057 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1058 $_ = join '', <FILEHANDLE>;
1061 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1064 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR
1065 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1067 s/\@$var\@/$config{$var}/g;
1069 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1070 s/\@VERSION\@/$version/ if defined $version;
1072 if ($file eq 'main.mk') {
1073 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1076 s/\@IFDEF (\S+)/ifdef $1/g;
1077 s/\@IFNDEF (\S+)/ifndef $1/g;
1078 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1079 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1082 s/ *\@BSD_ONLY .*\n//g;
1084 s/\@DO_EXPORT (.*)/export $1/g;
1085 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1089 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1091 s/\@IFDEF (\S+)/.if defined($1)/g;
1092 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1093 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1094 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1098 s/ *\@GNU_ONLY .*\n//g;
1100 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1101 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1105 print "Writing \e[1;32m$file\e[0m ...\n";
1106 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1107 print FILEHANDLE $_;
1112 chmod 0755, 'inspircd';
1118 for my $mod (@modlist) {
1119 getcompilerflags("src/modules/m_$mod.cpp");
1120 getlinkerflags("src/modules/m_$mod.cpp");
1124 sub prepare_dynamic_makefile
1130 $config{USE_EPOLL} = 0;
1134 $config{USE_KQUEUE} = 0;
1138 $config{USE_PORTS} = 0;
1142 # Routine to list out the extra/ modules that have been enabled.
1143 # Note: when getting any filenames out and comparing, it's important to lc it if the
1144 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1145 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1146 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1147 sub list_extras () {
1150 my $srcdir = File::Spec->catdir("src", "modules");
1151 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1154 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1155 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1158 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1159 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1162 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1164 EXTRA: for my $extra (@extras) {
1165 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1166 next if ($extra eq '.svn');
1167 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1168 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1169 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1170 if (-l $abs_source) {
1171 # Symlink, is it in the right place?
1172 my $targ = readlink($abs_source);
1173 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1174 if ($abs_targ eq $abs_extra) {
1175 $extras{$extra} = "\e[32;1menabled\e[0m";
1177 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1179 } elsif (-e $abs_source) {
1180 my ($devext, $inoext) = stat($abs_extra);
1181 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1183 if ($devsrc == $devext && $inosrc == $inoext) {
1184 $extras{$extra} = "\e[32;1menabled\e[0m";
1186 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1189 open my $extfd, "<", $abs_extra;
1190 open my $srcfd, "<", $abs_source;
1192 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1193 $extras{$extra} = "\e[32;1menabled\e[0m";
1195 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1199 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1202 # Now let's add dependency info
1203 for my $extra (keys(%extras)) {
1204 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1205 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1206 my @deps = split / +/, getdependencies($abs_extra);
1207 for my $dep (@deps) {
1208 if (exists($extras{$dep})) {
1209 my $ref = \$extras{$dep}; # Take reference.
1210 if ($$ref !~ m/needed by/) {
1211 # First dependency found.
1212 if ($$ref =~ m/enabled/) {
1213 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1215 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1216 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1219 if ($$ref =~ m/enabled/) {
1220 $$ref .= ", \e[32;1m$extra\e[0m";
1222 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1228 for my $extra (sort {$a cmp $b} keys(%extras)) {
1229 my $text = $extras{$extra};
1230 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1231 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1233 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1236 return keys(%extras) if wantarray; # Can be used by manage_extras.
1239 sub enable_extras (@) {
1241 for my $extra (@extras) {
1242 my $extrapath = "src/modules/extra/$extra";
1243 if (!-e $extrapath) {
1244 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1247 my $source = "src/modules/$extra";
1249 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1252 # Get dependencies, and add them to be processed.
1253 my @deps = split / +/, getdependencies($extrapath);
1254 for my $dep (@deps) {
1255 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1256 if (!-e "src/modules/$dep") {
1257 if (-e "src/modules/extra/$dep") {
1258 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1261 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";
1265 print "Enabling $extra ... \n";
1266 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1270 sub disable_extras (@)
1272 opendir my $dd, "src/modules/extra/";
1273 my @files = readdir($dd);
1276 EXTRA: for my $extra (@extras) {
1277 my $extrapath = "src/modules/extra/$extra";
1278 my $source = "src/modules/$extra";
1279 if (!-e $extrapath) {
1280 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1283 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1284 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";
1287 # Check if anything needs this.
1288 for my $file (@files) {
1289 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1290 # File depends on this extra...
1291 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1292 # And is both enabled and not about to be disabled.
1293 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1294 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1300 print "Disabling $extra ... \n";
1301 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";