#!/usr/bin/perl # InspIRCd Configuration Script # # Copyright 2003 The ChatSpike Development Team # # # # [14:21] Brain: i know perl-fu! # # $Id$ # ######################################## chomp($topdir = `pwd`); $this = resolve_directory($topdir); # PWD, Regardless. @modlist = (); # Declare for Module List.. %config = (); # Initiate Configuration Hash.. $config{ME} = resolve_directory($topdir); # Present Working Directory $config{BASE_DIR} = $config{ME}; # Use CWD as 'Base' Directory. $config{CONFIG_DIR} = resolve_directory($config{ME}."/conf"); # Configuration Directory $config{MODULE_DIR} = resolve_directory($config{ME}."/modules"); # Modules Directory $config{BINARY_DIR} = resolve_directory($config{ME}."/bin"); # Binary Directory $config{LIBRARY_DIR} = resolve_directory($config{ME}."/lib"); # Library Directory chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version. chomp($config{HAS_OPENSSL} = `openssl version 2>/dev/null`); # Openssl version $config{USE_GNUTLS} = "n"; # Use gnutls. $config{USE_OPENSSL} = "n"; # Use openssl. $config{OPTIMITEMP} = "0"; # Default Optimisation Value $config{OPTIMISATI} = "-g"; # Optimisation Flag $config{NICK_LENGT} = "31"; # Default Nick Length $config{CHAN_LENGT} = "64"; # Default Channel Name Length $config{MAX_CHANNE} = "20"; # Default Max. Channels per user $config{MAX_OPERCH} = "60"; # Default Max. Channels per oper $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once. $config{HAS_STRLCPY} = "false"; # strlcpy Check. $config{USE_KQUEUE} = "y"; # kqueue enabled $config{USE_EPOLL} = "y"; # epoll enabled $config{THREADED_DNS} = "n"; # threaded dns (experimental) $config{STATIC_LINK} = "no"; # are doing static modules? chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit chomp($config{GCCVER} = `gcc -dumpversion | cut -c 1`); # Major GCC Version chomp($config{GCC34} = `gcc -dumpversion | cut -c 3`); # Minor GCC Version chomp($config{OSNAME} = `/bin/uname`); # Operating System Name $config{CC} = "g++"; # C++ compiler $config{MAKEORDER} = "ircd mods config bininst"; # build order $config{STATICLIBS} = ""; # library archive path $config{MAX_IDENT} = "12"; # max ident size $config{MAX_QUIT} = "255"; # max quit message size $config{MAX_TOPIC} = "307"; # max topic size $config{MAX_KICK} = "255"; # max kick message size $config{MAX_GECOS} = "128"; # max GECOS size $config{MAX_AWAY} = "200"; # max AWAY size $config{HAS_OPENSSL} =~ /OpenSSL (\S+) \d+ \S+ \d{4}/; $config{HAS_OPENSSL} = $1; # Minihack! Convert Cygwin to 'Cyg-Static' so i can # Keep my dynamic module experiments here for later # concideration! if ($config{OSNAME} =~ /CYGWIN/) { $config{OSNAME} = "CYG-STATIC"; } if ((!$config{OSNAME}) || ($config{OSNAME} eq "")) { chomp($config{OSNAME} = `/usr/bin/uname`); if ((!$config{OSNAME}) || ($config{OSNAME} eq "")){ $config{OSNAME} = "Unknown"; } } if (!$config{MAX_CLIENT_T}) { $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default' $fd_scan_fail = "true"; # Used Later } # Get and Set some important vars.. getmodules(); my $arg = $ARGV[0]; # Do Some Argument Checks.. if ($arg eq "-clean") { system("rm -rf .config.cache"); } # Remove the config.cache file. if ($arg eq "-update") { # Does the cache file exist? if (!getcache()) { # No, No it doesn't.. *BASH* print "You have not run ./configure before. Please do this before trying to run the update script.\n"; exit 0; } else { # We've Loaded the cache file and all our variables.. print "Updating Files..\n"; getosflags(); $has_epoll = $config{HAS_EPOLL}; $has_kqueue = $config{HAS_KQUEUE}; writefiles(); print "Complete.\n"; exit; } } if ($arg eq "-modupdate") { # Does the cache file exist? if (!getcache()) { # No, No it doesn't.. *BASH* print "You have not run ./configure before. Please do this before trying to run the update script.\n"; exit 0; } else { # We've Loaded the cache file and all our variables.. print "Updating Files..\n"; getosflags(); $has_epoll = $config{HAS_EPOLL}; $has_kqueue = $config{HAS_KQUEUE}; if ($config{STATIC_LINK} eq "yes") { write_static_modules_makefile(); } else { write_dynamic_modules_makefile(); } print "Complete.\n"; exit; } } print "Checking for cache from previous configure...\n"; getcache(); print "Checking operating system version...\n"; getosflags(); if (!$config{MAX_CLIENT}) { # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go # higher than the found value" :)) $config{MAX_CLIENT} = $config{MAX_CLIENT_T}; } printf "Checking if strlcpy exists... "; # Perform the strlcpy() test.. $config{HAS_STRLCPY} = "false"; my $fail = 0; open(STRLCPY, ")) { # try and find the delcaration of: # size_t strlcpy(...) if ($line =~ /size_t(\0x9|\s)+strlcpy/) { $config{HAS_STRLCPY} = "true"; } } close(STRLCPY); } print "yes\n" if $config{HAS_STRLCPY} eq "true"; print "no\n" if $config{HAS_STRLCPY} eq "false"; printf "Checking if kqueue exists... "; $has_kqueue = 0; $fail = 0; open(KQUEUE, ")) { # try and find the delcaration of: # int kqueue(void); if ($line =~ /int(\0x9|\s)+kqueue/) { $has_kqueue = 1; } } close(KQUEUE); } print "yes\n" if $has_kqueue == 1; print "no\n" if $has_kqueue == 0; printf "Checking if epoll exists... "; $has_epoll = 0; $fail = 0; open(EPOLL, ")) { # try and find the declaration of: # extern int epoll_create (int __size) __THROW; if (($line =~ /int(\0x9|\s)+epoll_create(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+epoll_create\(/)) { $has_epoll = 1; } } close(EPOLL); } if ($has_epoll) { my $kernel = `uname -r`; chomp($kernel); if (($kernel =~ /2\.0/) || ($kernel =~ /2\.2/) || ($kernel =~ /2\.4/)) { $has_epoll = 0; } } print "yes\n" if $has_epoll == 1; print "no\n" if $has_epoll == 0; if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) { $config{HAS_STRLCPY} = "true"; } $config{HAS_EPOLL} = $has_epoll; $config{HAS_KQUEUE} = $has_kqueue; printf "Checking for libgnutls... "; if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) { print "yes\n"; $config{HAS_GNUTLS} = "y"; } else { print "no\n"; $config{HAS_GNUTLS} = "n"; } printf "Checking for openssl... "; if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) { print "yes\n"; $config{HAS_OPENSSL} = "y"; } else { print "no\n"; $config{HAS_OPENSSL} = "n"; } ################################################################################ # BEGIN INTERACTIVE PART # ################################################################################ # Clear the Screen.. system("clear"); # Display Splash Logo.. show_splash(); chomp($wholeos = `uname -mnr`); # Display Introduction Message.. print " Welcome to the InspIRCd Configuration program! *** If you are unsure of any of these values, leave it blank for *** *** standard settings that will work, and your server will run *** *** using them. If you are running this server as part of a *** *** larger network, you must consult with your network admins *** *** for the proper values to use, or server links will be unstable! *** Press \033[1m\033[0m to accept the default for any option, or enter a new value. Please note: You will \033[1mHAVE\033[0m to read the docs dir, otherwise you won't have a config file! Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n"; $config{CHANGE_COMPILER} = "n"; print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.$config{GCC34}\033[0m)\n"; while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) { print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and should NOT be used. You should probably specify a newer compiler.\n\n"; yesno(CHANGE_COMPILER,"Do you want to change the compiler?"); if ($config{CHANGE_COMPILER} =~ /y/i) { print "What command do you want to use to invoke your compiler?\n"; print "[\033[1;32m$config{CC}\033[0m] -> "; chomp($config{CC} = ); if ($config{CC} eq "") { $config{CC} = "g++"; } chomp($foo = `$config{CC} -dumpversion | cut -c 1`); if ($foo ne "") { chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change chomp($config{GCC34} = `$config{CC} -dumpversion | cut -c 3`); # the compiler path print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.$config{GCC34}\033[0m)\n"; if ($config{GCCVER} < 3) { print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n"; } } else { print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n"; } } } print "\n"; # Directory Settings.. my $tmpbase = $config{BASE_DIR}; dir_check("do you wish to install the InspIRCd base", "BASE_DIR"); if ($tmpbase ne $config{BASE_DIR}) { $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory } dir_check("are the configuration files", "CONFIG_DIR"); dir_check("are the modules to be compiled to", "MODULE_DIR"); dir_check("is the IRCd binary to be placed", "BINARY_DIR"); dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR"); if ($has_kqueue) { 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?"); print "\n"; } if ($has_epoll) { 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?"); print "\n"; } $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y")); if (!$chose_hiperf) { print "No high-performance socket engines are available, or you chose\n"; print "not to enable one. Defaulting to select() engine.\n\n"; } yesno(THREADED_DNS,"Would you like to enable the experimental multi-threaded DNS lookup?"); print "\n"; if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) { print "I have detected both GnuTLS and OpenSSL on your system.\n"; print "I will default to GnuTLS. If you wish to use OpenSSL\n"; print "instead, you should enable the OpenSSL module yourself\n"; print "by copying it from src/modules/extra to src/modules.\n\n"; } if ($config{HAS_GNUTLS} eq "y") { yesno(USE_GNUTLS, "Would you like to enable SSL Support?"); if ($config{USE_GNUTLS} eq "y") { print "\nUsing GnuTLS SSL module.\n"; } } elsif ($config{HAS_OPENSSL} eq "y") { yesno(USE_OPENSSL, "Would you like to enable SSL Support?"); if ($config{USE_OPENSSL} eq "y") { print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n"; } } print "\nThe following questions will ask you for various figures relating\n"; print "To your IRCd install. Please note that these should usually be left\n"; print "as defaults unless you have a real reason to change them. If they\n"; print "changed, then the values must be identical on all servers on your\n"; print "network, or malfunctions and/or crashes may occur, with the exception\n"; print "of the 'maximum number of clients' setting which may be different on\n"; print "different servers on the network.\n\n"; # File Descriptor Settings.. my $continue = 0; while (!$continue) { print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n"; print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_CLIENT}; } if ($var =~ /^\d+$/) { if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) { # Client has entered a larger number than the 'discovered' value # Confirm. print "WARNING: Our scans have indicated that you are attempting to use more sockets than there are avaliable. Are you sure you wish to do this? It may cause the IRCd to malfunction [y/n] [\033[1;32mn\033[0m] -> $c"; chomp($tmp = ); if ($tmp ne "y") { print "Please enter the correct value.\n\n"; next; } } } else { print "You must enter a number in this field. Please try again.\n\n"; next; } # If we get here, we should be good to go. $config{MAX_CLIENT} = $var; $continue = 1; print "\n"; } my $continue = 0; while (!$continue) { print "What is the maximum length of nicknames?\n"; print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{NICK_LENGT}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{NICK_LENGT} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of channel names?\n"; print "[\033[1;32m$config{CHAN_LENGT}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{CHAN_LENGT}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{CHAN_LENGT} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum number of channels a normal user may join at any one time?\n"; print "[\033[1;32m$config{MAX_CHANNE}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_CHANNE}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_CHANNE} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum number of channels an oper may join at any one time?\n"; print "[\033[1;32m$config{MAX_OPERCH}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_OPERCH}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_OPERCH} = $var; $continue = 1; print "\n"; } } $continue = 0; while (!$continue) { print "What is the maximum number of mode changes in one line?\n"; print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAXI_MODES}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAXI_MODES} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of an ident (username)?\n"; print "[\033[1;32m$config{MAX_IDENT}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_IDENT}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_IDENT} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of a quit message?\n"; print "[\033[1;32m$config{MAX_QUIT}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_QUIT}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_QUIT} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of a channel topic?\n"; print "[\033[1;32m$config{MAX_TOPIC}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_TOPIC}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_TOPIC} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of a kick message?\n"; print "[\033[1;32m$config{MAX_KICK}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_KICK}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_KICK} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of a GECOS (real name) field?\n"; print "[\033[1;32m$config{MAX_GECOS}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_GECOS}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_GECOS} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } $continue = 0; while (!$continue) { print "What is the maximum length of an away message?\n"; print "[\033[1;32m$config{MAX_AWAY}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{MAX_AWAY}; } if ($var =~ /^\d+$/) { # We don't care what the number is, set it and be on our way. $config{MAX_AWAY} = $var; $continue = 1; print "\n"; } else { print "You must enter a number in this field. Please try again.\n\n"; } } # Code Optimisation print "Enter the Level Of Binary optimisation. This is a number between 0 and 3. The InspIRCd Team will NOT support any bug reports above 0. Also note, the IRCd behaviour will be different depending on this value. Please read the documentation for more information. The higher the number, the more optimised your binary will be. This value will default to 0 if you either don't enter a number, or enter a value outside the range. As always, if you are unsure, just press enter and accept the default.\n\n"; print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{OPTIMITEMP}; } if ($var eq "1") { $config{OPTIMITEMP} = 1; $config{OPTIMISATI} = "-O"; } elsif ($var eq "2") { $config{OPTIMITEMP} = 2; $config{OPTIMISATI} = "-O2"; } elsif ($var eq "3") { $config{OPTIMITEMP} = 3; $config{OPTIMISATI} = "-O3"; } else { $config{OPTIMITEMP} = 0; $config{OPTIMISATI} = "-g"; } print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n"; print "\033[0mBase install path:\033[1;32m\t\t$config{BASE_DIR}\n"; print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n"; print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n"; print "\033[0mLibrary path:\033[1;32m\t\t\t$config{LIBRARY_DIR}\n"; print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n"; print "\033[0mMax User Channels:\033[1;32m\t\t$config{MAX_CHANNE}\n"; print "\033[0mMax Oper Channels:\033[1;32m\t\t$config{MAX_OPERCH}\n"; print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n"; print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n"; print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n"; print "\033[0mMax ident length:\033[1;32m\t\t$config{MAX_IDENT}\n"; print "\033[0mMax quit length:\033[1;32m\t\t$config{MAX_QUIT}\n"; print "\033[0mMax topic length:\033[1;32m\t\t$config{MAX_TOPIC}\n"; print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\n"; print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\n"; print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\n"; print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n"; print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n"; print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n"; print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n"; print "\033[0mMultithread DNS:\033[1;32m\t\t$config{THREADED_DNS}\033[0m\n"; print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n"; print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n"; if ($config{USE_GNUTLS} eq "y") { $failed = 0; open(TMP, ") { chomp; # Ignore Blank lines, and comments.. next if /^\s*$/; next if /^\s*#/; my ($key, $value) = split("=", $_); $value =~ /^\"(.*)\"$/; # Do something with data here! $config{$key} = $1; } close(CONFIG); return "true"; } sub makecache { # Dump the contents of %config print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n"; open(FILEHANDLE, ">.config.cache"); foreach $key (keys %config) { print FILEHANDLE "$key=\"$config{$key}\"\n"; } close(FILEHANDLE); } sub dir_check { my ($desc, $hash_key) = @_; my $complete = 0; while (!$complete) { print "In what directory $desc?\n"; print "[\033[1;32m$config{$hash_key}\033[0m] -> "; chomp($var = ); if ($var eq "") { $var = $config{$hash_key}; } if ($var =~ /^\~\/(.+)$/) { # Convert it to a full path.. $var = resolve_directory($ENV{HOME} . "/" . $1); } if (substr($var,0,1) ne "/") { # Assume relative Path was given.. fill in the rest. $var = $this . "/$var"; } $var = resolve_directory($var); if (! -e $var) { print "$var does not exist. Create it?\n[\033[1;32my\033[0m] "; chomp($tmp = ); if (($tmp eq "") || ($tmp =~ /^y/i)) { # Attempt to Create the Dir.. $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256; if ($chk != 0) { print "Unable to create directory. ($var)\n\n"; # Restart Loop.. next; } } else { # They said they don't want to create, and we can't install there. print "\n\n"; next; } } else { if (!is_dir($var)) { # Target exists, but is not a directory. print "File $var exists, but is not a directory.\n\n"; next; } } # Either Dir Exists, or was created fine. $config{$hash_key} = $var; $complete = 1; print "\n"; } } sub getosflags { if ($config{OSNAME} =~ /BSD$/) { $config{LDLIBS} = "-Ldl -lstdc++"; $config{FLAGS} = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}"; $config{MAKEPROG} = "gmake"; if ($config{OSNAME} eq "OpenBSD") { chomp($foo = `eg++ -dumpversion | cut -c 1`); # theyre running the package version of gcc (eg++)... detect it and set up its version numbers. # if theyre not running this, configure lets the build continue but they probably wont manage to # compile as this standard version is 2.95.3! if ($foo ne "") { $config{CC} = "eg++"; chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change chomp($config{GCC34} = `eg++ -dumpversion | cut -c 3`); # the compiler path } } } else { $config{LDLIBS} = "-ldl -lstdc++"; $config{FLAGS} = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}"; $config{MAKEPROG} = "make"; if ($config{OSNAME} =~ /CYGWIN/) { $config{FLAGS} = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}"; $config{LDLIBS} = ""; $config{MAKEPROG} = "/usr/bin/make"; $config{MAKEORDER} = "ircd mods config bininst"; } elsif ($config{OSNAME} eq "CYG-STATIC") { $config{FLAGS} = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}"; $config{LDLIBS} = ""; $config{MAKEPROG} = "/usr/bin/make"; $config{MAKEORDER} = "mods ircd config bininst"; $config{STATICLIBS} = "modules/mods.a"; $config{STATIC_LINK} = "yes"; } } if ($config{OSNAME} =~ /SunOS/) { # solaris/sunos needs these # socket = bsd sockets api # nsl = dns stuff # rt = POSIX realtime extensions # resolv = inet_aton only (why isnt this in nsl?!) $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv"; } } sub is_dir { my ($path) = @_; if (chdir($path)) { chdir($this); return 1; } else { # Just in case.. chdir($this); return 0; } } sub getmodules { my $i = 0; opendir(DIRHANDLE, "src/modules"); foreach $name (sort readdir(DIRHANDLE)) { if ($name =~ /^m_(.+)\.cpp$/) { $mod = $1; if ($mod !~ /_static$/) { $modlist[$i++] = $mod; } } } closedir(DIRHANDLE); } sub writefiles { print "Writing \033[1;32minspircd_config.h\033[0m\n"; # First File.. inspircd_config.h chomp(my $incos = `uname -n -s -r`); chomp(my $version = `sh ./src/version.sh`); open(FILEHANDLE, ">include/inspircd_config.h"); my $NL = $config{NICK_LENGT}+1; my $CL = $config{CHAN_LENGT}+1; print FILEHANDLE < 3) { print FILEHANDLE "#define GCC3\n"; print FILEHANDLE "#define GCC34\n"; } else { if ($config{GCCVER} == 3) { print FILEHANDLE "#define GCC3\n"; if ($config{GCC34} > 3) { print FILEHANDLE "#define GCC34\n"; } } } if ($config{HAS_STRLCPY} eq "true") { print FILEHANDLE "#define HAS_STRLCPY\n"; } if ($config{THREADED_DNS} =~ /y/i) { print FILEHANDLE "#define THREADED_DNS\n"; } my $use_hiperf = 0; if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) { print FILEHANDLE "#define USE_KQUEUE\n"; $use_hiperf = 1; } if (($has_epoll) && ($config{USE_EPOLL} eq "y")) { print FILEHANDLE "#define USE_EPOLL\n"; $use_hiperf = 1; } # user didn't choose either epoll or select for their OS. # default them to USE_SELECT (ewwy puke puke) if (!$use_hiperf) { print FILEHANDLE "#define USE_SELECT\n"; } print FILEHANDLE "\n#endif\n"; close(FILEHANDLE); # Create a Modules List.. my $modules = ""; foreach $i (@modlist) { if ($config{STATIC_LINK} eq "yes") { $modules .= "m_".$i.".o "; } else { $modules .= "m_".$i.".so "; } } chomp($modules); # Remove Redundant whitespace.. # Write all .in files. my $tmp = ""; my $file = ""; my $exe = "inspircd"; if ($config{OSNAME} =~ /CYGWIN/) { $exe = "inspircd.exe"; } opendir(DIRHANDLE, $this); if ($config{THREADED_DNS} =~ /y/i) { $config{LDLIBS} = $config{LDLIBS} . " -pthread"; } foreach $name (sort readdir(DIRHANDLE)) { if ($name =~ /^\.(.+)\.inc$/) { $file = $1; # All .name.inc files need parsing! $tmp = ""; open(FILEHANDLE, ".$file.inc"); while () { $tmp .= $_; } close(FILEHANDLE); $tmp =~ s/\@CC\@/$config{CC}/; $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/; $tmp =~ s/\@FLAGS\@/$config{FLAGS}/; $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/; $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/; $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/; $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/; $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/; $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/; $tmp =~ s/\@MODULES\@/$modules/; $tmp =~ s/\@EXECUTABLE\@/$exe/; $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/; $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/; print "Writing \033[1;32m$file\033[0m\n"; open(FILEHANDLE, ">$file"); print FILEHANDLE $tmp; } } closedir(DIRHANDLE); # Make inspircd executable! chmod 0744, 'inspircd'; if ($config{STATIC_LINK} eq "yes") { print "Writing static-build \033[1;32msrc/Makefile\033[0m\n"; write_static_makefile(); write_static_modules_makefile(); } elsif ($config{OSNAME} =~ /CYGWIN/) { print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n"; write_static_makefile(); write_dynamic_modules_makefile(); } else { print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n"; write_dynamic_makefile(); write_dynamic_modules_makefile(); } } sub getcompilerflags { my ($file) = @_; open(FLAGS, $file); while () { if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) { close(FLAGS); return $1; } } close(FLAGS); return undef; } sub getlinkerflags { my ($file) = @_; open(FLAGS, $file); while () { if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) { close(FLAGS); return $1; } } close(FLAGS); return undef; } sub show_splash { print "'\033[1;33m####\033[0m:'\033[1;33m##\033[0m::: \033[1;33m##\033[0m::'\033[1;33m######\033[0m::'\033[1;33m########\033[0m::'\033[1;33m####\033[0m:'\033[1;33m########\033[0m:::'\033[1;33m######\033[0m::'\033[1;33m########\033[0m::\n"; print ". \033[1;33m##\033[0m:: \033[1;33m###\033[0m:: \033[1;33m##\033[0m:'\033[1;33m##\033[0m... \033[1;33m##\033[0m: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:. \033[1;33m##\033[0m:: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:'\033[1;33m##\033[0m... \033[1;33m##\033[0m: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:\n"; print ": \033[1;33m##\033[0m:: \033[1;33m####\033[0m: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::..:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::..:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n"; print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m \033[1;33m##\033[0m \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m########\033[0m::: \033[1;33m##\033[0m:: \033[1;33m########\033[0m:: \033[1;33m##\033[0m::::::: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n"; print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m. \033[1;33m####\033[0m::..... \033[1;33m##\033[0m: \033[1;33m##\033[0m.....:::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m.. \033[1;33m##\033[0m::: \033[1;33m##\033[0m::::::: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n"; print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m:. \033[1;33m###\033[0m:'\033[1;33m##\033[0m::: \033[1;33m##\033[0m: \033[1;33m##\033[0m::::::::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m::. \033[1;33m##\033[0m:: \033[1;33m##\033[0m::: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n"; print "'\033[1;33m####\033[0m: \033[1;33m##\033[0m::. \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m##\033[0m::::::::'\033[1;33m####\033[0m: \033[1;33m##\033[0m:::. \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m########\033[0m::\n"; print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n"; } sub resolve_directory { use File::Spec; return File::Spec->rel2abs($_[0]); } sub yesno { my ($flag,$prompt) = @_; print "$prompt [\033[1;32m$config{$flag}\033[0m] -> "; chomp($tmp = ); if ($tmp eq "") { $tmp = $config{$flag} } if (($tmp eq "") || ($tmp =~ /^y/i)) { $config{$flag} = "y"; } else { $config{$flag} = "n"; } return; } sub write_static_modules_makefile { # Modules Makefile.. print "Writing \033[1;32msrc/modules/Makefile\033[0m\n"; open(FILEHANDLE, ">src/modules/Makefile"); ### # Module Makefile Header ### print FILEHANDLE < # Many Thanks to Andrew Church # for assisting with making this work right. # # Automatically Generated by ./configure to add a modules # please run ./configure --update all: \$(MODULES) EOF ### # End Module Makefile Header ### # Create a Modules List.. my $modules = ""; my $cmflags = ""; my $liflags = ""; open(MODLIST,">include/modlist.h"); ### # Include File Header ### print MODLIST <src/modules/m_".$i."_static.cpp") or die("Could not create m_".$i."_static.cpp"); while (chomp($a = )) { $a =~ s/init_module/$i\_init/g; $a =~ s/Srv/$i\Srv/g; print MUNGED "$a\n"; } close(MODULE); close(MUNGED); print MODLIST <src/modules/Makefile"); my $extra = ""; if ($config{OSNAME} =~ /CYGWIN/) { $extra = "../inspircd.dll.a"; } ### # Module Makefile Header ### print FILEHANDLE < # Many Thanks to Andrew Church # for assisting with making this work right. # # Automatically Generated by ./configure to add a modules # please run ./configure -update or ./configure -modupdate all: \$(MODULES) EOF ### # End Module Makefile Header ### # Create a Modules List.. my $modules = ""; my $cmflags = ""; my $liflags = ""; foreach $i (@modlist) { ### # Write Entry to the MakeFile ### $cmflags = getcompilerflags("src/modules/m_".$i.".cpp"); $liflags = getlinkerflags("src/modules/m_".$i.".cpp"); print FILEHANDLE <src/Makefile") or die("Could not write src/Makefile!"); my $i = 0; my @cmdlist = (); opendir(DIRHANDLE, "src"); foreach $name (sort readdir(DIRHANDLE)) { if ($name =~ /^cmd_(.+)\.cpp$/) { $cmdlist[$i++] = $1; } } closedir(DIRHANDLE); my $cmdobjs = ""; my $srcobjs = ""; foreach my $cmd (@cmdlist) { $cmdobjs = $cmdobjs . "cmd_$cmd.o "; $srcobjs = $srcobjs . "cmd_$cmd.cpp "; } print FH < # Makefile version 2 (statically linked core) by # CC = im a cheezeball CXXFLAGS = -I../include \${FLAGS} EOM ### # This next section is for cygwin dynamic module builds. # Basically, what we do, is build the inspircd core as a library # then the main executable uses that. the library is capable of # loading / unloading the modules dynamically :) # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping # make this work :) ### if ($config{OSNAME} =~ /CYGWIN/) { print FH <src/Makefile") or die("Could not write src/Makefile"); print FH < # Makefile version 2 (dynamically linked core) by # CC = im a cheezeball CXXFLAGS = -I../include \${FLAGS} all: libIRCDtimers.so libIRCDaes.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDio.so libIRCDmessage.so $cmdobjs libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so inspircd inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h \$(CC) -I../include -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDio.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so libIRCDuserprocess.so libIRCDcull_list.so libIRCDcommand_parse.so libIRCDaes.so libIRCDtimers.so libIRCDsocketengine.so: socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o libIRCDcommand_parse.so: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o libIRCDcull_list.so: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o libIRCDmode.so: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o libIRCDxline.so: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o libIRCDstring.so: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o libIRCDasyncdns.so: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o libIRCDio.so: inspircd_io.cpp ../include/base.h ../include/inspircd_io.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_io.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDio.so inspircd_io.o libIRCDmessage.so: message.cpp ../include/base.h ../include/message.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmessage.so message.o libIRCDcommands.so: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h $srcobjs \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o $cmdobjs libIRCDdnsqueue.so: dnsqueue.cpp ../include/base.h ../include/dnsqueue.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dnsqueue.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdnsqueue.so dnsqueue.o libIRCDdynamic.so: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o libIRCDusers.so: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o libIRCDmodules.so: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o libIRCDwildcard.so: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o libIRCDaes.so: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDaes.so aes.o libIRCDtimers.so: timers.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timers.cpp \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimers.so timers.o EOM foreach my $cmd (@cmdlist) { print FH <