2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2009 The InspIRCd Development Team
6 # http://wiki.inspircd.org/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
41 # NON-EDITABLE VARIABLES
43 ###############################################################################################
45 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
46 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
47 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port);
49 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
54 sub enable_extras (@);
56 sub disable_extras (@);
59 my @opt_disableextras;
62 'enable-gnutls' => \$opt_use_gnutls,
63 'rebuild' => \$opt_rebuild,
64 'enable-openssl' => \$opt_use_openssl,
65 'disable-interactive' => \$opt_nointeractive,
66 'enable-ports' => \$opt_ports,
67 'enable-epoll' => \$opt_epoll,
68 'enable-kqueue' => \$opt_kqueue,
69 'disable-ports' => \$opt_noports,
70 'disable-epoll' => \$opt_noepoll,
71 'disable-kqueue' => \$opt_nokqueue,
72 'disable-ipv6' => \$opt_noipv6,
73 'with-cc=s' => \$opt_cc,
74 'with-maxbuf=i' => \$opt_maxbuf,
75 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
76 'prefix=s' => \$opt_base_dir,
77 'config-dir=s' => \$opt_config_dir,
78 'module-dir=s' => \$opt_module_dir,
79 'binary-dir=s' => \$opt_binary_dir,
80 'library-dir=s' => \$opt_library_dir,
81 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
82 'help' => sub { showhelp(); },
83 'update' => sub { update(); },
84 'svnupdate' => sub { svnupdate(); },
85 'clean' => sub { clean(); },
86 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
87 'enable-extras=s@' => \@opt_enableextras, # ^
88 'disable-extras=s@' => \@opt_disableextras, # ^
89 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
90 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
93 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
94 @opt_enableextras = split /,/, join(',', @opt_enableextras);
95 @opt_disableextras = split /,/, join(',', @opt_disableextras);
96 enable_extras(@opt_enableextras);
97 disable_extras(@opt_disableextras);
99 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
103 our $non_interactive = (
104 (defined $opt_library_dir) ||
105 (defined $opt_base_dir) ||
106 (defined $opt_config_dir) ||
107 (defined $opt_module_dir) ||
108 (defined $opt_base_dir) ||
109 (defined $opt_binary_dir) ||
110 (defined $opt_nointeractive) ||
112 (defined $opt_noipv6) ||
113 (defined $opt_kqueue) ||
114 (defined $opt_epoll) ||
115 (defined $opt_ports) ||
116 (defined $opt_use_openssl) ||
117 (defined $opt_nokqueue) ||
118 (defined $opt_noepoll) ||
119 (defined $opt_noports) ||
120 (defined $opt_maxbuf) ||
121 (defined $opt_use_gnutls) ||
122 (defined $opt_freebsd_port)
124 our $interactive = !$non_interactive;
126 chomp(our $topdir = getcwd());
127 our $this = resolve_directory($topdir); # PWD, Regardless.
128 our @modlist = (); # Declare for Module List..
129 our %config = (); # Initiate Configuration Hash..
130 $config{ME} = resolve_directory($topdir); # Present Working Directory
132 $config{BASE_DIR} = $config{ME};
134 if (defined $opt_base_dir)
136 $config{BASE_DIR} = $opt_base_dir;
139 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
140 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
141 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
142 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
144 if (defined $opt_config_dir)
146 $config{CONFIG_DIR} = $opt_config_dir;
148 if (defined $opt_module_dir)
150 $config{MODULE_DIR} = $opt_module_dir;
152 if (defined $opt_binary_dir)
154 $config{BINARY_DIR} = $opt_binary_dir;
156 if (defined $opt_library_dir)
158 $config{LIBRARY_DIR} = $opt_library_dir;
160 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
162 if (defined $opt_freebsd_port)
164 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
165 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
166 $config{USE_FREEBSD_BASE_SSL} = "n";
170 if ($^O eq "freebsd")
172 # default: use base ssl
173 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
174 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
178 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
179 $config{HAS_OPENSSL_PORT} = "";
183 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
184 chomp(our $openssl_ver = $config{HAS_OPENSSL});
185 $config{USE_GNUTLS} = "n";
186 if (defined $opt_use_gnutls)
188 $config{USE_GNUTLS} = "y"; # Use gnutls.
190 $config{USE_OPENSSL} = "n"; # Use openssl.
191 if (defined $opt_use_openssl)
193 $config{USE_OPENSSL} = "y";
196 # no, let's not change these.
197 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
198 if (!defined $opt_disable_debug)
200 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
204 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
207 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
208 $config{HAS_STDINT} = "false"; # stdint.h check
209 $config{USE_KQUEUE} = "y"; # kqueue enabled
210 if (defined $opt_kqueue)
212 $config{USE_KQUEUE} = "y";
214 if (defined $opt_nokqueue)
216 $config{USE_KQUEUE} = "n";
218 $config{USE_POLL} = "y"; # poll enabled
219 $config{USE_EPOLL} = "y"; # epoll enabled
220 if (defined $opt_epoll)
222 $config{USE_EPOLL} = "y";
224 if (defined $opt_noepoll)
226 $config{USE_EPOLL} = "n";
228 $config{USE_PORTS} = "y"; # epoll enabled
229 if (defined $opt_ports)
231 $config{USE_PORTS} = "y";
233 if (defined $opt_noports)
235 $config{USE_PORTS} = "n";
237 $config{IPV6} = "y"; # IPv6 support
238 if (defined $opt_noipv6)
242 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
243 chomp($config{GCCMINOR} = `g++ -dumpversion | cut -c 3`);
244 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
245 $config{OSNAME} = $^O; # Operating System Name
246 $config{IS_DARWIN} = "NO"; # Is OSX?
247 $config{STARTSCRIPT} = "inspircd"; # start script?
248 $config{DESTINATION} = "BASE"; # Is target path.
249 $config{EXTRA_DIR} = ""; # Is empty.
250 if ($config{OSNAME} =~ /darwin/i)
252 $config{IS_DARWIN} = "YES";
253 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
254 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
255 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
257 $config{CC} = "g++"; # C++ compiler
260 $config{CC} = $opt_cc;
262 our $exec = $config{CC} . " -dumpversion | cut -c 1";
263 chomp($config{GCCVER} = `$exec`); # Major GCC Version
264 $exec = $config{CC} . " -dumpversion | cut -c 3";
265 chomp($config{GCCMINOR} = `$exec`);
266 $config{MAXBUF} = "512"; # Max buffer size
268 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
269 $config{HAS_OPENSSL} = $1;
271 $config{HAS_OPENSSL} = "";
274 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
275 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
279 # Get and Set some important vars..
284 unlink(".config.cache");
287 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
292 chomp($topdir = getcwd());
293 $this = resolve_directory($topdir); # PWD, Regardless.
295 # Does the cache file exist?
297 # No, No it doesn't.. *BASH*
298 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
301 # We've Loaded the cache file and all our variables..
302 print "Updating files...\n";
303 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
305 print "Disabling debug information (-g).\n";
306 $config{OPTIMISATI} = "";
308 $has_epoll = $config{HAS_EPOLL};
309 $has_ports = $config{HAS_PORTS};
310 $has_kqueue = $config{HAS_KQUEUE};
319 print "Configure update failed: $@\n";
327 open(FH,"<.svn/entries") or $fail = 1;
329 print "This is not an SVN copy of InspIRCd.\n";
336 open my $fd, "-|", "svn update";
337 my $configurechanged = 0; # Needs ./configure -update
338 my $rootincchanged = 0;
340 while (defined(my $line = <$fd>))
344 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
345 ($action, $file) = ($1, $2);
348 push @conflicted, $file;
349 if ($file eq "configure")
351 $configurechanged = 1;
353 elsif ($file =~ m/^\..*\.inc$/)
358 elsif ($action eq "U" || $action eq "G")
360 if ($file eq "configure")
362 $configurechanged = 1;
364 elsif ($file =~ m/^\..*\.inc$/)
370 unless (close $fd) # close() waits for exit and returns false if the command failed
374 print STDERR "Problem updating from SVN, please check above for errors\n";
378 print STDERR "Failed to run SVN: $!\n";
382 if (scalar(@conflicted) > 0)
384 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
385 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
386 print "Conflicted files: " . join ", ", @conflicted . "\n";
389 if ($configurechanged)
391 system("perl configure -update");
395 print "No need to update Makefiles.\n";
397 if (defined $opt_rebuild) {
398 system("make install");
406 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
407 $fail ||= system "./test_$feature";
408 unlink "test_$feature";
412 print "Running non-interactive configure...\n" unless $interactive;
413 print "Checking for cache from previous configure... ";
414 print ((!getcache()) ? "not found\n" : "found\n");
415 $config{SYSTEM} = lc $^O;
416 print "Checking operating system version... $config{SYSTEM}\n";
418 printf "Checking if stdint.h exists... ";
419 $config{HAS_STDINT} = "true";
421 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
422 if ($config{HAS_STDINT} eq "true") {
425 print "yes\n" if $config{HAS_STDINT} eq "true";
426 print "no\n" if $config{HAS_STDINT} eq "false";
428 printf "Checking if strlcpy exists... ";
429 # Perform the strlcpy() test..
430 $config{HAS_STRLCPY} = "false";
432 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
434 while (defined(my $line = <STRLCPY>)) {
436 # try and find the delcaration of:
437 # size_t strlcpy(...)
438 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
439 $config{HAS_STRLCPY} = "true";
444 print "yes\n" if $config{HAS_STRLCPY} eq "true";
445 print "no\n" if $config{HAS_STRLCPY} eq "false";
447 printf "Checking if kqueue exists... ";
450 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
452 while (defined(my $line = <KQUEUE>)) {
454 # try and find the delcaration of:
456 if ($line =~ /int(\0x9|\s)+kqueue/) {
462 print "yes\n" if $has_kqueue == 1;
463 print "no\n" if $has_kqueue == 0;
465 printf "Checking for epoll support... ";
466 $has_epoll = test_compile('epoll');
467 print $has_epoll ? "yes\n" : "no\n";
469 printf "Checking for eventfd support... ";
470 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
471 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
473 printf "Checking if Solaris I/O completion ports are available... ";
475 our $system = `uname -s`;
477 $has_ports = 1 if ($system eq "SunOS");
480 my $kernel = `uname -r`;
482 if (($kernel !~ /^5\.1./)) {
486 print "yes\n" if $has_ports == 1;
487 print "no\n" if $has_ports == 0;
489 $config{HAS_EPOLL} = $has_epoll;
490 $config{HAS_KQUEUE} = $has_kqueue;
492 printf "Checking for libgnutls... ";
493 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
494 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
496 $config{HAS_GNUTLS} = "y";
499 $config{HAS_GNUTLS} = "n";
503 $config{HAS_GNUTLS} = "n";
506 printf "Checking for openssl... ";
507 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
508 if (defined($openssl_ver) && ($openssl_ver ne "")) {
510 $config{HAS_OPENSSL} = "y";
513 $config{HAS_OPENSSL} = "n";
517 $config{HAS_OPENSSL} = "n";
520 printf "Checking if you are running an ancient, unsupported OS... ";
521 if ($config{OSNAME} =~ /FreeBSD/i)
523 my $version = `uname -r`;
524 if ($version =~ /^4\./)
527 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
528 print "To build, you will need to add the following to CXXFLAGS:\n";
529 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
533 print "no ($version)\n";
538 print "no ($config{OSNAME})\n";
541 print "Checking for upgrades to extra and third party modules... ";
542 system "./modulemanager upgrade";
544 ################################################################################
545 # BEGIN INTERACTIVE PART #
546 ################################################################################
551 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
554 my $rev = getrevision();
555 # Display Introduction Message..
557 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
558 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
560 *** If you are unsure of any of these values, leave it blank for ***
561 *** standard settings that will work, and your server will run ***
562 *** using them. Please consult your IRC network admin if in doubt. ***
564 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
565 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
566 dir, otherwise you won't have a config file!
568 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
569 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
572 print " (Non-SVN build)";
576 $config{CHANGE_COMPILER} = "n";
577 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";
579 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
580 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
581 should NOT be used. You should probably specify a newer compiler.\n\n";
582 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
583 if ($config{CHANGE_COMPILER} =~ /y/i) {
584 print "What command do you want to use to invoke your compiler?\n";
585 print "[\e[1;32m$config{CC}\e[0m] -> ";
586 chomp($config{CC} = <STDIN>);
587 if ($config{CC} eq "") {
590 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
592 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
593 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
594 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
595 if ($config{GCCVER} < 3) {
596 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
600 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
607 # Directory Settings..
608 my $tmpbase = $config{BASE_DIR};
609 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
610 if ($tmpbase ne $config{BASE_DIR}) {
611 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
612 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
613 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
614 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
617 dir_check("are the configuration files", "CONFIG_DIR");
618 dir_check("are the modules to be compiled to", "MODULE_DIR");
619 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
620 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
622 my $chose_hiperf = 0;
624 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?");
626 if ($config{USE_KQUEUE} eq "y") {
631 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?");
633 if ($config{USE_EPOLL} eq "y") {
638 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?");
640 if ($config{USE_PORTS} eq "y") {
645 if (!$chose_hiperf) {
646 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?");
647 if ($config{USE_POLL} ne "y")
649 print "No high-performance socket engines are available, or you chose\n";
650 print "not to enable one. Defaulting to select() engine.\n\n";
654 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
657 $config{USE_FREEBSD_BASE_SSL} = "n";
658 $config{USE_FREEBSD_PORTS_SSL} = "n";
659 if ($config{HAS_OPENSSL_PORT} ne "")
661 $config{USE_FREEBSD_PORTS_SSL} = "y";
662 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
663 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";
664 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
666 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
668 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
670 # update to port version
671 $openssl_ver = $config{HAS_OPENSSL_PORT};
676 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
679 $config{USE_SSL} = "n";
681 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
683 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
684 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
686 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
687 if ($config{USE_SSL} eq "y")
689 if ($config{HAS_GNUTLS} eq "y")
691 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
692 if ($config{USE_GNUTLS} eq "y")
694 print "\nUsing GnuTLS SSL module.\n";
698 if ($config{HAS_OPENSSL} eq "y")
700 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
701 if ($config{USE_OPENSSL} eq "y")
703 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
710 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
711 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
717 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
719 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
722 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
724 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
729 $config{CERTGEN} ||= 'y';
730 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
732 if ($config{USE_GNUTLS} eq "y") {
733 unless (-r "src/modules/m_ssl_gnutls.cpp") {
734 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
735 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
737 if ($interactive && $config{CERTGEN} eq 'y')
739 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
740 print "SSL Certificates Not found, Generating.. \n\n
741 *************************************************************
742 * Generating the Private Key may take some time, go grab a *
743 * Coffee. Even better, to generate some more entropy if it *
744 * is taking a while, open another console and type du / a *
745 * few times and get that HD going :) Then answer the *
746 * Questions which follow. If you are unsure, just hit enter *
747 *************************************************************\n\n";
748 $failed = make_gnutls_cert();
750 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
752 print "\nCertificate generation complete, copying to config directory... ";
753 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
754 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
759 print "SSL Certificates found, skipping.\n\n";
764 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
768 if ($config{USE_OPENSSL} eq "y") {
769 unless (-r "src/modules/m_ssl_openssl.cpp") {
770 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
771 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
774 if ($interactive && $config{CERTGEN} eq 'y')
776 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
777 print "SSL Certificates Not found, Generating.. \n\n
778 *************************************************************
779 * Generating the certificates may take some time, go grab a *
780 * coffee, or something. *
781 *************************************************************\n\n";
783 print "\nCertificate generation complete, copying to config directory... ";
784 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
785 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
786 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
789 print "SSL Certificates found, skipping.\n\n"
794 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
797 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
798 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
806 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
807 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
808 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
809 print "modules in your config. This configure script has added those modules to the\n";
810 print "build process. For more info please refer to:\n";
811 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
813 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
814 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
815 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";
818 if ($config{GCCVER} < "3") {
820 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
821 GCC 2.x series compilers only had partial (read as broken) C++ support, and
822 your compile will most likely fail horribly! If you have any problems, do NOT
823 report them to the bugtracker or forums without first upgrading your compiler
824 to a newer 3.x or 4.x (or whatever is available currently) version.
828 ################################################################################
830 ################################################################################
832 # Retrieves the .config.cache file, and loads values into the main config hash.
833 open(CACHE, ".config.cache") or return 0;
836 # Ignore Blank lines, and comments..
839 my ($key, $value) = split("=", $_, 2);
840 $value =~ /^\"(.*)\"$/;
841 # Do something with data here!
849 # Dump the contents of %config
850 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
851 open(FILEHANDLE, ">.config.cache");
852 foreach my $key (keys %config) {
853 print FILEHANDLE "$key=\"$config{$key}\"\n";
859 my ($desc, $hash_key) = @_;
862 print "In what directory $desc?\n";
863 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
864 chomp(my $var = <STDIN>);
866 $var = $config{$hash_key};
868 if ($var =~ /^\~\/(.+)$/) {
869 # Convert it to a full path..
870 $var = resolve_directory($ENV{HOME} . "/" . $1);
872 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
874 # Assume relative Path was given.. fill in the rest.
875 $var = $this . "/$var";
878 $var = resolve_directory($var);
880 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
881 chomp(my $tmp = <STDIN>);
882 if (($tmp eq "") || ($tmp =~ /^y/i)) {
883 # Attempt to Create the Dir..
886 File::Path::mkpath($var, 0, 0777);
889 unless (defined($chk) && -d $var) {
890 print "Unable to create directory. ($var)\n\n";
895 # They said they don't want to create, and we can't install there.
901 # Target exists, but is not a directory.
902 print "File $var exists, but is not a directory.\n\n";
906 # Either Dir Exists, or was created fine.
907 $config{$hash_key} = $var;
915 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
918 my($writeheader) = @_;
919 # First File.. inspircd_config.h
920 chomp(my $incos = `uname -n -s -r`);
921 chomp(my $version = `sh src/version.sh`);
922 chomp(my $revision2 = getrevision());
923 if ($writeheader == 1)
925 print "Writing \e[1;32minspircd_config.h\e[0m\n";
926 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
927 print FILEHANDLE <<EOF;
928 /* Auto generated by configure, do not modify! */
929 #ifndef __CONFIGURATION_AUTO__
930 #define __CONFIGURATION_AUTO__
932 /* this is for windows support. */
933 #define CoreExport /**/
934 #define DllExport /**/
936 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
937 #define MOD_PATH "$config{MODULE_DIR}"
938 #define SOMAXCONN_S "$config{_SOMAXCONN}"
939 #define OPTIMISATION $config{OPTIMITEMP}
940 #define LIBRARYDIR "$config{LIBRARY_DIR}"
941 #define ENTRYPOINT int main(int argc, char** argv)
944 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
946 if ($config{OSNAME} =~ /SunOS/i) {
947 print FILEHANDLE "#define IS_SOLARIS\n";
949 if ($config{OSNAME} =~ /MINGW32/i) {
950 print FILEHANDLE "#define IS_MINGW\n";
952 if ($config{GCCVER} >= 3) {
953 print FILEHANDLE "#define GCC3\n";
956 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
958 ($config{GCCVER} > 4)
960 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
962 if ($config{HAS_STRLCPY} eq "true") {
963 print FILEHANDLE "#define HAS_STRLCPY\n";
965 if ($config{HAS_STDINT} eq "true") {
966 print FILEHANDLE "#define HAS_STDINT\n";
968 if ($config{IPV6} =~ /y/i) {
969 print FILEHANDLE "#define IPV6\n";
971 if ($config{HAS_EVENTFD} eq 'true') {
972 print FILEHANDLE "#define HAS_EVENTFD\n";
975 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
976 print FILEHANDLE "#define USE_KQUEUE\n";
977 $config{SOCKETENGINE} = "socketengine_kqueue";
980 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
981 print FILEHANDLE "#define USE_EPOLL\n";
982 $config{SOCKETENGINE} = "socketengine_epoll";
985 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
986 print FILEHANDLE "#define USE_PORTS\n";
987 $config{SOCKETENGINE} = "socketengine_ports";
990 # user didn't choose either epoll or select for their OS.
991 # default them to USE_SELECT (ewwy puke puke)
993 print "no hi-perf, " . $config{USE_POLL};
994 if ($config{USE_POLL} eq "y")
996 print FILEHANDLE "#define USE_POLL\n";
997 $config{SOCKETENGINE} = "socketengine_poll";
1001 print FILEHANDLE "#define USE_SELECT\n";
1002 $config{SOCKETENGINE} = "socketengine_select";
1005 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1008 open(FILEHANDLE, ">include/inspircd_se_config.h.tmp");
1009 print FILEHANDLE <<EOF;
1010 /* Auto generated by configure, do not modify or commit to svn! */
1011 #ifndef __CONFIGURATION_SOCKETENGINE__
1012 #define __CONFIGURATION_SOCKETENGINE__
1014 #include "socketengines/$config{SOCKETENGINE}.h"
1020 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1021 print FILEHANDLE <<EOF;
1022 #define VERSION "$version"
1023 #define REVISION "$revision2"
1024 #define SYSTEM "$incos"
1028 for my $file (qw(include/inspircd_config.h include/inspircd_se_config.h include/inspircd_version.h)) {
1030 open my $fh1, $file or $diff = 1;
1031 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1035 if (defined($line1) != defined($line2)) {
1037 } elsif (!defined $line1) {
1040 $diff = ($line1 ne $line2);
1045 rename "$file.tmp", $file;
1052 # Write all .in files.
1055 my $exe = "inspircd";
1057 # Do this once here, and cache it in the .*.inc files,
1058 # rather than attempting to read src/version.sh from
1059 # compiled code -- we might not have the source to hand.
1060 # Fix for bug#177 by Brain.
1062 chomp($version = `sh ./src/version.sh`);
1063 chomp(my $revision = getrevision());
1064 $version = "$version(r$revision)";
1066 # We can actually parse any file starting with . and ending with .inc,
1067 # but right now we only parse .inspircd.inc to form './inspircd'
1068 prepare_dynamic_makefile();
1070 print "Writing \e[1;32mMakefiles\e[0m\n";
1072 opendir(DIRHANDLE, $this);
1074 foreach my $name (sort readdir(DIRHANDLE)) {
1075 if ($name =~ /^\.(.+)\.inc$/) {
1078 # Bug #353, omit this on non-darwin
1079 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1081 # All .name.inc files need parsing!
1082 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1083 $_ = join '', <FILEHANDLE>;
1086 print "Writing \e[1;32m$file\e[0m ...\n";
1088 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR LIBRARY_DIR
1089 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE CORE_FLAGS
1091 s/\@$var\@/$config{$var}/g;
1093 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1094 s/\@VERSION\@/$version/ if defined $version;
1096 if ($file eq 'Makefile') {
1098 s/\@IFDEF (\S+)/ifdef $1/g;
1099 s/\@IFNDEF (\S+)/ifndef $1/g;
1100 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1101 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1104 s/ *\@BSD_ONLY .*\n//g;
1106 s/\@DO_EXPORT (.*)/export $1/g;
1107 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1111 s/\@IFDEF (\S+)/.if defined($1)/g;
1112 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1113 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1114 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1118 s/ *\@GNU_ONLY .*\n//g;
1120 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1121 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1125 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1126 print FILEHANDLE $_;
1131 closedir(DIRHANDLE);
1133 # Make inspircd executable!
1134 chmod 0744, 'inspircd';
1140 for my $mod (@modlist) {
1141 getcompilerflags("src/modules/m_$mod.cpp");
1142 getlinkerflags("src/modules/m_$mod.cpp");
1146 sub prepare_dynamic_makefile
1152 $config{USE_EPOLL} = 0;
1156 $config{USE_KQUEUE} = 0;
1160 $config{USE_PORTS} = 0;
1164 # Routine to list out the extra/ modules that have been enabled.
1165 # Note: when getting any filenames out and comparing, it's important to lc it if the
1166 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1167 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1168 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1169 sub list_extras () {
1172 my $srcdir = File::Spec->catdir("src", "modules");
1173 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1176 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1177 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1180 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1181 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1184 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1186 EXTRA: for my $extra (@extras) {
1187 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1188 next if ($extra eq '.svn');
1189 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1190 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1191 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1192 if (-l $abs_source) {
1193 # Symlink, is it in the right place?
1194 my $targ = readlink($abs_source);
1195 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1196 if ($abs_targ eq $abs_extra) {
1197 $extras{$extra} = "\e[32;1menabled\e[0m";
1199 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1201 } elsif (-e $abs_source) {
1202 my ($devext, $inoext) = stat($abs_extra);
1203 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1205 if ($devsrc == $devext && $inosrc == $inoext) {
1206 $extras{$extra} = "\e[32;1menabled\e[0m";
1208 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1211 open my $extfd, "<", $abs_extra;
1212 open my $srcfd, "<", $abs_source;
1214 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1215 $extras{$extra} = "\e[32;1menabled\e[0m";
1217 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1221 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1224 # Now let's add dependency info
1225 for my $extra (keys(%extras)) {
1226 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1227 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1228 my @deps = split / +/, getdependencies($abs_extra);
1229 for my $dep (@deps) {
1230 if (exists($extras{$dep})) {
1231 my $ref = \$extras{$dep}; # Take reference.
1232 if ($$ref !~ m/needed by/) {
1233 # First dependency found.
1234 if ($$ref =~ m/enabled/) {
1235 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1237 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1238 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1241 if ($$ref =~ m/enabled/) {
1242 $$ref .= ", \e[32;1m$extra\e[0m";
1244 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1250 for my $extra (sort {$a cmp $b} keys(%extras)) {
1251 my $text = $extras{$extra};
1252 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1253 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1255 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1258 return keys(%extras) if wantarray; # Can be used by manage_extras.
1261 sub enable_extras (@) {
1263 for my $extra (@extras) {
1264 my $extrapath = "src/modules/extra/$extra";
1265 if (!-e $extrapath) {
1266 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1269 my $source = "src/modules/$extra";
1271 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1274 # Get dependencies, and add them to be processed.
1275 my @deps = split / +/, getdependencies($extrapath);
1276 for my $dep (@deps) {
1277 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1278 if (!-e "src/modules/$dep") {
1279 if (-e "src/modules/extra/$dep") {
1280 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1283 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";
1287 print "Enabling $extra ... \n";
1288 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1292 sub disable_extras (@)
1294 opendir my $dd, "src/modules/extra/";
1295 my @files = readdir($dd);
1298 EXTRA: for my $extra (@extras) {
1299 my $extrapath = "src/modules/extra/$extra";
1300 my $source = "src/modules/$extra";
1301 if (!-e $extrapath) {
1302 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1305 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1306 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";
1309 # Check if anything needs this.
1310 for my $file (@files) {
1311 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1312 # File depends on this extra...
1313 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1314 # And is both enabled and not about to be disabled.
1315 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1316 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1322 print "Disabling $extra ... \n";
1323 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";