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 LIBRARYDIR "$config{LIBRARY_DIR}"
940 #define ENTRYPOINT int main(int argc, char** argv)
943 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
945 if ($config{OSNAME} =~ /SunOS/i) {
946 print FILEHANDLE "#define IS_SOLARIS\n";
948 if ($config{OSNAME} =~ /MINGW32/i) {
949 print FILEHANDLE "#define IS_MINGW\n";
951 if ($config{GCCVER} >= 3) {
952 print FILEHANDLE "#define GCC3\n";
955 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
957 ($config{GCCVER} > 4)
959 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
961 if ($config{HAS_STRLCPY} eq "true") {
962 print FILEHANDLE "#define HAS_STRLCPY\n";
964 if ($config{HAS_STDINT} eq "true") {
965 print FILEHANDLE "#define HAS_STDINT\n";
967 if ($config{IPV6} =~ /y/i) {
968 print FILEHANDLE "#define IPV6\n";
970 if ($config{HAS_EVENTFD} eq 'true') {
971 print FILEHANDLE "#define HAS_EVENTFD\n";
974 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
975 print FILEHANDLE "#define USE_KQUEUE\n";
976 $config{SOCKETENGINE} = "socketengine_kqueue";
979 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
980 print FILEHANDLE "#define USE_EPOLL\n";
981 $config{SOCKETENGINE} = "socketengine_epoll";
984 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
985 print FILEHANDLE "#define USE_PORTS\n";
986 $config{SOCKETENGINE} = "socketengine_ports";
989 # user didn't choose either epoll or select for their OS.
990 # default them to USE_SELECT (ewwy puke puke)
992 print "no hi-perf, " . $config{USE_POLL};
993 if ($config{USE_POLL} eq "y")
995 print FILEHANDLE "#define USE_POLL\n";
996 $config{SOCKETENGINE} = "socketengine_poll";
1000 print FILEHANDLE "#define USE_SELECT\n";
1001 $config{SOCKETENGINE} = "socketengine_select";
1004 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1007 open(FILEHANDLE, ">include/inspircd_se_config.h.tmp");
1008 print FILEHANDLE <<EOF;
1009 /* Auto generated by configure, do not modify or commit to svn! */
1010 #ifndef __CONFIGURATION_SOCKETENGINE__
1011 #define __CONFIGURATION_SOCKETENGINE__
1013 #include "socketengines/$config{SOCKETENGINE}.h"
1019 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
1020 print FILEHANDLE <<EOF;
1021 #define VERSION "$version"
1022 #define REVISION "$revision2"
1023 #define SYSTEM "$incos"
1027 for my $file (qw(include/inspircd_config.h include/inspircd_se_config.h include/inspircd_version.h)) {
1029 open my $fh1, $file or $diff = 1;
1030 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1034 if (defined($line1) != defined($line2)) {
1036 } elsif (!defined $line1) {
1039 $diff = ($line1 ne $line2);
1044 rename "$file.tmp", $file;
1051 # Write all .in files.
1054 my $exe = "inspircd";
1056 # Do this once here, and cache it in the .*.inc files,
1057 # rather than attempting to read src/version.sh from
1058 # compiled code -- we might not have the source to hand.
1059 # Fix for bug#177 by Brain.
1061 chomp($version = `sh ./src/version.sh`);
1062 chomp(my $revision = getrevision());
1063 $version = "$version(r$revision)";
1065 # We can actually parse any file starting with . and ending with .inc,
1066 # but right now we only parse .inspircd.inc to form './inspircd'
1067 prepare_dynamic_makefile();
1069 print "Writing \e[1;32mMakefiles\e[0m\n";
1071 opendir(DIRHANDLE, $this);
1073 foreach my $name (sort readdir(DIRHANDLE)) {
1074 if ($name =~ /^\.(.+)\.inc$/) {
1077 # Bug #353, omit this on non-darwin
1078 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1080 # All .name.inc files need parsing!
1081 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1082 $_ = join '', <FILEHANDLE>;
1085 print "Writing \e[1;32m$file\e[0m ...\n";
1087 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR LIBRARY_DIR
1088 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE CORE_FLAGS
1090 s/\@$var\@/$config{$var}/g;
1092 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1093 s/\@VERSION\@/$version/ if defined $version;
1095 if ($file eq 'Makefile') {
1097 s/\@IFDEF (\S+)/ifdef $1/g;
1098 s/\@IFNDEF (\S+)/ifndef $1/g;
1099 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1100 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1103 s/ *\@BSD_ONLY .*\n//g;
1105 s/\@DO_EXPORT (.*)/export $1/g;
1106 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1110 s/\@IFDEF (\S+)/.if defined($1)/g;
1111 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1112 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1113 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1117 s/ *\@GNU_ONLY .*\n//g;
1119 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1120 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1124 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1125 print FILEHANDLE $_;
1130 closedir(DIRHANDLE);
1132 # Make inspircd executable!
1133 chmod 0744, 'inspircd';
1139 for my $mod (@modlist) {
1140 getcompilerflags("src/modules/m_$mod.cpp");
1141 getlinkerflags("src/modules/m_$mod.cpp");
1145 sub prepare_dynamic_makefile
1151 $config{USE_EPOLL} = 0;
1155 $config{USE_KQUEUE} = 0;
1159 $config{USE_PORTS} = 0;
1163 # Routine to list out the extra/ modules that have been enabled.
1164 # Note: when getting any filenames out and comparing, it's important to lc it if the
1165 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1166 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1167 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1168 sub list_extras () {
1171 my $srcdir = File::Spec->catdir("src", "modules");
1172 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1175 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1176 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1179 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1180 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1183 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1185 EXTRA: for my $extra (@extras) {
1186 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1187 next if ($extra eq '.svn');
1188 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1189 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1190 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1191 if (-l $abs_source) {
1192 # Symlink, is it in the right place?
1193 my $targ = readlink($abs_source);
1194 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1195 if ($abs_targ eq $abs_extra) {
1196 $extras{$extra} = "\e[32;1menabled\e[0m";
1198 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1200 } elsif (-e $abs_source) {
1201 my ($devext, $inoext) = stat($abs_extra);
1202 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1204 if ($devsrc == $devext && $inosrc == $inoext) {
1205 $extras{$extra} = "\e[32;1menabled\e[0m";
1207 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1210 open my $extfd, "<", $abs_extra;
1211 open my $srcfd, "<", $abs_source;
1213 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1214 $extras{$extra} = "\e[32;1menabled\e[0m";
1216 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1220 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1223 # Now let's add dependency info
1224 for my $extra (keys(%extras)) {
1225 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1226 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1227 my @deps = split / +/, getdependencies($abs_extra);
1228 for my $dep (@deps) {
1229 if (exists($extras{$dep})) {
1230 my $ref = \$extras{$dep}; # Take reference.
1231 if ($$ref !~ m/needed by/) {
1232 # First dependency found.
1233 if ($$ref =~ m/enabled/) {
1234 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1236 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1237 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1240 if ($$ref =~ m/enabled/) {
1241 $$ref .= ", \e[32;1m$extra\e[0m";
1243 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1249 for my $extra (sort {$a cmp $b} keys(%extras)) {
1250 my $text = $extras{$extra};
1251 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1252 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1254 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1257 return keys(%extras) if wantarray; # Can be used by manage_extras.
1260 sub enable_extras (@) {
1262 for my $extra (@extras) {
1263 my $extrapath = "src/modules/extra/$extra";
1264 if (!-e $extrapath) {
1265 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1268 my $source = "src/modules/$extra";
1270 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1273 # Get dependencies, and add them to be processed.
1274 my @deps = split / +/, getdependencies($extrapath);
1275 for my $dep (@deps) {
1276 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1277 if (!-e "src/modules/$dep") {
1278 if (-e "src/modules/extra/$dep") {
1279 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1282 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";
1286 print "Enabling $extra ... \n";
1287 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1291 sub disable_extras (@)
1293 opendir my $dd, "src/modules/extra/";
1294 my @files = readdir($dd);
1297 EXTRA: for my $extra (@extras) {
1298 my $extrapath = "src/modules/extra/$extra";
1299 my $source = "src/modules/$extra";
1300 if (!-e $extrapath) {
1301 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1304 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1305 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";
1308 # Check if anything needs this.
1309 for my $file (@files) {
1310 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1311 # File depends on this extra...
1312 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1313 # And is both enabled and not about to be disabled.
1314 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1315 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1321 print "Disabling $extra ... \n";
1322 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";