2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2010 The InspIRCd Development Team
6 # http://wiki.inspircd.org/Credits
8 # Licensed under GPL, please see the COPYING file
13 ###################################################
20 use warnings FATAL => qw(all);
24 $Data::Dumper::Sortkeys = 1;
25 $Data::Dumper::Useqq = 1;
33 # Utility functions for our buildsystem
37 use make::opensslcert;
39 ###############################################################################################
41 # NON-EDITABLE VARIABLES
43 ###############################################################################################
45 our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports,
46 $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue,
47 $opt_noipv6, $opt_maxbuf, $opt_disable_debug, $opt_freebsd_port,
48 $opt_system, $opt_uid);
50 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir);
54 sub enable_extras (@);
56 sub disable_extras (@);
59 my @opt_disableextras;
62 'enable-gnutls' => \$opt_use_gnutls,
63 'rebuild' => \$opt_rebuild,
64 'system' => \$opt_system,
66 'enable-openssl' => \$opt_use_openssl,
67 'disable-interactive' => \$opt_nointeractive,
68 'enable-ports' => \$opt_ports,
69 'enable-epoll' => \$opt_epoll,
70 'enable-kqueue' => \$opt_kqueue,
71 'disable-ports' => \$opt_noports,
72 'disable-epoll' => \$opt_noepoll,
73 'disable-kqueue' => \$opt_nokqueue,
74 'disable-ipv6' => \$opt_noipv6,
75 'with-cc=s' => \$opt_cc,
76 'with-maxbuf=i' => \$opt_maxbuf,
77 'enable-freebsd-ports-openssl' => \$opt_freebsd_port,
78 'prefix=s' => \$opt_base_dir,
79 'config-dir=s' => \$opt_config_dir,
80 'module-dir=s' => \$opt_module_dir,
81 'binary-dir=s' => \$opt_binary_dir,
82 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
83 'help' => sub { showhelp(); },
84 'update' => sub { update(); },
85 'svnupdate' => sub { svnupdate(); },
86 'clean' => sub { clean(); },
87 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
88 'enable-extras=s@' => \@opt_enableextras, # ^
89 'disable-extras=s@' => \@opt_disableextras, # ^
90 'generate-openssl-cert' => sub { make_openssl_cert(); exit(0); },
91 'generate-gnutls-cert' => sub { make_gnutls_cert(); exit(0); }
94 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
95 @opt_enableextras = split /,/, join(',', @opt_enableextras);
96 @opt_disableextras = split /,/, join(',', @opt_disableextras);
97 enable_extras(@opt_enableextras);
98 disable_extras(@opt_disableextras);
100 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
104 our $interactive = !(
105 (defined $opt_base_dir) ||
106 (defined $opt_config_dir) ||
107 (defined $opt_module_dir) ||
108 (defined $opt_base_dir) ||
109 (defined $opt_binary_dir) ||
110 (defined $opt_nointeractive) ||
112 (defined $opt_noipv6) ||
113 (defined $opt_kqueue) ||
114 (defined $opt_epoll) ||
115 (defined $opt_ports) ||
116 (defined $opt_use_openssl) ||
117 (defined $opt_nokqueue) ||
118 (defined $opt_noepoll) ||
119 (defined $opt_noports) ||
120 (defined $opt_maxbuf) ||
121 (defined $opt_system) ||
122 (defined $opt_uid) ||
123 (defined $opt_use_gnutls) ||
124 (defined $opt_freebsd_port)
127 chomp(our $topdir = getcwd());
128 our $this = resolve_directory($topdir); # PWD, Regardless.
129 our @modlist = (); # Declare for Module List..
130 our %config = (); # Initiate Configuration Hash..
131 $config{ME} = resolve_directory($topdir); # Present Working Directory
133 $config{BASE_DIR} = $config{ME}."/run";
135 if (defined $opt_base_dir) {
136 $config{BASE_DIR} = $opt_base_dir;
137 } elsif (defined $opt_system || defined $opt_uid) {
138 $config{BASE_DIR} = '/var/lib/inspircd';
141 if (defined $opt_system || defined $opt_uid) {
142 $config{UID} = $opt_uid || 'ircd';
143 $config{CONFIG_DIR} = '/etc/inspircd';
144 $config{MODULE_DIR} = '/usr/lib/inspircd';
145 $config{BINARY_DIR} = '/usr/sbin/';
146 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
149 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
150 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
151 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
152 $config{BUILD_DIR} = resolve_directory($config{ME}."/build"); # Build Directory
155 if (defined $opt_config_dir) {
156 $config{CONFIG_DIR} = $opt_config_dir;
158 if (defined $opt_module_dir) {
159 $config{MODULE_DIR} = $opt_module_dir;
161 if (defined $opt_binary_dir) {
162 $config{BINARY_DIR} = $opt_binary_dir;
164 chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
166 if (defined $opt_freebsd_port)
168 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`);
169 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`);
170 $config{USE_FREEBSD_BASE_SSL} = "n";
174 if ($^O eq "freebsd")
176 # default: use base ssl
177 chomp($config{HAS_OPENSSL} = `openssl version | cut -d ' ' -f 2`); # OpenSSL version, freebsd specific
178 chomp($config{HAS_OPENSSL_PORT} = `pkg-config --modversion openssl 2>/dev/null`); # Port version, may be different
182 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version, others
183 $config{HAS_OPENSSL_PORT} = "";
187 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
188 chomp(our $openssl_ver = $config{HAS_OPENSSL});
189 $config{USE_GNUTLS} = "n";
190 if (defined $opt_use_gnutls)
192 $config{USE_GNUTLS} = "y"; # Use gnutls.
194 $config{USE_OPENSSL} = "n"; # Use openssl.
195 if (defined $opt_use_openssl)
197 $config{USE_OPENSSL} = "y";
200 if (!defined $opt_disable_debug) {
201 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
203 $config{OPTIMISATI} = "-O2";
206 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
207 $config{HAS_STDINT} = "false"; # stdint.h check
208 $config{USE_KQUEUE} = "y"; # kqueue enabled
209 if (defined $opt_nokqueue) {
210 $config{USE_KQUEUE} = "n";
212 $config{USE_POLL} = "y"; # poll enabled
213 $config{USE_EPOLL} = "y"; # epoll enabled
214 if (defined $opt_noepoll)
216 $config{USE_EPOLL} = "n";
218 $config{USE_PORTS} = "y"; # epoll enabled
219 if (defined $opt_noports)
221 $config{USE_PORTS} = "n";
223 $config{IPV6} = "y"; # IPv6 support
224 if (defined $opt_noipv6)
228 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
229 $config{OSNAME} = $^O; # Operating System Name
230 $config{IS_DARWIN} = "NO"; # Is OSX?
231 $config{STARTSCRIPT} = "inspircd"; # start script?
232 $config{DESTINATION} = "BASE"; # Is target path.
233 $config{EXTRA_DIR} = ""; # Is empty.
234 if ($config{OSNAME} =~ /darwin/i)
236 $config{IS_DARWIN} = "YES";
237 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
239 $config{CC} = "g++"; # C++ compiler
242 $config{CC} = $opt_cc;
244 our $exec = $config{CC} . " -dumpversion | cut -c 1";
245 chomp($config{GCCVER} = `$exec`); # Major GCC Version
246 $exec = $config{CC} . " -dumpversion | cut -c 3";
247 chomp($config{GCCMINOR} = `$exec`);
248 $config{MAXBUF} = "512"; # Max buffer size
250 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
251 $config{HAS_OPENSSL} = $1;
253 $config{HAS_OPENSSL} = "";
256 if (($config{GCCVER} eq "") || ($config{GCCMINOR} eq "")) {
257 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
261 # Get and Set some important vars..
266 unlink(".config.cache");
269 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
274 chomp($topdir = getcwd());
275 $this = resolve_directory($topdir); # PWD, Regardless.
277 # Does the cache file exist?
279 # No, No it doesn't.. *BASH*
280 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
283 # We've Loaded the cache file and all our variables..
284 print "Updating files...\n";
285 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
287 print "Disabling debug information (-g).\n";
288 $config{OPTIMISATI} = "";
290 $has_epoll = $config{HAS_EPOLL};
291 $has_ports = $config{HAS_PORTS};
292 $has_kqueue = $config{HAS_KQUEUE};
301 print "Configure update failed: $@\n";
309 open(FH,"<.svn/entries") or $fail = 1;
311 print "This is not an SVN copy of InspIRCd.\n";
318 open my $fd, "-|", "svn update";
319 my $configurechanged = 0; # Needs ./configure -update
320 my $rootincchanged = 0;
322 while (defined(my $line = <$fd>))
326 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
327 ($action, $file) = ($1, $2);
330 push @conflicted, $file;
331 if ($file eq "configure")
333 $configurechanged = 1;
335 elsif ($file =~ m/^\..*\.inc$/)
340 elsif ($action eq "U" || $action eq "G")
342 if ($file eq "configure")
344 $configurechanged = 1;
346 elsif ($file =~ m/^\..*\.inc$/)
352 unless (close $fd) # close() waits for exit and returns false if the command failed
356 print STDERR "Problem updating from SVN, please check above for errors\n";
360 print STDERR "Failed to run SVN: $!\n";
364 if (scalar(@conflicted) > 0)
366 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
367 print STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -update\n";
368 print "Conflicted files: " . join ", ", @conflicted . "\n";
371 if ($configurechanged)
373 system("perl configure -update");
377 print "No need to update Makefiles.\n";
379 if (defined $opt_rebuild) {
380 system("make install");
388 $fail ||= system "$config{CC} -o test_$feature make/check_$feature.cpp >/dev/null 2>&1";
389 $fail ||= system "./test_$feature";
390 unlink "test_$feature";
394 print "Running non-interactive configure...\n" unless $interactive;
395 print "Checking for cache from previous configure... ";
396 print ((!getcache()) ? "not found\n" : "found\n");
397 $config{SYSTEM} = lc $^O;
398 print "Checking operating system version... $config{SYSTEM}\n";
400 $exec = $config{CC} . " -dumpversion | cut -c 1";
401 chomp($config{GCCVER} = `$exec`); # Major GCC Version
402 $exec = $config{CC} . " -dumpversion | cut -c 3";
403 chomp($config{GCCMINOR} = `$exec`);
405 printf "Checking if stdint.h exists... ";
406 $config{HAS_STDINT} = "true";
408 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
409 if ($config{HAS_STDINT} eq "true") {
412 print "yes\n" if $config{HAS_STDINT} eq "true";
413 print "no\n" if $config{HAS_STDINT} eq "false";
415 printf "Checking if strlcpy exists... ";
416 # Perform the strlcpy() test..
417 $config{HAS_STRLCPY} = "false";
419 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
421 while (defined(my $line = <STRLCPY>)) {
423 # try and find the delcaration of:
424 # size_t strlcpy(...)
425 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
426 $config{HAS_STRLCPY} = "true";
431 print "yes\n" if $config{HAS_STRLCPY} eq "true";
432 print "no\n" if $config{HAS_STRLCPY} eq "false";
434 printf "Checking if kqueue exists... ";
437 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
439 while (defined(my $line = <KQUEUE>)) {
441 # try and find the delcaration of:
443 if ($line =~ /int(\0x9|\s)+kqueue/) {
449 print "yes\n" if $has_kqueue == 1;
450 print "no\n" if $has_kqueue == 0;
452 printf "Checking for epoll support... ";
453 $has_epoll = test_compile('epoll');
454 print $has_epoll ? "yes\n" : "no\n";
456 printf "Checking for eventfd support... ";
457 $config{HAS_EVENTFD} = test_compile('eventfd') ? 'true' : 'false';
458 print $config{HAS_EVENTFD} eq 'true' ? "yes\n" : "no\n";
460 printf "Checking if Solaris I/O completion ports are available... ";
462 our $system = `uname -s`;
464 $has_ports = 1 if ($system eq "SunOS");
467 my $kernel = `uname -r`;
469 if (($kernel !~ /^5\.1./)) {
473 print "yes\n" if $has_ports == 1;
474 print "no\n" if $has_ports == 0;
476 $config{HAS_EPOLL} = $has_epoll;
477 $config{HAS_KQUEUE} = $has_kqueue;
479 printf "Checking for libgnutls... ";
480 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
481 if (defined($gnutls_ver) && ($gnutls_ver ne "")) {
483 $config{HAS_GNUTLS} = "y";
486 $config{HAS_GNUTLS} = "n";
490 $config{HAS_GNUTLS} = "n";
493 printf "Checking for openssl... ";
494 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
495 if (defined($openssl_ver) && ($openssl_ver ne "")) {
497 $config{HAS_OPENSSL} = "y";
500 $config{HAS_OPENSSL} = "n";
504 $config{HAS_OPENSSL} = "n";
507 printf "Checking if you are running an ancient, unsupported OS... ";
508 if ($config{OSNAME} =~ /FreeBSD/i)
510 my $version = `uname -r`;
511 if ($version =~ /^4\./)
514 print "FreeBSD 4.x is no longer supported. By ANYONE.\n";
515 print "To build, you will need to add the following to CXXFLAGS:\n";
516 print "\t-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1\n";
520 print "no ($version)\n";
525 print "no ($config{OSNAME})\n";
528 ################################################################################
529 # BEGIN INTERACTIVE PART #
530 ################################################################################
535 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
538 my $rev = getrevision();
539 # Display Introduction Message..
541 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
542 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
544 *** If you are unsure of any of these values, leave it blank for ***
545 *** standard settings that will work, and your server will run ***
546 *** using them. Please consult your IRC network admin if in doubt. ***
548 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
549 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
550 dir, otherwise you won't have a config file!
552 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
553 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
556 print " (Non-SVN build)";
560 $config{CHANGE_COMPILER} = "n";
561 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";
563 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
564 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
565 should NOT be used. You should probably specify a newer compiler.\n\n";
566 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
567 if ($config{CHANGE_COMPILER} =~ /y/i) {
568 print "What command do you want to use to invoke your compiler?\n";
569 print "[\e[1;32m$config{CC}\e[0m] -> ";
570 chomp($config{CC} = <STDIN>);
571 if ($config{CC} eq "") {
574 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
576 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
577 chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`);
578 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n";
579 if ($config{GCCVER} < 3) {
580 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
584 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
591 # Directory Settings..
592 my $tmpbase = $config{BASE_DIR};
593 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
594 if ($tmpbase ne $config{BASE_DIR}) {
595 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
596 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
597 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
600 dir_check("are the configuration files", "CONFIG_DIR");
601 dir_check("are the modules to be compiled to", "MODULE_DIR");
602 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
603 dir_check("do you want the build to take place", "BUILD_DIR");
605 my $chose_hiperf = 0;
607 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?");
609 if ($config{USE_KQUEUE} eq "y") {
614 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?");
616 if ($config{USE_EPOLL} eq "y") {
621 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?");
623 if ($config{USE_PORTS} eq "y") {
628 if (!$chose_hiperf) {
629 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?");
630 if ($config{USE_POLL} ne "y")
632 print "No high-performance socket engines are available, or you chose\n";
633 print "not to enable one. Defaulting to select() engine.\n\n";
637 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?\nYou can still use IPv4 addresses in your port bindings.\n\nEnable IPv6?");
640 $config{USE_FREEBSD_BASE_SSL} = "n";
641 $config{USE_FREEBSD_PORTS_SSL} = "n";
642 if ($config{HAS_OPENSSL_PORT} ne "")
644 $config{USE_FREEBSD_PORTS_SSL} = "y";
645 print "I have detected the OpenSSL FreeBSD port installed on your system,\n";
646 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";
647 yesno('USE_FREEBSD_PORTS_SSL', "Do you want to use the FreeBSD ports version?");
649 $config{USE_FREEBSD_BASE_SSL} = "y" if ($config{USE_FREEBSD_PORTS_SSL} eq "n");
651 if ($config{USE_FREEBSD_BASE_SSL} eq "n")
653 # update to port version
654 $openssl_ver = $config{HAS_OPENSSL_PORT};
659 $config{USE_FREEBSD_BASE_SSL} = "y" if ($^O eq "freebsd");
662 $config{USE_SSL} = "n";
663 $config{MODUPDATE} = 'n';
665 if ($config{HAS_GNUTLS} eq "y" || $config{HAS_OPENSSL} eq "y")
667 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
668 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
670 yesno('USE_SSL', "One or more SSL libraries detected. Would you like to enable SSL support?");
671 if ($config{USE_SSL} eq "y")
673 if ($config{HAS_GNUTLS} eq "y")
675 yesno('USE_GNUTLS',"Would you like to enable SSL with m_ssl_gnutls? (recommended)");
676 if ($config{USE_GNUTLS} eq "y")
678 print "\nUsing GnuTLS SSL module.\n";
682 if ($config{HAS_OPENSSL} eq "y")
684 yesno('USE_OPENSSL', "Would you like to enable SSL with m_ssl_openssl?");
685 if ($config{USE_OPENSSL} eq "y")
687 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
694 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\n";
695 print "you intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
698 yesno('MODUPDATE',"Would you like to check for updates to third-party modules?");
700 if ($config{MODUPDATE} eq "y") {
701 print "Checking for upgrades to extra and third party modules... ";
702 system "./modulemanager upgrade";
708 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
710 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
713 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
715 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
720 $config{CERTGEN} ||= 'y';
721 yesno('CERTGEN',"Would you like generate SSL certificates now?") if ($interactive && ($config{USE_GNUTLS} eq "y" || $config{USE_OPENSSL} eq "y"));
723 if ($config{USE_GNUTLS} eq "y") {
724 unless (-r "src/modules/m_ssl_gnutls.cpp") {
725 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
726 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
728 if ($interactive && $config{CERTGEN} eq 'y')
730 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
731 print "SSL Certificates Not found, Generating.. \n\n
732 *************************************************************
733 * Generating the Private Key may take some time, go grab a *
734 * Coffee. Even better, to generate some more entropy if it *
735 * is taking a while, open another console and type du / a *
736 * few times and get that HD going :) Then answer the *
737 * Questions which follow. If you are unsure, just hit enter *
738 *************************************************************\n\n";
739 $failed = make_gnutls_cert();
741 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
743 print "\nCertificate generation complete, copying to config directory... ";
744 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
745 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
750 print "SSL Certificates found, skipping.\n\n";
755 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
759 if ($config{USE_OPENSSL} eq "y") {
760 unless (-r "src/modules/m_ssl_openssl.cpp") {
761 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
762 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
765 if ($interactive && $config{CERTGEN} eq 'y')
767 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
768 print "SSL Certificates Not found, Generating.. \n\n
769 *************************************************************
770 * Generating the certificates may take some time, go grab a *
771 * coffee, or something. *
772 *************************************************************\n\n";
774 print "\nCertificate generation complete, copying to config directory... ";
775 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
776 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
777 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
780 print "SSL Certificates found, skipping.\n\n"
785 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
788 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
789 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
797 print "To build your server with these settings, please run '\e[1;32mmake\e[0m' now.\n";
798 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
799 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
800 print "modules in your config. This configure script has added those modules to the\n";
801 print "build process. For more info please refer to:\n";
802 print "\e[1;32mhttp://wiki.inspircd.org/Installation_From_Tarball\e[0m\n";
804 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
805 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
806 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";
809 if ($config{GCCVER} < "3") {
811 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
812 GCC 2.x series compilers only had partial (read as broken) C++ support, and
813 your compile will most likely fail horribly! If you have any problems, do NOT
814 report them to the bugtracker or forums without first upgrading your compiler
815 to a newer 3.x or 4.x (or whatever is available currently) version.
819 ################################################################################
821 ################################################################################
823 # Retrieves the .config.cache file, and loads values into the main config hash.
824 open(CACHE, ".config.cache") or return 0;
827 # Ignore Blank lines, and comments..
830 my ($key, $value) = split("=", $_, 2);
831 $value =~ /^\"(.*)\"$/;
832 # Do something with data here!
840 # Dump the contents of %config
841 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
842 open(FILEHANDLE, ">.config.cache");
843 foreach my $key (keys %config) {
844 print FILEHANDLE "$key=\"$config{$key}\"\n";
850 my ($desc, $hash_key) = @_;
853 print "In what directory $desc?\n";
854 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
855 chomp(my $var = <STDIN>);
857 $var = $config{$hash_key};
859 if ($var =~ /^\~\/(.+)$/) {
860 # Convert it to a full path..
861 $var = resolve_directory($ENV{HOME} . "/" . $1);
863 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
865 # Assume relative Path was given.. fill in the rest.
866 $var = $this . "/$var";
869 $var = resolve_directory($var);
871 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
872 chomp(my $tmp = <STDIN>);
873 if (($tmp eq "") || ($tmp =~ /^y/i)) {
874 # Attempt to Create the Dir..
877 File::Path::mkpath($var, 0, 0777);
880 unless (defined($chk) && -d $var) {
881 print "Unable to create directory. ($var)\n\n";
886 # They said they don't want to create, and we can't install there.
892 # Target exists, but is not a directory.
893 print "File $var exists, but is not a directory.\n\n";
897 # Either Dir Exists, or was created fine.
898 $config{$hash_key} = $var;
906 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
909 my($writeheader) = @_;
910 # First File.. inspircd_config.h
911 chomp(my $incos = `uname -n -s -r`);
912 chomp(my $version = `sh src/version.sh`);
913 chomp(my $revision2 = getrevision());
914 if ($writeheader == 1)
916 print "Writing \e[1;32minspircd_config.h\e[0m\n";
917 open(FILEHANDLE, ">include/inspircd_config.h.tmp");
918 print FILEHANDLE <<EOF;
919 /* Auto generated by configure, do not modify! */
920 #ifndef __CONFIGURATION_AUTO__
921 #define __CONFIGURATION_AUTO__
923 /* this is for windows support. */
924 #define CoreExport /**/
925 #define DllExport /**/
927 #define MOD_PATH "$config{MODULE_DIR}"
928 #define SOMAXCONN_S "$config{_SOMAXCONN}"
929 #define ENTRYPOINT int main(int argc, char** argv)
932 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
934 if ($config{OSNAME} =~ /SunOS/i) {
935 print FILEHANDLE "#define IS_SOLARIS\n";
937 if ($config{OSNAME} =~ /MINGW32/i) {
938 print FILEHANDLE "#define IS_MINGW\n";
940 if ($config{GCCVER} >= 3) {
941 print FILEHANDLE "#define GCC3\n";
944 (($config{GCCVER} == 4) && ($config{GCCMINOR} >= 3))
946 ($config{GCCVER} > 4)
948 print FILEHANDLE "#define HASHMAP_DEPRECATED\n";
950 if ($config{HAS_STRLCPY} eq "true") {
951 print FILEHANDLE "#define HAS_STRLCPY\n";
953 if ($config{HAS_STDINT} eq "true") {
954 print FILEHANDLE "#define HAS_STDINT\n";
956 if ($config{IPV6} =~ /y/i) {
957 print FILEHANDLE "#define IPV6\n";
959 if ($config{HAS_EVENTFD} eq 'true') {
960 print FILEHANDLE "#define HAS_EVENTFD\n";
963 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
964 print FILEHANDLE "#define USE_KQUEUE\n";
965 $config{SOCKETENGINE} = "socketengine_kqueue";
968 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
969 print FILEHANDLE "#define USE_EPOLL\n";
970 $config{SOCKETENGINE} = "socketengine_epoll";
973 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
974 print FILEHANDLE "#define USE_PORTS\n";
975 $config{SOCKETENGINE} = "socketengine_ports";
978 # user didn't choose either epoll or select for their OS.
979 # default them to USE_SELECT (ewwy puke puke)
981 print "no hi-perf, " . $config{USE_POLL};
982 if ($config{USE_POLL} eq "y")
984 print FILEHANDLE "#define USE_POLL\n";
985 $config{SOCKETENGINE} = "socketengine_poll";
989 print FILEHANDLE "#define USE_SELECT\n";
990 $config{SOCKETENGINE} = "socketengine_select";
993 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
996 open(FILEHANDLE, ">include/inspircd_version.h.tmp");
997 print FILEHANDLE <<EOF;
998 #define VERSION "$version"
999 #define REVISION "$revision2"
1000 #define SYSTEM "$incos"
1004 for my $file (qw(include/inspircd_config.h include/inspircd_version.h)) {
1006 open my $fh1, $file or $diff = 1;
1007 open my $fh2, $file.'.tmp' or die "Can't read $file.tmp that we just wrote: $!";
1011 if (defined($line1) != defined($line2)) {
1013 } elsif (!defined $line1) {
1016 $diff = ($line1 ne $line2);
1021 rename "$file.tmp", $file;
1028 # Write all .in files.
1031 my $exe = "inspircd";
1033 # Do this once here, and cache it in the .*.inc files,
1034 # rather than attempting to read src/version.sh from
1035 # compiled code -- we might not have the source to hand.
1036 # Fix for bug#177 by Brain.
1038 chomp($version = `sh ./src/version.sh`);
1039 chomp(my $revision = getrevision());
1040 $version = "$version(r$revision)";
1042 # We can actually parse any file starting with . and ending with .inc,
1043 # but right now we only parse .inspircd.inc to form './inspircd'
1044 prepare_dynamic_makefile();
1046 my @dotfiles = qw(main.mk inspircd);
1047 push @dotfiles, 'org.inspircd.plist' if $config{OSNAME} eq 'darwin';
1049 foreach my $file (@dotfiles) {
1050 open(FILEHANDLE, "make/template/$file") or die "Can't open make/template/$file: $!";
1051 $_ = join '', <FILEHANDLE>;
1054 $config{BUILD_DIR} ||= resolve_directory($config{ME}."/build");
1057 CC SYSTEM BASE_DIR CONFIG_DIR MODULE_DIR BINARY_DIR BUILD_DIR UID
1058 STARTSCRIPT DESTINATION EXTRA_DIR SOCKETENGINE
1060 s/\@$var\@/$config{$var}/g;
1062 s/\@EXECUTABLE\@/$exe/ if defined $exe;
1063 s/\@VERSION\@/$version/ if defined $version;
1065 if ($file eq 'main.mk') {
1066 print "Writing \e[1;32mGNUmakefile\e[0m ...\n";
1069 s/\@IFDEF (\S+)/ifdef $1/g;
1070 s/\@IFNDEF (\S+)/ifndef $1/g;
1071 s/\@IFEQ (\S+) (\S+)/ifeq ($1,$2)/g;
1072 s/\@ELSIFEQ (\S+) (\S+)/else ifeq ($1,$2)/g;
1075 s/ *\@BSD_ONLY .*\n//g;
1077 s/\@DO_EXPORT (.*)/export $1/g;
1078 open MKF, '>GNUmakefile' or die "Can't write to GNUmakefile: $!";
1082 print "Writing \e[1;32mBSDmakefile\e[0m ...\n";
1084 s/\@IFDEF (\S+)/.if defined($1)/g;
1085 s/\@IFNDEF (\S+)/.if !defined($1)/g;
1086 s/\@IFEQ (\S+) (\S+)/.if $1 == $2/g;
1087 s/\@ELSIFEQ (\S+) (\S+)/.elif $1 == $2/g;
1091 s/ *\@GNU_ONLY .*\n//g;
1093 $mk_tmp =~ s#\@DO_EXPORT (.*)#"MAKEENV += ".join ' ', map "$_='\${$_}'", split /\s/, $1#eg;
1094 open MKF, '>BSDmakefile' or die "Can't write to BSDmakefile: $!";
1098 print "Writing \e[1;32m$file\e[0m ...\n";
1099 open(FILEHANDLE, ">$file") or die("Can't write to $file: $!\n");
1100 print FILEHANDLE $_;
1105 chmod 0755, 'inspircd';
1111 for my $mod (@modlist) {
1112 getcompilerflags("src/modules/m_$mod.cpp");
1113 getlinkerflags("src/modules/m_$mod.cpp");
1117 sub prepare_dynamic_makefile
1123 $config{USE_EPOLL} = 0;
1127 $config{USE_KQUEUE} = 0;
1131 $config{USE_PORTS} = 0;
1135 # Routine to list out the extra/ modules that have been enabled.
1136 # Note: when getting any filenames out and comparing, it's important to lc it if the
1137 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1138 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1139 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1140 sub list_extras () {
1143 my $srcdir = File::Spec->catdir("src", "modules");
1144 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1147 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1148 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1151 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1152 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1155 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1157 EXTRA: for my $extra (@extras) {
1158 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1159 next if ($extra eq '.svn');
1160 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1161 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1162 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1163 if (-l $abs_source) {
1164 # Symlink, is it in the right place?
1165 my $targ = readlink($abs_source);
1166 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1167 if ($abs_targ eq $abs_extra) {
1168 $extras{$extra} = "\e[32;1menabled\e[0m";
1170 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1172 } elsif (-e $abs_source) {
1173 my ($devext, $inoext) = stat($abs_extra);
1174 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1176 if ($devsrc == $devext && $inosrc == $inoext) {
1177 $extras{$extra} = "\e[32;1menabled\e[0m";
1179 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1182 open my $extfd, "<", $abs_extra;
1183 open my $srcfd, "<", $abs_source;
1185 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1186 $extras{$extra} = "\e[32;1menabled\e[0m";
1188 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1192 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1195 # Now let's add dependency info
1196 for my $extra (keys(%extras)) {
1197 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1198 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1199 my @deps = split / +/, getdependencies($abs_extra);
1200 for my $dep (@deps) {
1201 if (exists($extras{$dep})) {
1202 my $ref = \$extras{$dep}; # Take reference.
1203 if ($$ref !~ m/needed by/) {
1204 # First dependency found.
1205 if ($$ref =~ m/enabled/) {
1206 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1208 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1209 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1212 if ($$ref =~ m/enabled/) {
1213 $$ref .= ", \e[32;1m$extra\e[0m";
1215 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1221 for my $extra (sort {$a cmp $b} keys(%extras)) {
1222 my $text = $extras{$extra};
1223 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1224 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1226 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1229 return keys(%extras) if wantarray; # Can be used by manage_extras.
1232 sub enable_extras (@) {
1234 for my $extra (@extras) {
1235 my $extrapath = "src/modules/extra/$extra";
1236 if (!-e $extrapath) {
1237 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1240 my $source = "src/modules/$extra";
1242 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1245 # Get dependencies, and add them to be processed.
1246 my @deps = split / +/, getdependencies($extrapath);
1247 for my $dep (@deps) {
1248 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1249 if (!-e "src/modules/$dep") {
1250 if (-e "src/modules/extra/$dep") {
1251 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1254 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";
1258 print "Enabling $extra ... \n";
1259 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1263 sub disable_extras (@)
1265 opendir my $dd, "src/modules/extra/";
1266 my @files = readdir($dd);
1269 EXTRA: for my $extra (@extras) {
1270 my $extrapath = "src/modules/extra/$extra";
1271 my $source = "src/modules/$extra";
1272 if (!-e $extrapath) {
1273 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1276 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1277 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";
1280 # Check if anything needs this.
1281 for my $file (@files) {
1282 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1283 # File depends on this extra...
1284 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1285 # And is both enabled and not about to be disabled.
1286 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1287 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1293 print "Disabling $extra ... \n";
1294 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";