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 if ($config{OSNAME} =~ /darwin/i)
230 $config{IS_DARWIN} = "YES";
231 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
233 $config{CC} = "g++"; # C++ compiler
236 $config{CC} = $opt_cc;
238 our $exec = $config{CC} . " -dumpversion | cut -c 1";
239 chomp($config{GCCVER} = `$exec`); # Major GCC Version
240 $exec = $config{CC} . " -dumpversion | cut -c 3";
241 chomp($config{GCCMINOR} = `$exec`);
242 $config{MAXBUF} = "512"; # Max buffer size
244 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
245 $config{HAS_OPENSSL} = $1;
247 $config{HAS_OPENSSL} = "";
250 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
251 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
255 # Get and Set some important vars..
260 unlink(".config.cache");
263 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
268 chomp($topdir = getcwd());
269 $this = resolve_directory($topdir); # PWD, Regardless.
271 # Does the cache file exist?
273 # No, No it doesn't.. *BASH*
274 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
277 # We've Loaded the cache file and all our variables..
278 print "Updating files...\n";
279 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
281 print "Disabling debug information (-g).\n";
282 $config{OPTIMISATI} = "";
284 $has_epoll = $config{HAS_EPOLL};
285 $has_ports = $config{HAS_PORTS};
286 $has_kqueue = $config{HAS_KQUEUE};
295 print "Configure update failed: $@\n";
303 open(FH,"<.svn/entries") or $fail = 1;
305 print "This is not an SVN copy of InspIRCd.\n";
312 open my $fd, "-|", "svn update";
313 my $configurechanged = 0; # Needs ./configure -update
314 my $rootincchanged = 0;
316 while (defined(my $line = <$fd>))
320 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
321 ($action, $file) = ($1, $2);
324 push @conflicted, $file;
325 if ($file eq "configure")
327 $configurechanged = 1;
329 elsif ($file =~ m/^\..*\.inc$/)
334 elsif ($action eq "U" || $action eq "G")
336 if ($file eq "configure")
338 $configurechanged = 1;
340 elsif ($file =~ m/^\..*\.inc$/)
346 unless (close $fd) # close() waits for exit and returns false if the command failed
350 print STDERR "Problem updating from SVN, please check above for errors\n";
354 print STDERR "Failed to run SVN: $!\n";
358 if (scalar(@conflicted) > 0)
360 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
361 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
362 print "Conflicted files: " . join ", ", @conflicted . "\n";
365 if ($configurechanged)
367 system("perl configure -update");
371 print "No need to update Makefiles.\n";
373 if (defined $opt_rebuild) {
374 system("make install");
382 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
383 $fail ||= system "./test_$feature";
384 unlink "test_$feature";
388 print "Running non-interactive configure...\n" unless $interactive;
389 print "Checking for cache from previous configure... ";
390 print ((!getcache()) ? "not found\n" : "found\n");
391 $config{SYSTEM} = lc $^O;
392 print "Checking operating system version... $config{SYSTEM}\n";
394 $exec = $config{CC} . " -dumpversion | cut -c 1";
395 chomp($config{GCCVER} = `$exec`); # Major GCC Version
396 $exec = $config{CC} . " -dumpversion | cut -c 3";
397 chomp($config{GCCMINOR} = `$exec`);
399 printf "Checking if stdint.h exists... ";
400 $config{HAS_STDINT} = "true";
402 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
403 if ($config{HAS_STDINT} eq "true") {
406 print "yes\n" if $config{HAS_STDINT} eq "true";
407 print "no\n" if $config{HAS_STDINT} eq "false";
409 printf "Checking if strlcpy exists... ";
410 # Perform the strlcpy() test..
411 $config{HAS_STRLCPY} = "false";
413 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
415 while (defined(my $line = <STRLCPY>)) {
417 # try and find the delcaration of:
418 # size_t strlcpy(...)
419 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
420 $config{HAS_STRLCPY} = "true";
425 print "yes\n" if $config{HAS_STRLCPY} eq "true";
426 print "no\n" if $config{HAS_STRLCPY} eq "false";
428 printf "Checking if kqueue exists... ";
431 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
433 while (defined(my $line = <KQUEUE>)) {
435 # try and find the delcaration of:
437 if ($line =~ /int(\0x9|\s)+kqueue/) {
443 print "yes\n" if $has_kqueue == 1;
444 print "no\n" if $has_kqueue == 0;
446 printf "Checking for epoll support... ";
447 $has_epoll = test_compile('epoll');
448 print $has_epoll ? "yes\n" : "no\n";
450 printf "Checking for eventfd support... ";
451 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
452 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
454 printf "Checking if Solaris I/O completion ports are available... ";
456 our $system = `uname -s`;
458 $has_ports = 1 if ($system eq "SunOS");
461 my $kernel = `uname -r`;
463 if (($kernel !~ /^5\.1./)) {
467 print "yes\n" if $has_ports == 1;
468 print "no\n" if $has_ports == 0;
470 $config{HAS_EPOLL} = $has_epoll;
471 $config{HAS_KQUEUE} = $has_kqueue;
473 printf "Checking for libgnutls... ";
474 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
475 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
477 $config{HAS_GNUTLS} = "y";
480 $config{HAS_GNUTLS} = "n";
484 $config{HAS_GNUTLS} = "n";
487 printf "Checking for openssl... ";
488 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
489 if (defined($openssl_ver) && ($openssl_ver ne "")) {
491 $config{HAS_OPENSSL} = "y";
494 $config{HAS_OPENSSL} = "n";
498 $config{HAS_OPENSSL} = "n";
501 printf "Checking if you are running an ancient, unsupported OS... ";
502 if ($config{OSNAME} =~ /FreeBSD/i)
504 my $version = `uname -r`;
505 if ($version =~ /^4\./)
508 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
509 print "To build, you will need to add the following to CXXFLAGS:\n";
510 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
514 print "no ($version)\n";
519 print "no ($config{OSNAME})\n";
522 ################################################################################
523 # BEGIN INTERACTIVE PART #
524 ################################################################################
529 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
532 my $rev = getrevision();
533 # Display Introduction Message..
535 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
536 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
538 *** If you are unsure of any of these values, leave it blank for ***
539 *** standard settings that will work, and your server will run ***
540 *** using them. Please consult your IRC network admin if in doubt. ***
542 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
543 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
544 dir, otherwise you won't have a config file!
546 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
547 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
550 print " (Non-SVN build)";
554 $config{CHANGE_COMPILER} = "n";
555 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";
557 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
558 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
559 should NOT be used. You should probably specify a newer compiler.\n\n";
560 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
561 if ($config{CHANGE_COMPILER} =~ /y/i) {
562 print "What command do you want to use to invoke your compiler?\n";
563 print "[\e[1;32m$config{CC}\e[0m] -> ";
564 chomp($config{CC} = <STDIN>);
565 if ($config{CC} eq "") {
568 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
570 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
571 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
572 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
573 if ($config{GCCVER} < 3) {
574 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
578 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
585 # Directory Settings..
586 my $tmpbase = $config{BASE_DIR};
587 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
588 if ($tmpbase ne $config{BASE_DIR}) {
589 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
590 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
591 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
594 dir_check("are the configuration files", "CONFIG_DIR");
595 dir_check("are the modules to be compiled to", "MODULE_DIR");
596 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
597 dir_check("do you want the build to take place", "BUILD_DIR");
599 my $chose_hiperf = 0;
601 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?");
603 if ($config{USE_KQUEUE} eq "y") {
608 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?");
610 if ($config{USE_EPOLL} eq "y") {
615 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?");
617 if ($config{USE_PORTS} eq "y") {
622 if (!$chose_hiperf) {
623 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?");
624 if ($config{USE_POLL} ne "y")
626 print "No high-performance socket engines are available, or you chose\n";
627 print "not to enable one. Defaulting to select() engine.\n\n";
631 $config{USE_FREEBSD_BASE_SSL} = "n";
632 $config{USE_FREEBSD_PORTS_SSL} = "n";
633 if ($config{HAS_OPENSSL_PORT} ne "")
635 $config{USE_FREEBSD_PORTS_SSL} = "y";
636 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
637 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";
638 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
640 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
642 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
644 # update to port version
645 $openssl_ver = $config{HAS_OPENSSL_PORT};
650 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
653 $config{USE_SSL} = "n";
654 $config{MODUPDATE} = 'n';
656 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
658 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
659 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
661 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
662 if ($config{USE_SSL} eq "y")
664 if ($config{HAS_GNUTLS} eq "y")
666 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
667 if ($config{USE_GNUTLS} eq "y")
669 print "\nUsing GnuTLS SSL module.\n";
673 if ($config{HAS_OPENSSL} eq "y")
675 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
676 if ($config{USE_OPENSSL} eq "y")
678 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
685 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
686 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
689 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
691 if ($config{MODUPDATE} eq "y") {
692 print "Checking for upgrades to extra and third party modules... ";
693 system "./modulemanager upgrade";
697 # We are on a POSIX system, we can enable POSIX extras without asking
698 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
702 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
704 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
707 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
709 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
714 $config{CERTGEN} ||= 'y';
715 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
717 if ($config{USE_GNUTLS} eq "y") {
718 unless (-r "src/modules/m_ssl_gnutls.cpp") {
719 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
720 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
722 if ($interactive && $config{CERTGEN} eq 'y')
724 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
725 print "SSL Certificates Not found, Generating.. \n\n
726 *************************************************************
727 * Generating the Private Key may take some time, go grab a *
728 * Coffee. Even better, to generate some more entropy if it *
729 * is taking a while, open another console and type du / a *
730 * few times and get that HD going :) Then answer the *
731 * Questions which follow. If you are unsure, just hit enter *
732 *************************************************************\n\n";
733 $failed = make_gnutls_cert();
735 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
737 print "\nCertificate generation complete, copying to config directory... ";
738 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
739 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
744 print "SSL Certificates found, skipping.\n\n";
749 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
753 if ($config{USE_OPENSSL} eq "y") {
754 unless (-r "src/modules/m_ssl_openssl.cpp") {
755 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
756 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
759 if ($interactive && $config{CERTGEN} eq 'y')
761 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
762 print "SSL Certificates Not found, Generating.. \n\n
763 *************************************************************
764 * Generating the certificates may take some time, go grab a *
765 * coffee, or something. *
766 *************************************************************\n\n";
768 print "\nCertificate generation complete, copying to config directory... ";
769 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
770 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
771 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
774 print "SSL Certificates found, skipping.\n\n"
779 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
782 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
783 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
791 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
792 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
793 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
794 print "modules in your config. This configure script has added those modules to the\n";
795 print "build process. For more info please refer to:\n";
796 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
798 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
799 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
800 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";
803 if ($config{GCCVER} < "3") {
805 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
806 GCC 2.x series compilers only had partial (read as broken) C++ support, and
807 your compile will most likely fail horribly! If you have any problems, do NOT
808 report them to the bugtracker or forums without first upgrading your compiler
809 to a newer 3.x or 4.x (or whatever is available currently) version.
813 ################################################################################
815 ################################################################################
817 # Retrieves the .config.cache file, and loads values into the main config hash.
818 open(CACHE, ".config.cache") or return 0;
821 # Ignore Blank lines, and comments..
824 my ($key, $value) = split("=", $_, 2);
825 $value =~ /^\"(.*)\"$/;
826 # Do something with data here!
834 # Dump the contents of %config
835 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
836 open(FILEHANDLE, ">.config.cache");
837 foreach my $key (keys %config) {
838 print FILEHANDLE "$key=\"$config{$key}\"\n";
844 my ($desc, $hash_key) = @_;
847 print "In what directory $desc?\n";
848 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
849 chomp(my $var = <STDIN>);
851 $var = $config{$hash_key};
853 if ($var =~ /^\~\/(.+)$/) {
854 # Convert it to a full path..
855 $var = resolve_directory($ENV{HOME} . "/" . $1);
857 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
859 # Assume relative Path was given.. fill in the rest.
860 $var = $this . "/$var";
863 $var = resolve_directory($var);
865 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
866 chomp(my $tmp = <STDIN>);
867 if (($tmp eq "") || ($tmp =~ /^y/i)) {
868 # Attempt to Create the Dir..
871 File::Path::mkpath($var, 0, 0777);
874 unless (defined($chk) && -d $var) {
875 print "Unable to create directory. ($var)\n\n";
880 # They said they don't want to create, and we can't install there.
886 # Target exists, but is not a directory.
887 print "File $var exists, but is not a directory.\n\n";
891 # Either Dir Exists, or was created fine.
892 $config{$hash_key} = $var;
900 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
903 my($writeheader) = @_;
904 # First File.. inspircd_config.h
905 chomp(my $incos = `uname -n -s -r`);
906 chomp(my $version = `sh src/version.sh`);
907 chomp(my $revision2 = getrevision());
908 if ($writeheader == 1)
910 print "Writing \e[1;32minspircd_config.h\e[0m\n";
911 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
912 print FILEHANDLE <<EOF;
913 /* Auto generated by configure, do not modify! */
914 #ifndef __CONFIGURATION_AUTO__
915 #define __CONFIGURATION_AUTO__
917 /* this is for windows support. */
918 #define CoreExport /**/
919 #define DllExport /**/
921 #define MOD_PATH "$config{MODULE_DIR}"
922 #define SOMAXCONN_S "$config{_SOMAXCONN}"
923 #define ENTRYPOINT int main(int argc, char** argv)
926 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
928 if ($config{OSNAME} =~ /SunOS/i) {
929 print FILEHANDLE "#define IS_SOLARIS\n";
931 if ($config{OSNAME} =~ /MINGW32/i) {
932 print FILEHANDLE "#define IS_MINGW\n";
934 if ($config{GCCVER} >= 3) {
935 print FILEHANDLE "#define GCC3\n";
938 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
940 ($config{GCCVER} > 4)
942 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
944 if ($config{HAS_STRLCPY} eq "true") {
945 print FILEHANDLE "#define HAS_STRLCPY\n";
947 if ($config{HAS_STDINT} eq "true") {
948 print FILEHANDLE "#define HAS_STDINT\n";
950 if ($config{HAS_EVENTFD} eq 'true') {
951 print FILEHANDLE "#define HAS_EVENTFD\n";
954 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
955 print FILEHANDLE "#define USE_KQUEUE\n";
956 $config{SOCKETENGINE} = "socketengine_kqueue";
959 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
960 print FILEHANDLE "#define USE_EPOLL\n";
961 $config{SOCKETENGINE} = "socketengine_epoll";
964 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
965 print FILEHANDLE "#define USE_PORTS\n";
966 $config{SOCKETENGINE} = "socketengine_ports";
969 # user didn't choose either epoll or select for their OS.
970 # default them to USE_SELECT (ewwy puke puke)
972 print "no hi-perf, " . $config{USE_POLL};
973 if ($config{USE_POLL} eq "y")
975 print FILEHANDLE "#define USE_POLL\n";
976 $config{SOCKETENGINE} = "socketengine_poll";
980 print FILEHANDLE "#define USE_SELECT\n";
981 $config{SOCKETENGINE} = "socketengine_select";
984 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
987 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
988 print FILEHANDLE <<EOF;
989 #define VERSION "$version"
990 #define REVISION "$revision2"
991 #define SYSTEM "$incos"
995 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
997 open my $fh1, $file or $diff = 1;
998 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1002 if (defined($line1) != defined($line2)) {
1004 } elsif (!defined $line1) {
1007 $diff = ($line1 ne $line2);
1012 rename "$file.tmp", $file;
1019 # Write all .in files.
1022 my $exe = "inspircd";
1024 # Do this once here, and cache it in the .*.inc files,
1025 # rather than attempting to read src/version.sh from
1026 # compiled code -- we might not have the source to hand.
1027 # Fix for bug#177 by Brain.
1029 chomp($version = `sh ./src/version.sh`);
1030 chomp(my $revision = getrevision());
1031 $version = "$version(r$revision)";
1033 # We can actually parse any file starting with . and ending with .inc,
1034 # but right now we only parse .inspircd.inc to form './inspircd'
1035 prepare_dynamic_makefile();
1037 my @dotfiles = qw(main.mk inspircd);
1038 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1040 foreach my $file (@dotfiles) {
1041 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1042 $_ = join '', <FILEHANDLE>;
1045 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1048 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR UID
1049 STARTSCRIPT DESTINATION SOCKETENGINE
1051 s/\@$var\@/$config{$var}/g;
1053 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1054 s/\@VERSION\@/$version/ if defined $version;
1056 if ($file eq 'main.mk') {
1057 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1060 s/\@IFDEF (\S+)/ifdef $1/g;
1061 s/\@IFNDEF (\S+)/ifndef $1/g;
1062 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1063 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1066 s/ *\@BSD_ONLY .*\n//g;
1068 s/\@DO_EXPORT (.*)/export $1/g;
1069 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1073 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1075 s/\@IFDEF (\S+)/.if defined($1)/g;
1076 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1077 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1078 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1082 s/ *\@GNU_ONLY .*\n//g;
1084 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1085 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1089 print "Writing \e[1;32m$file\e[0m ...\n";
1090 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1091 print FILEHANDLE $_;
1096 chmod 0755, 'inspircd';
1102 for my $mod (@modlist) {
1103 getcompilerflags("src/modules/m_$mod.cpp");
1104 getlinkerflags("src/modules/m_$mod.cpp");
1108 sub prepare_dynamic_makefile
1114 $config{USE_EPOLL} = 0;
1118 $config{USE_KQUEUE} = 0;
1122 $config{USE_PORTS} = 0;
1126 # Routine to list out the extra/ modules that have been enabled.
1127 # Note: when getting any filenames out and comparing, it's important to lc it if the
1128 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1129 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1130 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1131 sub list_extras () {
1134 my $srcdir = File::Spec->catdir("src", "modules");
1135 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1138 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1139 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1142 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1143 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1146 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1148 EXTRA: for my $extra (@extras) {
1149 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1150 next if ($extra eq '.svn');
1151 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1152 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1153 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1154 if (-l $abs_source) {
1155 # Symlink, is it in the right place?
1156 my $targ = readlink($abs_source);
1157 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1158 if ($abs_targ eq $abs_extra) {
1159 $extras{$extra} = "\e[32;1menabled\e[0m";
1161 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1163 } elsif (-e $abs_source) {
1164 my ($devext, $inoext) = stat($abs_extra);
1165 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1167 if ($devsrc == $devext && $inosrc == $inoext) {
1168 $extras{$extra} = "\e[32;1menabled\e[0m";
1170 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1173 open my $extfd, "<", $abs_extra;
1174 open my $srcfd, "<", $abs_source;
1176 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1177 $extras{$extra} = "\e[32;1menabled\e[0m";
1179 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1183 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1186 # Now let's add dependency info
1187 for my $extra (keys(%extras)) {
1188 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1189 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1190 my @deps = split / +/, getdependencies($abs_extra);
1191 for my $dep (@deps) {
1192 if (exists($extras{$dep})) {
1193 my $ref = \$extras{$dep}; # Take reference.
1194 if ($$ref !~ m/needed by/) {
1195 # First dependency found.
1196 if ($$ref =~ m/enabled/) {
1197 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1199 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1200 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1203 if ($$ref =~ m/enabled/) {
1204 $$ref .= ", \e[32;1m$extra\e[0m";
1206 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1212 for my $extra (sort {$a cmp $b} keys(%extras)) {
1213 my $text = $extras{$extra};
1214 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1215 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1217 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1220 return keys(%extras) if wantarray; # Can be used by manage_extras.
1223 sub enable_extras (@) {
1225 for my $extra (@extras) {
1226 my $extrapath = "src/modules/extra/$extra";
1227 if (!-e $extrapath) {
1228 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1231 my $source = "src/modules/$extra";
1233 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1236 # Get dependencies, and add them to be processed.
1237 my @deps = split / +/, getdependencies($extrapath);
1238 for my $dep (@deps) {
1239 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1240 if (!-e "src/modules/$dep") {
1241 if (-e "src/modules/extra/$dep") {
1242 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1245 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";
1249 print "Enabling $extra ... \n";
1250 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1254 sub disable_extras (@)
1256 opendir my $dd, "src/modules/extra/";
1257 my @files = readdir($dd);
1260 EXTRA: for my $extra (@extras) {
1261 my $extrapath = "src/modules/extra/$extra";
1262 my $source = "src/modules/$extra";
1263 if (!-e $extrapath) {
1264 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1267 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1268 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";
1271 # Check if anything needs this.
1272 for my $file (@files) {
1273 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1274 # File depends on this extra...
1275 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1276 # And is both enabled and not about to be disabled.
1277 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1278 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1284 print "Disabling $extra ... \n";
1285 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";