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";
71 if (!$config{MAX_CLIENT}) {
72 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
73 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
74 # higher than the found value" :))
75 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
78 # Perform the strlcpy() test..
79 open(STRLCPY, ">.test.cpp");
80 print STRLCPY "#include <string.h>
82 int main() { char a[10]; char b[10]; strlcpy(a,b,10); printf(\"%d\\n\",9); }\n";
86 system("g++ -o .test .test.cpp 2>&1");
88 # Was the build succesful?
90 $config{HAS_STRLCPY} = "true";
91 system("rm -f .test .test.cpp");
94 ################################################################################
95 # BEGIN INTERACTIVE PART #
96 ################################################################################
100 # Display Splash Logo..
102 chomp($wholeos = `uname -mnr`);
104 # Display Introduction Message..
106 Welcome to the InspIRCd Configuration program!
108 *** If you are unsure of any of these values, leave it blank for ***
109 *** standard settings that will work, and your server will run ***
110 *** using them. If you are running this server as part of a ***
111 *** larger network, you must consult with your network admins ***
112 *** for the proper values to use, or server links will be unstable! ***
114 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
115 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
116 dir, otherwise you won't have a config file!
118 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
120 # Directory Settings..
121 dir_check("are the configuration files", "CONFIG_DIR");
122 dir_check("are the modules to be compiled to", "MODULE_DIR");
123 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
124 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
126 if ($config{OSNAME} =~ /BSD$/) {
127 yesno(USE_KQUEUE,"You are running a BSD operating system.\nWould you like to enable kqueue support?\nPlease be aware that kqueue support is\nEXPERIMENTAL and not gauranteed to work properly.\nIf you are unsure, answer no.\n\nEnable kqueue?");
130 # File Descriptor Settings..
133 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
134 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
135 chomp($var = <STDIN>);
136 if ($var eq "") { $var = $config{MAX_CLIENT}; }
137 if ($var =~ /^\d+$/) {
138 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
139 # Client has entered a larger number than the 'discovered' value
141 print "WARNING: Our scans have indicated that you are attempting
142 to use more sockets than there are avaliable. Are you sure
143 you wish to do this? It may cause the IRCd to malfunction [y/n]
144 [\033[1;32mn\033[0m] -> $c";
145 chomp($tmp = <STDIN>);
147 print "Please enter the correct value.\n\n";
152 print "You must enter a number in this field. Please try again.\n\n";
155 # If we get here, we should be good to go.
156 $config{MAX_CLIENT} = $var;
163 print "What is the Maximum length of nicknames?\n";
164 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
165 chomp($var = <STDIN>);
166 if ($var eq "") { $var = $config{NICK_LENGT}; }
167 if ($var =~ /^\d+$/) {
168 # We don't care what the number is, set it and be on our way.
169 $config{NICK_LENGT} = $var;
173 print "You must enter a number in this field. Please try again.\n\n";
179 print "What is the Maximum number of mode changes in one line?\n";
180 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
181 chomp($var = <STDIN>);
182 if ($var eq "") { $var = $config{MAXI_MODES}; }
183 if ($var =~ /^\d+$/) {
184 # We don't care what the number is, set it and be on our way.
185 $config{MAXI_MODES} = $var;
189 print "You must enter a number in this field. Please try again.\n\n";
194 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
195 The InspIRCd Team will _NOT_ support any bug reports above 0.
196 Also note, the IRCd behaviour will be different depending on this value.
197 Please read the documentation for more information.
199 The Higher the number, the more optimised your binary will be. This value will default to 0
200 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
201 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
202 chomp($var = <STDIN>);
204 $var = $config{OPTIMITEMP};
208 $config{OPTIMITEMP} = 1;
209 $config{OPTIMISATI} = "-O";
210 } elsif ($var eq "2") {
211 $config{OPTIMITEMP} = 2;
212 $config{OPTIMISATI} = "-O2";
213 } elsif ($var eq "3") {
214 $config{OPTIMITEMP} = 3;
215 $config{OPTIMISATI} = "-O3";
217 $config{OPTIMITEMP} = 0;
218 $config{OPTIMISATI} = "-g";
221 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
222 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
223 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
224 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
225 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
226 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
227 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
228 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
229 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
230 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
236 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
237 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
239 ################################################################################
241 ################################################################################
243 # Retrieves the .config.cache file, and loads values into the main config hash.
244 open(CACHE, ".config.cache") or return undef;
248 # Ignore Blank lines, and comments..
252 my ($key, $value) = split("=", $_);
253 $value =~ /^\"(.*)\"$/;
254 # Do something with data here!
262 # Dump the contents of %config
263 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
264 open(FILEHANDLE, ">.config.cache");
265 foreach $key (keys %config)
267 print FILEHANDLE "$key=\"$config{$key}\"\n";
273 my ($desc, $hash_key) = @_;
276 print "In what directory $desc?\n";
277 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
278 chomp($var = <STDIN>);
279 if ($var eq "") { $var = $config{$hash_key}; }
280 if ($var =~ /^\~\/(.+)$/) {
281 # Convert it to a full path..
282 $var = resolve_directory($ENV{HOME} . "/" . $1);
284 if (substr($var,0,1) ne "/")
286 # Assume relative Path was given.. fill in the rest.
287 $var = $this . "/$var";
289 $var = resolve_directory($var);
291 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
292 chomp($tmp = <STDIN>);
293 if (($tmp eq "") || ($tmp =~ /^y/i)) {
294 # Attempt to Create the Dir..
295 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
297 print "Unable to create directory. ($var)\n\n";
302 # They said they don't want to create, and we can't install there.
308 # Target exists, but is not a directory.
309 print "File $var exists, but is not a directory.\n\n";
313 # Either Dir Exists, or was created fine.
314 $config{$hash_key} = $var;
321 if ($config{OSNAME} eq "FreeBSD") {
322 $config{LDLIBS} = "-Ldl";
323 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
324 $config{MAKEPROG} = "gmake";
326 $config{LDLIBS} = "-ldl";
327 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
328 $config{MAKEPROG} = "make";
346 opendir(DIRHANDLE, "src/modules");
347 foreach $name (sort readdir(DIRHANDLE)) {
348 if ($name =~ /^m_(.+)\.cpp$/)
358 print "Writing \033[1;32minspircd_config.h\033[0m\n";
359 # First File.. inspircd_config.h
360 chomp(my $incos = `uname -n -s -r`);
361 chomp(my $version = `sh ./src/version.sh`);
362 open(FILEHANDLE, "> include/inspircd_config.h");
363 print FILEHANDLE <<EOF;
364 /* Auto generated by configure, do not modify! */
365 #define SYSLOG_FACILITY LOG_DAEMON
366 #define SYSLOG_LEVEL LOG_NOTICE
367 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
368 #define MOD_PATH "$config{MODULE_DIR}"
369 #define VERSION "$version"
370 #define MAXCLIENTS $config{MAX_CLIENT}
371 #define NICKMAX $config{NICK_LENGT}
372 #define CHANMAX $config{CHAN_LENGT}
373 #define MAXCHANS $config{MAX_CHANNE}
374 #define MAXMODES $config{MAXI_MODES}
375 #define OPTIMISATION $config{OPTIMITEMP}
376 #define SYSTEM "$incos"
380 if ($config{GCCVER} > 3) {
381 print FILEHANDLE "#define GCC3\n";
382 print FILEHANDLE "#define GCC34\n";
386 if ($config{GCCVER} == 3) {
387 print FILEHANDLE "#define GCC3\n";
388 if ($config{GCC34} > 3) {
389 print FILEHANDLE "#define GCC34\n";
393 if ($config{HAS_STRLCPY} eq "true") {
394 print FILEHANDLE "#define HAS_STRLCPY\n";
396 if ($config{USE_KQUEUE} eq "y") {
397 print FILEHANDLE "#define USE_KQUEUE\n";
401 # Create a Modules List..
403 foreach $i (@modlist)
405 $modules .= "m_".$i.".so ";
407 chomp($modules); # Remove Redundant whitespace..
410 # Write all .in files.
413 opendir(DIRHANDLE, $this);
414 foreach $name (sort readdir(DIRHANDLE)) {
415 if ($name =~ /^\.(.+)\.inc$/)
418 # All .name.inc files need parsing!
420 open(FILEHANDLE, ".$file.inc");
421 while (<FILEHANDLE>) {
426 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
427 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
428 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
429 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
430 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
431 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
432 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
433 $tmp =~ s/\@MODULES\@/$modules/;
435 print "Writing \033[1;32m$file\033[0m\n";
436 open(FILEHANDLE, ">$file");
437 print FILEHANDLE $tmp;
442 # Make inspircd executable!
443 chmod 0744, 'inspircd';
446 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
447 open(FILEHANDLE, ">src/modules/Makefile");
448 print FILEHANDLE <<EOF;
449 # (C) ChatSpike development team
450 # Makefile by <Craig\@ChatSpike.net>
451 # Many Thanks to Andrew Church <achurch\@achurch.org>
452 # for assisting with making this work right.
454 # Automatically Generated by ./configure to add a modules
455 # please run ./configure --update
461 # Create a Modules List..
464 foreach $i (@modlist)
466 $flags = getcompilerflags("src/modules/m_".$i.".cpp");
467 print FILEHANDLE <<EOCHEESE;
468 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
469 \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
470 \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
471 cp m_$i.so \$(MODPATH)/
472 chmod 0700 \$(MODPATH)/m_$i.so
478 sub getcompilerflags {
482 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
492 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";
493 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";
494 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";
495 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";
496 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";
497 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";
498 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";
499 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
502 sub resolve_directory {
504 return File::Spec->rel2abs($_[0]);
508 my ($flag,$prompt) = @_;
509 print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
510 chomp($tmp = <STDIN>);
511 if ($tmp eq "") { $tmp = $config{$flag} }
513 if (($tmp eq "") || ($tmp =~ /^y/i)) {
514 $config{$flag} = "y";
516 $config{$flag} = "n";