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 'clean' => sub { clean(); },
86 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
87 'enable-extras=s@' => \@opt_enableextras, # ^
88 'disable-extras=s@' => \@opt_disableextras, # ^
89 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
90 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
93 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
94 @opt_enableextras = split /,/, join(',', @opt_enableextras);
95 @opt_disableextras = split /,/, join(',', @opt_disableextras);
96 enable_extras(@opt_enableextras);
97 disable_extras(@opt_disableextras);
99 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
103 our $interactive = !(
104 (defined $opt_base_dir) ||
105 (defined $opt_config_dir) ||
106 (defined $opt_module_dir) ||
107 (defined $opt_base_dir) ||
108 (defined $opt_binary_dir) ||
109 (defined $opt_nointeractive) ||
111 (defined $opt_noipv6) ||
112 (defined $opt_kqueue) ||
113 (defined $opt_epoll) ||
114 (defined $opt_ports) ||
115 (defined $opt_use_openssl) ||
116 (defined $opt_nokqueue) ||
117 (defined $opt_noepoll) ||
118 (defined $opt_noports) ||
119 (defined $opt_maxbuf) ||
120 (defined $opt_system) ||
121 (defined $opt_uid) ||
122 (defined $opt_use_gnutls) ||
123 (defined $opt_freebsd_port)
126 chomp(our $topdir = getcwd());
127 our $this = resolve_directory($topdir); # PWD, Regardless.
128 our @modlist = (); # Declare for Module List..
129 our %config = (); # Initiate Configuration Hash..
130 $config{ME} = resolve_directory($topdir); # Present Working Directory
132 $config{BASE_DIR} = $config{ME}."/run";
134 if (defined $opt_base_dir) {
135 $config{BASE_DIR} = $opt_base_dir;
136 } elsif (defined $opt_system || defined $opt_uid) {
137 $config{BASE_DIR} = '/var/lib/inspircd';
140 if (defined $opt_system || defined $opt_uid) {
141 $config{UID} = $opt_uid || 'ircd';
142 $config{CONFIG_DIR} = '/etc/inspircd';
143 $config{MODULE_DIR} = '/usr/lib/inspircd';
144 $config{BINARY_DIR} = '/usr/sbin/';
145 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
148 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
149 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
150 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
151 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
154 if (defined $opt_config_dir) {
155 $config{CONFIG_DIR} = $opt_config_dir;
157 if (defined $opt_module_dir) {
158 $config{MODULE_DIR} = $opt_module_dir;
160 if (defined $opt_binary_dir) {
161 $config{BINARY_DIR} = $opt_binary_dir;
163 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
165 if (defined $opt_freebsd_port)
167 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
168 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
169 $config{USE_FREEBSD_BASE_SSL} = "n";
173 if ($^O eq "freebsd")
175 # default: use base ssl
176 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
177 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
181 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
182 $config{HAS_OPENSSL_PORT} = "";
186 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
187 chomp(our $openssl_ver = $config{HAS_OPENSSL});
188 $config{USE_GNUTLS} = "n";
189 if (defined $opt_use_gnutls)
191 $config{USE_GNUTLS} = "y"; # Use gnutls.
193 $config{USE_OPENSSL} = "n"; # Use openssl.
194 if (defined $opt_use_openssl)
196 $config{USE_OPENSSL} = "y";
199 if (!defined $opt_disable_debug) {
200 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
202 $config{OPTIMISATI} = "-O2";
205 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
206 $config{HAS_STDINT} = "false"; # stdint.h check
207 $config{USE_KQUEUE} = "y"; # kqueue enabled
208 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_noepoll)
215 $config{USE_EPOLL} = "n";
217 $config{USE_PORTS} = "y"; # epoll enabled
218 if (defined $opt_noports)
220 $config{USE_PORTS} = "n";
222 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
223 $config{OSNAME} = $^O; # Operating System Name
224 $config{IS_DARWIN} = "NO"; # Is OSX?
225 $config{STARTSCRIPT} = "inspircd"; # start script?
226 $config{DESTINATION} = "BASE"; # Is target path.
227 if ($config{OSNAME} =~ /darwin/i)
229 $config{IS_DARWIN} = "YES";
230 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
231 $config{CC} = "xcrun clang++"; # C++ compiler for OSX.
235 $config{CC} = "g++"; # C++ compiler
239 $config{CC} = $opt_cc;
241 our $exec = $config{CC} . " -dumpversion | cut -c 1";
242 chomp($config{GCCVER} = `$exec`); # Major GCC Version
243 $exec = $config{CC} . " -dumpversion | cut -c 3";
244 chomp($config{GCCMINOR} = `$exec`);
245 $config{MAXBUF} = "512"; # Max buffer size
247 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
248 $config{HAS_OPENSSL} = $1;
250 $config{HAS_OPENSSL} = "";
253 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
254 if ($config{IS_DARWIN} eq "YES") {
255 print $config{CC} . " was not found! You require clang++ (the LLVM C++ compiler, part of the OSX developer tools) to build InspIRCd!\n";
257 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
262 # Get and Set some important vars..
267 unlink(".config.cache");
270 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
275 chomp($topdir = getcwd());
276 $this = resolve_directory($topdir); # PWD, Regardless.
278 # Does the cache file exist?
280 # No, No it doesn't.. *BASH*
281 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
284 # We've Loaded the cache file and all our variables..
285 print "Updating files...\n";
286 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
288 print "Disabling debug information (-g).\n";
289 $config{OPTIMISATI} = "";
291 $has_epoll = $config{HAS_EPOLL};
292 $has_ports = $config{HAS_PORTS};
293 $has_kqueue = $config{HAS_KQUEUE};
302 print "Configure update failed: $@\n";
311 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
312 $fail ||= system "./test_$feature";
313 unlink "test_$feature";
317 print "Running non-interactive configure...\n" unless $interactive;
318 print "Checking for cache from previous configure... ";
319 print ((!getcache()) ? "not found\n" : "found\n");
320 $config{SYSTEM} = lc $^O;
321 print "Checking operating system version... $config{SYSTEM}\n";
323 $exec = $config{CC} . " -dumpversion | cut -c 1";
324 chomp($config{GCCVER} = `$exec`); # Major GCC Version
325 $exec = $config{CC} . " -dumpversion | cut -c 3";
326 chomp($config{GCCMINOR} = `$exec`);
328 printf "Checking if stdint.h exists... ";
329 $config{HAS_STDINT} = "true";
331 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
332 if ($config{HAS_STDINT} eq "true") {
335 print "yes\n" if $config{HAS_STDINT} eq "true";
336 print "no\n" if $config{HAS_STDINT} eq "false";
338 printf "Checking if strlcpy exists... ";
339 # Perform the strlcpy() test..
340 $config{HAS_STRLCPY} = "false";
342 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
344 while (defined(my $line = <STRLCPY>)) {
346 # try and find the delcaration of:
347 # size_t strlcpy(...)
348 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
349 $config{HAS_STRLCPY} = "true";
354 print "yes\n" if $config{HAS_STRLCPY} eq "true";
355 print "no\n" if $config{HAS_STRLCPY} eq "false";
357 printf "Checking if kqueue exists... ";
360 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
362 while (defined(my $line = <KQUEUE>)) {
364 # try and find the delcaration of:
366 if ($line =~ /int(\0x9|\s)+kqueue/) {
372 print "yes\n" if $has_kqueue == 1;
373 print "no\n" if $has_kqueue == 0;
375 printf "Checking for epoll support... ";
376 $has_epoll = test_compile('epoll');
377 print $has_epoll ? "yes\n" : "no\n";
379 printf "Checking for eventfd support... ";
380 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
381 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
383 printf "Checking if Solaris I/O completion ports are available... ";
385 our $system = `uname -s`;
387 $has_ports = 1 if ($system eq "SunOS");
390 my $kernel = `uname -r`;
392 if (($kernel !~ /^5\.1./)) {
396 print "yes\n" if $has_ports == 1;
397 print "no\n" if $has_ports == 0;
399 $config{HAS_EPOLL} = $has_epoll;
400 $config{HAS_KQUEUE} = $has_kqueue;
402 printf "Checking for libgnutls... ";
403 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
404 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
406 $config{HAS_GNUTLS} = "y";
409 $config{HAS_GNUTLS} = "n";
413 $config{HAS_GNUTLS} = "n";
416 printf "Checking for openssl... ";
417 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
418 if (defined($openssl_ver) && ($openssl_ver ne "")) {
420 $config{HAS_OPENSSL} = "y";
423 $config{HAS_OPENSSL} = "n";
427 $config{HAS_OPENSSL} = "n";
430 printf "Checking if you are running an ancient, unsupported OS... ";
431 if ($config{OSNAME} =~ /FreeBSD/i)
433 my $version = `uname -r`;
434 if ($version =~ /^4\./)
437 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
438 print "To build, you will need to add the following to CXXFLAGS:\n";
439 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
443 print "no ($version)\n";
448 print "no ($config{OSNAME})\n";
451 ################################################################################
452 # BEGIN INTERACTIVE PART #
453 ################################################################################
458 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
461 my $rev = getrevision();
462 # Display Introduction Message..
464 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
465 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
467 *** If you are unsure of any of these values, leave it blank for ***
468 *** standard settings that will work, and your server will run ***
469 *** using them. Please consult your IRC network admin if in doubt. ***
471 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
472 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
473 dir, otherwise you won't have a config file!
475 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
476 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
479 print " (Non-SVN build)";
483 $config{CHANGE_COMPILER} = "n";
484 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";
486 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
487 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
488 should NOT be used. You should probably specify a newer compiler.\n\n";
489 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
490 if ($config{CHANGE_COMPILER} =~ /y/i) {
491 print "What command do you want to use to invoke your compiler?\n";
492 print "[\e[1;32m$config{CC}\e[0m] -> ";
493 chomp($config{CC} = <STDIN>);
494 if ($config{CC} eq "") {
497 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
499 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
500 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
501 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
502 if ($config{GCCVER} < 3) {
503 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
507 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
514 # Directory Settings..
515 my $tmpbase = $config{BASE_DIR};
516 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
517 if ($tmpbase ne $config{BASE_DIR}) {
518 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
519 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
520 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
523 dir_check("are the configuration files", "CONFIG_DIR");
524 dir_check("are the modules to be compiled to", "MODULE_DIR");
525 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
526 dir_check("do you want the build to take place", "BUILD_DIR");
528 my $chose_hiperf = 0;
530 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?");
532 if ($config{USE_KQUEUE} eq "y") {
537 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?");
539 if ($config{USE_EPOLL} eq "y") {
544 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?");
546 if ($config{USE_PORTS} eq "y") {
551 if (!$chose_hiperf) {
552 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?");
553 if ($config{USE_POLL} ne "y")
555 print "No high-performance socket engines are available, or you chose\n";
556 print "not to enable one. Defaulting to select() engine.\n\n";
560 $config{USE_FREEBSD_BASE_SSL} = "n";
561 $config{USE_FREEBSD_PORTS_SSL} = "n";
562 if ($config{HAS_OPENSSL_PORT} ne "")
564 $config{USE_FREEBSD_PORTS_SSL} = "y";
565 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
566 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";
567 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
569 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
571 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
573 # update to port version
574 $openssl_ver = $config{HAS_OPENSSL_PORT};
579 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
582 $config{USE_SSL} = "n";
583 $config{MODUPDATE} = 'n';
585 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
587 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
588 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
590 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
591 if ($config{USE_SSL} eq "y")
593 if ($config{HAS_GNUTLS} eq "y")
595 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
596 if ($config{USE_GNUTLS} eq "y")
598 print "\nUsing GnuTLS SSL module.\n";
602 if ($config{HAS_OPENSSL} eq "y")
604 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
605 if ($config{USE_OPENSSL} eq "y")
607 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
614 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
615 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
618 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
620 if ($config{MODUPDATE} eq "y") {
621 print "Checking for upgrades to extra and third party modules... ";
622 system "./modulemanager upgrade";
626 # We are on a POSIX system, we can enable POSIX extras without asking
627 symlink "extra/m_regex_posix.cpp", "src/modules/m_regex_posix.cpp";
631 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
633 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
636 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
638 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
643 $config{CERTGEN} ||= 'y';
644 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
646 if ($config{USE_GNUTLS} eq "y") {
647 unless (-r "src/modules/m_ssl_gnutls.cpp") {
648 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
649 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
651 if ($interactive && $config{CERTGEN} eq 'y')
653 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
654 print "SSL Certificates Not found, Generating.. \n\n
655 *************************************************************
656 * Generating the Private Key may take some time, go grab a *
657 * Coffee. Even better, to generate some more entropy if it *
658 * is taking a while, open another console and type du / a *
659 * few times and get that HD going :) Then answer the *
660 * Questions which follow. If you are unsure, just hit enter *
661 *************************************************************\n\n";
662 $failed = make_gnutls_cert();
664 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
666 print "\nCertificate generation complete, copying to config directory... ";
667 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
668 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
673 print "SSL Certificates found, skipping.\n\n";
678 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
682 if ($config{USE_OPENSSL} eq "y") {
683 unless (-r "src/modules/m_ssl_openssl.cpp") {
684 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
685 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
688 if ($interactive && $config{CERTGEN} eq 'y')
690 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
691 print "SSL Certificates Not found, Generating.. \n\n
692 *************************************************************
693 * Generating the certificates may take some time, go grab a *
694 * coffee, or something. *
695 *************************************************************\n\n";
697 print "\nCertificate generation complete, copying to config directory... ";
698 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
699 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
700 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
703 print "SSL Certificates found, skipping.\n\n"
708 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
711 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
712 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
720 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
721 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
722 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
723 print "modules in your config. This configure script has added those modules to the\n";
724 print "build process. For more info please refer to:\n";
725 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
727 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
728 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
729 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";
732 if ($config{GCCVER} < "3") {
734 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
735 GCC 2.x series compilers only had partial (read as broken) C++ support, and
736 your compile will most likely fail horribly! If you have any problems, do NOT
737 report them to the bugtracker or forums without first upgrading your compiler
738 to a newer 3.x or 4.x (or whatever is available currently) version.
742 ################################################################################
744 ################################################################################
746 # Retrieves the .config.cache file, and loads values into the main config hash.
747 open(CACHE, ".config.cache") or return 0;
750 # Ignore Blank lines, and comments..
753 my ($key, $value) = split("=", $_, 2);
754 $value =~ /^\"(.*)\"$/;
755 # Do something with data here!
763 # Dump the contents of %config
764 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
765 open(FILEHANDLE, ">.config.cache");
766 foreach my $key (keys %config) {
767 print FILEHANDLE "$key=\"$config{$key}\"\n";
773 my ($desc, $hash_key) = @_;
776 print "In what directory $desc?\n";
777 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
778 chomp(my $var = <STDIN>);
780 $var = $config{$hash_key};
782 if ($var =~ /^\~\/(.+)$/) {
783 # Convert it to a full path..
784 $var = resolve_directory($ENV{HOME} . "/" . $1);
786 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
788 # Assume relative Path was given.. fill in the rest.
789 $var = $this . "/$var";
792 $var = resolve_directory($var);
794 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
795 chomp(my $tmp = <STDIN>);
796 if (($tmp eq "") || ($tmp =~ /^y/i)) {
797 # Attempt to Create the Dir..
800 File::Path::mkpath($var, 0, 0777);
803 unless (defined($chk) && -d $var) {
804 print "Unable to create directory. ($var)\n\n";
809 # They said they don't want to create, and we can't install there.
815 # Target exists, but is not a directory.
816 print "File $var exists, but is not a directory.\n\n";
820 # Either Dir Exists, or was created fine.
821 $config{$hash_key} = $var;
829 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
832 my($writeheader) = @_;
833 # First File.. inspircd_config.h
834 chomp(my $incos = `uname -n -s -r`);
835 chomp(my $version = `sh src/version.sh`);
836 chomp(my $revision2 = getrevision());
837 if ($writeheader == 1)
839 print "Writing \e[1;32minspircd_config.h\e[0m\n";
840 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
841 print FILEHANDLE <<EOF;
842 /* Auto generated by configure, do not modify! */
843 #ifndef __CONFIGURATION_AUTO__
844 #define __CONFIGURATION_AUTO__
846 /* this is for windows support. */
847 #define CoreExport /**/
848 #define DllExport /**/
850 #define MOD_PATH "$config{MODULE_DIR}"
851 #define SOMAXCONN_S "$config{_SOMAXCONN}"
852 #define ENTRYPOINT int main(int argc, char** argv)
855 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
857 if ($config{OSNAME} =~ /SunOS/i) {
858 print FILEHANDLE "#define IS_SOLARIS\n";
860 if ($config{OSNAME} =~ /MINGW32/i) {
861 print FILEHANDLE "#define IS_MINGW\n";
863 if ($config{GCCVER} >= 3) {
864 print FILEHANDLE "#define GCC3\n";
867 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
869 ($config{GCCVER} > 4)
871 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
873 if ($config{HAS_STRLCPY} eq "true") {
874 print FILEHANDLE "#define HAS_STRLCPY\n";
876 if ($config{HAS_STDINT} eq "true") {
877 print FILEHANDLE "#define HAS_STDINT\n";
879 if ($config{HAS_EVENTFD} eq 'true') {
880 print FILEHANDLE "#define HAS_EVENTFD\n";
882 if ($config{OSNAME} !~ /DARWIN/i) {
883 print FILEHANDLE "#define HAS_CLOCK_GETTIME\n";
886 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
887 print FILEHANDLE "#define USE_KQUEUE\n";
888 $config{SOCKETENGINE} = "socketengine_kqueue";
891 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
892 print FILEHANDLE "#define USE_EPOLL\n";
893 $config{SOCKETENGINE} = "socketengine_epoll";
896 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
897 print FILEHANDLE "#define USE_PORTS\n";
898 $config{SOCKETENGINE} = "socketengine_ports";
901 # user didn't choose either epoll or select for their OS.
902 # default them to USE_SELECT (ewwy puke puke)
904 print "no hi-perf, " . $config{USE_POLL};
905 if ($config{USE_POLL} eq "y")
907 print FILEHANDLE "#define USE_POLL\n";
908 $config{SOCKETENGINE} = "socketengine_poll";
912 print FILEHANDLE "#define USE_SELECT\n";
913 $config{SOCKETENGINE} = "socketengine_select";
916 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
919 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
920 print FILEHANDLE <<EOF;
921 #define VERSION "$version"
922 #define REVISION "$revision2"
923 #define SYSTEM "$incos"
927 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
929 open my $fh1, $file or $diff = 1;
930 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
934 if (defined($line1) != defined($line2)) {
936 } elsif (!defined $line1) {
939 $diff = ($line1 ne $line2);
944 rename "$file.tmp", $file;
951 # Write all .in files.
954 my $exe = "inspircd";
956 # Do this once here, and cache it in the .*.inc files,
957 # rather than attempting to read src/version.sh from
958 # compiled code -- we might not have the source to hand.
959 # Fix for bug#177 by Brain.
961 chomp($version = `sh ./src/version.sh`);
962 chomp(my $revision = getrevision());
963 $version = "$version(r$revision)";
965 # We can actually parse any file starting with . and ending with .inc,
966 # but right now we only parse .inspircd.inc to form './inspircd'
967 prepare_dynamic_makefile();
969 my @dotfiles = qw(main.mk inspircd);
970 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
972 foreach my $file (@dotfiles) {
973 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
974 $_ = join '', <FILEHANDLE>;
977 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
980 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR UID
981 STARTSCRIPT DESTINATION SOCKETENGINE
983 s/\@$var\@/$config{$var}/g;
985 s/\@EXECUTABLE\@/$exe/ if defined $exe;
986 s/\@VERSION\@/$version/ if defined $version;
988 if ($file eq 'main.mk') {
989 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
992 s/\@IFDEF (\S+)/ifdef $1/g;
993 s/\@IFNDEF (\S+)/ifndef $1/g;
994 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
995 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
998 s/ *\@BSD_ONLY .*\n//g;
1000 s/\@DO_EXPORT (.*)/export $1/g;
1001 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1005 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1007 s/\@IFDEF (\S+)/.if defined($1)/g;
1008 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1009 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1010 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1014 s/ *\@GNU_ONLY .*\n//g;
1016 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1017 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1021 print "Writing \e[1;32m$file\e[0m ...\n";
1022 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1023 print FILEHANDLE $_;
1028 chmod 0755, 'inspircd';
1034 for my $mod (@modlist) {
1035 getcompilerflags("src/modules/m_$mod.cpp");
1036 getlinkerflags("src/modules/m_$mod.cpp");
1040 sub prepare_dynamic_makefile
1046 $config{USE_EPOLL} = 0;
1050 $config{USE_KQUEUE} = 0;
1054 $config{USE_PORTS} = 0;
1058 # Routine to list out the extra/ modules that have been enabled.
1059 # Note: when getting any filenames out and comparing, it's important to lc it if the
1060 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1061 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1062 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1063 sub list_extras () {
1066 my $srcdir = File::Spec->catdir("src", "modules");
1067 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1070 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1071 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1074 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1075 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1078 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1080 EXTRA: for my $extra (@extras) {
1081 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1082 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1083 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1084 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1085 if (-l $abs_source) {
1086 # Symlink, is it in the right place?
1087 my $targ = readlink($abs_source);
1088 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1089 if ($abs_targ eq $abs_extra) {
1090 $extras{$extra} = "\e[32;1menabled\e[0m";
1092 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1094 } elsif (-e $abs_source) {
1095 my ($devext, $inoext) = stat($abs_extra);
1096 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1098 if ($devsrc == $devext && $inosrc == $inoext) {
1099 $extras{$extra} = "\e[32;1menabled\e[0m";
1101 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1104 open my $extfd, "<", $abs_extra;
1105 open my $srcfd, "<", $abs_source;
1107 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1108 $extras{$extra} = "\e[32;1menabled\e[0m";
1110 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1114 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1117 # Now let's add dependency info
1118 for my $extra (keys(%extras)) {
1119 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1120 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1121 my @deps = split / +/, getdependencies($abs_extra);
1122 for my $dep (@deps) {
1123 if (exists($extras{$dep})) {
1124 my $ref = \$extras{$dep}; # Take reference.
1125 if ($$ref !~ m/needed by/) {
1126 # First dependency found.
1127 if ($$ref =~ m/enabled/) {
1128 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1130 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1131 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1134 if ($$ref =~ m/enabled/) {
1135 $$ref .= ", \e[32;1m$extra\e[0m";
1137 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1143 for my $extra (sort {$a cmp $b} keys(%extras)) {
1144 my $text = $extras{$extra};
1145 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1146 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1148 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1151 return keys(%extras) if wantarray; # Can be used by manage_extras.
1154 sub enable_extras (@) {
1156 for my $extra (@extras) {
1157 my $extrapath = "src/modules/extra/$extra";
1158 if (!-e $extrapath) {
1159 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1162 my $source = "src/modules/$extra";
1164 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1167 # Get dependencies, and add them to be processed.
1168 my @deps = split / +/, getdependencies($extrapath);
1169 for my $dep (@deps) {
1170 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1171 if (!-e "src/modules/$dep") {
1172 if (-e "src/modules/extra/$dep") {
1173 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1176 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";
1180 print "Enabling $extra ... \n";
1181 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1185 sub disable_extras (@)
1187 opendir my $dd, "src/modules/extra/";
1188 my @files = readdir($dd);
1191 EXTRA: for my $extra (@extras) {
1192 my $extrapath = "src/modules/extra/$extra";
1193 my $source = "src/modules/$extra";
1194 if (!-e $extrapath) {
1195 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1198 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1199 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";
1202 # Check if anything needs this.
1203 for my $file (@files) {
1204 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1205 # File depends on this extra...
1206 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1207 # And is both enabled and not about to be disabled.
1208 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1209 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1215 print "Disabling $extra ... \n";
1216 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";