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,
48 $opt_system, $opt_uid);
50 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 'system' => \$opt_system,
66 'enable-openssl' => \$opt_use_openssl,
67 'disable-interactive' => \$opt_nointeractive,
68 'enable-ports' => \$opt_ports,
69 'enable-epoll' => \$opt_epoll,
70 'enable-kqueue' => \$opt_kqueue,
71 'disable-ports' => \$opt_noports,
72 'disable-epoll' => \$opt_noepoll,
73 'disable-kqueue' => \$opt_nokqueue,
74 'disable-ipv6' => \$opt_noipv6,
75 'with-cc=s' => \$opt_cc,
76 'with-maxbuf=i' => \$opt_maxbuf,
77 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
78 'prefix=s' => \$opt_base_dir,
79 'config-dir=s' => \$opt_config_dir,
80 'module-dir=s' => \$opt_module_dir,
81 'binary-dir=s' => \$opt_binary_dir,
82 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
83 'help' => sub { showhelp(); },
84 'update' => sub { update(); },
85 'svnupdate' => sub { svnupdate(); },
86 'clean' => sub { clean(); },
87 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
88 'enable-extras=s@' => \@opt_enableextras, # ^
89 'disable-extras=s@' => \@opt_disableextras, # ^
90 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
91 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
94 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
95 @opt_enableextras = split /,/, join(',', @opt_enableextras);
96 @opt_disableextras = split /,/, join(',', @opt_disableextras);
97 enable_extras(@opt_enableextras);
98 disable_extras(@opt_disableextras);
100 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
104 our $interactive = !(
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_system) ||
122 (defined $opt_uid) ||
123 (defined $opt_use_gnutls) ||
124 (defined $opt_freebsd_port)
127 chomp(our $topdir = getcwd());
128 our $this = resolve_directory($topdir); # PWD, Regardless.
129 our @modlist = (); # Declare for Module List..
130 our %config = (); # Initiate Configuration Hash..
131 $config{ME} = resolve_directory($topdir); # Present Working Directory
133 $config{BASE_DIR} = $config{ME}."/run";
135 if (defined $opt_base_dir) {
136 $config{BASE_DIR} = $opt_base_dir;
137 } elsif (defined $opt_system || defined $opt_uid) {
138 $config{BASE_DIR} = '/var/lib/inspircd';
141 if (defined $opt_system || defined $opt_uid) {
142 $config{UID} = $opt_uid || 'ircd';
143 $config{CONFIG_DIR} = '/etc/inspircd';
144 $config{MODULE_DIR} = '/usr/lib/inspircd';
145 $config{BINARY_DIR} = '/usr/sbin/';
146 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
149 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
150 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
151 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
152 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
155 if (defined $opt_config_dir) {
156 $config{CONFIG_DIR} = $opt_config_dir;
158 if (defined $opt_module_dir) {
159 $config{MODULE_DIR} = $opt_module_dir;
161 if (defined $opt_binary_dir) {
162 $config{BINARY_DIR} = $opt_binary_dir;
164 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
166 if (defined $opt_freebsd_port)
168 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
169 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
170 $config{USE_FREEBSD_BASE_SSL} = "n";
174 if ($^O eq "freebsd")
176 # default: use base ssl
177 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
178 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
182 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
183 $config{HAS_OPENSSL_PORT} = "";
187 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
188 chomp(our $openssl_ver = $config{HAS_OPENSSL});
189 $config{USE_GNUTLS} = "n";
190 if (defined $opt_use_gnutls)
192 $config{USE_GNUTLS} = "y"; # Use gnutls.
194 $config{USE_OPENSSL} = "n"; # Use openssl.
195 if (defined $opt_use_openssl)
197 $config{USE_OPENSSL} = "y";
200 if (!defined $opt_disable_debug) {
201 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
203 $config{OPTIMISATI} = "-O2";
206 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
207 $config{HAS_STDINT} = "false"; # stdint.h check
208 $config{USE_KQUEUE} = "y"; # kqueue enabled
209 if (defined $opt_nokqueue) {
210 $config{USE_KQUEUE} = "n";
212 $config{USE_POLL} = "y"; # poll enabled
213 $config{USE_EPOLL} = "y"; # epoll enabled
214 if (defined $opt_noepoll)
216 $config{USE_EPOLL} = "n";
218 $config{USE_PORTS} = "y"; # epoll enabled
219 if (defined $opt_noports)
221 $config{USE_PORTS} = "n";
223 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
224 $config{OSNAME} = $^O; # Operating System Name
225 $config{IS_DARWIN} = "NO"; # Is OSX?
226 $config{STARTSCRIPT} = "inspircd"; # start script?
227 $config{DESTINATION} = "BASE"; # Is target path.
228 $config{EXTRA_DIR} = ""; # Is empty.
229 if ($config{OSNAME} =~ /darwin/i)
231 $config{IS_DARWIN} = "YES";
232 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
234 $config{CC} = "g++"; # C++ compiler
237 $config{CC} = $opt_cc;
239 our $exec = $config{CC} . " -dumpversion | cut -c 1";
240 chomp($config{GCCVER} = `$exec`); # Major GCC Version
241 $exec = $config{CC} . " -dumpversion | cut -c 3";
242 chomp($config{GCCMINOR} = `$exec`);
243 $config{MAXBUF} = "512"; # Max buffer size
245 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
246 $config{HAS_OPENSSL} = $1;
248 $config{HAS_OPENSSL} = "";
251 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
252 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
256 # Get and Set some important vars..
261 unlink(".config.cache");
264 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
269 chomp($topdir = getcwd());
270 $this = resolve_directory($topdir); # PWD, Regardless.
272 # Does the cache file exist?
274 # No, No it doesn't.. *BASH*
275 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
278 # We've Loaded the cache file and all our variables..
279 print "Updating files...\n";
280 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
282 print "Disabling debug information (-g).\n";
283 $config{OPTIMISATI} = "";
285 $has_epoll = $config{HAS_EPOLL};
286 $has_ports = $config{HAS_PORTS};
287 $has_kqueue = $config{HAS_KQUEUE};
296 print "Configure update failed: $@\n";
304 open(FH,"<.svn/entries") or $fail = 1;
306 print "This is not an SVN copy of InspIRCd.\n";
313 open my $fd, "-|", "svn update";
314 my $configurechanged = 0; # Needs ./configure -update
315 my $rootincchanged = 0;
317 while (defined(my $line = <$fd>))
321 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
322 ($action, $file) = ($1, $2);
325 push @conflicted, $file;
326 if ($file eq "configure")
328 $configurechanged = 1;
330 elsif ($file =~ m/^\..*\.inc$/)
335 elsif ($action eq "U" || $action eq "G")
337 if ($file eq "configure")
339 $configurechanged = 1;
341 elsif ($file =~ m/^\..*\.inc$/)
347 unless (close $fd) # close() waits for exit and returns false if the command failed
351 print STDERR "Problem updating from SVN, please check above for errors\n";
355 print STDERR "Failed to run SVN: $!\n";
359 if (scalar(@conflicted) > 0)
361 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
362 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
363 print "Conflicted files: " . join ", ", @conflicted . "\n";
366 if ($configurechanged)
368 system("perl configure -update");
372 print "No need to update Makefiles.\n";
374 if (defined $opt_rebuild) {
375 system("make install");
383 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
384 $fail ||= system "./test_$feature";
385 unlink "test_$feature";
389 print "Running non-interactive configure...\n" unless $interactive;
390 print "Checking for cache from previous configure... ";
391 print ((!getcache()) ? "not found\n" : "found\n");
392 $config{SYSTEM} = lc $^O;
393 print "Checking operating system version... $config{SYSTEM}\n";
395 $exec = $config{CC} . " -dumpversion | cut -c 1";
396 chomp($config{GCCVER} = `$exec`); # Major GCC Version
397 $exec = $config{CC} . " -dumpversion | cut -c 3";
398 chomp($config{GCCMINOR} = `$exec`);
400 printf "Checking if stdint.h exists... ";
401 $config{HAS_STDINT} = "true";
403 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
404 if ($config{HAS_STDINT} eq "true") {
407 print "yes\n" if $config{HAS_STDINT} eq "true";
408 print "no\n" if $config{HAS_STDINT} eq "false";
410 printf "Checking if strlcpy exists... ";
411 # Perform the strlcpy() test..
412 $config{HAS_STRLCPY} = "false";
414 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
416 while (defined(my $line = <STRLCPY>)) {
418 # try and find the delcaration of:
419 # size_t strlcpy(...)
420 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
421 $config{HAS_STRLCPY} = "true";
426 print "yes\n" if $config{HAS_STRLCPY} eq "true";
427 print "no\n" if $config{HAS_STRLCPY} eq "false";
429 printf "Checking if kqueue exists... ";
432 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
434 while (defined(my $line = <KQUEUE>)) {
436 # try and find the delcaration of:
438 if ($line =~ /int(\0x9|\s)+kqueue/) {
444 print "yes\n" if $has_kqueue == 1;
445 print "no\n" if $has_kqueue == 0;
447 printf "Checking for epoll support... ";
448 $has_epoll = test_compile('epoll');
449 print $has_epoll ? "yes\n" : "no\n";
451 printf "Checking for eventfd support... ";
452 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
453 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
455 printf "Checking if Solaris I/O completion ports are available... ";
457 our $system = `uname -s`;
459 $has_ports = 1 if ($system eq "SunOS");
462 my $kernel = `uname -r`;
464 if (($kernel !~ /^5\.1./)) {
468 print "yes\n" if $has_ports == 1;
469 print "no\n" if $has_ports == 0;
471 $config{HAS_EPOLL} = $has_epoll;
472 $config{HAS_KQUEUE} = $has_kqueue;
474 printf "Checking for libgnutls... ";
475 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
476 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
478 $config{HAS_GNUTLS} = "y";
481 $config{HAS_GNUTLS} = "n";
485 $config{HAS_GNUTLS} = "n";
488 printf "Checking for openssl... ";
489 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
490 if (defined($openssl_ver) && ($openssl_ver ne "")) {
492 $config{HAS_OPENSSL} = "y";
495 $config{HAS_OPENSSL} = "n";
499 $config{HAS_OPENSSL} = "n";
502 printf "Checking if you are running an ancient, unsupported OS... ";
503 if ($config{OSNAME} =~ /FreeBSD/i)
505 my $version = `uname -r`;
506 if ($version =~ /^4\./)
509 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
510 print "To build, you will need to add the following to CXXFLAGS:\n";
511 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
515 print "no ($version)\n";
520 print "no ($config{OSNAME})\n";
523 ################################################################################
524 # BEGIN INTERACTIVE PART #
525 ################################################################################
530 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
533 my $rev = getrevision();
534 # Display Introduction Message..
536 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
537 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
539 *** If you are unsure of any of these values, leave it blank for ***
540 *** standard settings that will work, and your server will run ***
541 *** using them. Please consult your IRC network admin if in doubt. ***
543 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
544 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
545 dir, otherwise you won't have a config file!
547 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
548 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
551 print " (Non-SVN build)";
555 $config{CHANGE_COMPILER} = "n";
556 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";
558 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
559 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
560 should NOT be used. You should probably specify a newer compiler.\n\n";
561 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
562 if ($config{CHANGE_COMPILER} =~ /y/i) {
563 print "What command do you want to use to invoke your compiler?\n";
564 print "[\e[1;32m$config{CC}\e[0m] -> ";
565 chomp($config{CC} = <STDIN>);
566 if ($config{CC} eq "") {
569 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
571 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
572 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
573 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
574 if ($config{GCCVER} < 3) {
575 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
579 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
586 # Directory Settings..
587 my $tmpbase = $config{BASE_DIR};
588 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
589 if ($tmpbase ne $config{BASE_DIR}) {
590 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
591 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
592 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
595 dir_check("are the configuration files", "CONFIG_DIR");
596 dir_check("are the modules to be compiled to", "MODULE_DIR");
597 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
598 dir_check("do you want the build to take place", "BUILD_DIR");
600 my $chose_hiperf = 0;
602 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?");
604 if ($config{USE_KQUEUE} eq "y") {
609 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?");
611 if ($config{USE_EPOLL} eq "y") {
616 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?");
618 if ($config{USE_PORTS} eq "y") {
623 if (!$chose_hiperf) {
624 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?");
625 if ($config{USE_POLL} ne "y")
627 print "No high-performance socket engines are available, or you chose\n";
628 print "not to enable one. Defaulting to select() engine.\n\n";
632 $config{USE_FREEBSD_BASE_SSL} = "n";
633 $config{USE_FREEBSD_PORTS_SSL} = "n";
634 if ($config{HAS_OPENSSL_PORT} ne "")
636 $config{USE_FREEBSD_PORTS_SSL} = "y";
637 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
638 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";
639 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
641 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
643 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
645 # update to port version
646 $openssl_ver = $config{HAS_OPENSSL_PORT};
651 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
654 $config{USE_SSL} = "n";
655 $config{MODUPDATE} = 'n';
657 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
659 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
660 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
662 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
663 if ($config{USE_SSL} eq "y")
665 if ($config{HAS_GNUTLS} eq "y")
667 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
668 if ($config{USE_GNUTLS} eq "y")
670 print "\nUsing GnuTLS SSL module.\n";
674 if ($config{HAS_OPENSSL} eq "y")
676 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
677 if ($config{USE_OPENSSL} eq "y")
679 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
686 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
687 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
690 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
692 if ($config{MODUPDATE} eq "y") {
693 print "Checking for upgrades to extra and third party modules... ";
694 system "./modulemanager upgrade";
698 # We are on a POSIX system, we can enable POSIX extras without asking
699 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
703 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
705 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
708 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
710 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
715 $config{CERTGEN} ||= 'y';
716 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
718 if ($config{USE_GNUTLS} eq "y") {
719 unless (-r "src/modules/m_ssl_gnutls.cpp") {
720 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
721 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
723 if ($interactive && $config{CERTGEN} eq 'y')
725 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
726 print "SSL Certificates Not found, Generating.. \n\n
727 *************************************************************
728 * Generating the Private Key may take some time, go grab a *
729 * Coffee. Even better, to generate some more entropy if it *
730 * is taking a while, open another console and type du / a *
731 * few times and get that HD going :) Then answer the *
732 * Questions which follow. If you are unsure, just hit enter *
733 *************************************************************\n\n";
734 $failed = make_gnutls_cert();
736 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
738 print "\nCertificate generation complete, copying to config directory... ";
739 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
740 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
745 print "SSL Certificates found, skipping.\n\n";
750 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
754 if ($config{USE_OPENSSL} eq "y") {
755 unless (-r "src/modules/m_ssl_openssl.cpp") {
756 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
757 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
760 if ($interactive && $config{CERTGEN} eq 'y')
762 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
763 print "SSL Certificates Not found, Generating.. \n\n
764 *************************************************************
765 * Generating the certificates may take some time, go grab a *
766 * coffee, or something. *
767 *************************************************************\n\n";
769 print "\nCertificate generation complete, copying to config directory... ";
770 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
771 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
772 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
775 print "SSL Certificates found, skipping.\n\n"
780 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
783 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
784 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
792 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
793 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
794 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
795 print "modules in your config. This configure script has added those modules to the\n";
796 print "build process. For more info please refer to:\n";
797 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
799 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
800 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
801 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";
804 if ($config{GCCVER} < "3") {
806 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
807 GCC 2.x series compilers only had partial (read as broken) C++ support, and
808 your compile will most likely fail horribly! If you have any problems, do NOT
809 report them to the bugtracker or forums without first upgrading your compiler
810 to a newer 3.x or 4.x (or whatever is available currently) version.
814 ################################################################################
816 ################################################################################
818 # Retrieves the .config.cache file, and loads values into the main config hash.
819 open(CACHE, ".config.cache") or return 0;
822 # Ignore Blank lines, and comments..
825 my ($key, $value) = split("=", $_, 2);
826 $value =~ /^\"(.*)\"$/;
827 # Do something with data here!
835 # Dump the contents of %config
836 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
837 open(FILEHANDLE, ">.config.cache");
838 foreach my $key (keys %config) {
839 print FILEHANDLE "$key=\"$config{$key}\"\n";
845 my ($desc, $hash_key) = @_;
848 print "In what directory $desc?\n";
849 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
850 chomp(my $var = <STDIN>);
852 $var = $config{$hash_key};
854 if ($var =~ /^\~\/(.+)$/) {
855 # Convert it to a full path..
856 $var = resolve_directory($ENV{HOME} . "/" . $1);
858 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
860 # Assume relative Path was given.. fill in the rest.
861 $var = $this . "/$var";
864 $var = resolve_directory($var);
866 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
867 chomp(my $tmp = <STDIN>);
868 if (($tmp eq "") || ($tmp =~ /^y/i)) {
869 # Attempt to Create the Dir..
872 File::Path::mkpath($var, 0, 0777);
875 unless (defined($chk) && -d $var) {
876 print "Unable to create directory. ($var)\n\n";
881 # They said they don't want to create, and we can't install there.
887 # Target exists, but is not a directory.
888 print "File $var exists, but is not a directory.\n\n";
892 # Either Dir Exists, or was created fine.
893 $config{$hash_key} = $var;
901 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
904 my($writeheader) = @_;
905 # First File.. inspircd_config.h
906 chomp(my $incos = `uname -n -s -r`);
907 chomp(my $version = `sh src/version.sh`);
908 chomp(my $revision2 = getrevision());
909 if ($writeheader == 1)
911 print "Writing \e[1;32minspircd_config.h\e[0m\n";
912 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
913 print FILEHANDLE <<EOF;
914 /* Auto generated by configure, do not modify! */
915 #ifndef __CONFIGURATION_AUTO__
916 #define __CONFIGURATION_AUTO__
918 /* this is for windows support. */
919 #define CoreExport /**/
920 #define DllExport /**/
922 #define MOD_PATH "$config{MODULE_DIR}"
923 #define SOMAXCONN_S "$config{_SOMAXCONN}"
924 #define ENTRYPOINT int main(int argc, char** argv)
927 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
929 if ($config{OSNAME} =~ /SunOS/i) {
930 print FILEHANDLE "#define IS_SOLARIS\n";
932 if ($config{OSNAME} =~ /MINGW32/i) {
933 print FILEHANDLE "#define IS_MINGW\n";
935 if ($config{GCCVER} >= 3) {
936 print FILEHANDLE "#define GCC3\n";
939 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
941 ($config{GCCVER} > 4)
943 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
945 if ($config{HAS_STRLCPY} eq "true") {
946 print FILEHANDLE "#define HAS_STRLCPY\n";
948 if ($config{HAS_STDINT} eq "true") {
949 print FILEHANDLE "#define HAS_STDINT\n";
951 if ($config{HAS_EVENTFD} eq 'true') {
952 print FILEHANDLE "#define HAS_EVENTFD\n";
955 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
956 print FILEHANDLE "#define USE_KQUEUE\n";
957 $config{SOCKETENGINE} = "socketengine_kqueue";
960 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
961 print FILEHANDLE "#define USE_EPOLL\n";
962 $config{SOCKETENGINE} = "socketengine_epoll";
965 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
966 print FILEHANDLE "#define USE_PORTS\n";
967 $config{SOCKETENGINE} = "socketengine_ports";
970 # user didn't choose either epoll or select for their OS.
971 # default them to USE_SELECT (ewwy puke puke)
973 print "no hi-perf, " . $config{USE_POLL};
974 if ($config{USE_POLL} eq "y")
976 print FILEHANDLE "#define USE_POLL\n";
977 $config{SOCKETENGINE} = "socketengine_poll";
981 print FILEHANDLE "#define USE_SELECT\n";
982 $config{SOCKETENGINE} = "socketengine_select";
985 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
988 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
989 print FILEHANDLE <<EOF;
990 #define VERSION "$version"
991 #define REVISION "$revision2"
992 #define SYSTEM "$incos"
996 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
998 open my $fh1, $file or $diff = 1;
999 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1003 if (defined($line1) != defined($line2)) {
1005 } elsif (!defined $line1) {
1008 $diff = ($line1 ne $line2);
1013 rename "$file.tmp", $file;
1020 # Write all .in files.
1023 my $exe = "inspircd";
1025 # Do this once here, and cache it in the .*.inc files,
1026 # rather than attempting to read src/version.sh from
1027 # compiled code -- we might not have the source to hand.
1028 # Fix for bug#177 by Brain.
1030 chomp($version = `sh ./src/version.sh`);
1031 chomp(my $revision = getrevision());
1032 $version = "$version(r$revision)";
1034 # We can actually parse any file starting with . and ending with .inc,
1035 # but right now we only parse .inspircd.inc to form './inspircd'
1036 prepare_dynamic_makefile();
1038 my @dotfiles = qw(main.mk inspircd);
1039 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1041 foreach my $file (@dotfiles) {
1042 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1043 $_ = join '', <FILEHANDLE>;
1046 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1049 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR UID
1050 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1052 s/\@$var\@/$config{$var}/g;
1054 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1055 s/\@VERSION\@/$version/ if defined $version;
1057 if ($file eq 'main.mk') {
1058 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1061 s/\@IFDEF (\S+)/ifdef $1/g;
1062 s/\@IFNDEF (\S+)/ifndef $1/g;
1063 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1064 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1067 s/ *\@BSD_ONLY .*\n//g;
1069 s/\@DO_EXPORT (.*)/export $1/g;
1070 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1074 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1076 s/\@IFDEF (\S+)/.if defined($1)/g;
1077 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1078 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1079 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1083 s/ *\@GNU_ONLY .*\n//g;
1085 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1086 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1090 print "Writing \e[1;32m$file\e[0m ...\n";
1091 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1092 print FILEHANDLE $_;
1097 chmod 0755, 'inspircd';
1103 for my $mod (@modlist) {
1104 getcompilerflags("src/modules/m_$mod.cpp");
1105 getlinkerflags("src/modules/m_$mod.cpp");
1109 sub prepare_dynamic_makefile
1115 $config{USE_EPOLL} = 0;
1119 $config{USE_KQUEUE} = 0;
1123 $config{USE_PORTS} = 0;
1127 # Routine to list out the extra/ modules that have been enabled.
1128 # Note: when getting any filenames out and comparing, it's important to lc it if the
1129 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1130 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1131 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1132 sub list_extras () {
1135 my $srcdir = File::Spec->catdir("src", "modules");
1136 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1139 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1140 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1143 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1144 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1147 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1149 EXTRA: for my $extra (@extras) {
1150 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1151 next if ($extra eq '.svn');
1152 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1153 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1154 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1155 if (-l $abs_source) {
1156 # Symlink, is it in the right place?
1157 my $targ = readlink($abs_source);
1158 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1159 if ($abs_targ eq $abs_extra) {
1160 $extras{$extra} = "\e[32;1menabled\e[0m";
1162 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1164 } elsif (-e $abs_source) {
1165 my ($devext, $inoext) = stat($abs_extra);
1166 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1168 if ($devsrc == $devext && $inosrc == $inoext) {
1169 $extras{$extra} = "\e[32;1menabled\e[0m";
1171 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1174 open my $extfd, "<", $abs_extra;
1175 open my $srcfd, "<", $abs_source;
1177 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1178 $extras{$extra} = "\e[32;1menabled\e[0m";
1180 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1184 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1187 # Now let's add dependency info
1188 for my $extra (keys(%extras)) {
1189 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1190 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1191 my @deps = split / +/, getdependencies($abs_extra);
1192 for my $dep (@deps) {
1193 if (exists($extras{$dep})) {
1194 my $ref = \$extras{$dep}; # Take reference.
1195 if ($$ref !~ m/needed by/) {
1196 # First dependency found.
1197 if ($$ref =~ m/enabled/) {
1198 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1200 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1201 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1204 if ($$ref =~ m/enabled/) {
1205 $$ref .= ", \e[32;1m$extra\e[0m";
1207 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1213 for my $extra (sort {$a cmp $b} keys(%extras)) {
1214 my $text = $extras{$extra};
1215 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1216 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1218 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1221 return keys(%extras) if wantarray; # Can be used by manage_extras.
1224 sub enable_extras (@) {
1226 for my $extra (@extras) {
1227 my $extrapath = "src/modules/extra/$extra";
1228 if (!-e $extrapath) {
1229 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1232 my $source = "src/modules/$extra";
1234 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1237 # Get dependencies, and add them to be processed.
1238 my @deps = split / +/, getdependencies($extrapath);
1239 for my $dep (@deps) {
1240 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1241 if (!-e "src/modules/$dep") {
1242 if (-e "src/modules/extra/$dep") {
1243 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1246 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";
1250 print "Enabling $extra ... \n";
1251 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1255 sub disable_extras (@)
1257 opendir my $dd, "src/modules/extra/";
1258 my @files = readdir($dd);
1261 EXTRA: for my $extra (@extras) {
1262 my $extrapath = "src/modules/extra/$extra";
1263 my $source = "src/modules/$extra";
1264 if (!-e $extrapath) {
1265 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1268 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1269 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";
1272 # Check if anything needs this.
1273 for my $file (@files) {
1274 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1275 # File depends on this extra...
1276 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1277 # And is both enabled and not about to be disabled.
1278 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1279 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1285 print "Disabling $extra ... \n";
1286 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";