2 # InspIRCd Configuration Script
4 # Copyright 2003 The ChatSpike Development Team
5 # <brain@chatspike.net>
6 # <Craig@chatspike.net>
8 # [14:21] Brain: <matrix impression> i know perl-fu!
12 ########################################
15 $this = resolve_directory($ENV{PWD}); # PWD, Regardless.
16 @modlist = (); # Declare for Module List..
17 %config = (); # Initiate Configuration Hash..
18 $config{ME} = resolve_directory($ENV{PWD}); # Present Working Directory
19 $config{CONFIG_DIR} = resolve_directory($ENV{PWD}."/conf"); # Configuration Directory
20 $config{MODULE_DIR} = resolve_directory($ENV{PWD}."/modules"); # Modules Directory
21 $config{BINARY_DIR} = resolve_directory($ENV{PWD}."/bin"); # Binary Directory
22 $config{LIBRARY_DIR} = resolve_directory($ENV{PWD}."/lib"); # Library Directory
23 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
24 $config{OPTIMISATI} = "-g"; # Optimisation Flag
25 $config{NICK_LENGT} = "32"; # Default Nick Length
26 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
27 $config{MAX_CHANNE} = "20"; # Default Max. Channels per user..
28 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
29 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
30 $config{USE_KQUEUE} = "n"; # kqueue enabled
31 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
32 chomp($config{GCCVER} = `gcc -dumpversion | cut -c 1`); # Major GCC Version
33 chomp($config{GCC34} = `gcc -dumpversion | cut -c 3`); # Minor GCC Version
34 chomp($config{OSNAME} = `uname -s`); # Operating System Name
36 if (!$config{OSNAME}) {
37 $config{OSNAME} = "Unknown"; # For use when uname fails.
40 if (!$config{MAX_CLIENT_T}) {
41 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
42 $fd_scan_fail = "true"; # Used Later
45 # Get and Set some important vars..
48 my $arg = $ARGV[0]; # Do Some Argument Checks..
49 if ($arg eq "-clean") { `rm -rf .config.cache`; } # Remove the config.cache file.
51 if ($arg eq "-update") {
52 # Does the cache file exist?
54 # No, No it doesn't.. *BASH*
55 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
58 # We've Loaded the cache file and all our variables..
59 print "Updating Files..\n";
67 print "Checking for cache from previous configure...\n";
69 print "Checking operating system version...\n";
72 if (!$config{MAX_CLIENT}) {
73 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
74 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
75 # higher than the found value" :))
76 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
79 printf "Checking if strlcpy exists... ";
80 # Perform the strlcpy() test..
81 $config{HAS_STRLCPY} = "false";
83 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
86 while (chomp($line = <STRLCPY>))
88 # try and find the delcaration of:
90 if (($line =~ /size_t(\0x9|\s)+strlcpy(\0x9|\s)+\(/) || ($line =~ /size_t(\0x9|\s)+strlcpy\(/))
92 $config{HAS_STRLCPY} = "true";
97 print "yes\n" if $config{HAS_STRLCPY} eq "true";
98 print "no\n" if $config{HAS_STRLCPY} eq "false";
100 printf "Checking if kqueue exists... ";
103 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
106 while (chomp($line = <KQUEUE>))
108 # try and find the delcaration of:
110 if (($line =~ /int(\0x9|\s)+kqueue(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+kqueue\(/))
117 print "yes\n" if $has_kqueue == 1;
118 print "no\n" if $has_kqueue == 0;
120 ################################################################################
121 # BEGIN INTERACTIVE PART #
122 ################################################################################
126 # Display Splash Logo..
128 chomp($wholeos = `uname -mnr`);
130 # Display Introduction Message..
132 Welcome to the InspIRCd Configuration program!
134 *** If you are unsure of any of these values, leave it blank for ***
135 *** standard settings that will work, and your server will run ***
136 *** using them. If you are running this server as part of a ***
137 *** larger network, you must consult with your network admins ***
138 *** for the proper values to use, or server links will be unstable! ***
140 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
141 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
142 dir, otherwise you won't have a config file!
144 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
146 # Directory Settings..
147 dir_check("are the configuration files", "CONFIG_DIR");
148 dir_check("are the modules to be compiled to", "MODULE_DIR");
149 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
150 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
153 yesno(USE_KQUEUE,"You are running a BSD operating system, and kqueue\nwas detected. Would you like to enable kqueue support?\nIf you are unsure, answer no.\n\nEnable kqueue?");
156 # File Descriptor Settings..
159 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
160 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
161 chomp($var = <STDIN>);
162 if ($var eq "") { $var = $config{MAX_CLIENT}; }
163 if ($var =~ /^\d+$/) {
164 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
165 # Client has entered a larger number than the 'discovered' value
167 print "WARNING: Our scans have indicated that you are attempting
168 to use more sockets than there are avaliable. Are you sure
169 you wish to do this? It may cause the IRCd to malfunction [y/n]
170 [\033[1;32mn\033[0m] -> $c";
171 chomp($tmp = <STDIN>);
173 print "Please enter the correct value.\n\n";
178 print "You must enter a number in this field. Please try again.\n\n";
181 # If we get here, we should be good to go.
182 $config{MAX_CLIENT} = $var;
189 print "What is the Maximum length of nicknames?\n";
190 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
191 chomp($var = <STDIN>);
192 if ($var eq "") { $var = $config{NICK_LENGT}; }
193 if ($var =~ /^\d+$/) {
194 # We don't care what the number is, set it and be on our way.
195 $config{NICK_LENGT} = $var;
199 print "You must enter a number in this field. Please try again.\n\n";
205 print "What is the Maximum number of mode changes in one line?\n";
206 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
207 chomp($var = <STDIN>);
208 if ($var eq "") { $var = $config{MAXI_MODES}; }
209 if ($var =~ /^\d+$/) {
210 # We don't care what the number is, set it and be on our way.
211 $config{MAXI_MODES} = $var;
215 print "You must enter a number in this field. Please try again.\n\n";
220 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
221 The InspIRCd Team will _NOT_ support any bug reports above 0.
222 Also note, the IRCd behaviour will be different depending on this value.
223 Please read the documentation for more information.
225 The Higher the number, the more optimised your binary will be. This value will default to 0
226 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
227 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
228 chomp($var = <STDIN>);
230 $var = $config{OPTIMITEMP};
234 $config{OPTIMITEMP} = 1;
235 $config{OPTIMISATI} = "-O";
236 } elsif ($var eq "2") {
237 $config{OPTIMITEMP} = 2;
238 $config{OPTIMISATI} = "-O2";
239 } elsif ($var eq "3") {
240 $config{OPTIMITEMP} = 3;
241 $config{OPTIMISATI} = "-O3";
243 $config{OPTIMITEMP} = 0;
244 $config{OPTIMISATI} = "-g";
247 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
248 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
249 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
250 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
251 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
252 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
253 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
254 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
255 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
256 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
262 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
263 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
265 ################################################################################
267 ################################################################################
269 # Retrieves the .config.cache file, and loads values into the main config hash.
270 open(CACHE, ".config.cache") or return undef;
274 # Ignore Blank lines, and comments..
278 my ($key, $value) = split("=", $_);
279 $value =~ /^\"(.*)\"$/;
280 # Do something with data here!
288 # Dump the contents of %config
289 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
290 open(FILEHANDLE, ">.config.cache");
291 foreach $key (keys %config)
293 print FILEHANDLE "$key=\"$config{$key}\"\n";
299 my ($desc, $hash_key) = @_;
302 print "In what directory $desc?\n";
303 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
304 chomp($var = <STDIN>);
305 if ($var eq "") { $var = $config{$hash_key}; }
306 if ($var =~ /^\~\/(.+)$/) {
307 # Convert it to a full path..
308 $var = resolve_directory($ENV{HOME} . "/" . $1);
310 if (substr($var,0,1) ne "/")
312 # Assume relative Path was given.. fill in the rest.
313 $var = $this . "/$var";
315 $var = resolve_directory($var);
317 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
318 chomp($tmp = <STDIN>);
319 if (($tmp eq "") || ($tmp =~ /^y/i)) {
320 # Attempt to Create the Dir..
321 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
323 print "Unable to create directory. ($var)\n\n";
328 # They said they don't want to create, and we can't install there.
334 # Target exists, but is not a directory.
335 print "File $var exists, but is not a directory.\n\n";
339 # Either Dir Exists, or was created fine.
340 $config{$hash_key} = $var;
347 if ($config{OSNAME} eq "FreeBSD") {
348 $config{LDLIBS} = "-Ldl";
349 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
350 $config{MAKEPROG} = "gmake";
352 $config{LDLIBS} = "-ldl";
353 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
354 $config{MAKEPROG} = "make";
372 opendir(DIRHANDLE, "src/modules");
373 foreach $name (sort readdir(DIRHANDLE)) {
374 if ($name =~ /^m_(.+)\.cpp$/)
384 print "Writing \033[1;32minspircd_config.h\033[0m\n";
385 # First File.. inspircd_config.h
386 chomp(my $incos = `uname -n -s -r`);
387 chomp(my $version = `sh ./src/version.sh`);
388 open(FILEHANDLE, "> include/inspircd_config.h");
389 print FILEHANDLE <<EOF;
390 /* Auto generated by configure, do not modify! */
391 #define SYSLOG_FACILITY LOG_DAEMON
392 #define SYSLOG_LEVEL LOG_NOTICE
393 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
394 #define MOD_PATH "$config{MODULE_DIR}"
395 #define VERSION "$version"
396 #define MAXCLIENTS $config{MAX_CLIENT}
397 #define NICKMAX $config{NICK_LENGT}
398 #define CHANMAX $config{CHAN_LENGT}
399 #define MAXCHANS $config{MAX_CHANNE}
400 #define MAXMODES $config{MAXI_MODES}
401 #define OPTIMISATION $config{OPTIMITEMP}
402 #define SYSTEM "$incos"
406 if ($config{GCCVER} > 3) {
407 print FILEHANDLE "#define GCC3\n";
408 print FILEHANDLE "#define GCC34\n";
412 if ($config{GCCVER} == 3) {
413 print FILEHANDLE "#define GCC3\n";
414 if ($config{GCC34} > 3) {
415 print FILEHANDLE "#define GCC34\n";
419 if ($config{HAS_STRLCPY} eq "true") {
420 print FILEHANDLE "#define HAS_STRLCPY\n";
422 if ($config{USE_KQUEUE} eq "y") {
423 print FILEHANDLE "#define USE_KQUEUE\n";
427 # Create a Modules List..
429 foreach $i (@modlist)
431 $modules .= "m_".$i.".so ";
433 chomp($modules); # Remove Redundant whitespace..
436 # Write all .in files.
439 opendir(DIRHANDLE, $this);
440 foreach $name (sort readdir(DIRHANDLE)) {
441 if ($name =~ /^\.(.+)\.inc$/)
444 # All .name.inc files need parsing!
446 open(FILEHANDLE, ".$file.inc");
447 while (<FILEHANDLE>) {
452 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
453 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
454 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
455 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
456 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
457 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
458 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
459 $tmp =~ s/\@MODULES\@/$modules/;
461 print "Writing \033[1;32m$file\033[0m\n";
462 open(FILEHANDLE, ">$file");
463 print FILEHANDLE $tmp;
468 # Make inspircd executable!
469 chmod 0744, 'inspircd';
472 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
473 open(FILEHANDLE, ">src/modules/Makefile");
474 print FILEHANDLE <<EOF;
475 # (C) ChatSpike development team
476 # Makefile by <Craig\@ChatSpike.net>
477 # Many Thanks to Andrew Church <achurch\@achurch.org>
478 # for assisting with making this work right.
480 # Automatically Generated by ./configure to add a modules
481 # please run ./configure --update
487 # Create a Modules List..
490 foreach $i (@modlist)
492 $flags = getcompilerflags("src/modules/m_".$i.".cpp");
493 print FILEHANDLE <<EOCHEESE;
494 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
495 \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
496 \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
497 cp m_$i.so \$(MODPATH)/
498 chmod 0700 \$(MODPATH)/m_$i.so
504 sub getcompilerflags {
508 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
518 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";
519 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";
520 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";
521 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";
522 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";
523 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";
524 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";
525 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
528 sub resolve_directory {
530 return File::Spec->rel2abs($_[0]);
534 my ($flag,$prompt) = @_;
535 print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
536 chomp($tmp = <STDIN>);
537 if ($tmp eq "") { $tmp = $config{$flag} }
539 if (($tmp eq "") || ($tmp =~ /^y/i)) {
540 $config{$flag} = "y";
542 $config{$flag} = "n";