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 $config{HAS_STRLCPY} = "false";
81 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
84 while (chomp($line = <STRLCPY>))
86 # try and find the delcaration of:
88 if (($line =~ /size_t(\0x9|\s)+strlcpy(\0x9|\s)+\(/) || ($line =~ /size_t(\0x9|\s)+strlcpy\(/))
90 $config{HAS_STRLCPY} = "true";
98 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
101 while (chomp($line = <KQUEUE>))
103 # try and find the delcaration of:
105 if (($line =~ /int(\0x9|\s)+kqueue(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+kqueue\(/))
113 ################################################################################
114 # BEGIN INTERACTIVE PART #
115 ################################################################################
119 # Display Splash Logo..
121 chomp($wholeos = `uname -mnr`);
123 # Display Introduction Message..
125 Welcome to the InspIRCd Configuration program!
127 *** If you are unsure of any of these values, leave it blank for ***
128 *** standard settings that will work, and your server will run ***
129 *** using them. If you are running this server as part of a ***
130 *** larger network, you must consult with your network admins ***
131 *** for the proper values to use, or server links will be unstable! ***
133 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
134 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
135 dir, otherwise you won't have a config file!
137 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
139 # Directory Settings..
140 dir_check("are the configuration files", "CONFIG_DIR");
141 dir_check("are the modules to be compiled to", "MODULE_DIR");
142 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
143 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
146 yesno(USE_KQUEUE,"You are running a BSD operating system, and kqueue\nwas detected. Would 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?");
149 # File Descriptor Settings..
152 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
153 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
154 chomp($var = <STDIN>);
155 if ($var eq "") { $var = $config{MAX_CLIENT}; }
156 if ($var =~ /^\d+$/) {
157 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
158 # Client has entered a larger number than the 'discovered' value
160 print "WARNING: Our scans have indicated that you are attempting
161 to use more sockets than there are avaliable. Are you sure
162 you wish to do this? It may cause the IRCd to malfunction [y/n]
163 [\033[1;32mn\033[0m] -> $c";
164 chomp($tmp = <STDIN>);
166 print "Please enter the correct value.\n\n";
171 print "You must enter a number in this field. Please try again.\n\n";
174 # If we get here, we should be good to go.
175 $config{MAX_CLIENT} = $var;
182 print "What is the Maximum length of nicknames?\n";
183 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
184 chomp($var = <STDIN>);
185 if ($var eq "") { $var = $config{NICK_LENGT}; }
186 if ($var =~ /^\d+$/) {
187 # We don't care what the number is, set it and be on our way.
188 $config{NICK_LENGT} = $var;
192 print "You must enter a number in this field. Please try again.\n\n";
198 print "What is the Maximum number of mode changes in one line?\n";
199 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
200 chomp($var = <STDIN>);
201 if ($var eq "") { $var = $config{MAXI_MODES}; }
202 if ($var =~ /^\d+$/) {
203 # We don't care what the number is, set it and be on our way.
204 $config{MAXI_MODES} = $var;
208 print "You must enter a number in this field. Please try again.\n\n";
213 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
214 The InspIRCd Team will _NOT_ support any bug reports above 0.
215 Also note, the IRCd behaviour will be different depending on this value.
216 Please read the documentation for more information.
218 The Higher the number, the more optimised your binary will be. This value will default to 0
219 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
220 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
221 chomp($var = <STDIN>);
223 $var = $config{OPTIMITEMP};
227 $config{OPTIMITEMP} = 1;
228 $config{OPTIMISATI} = "-O";
229 } elsif ($var eq "2") {
230 $config{OPTIMITEMP} = 2;
231 $config{OPTIMISATI} = "-O2";
232 } elsif ($var eq "3") {
233 $config{OPTIMITEMP} = 3;
234 $config{OPTIMISATI} = "-O3";
236 $config{OPTIMITEMP} = 0;
237 $config{OPTIMISATI} = "-g";
240 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
241 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
242 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
243 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
244 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
245 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
246 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
247 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
248 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
249 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
255 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
256 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
258 ################################################################################
260 ################################################################################
262 # Retrieves the .config.cache file, and loads values into the main config hash.
263 open(CACHE, ".config.cache") or return undef;
267 # Ignore Blank lines, and comments..
271 my ($key, $value) = split("=", $_);
272 $value =~ /^\"(.*)\"$/;
273 # Do something with data here!
281 # Dump the contents of %config
282 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
283 open(FILEHANDLE, ">.config.cache");
284 foreach $key (keys %config)
286 print FILEHANDLE "$key=\"$config{$key}\"\n";
292 my ($desc, $hash_key) = @_;
295 print "In what directory $desc?\n";
296 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
297 chomp($var = <STDIN>);
298 if ($var eq "") { $var = $config{$hash_key}; }
299 if ($var =~ /^\~\/(.+)$/) {
300 # Convert it to a full path..
301 $var = resolve_directory($ENV{HOME} . "/" . $1);
303 if (substr($var,0,1) ne "/")
305 # Assume relative Path was given.. fill in the rest.
306 $var = $this . "/$var";
308 $var = resolve_directory($var);
310 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
311 chomp($tmp = <STDIN>);
312 if (($tmp eq "") || ($tmp =~ /^y/i)) {
313 # Attempt to Create the Dir..
314 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
316 print "Unable to create directory. ($var)\n\n";
321 # They said they don't want to create, and we can't install there.
327 # Target exists, but is not a directory.
328 print "File $var exists, but is not a directory.\n\n";
332 # Either Dir Exists, or was created fine.
333 $config{$hash_key} = $var;
340 if ($config{OSNAME} eq "FreeBSD") {
341 $config{LDLIBS} = "-Ldl";
342 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
343 $config{MAKEPROG} = "gmake";
345 $config{LDLIBS} = "-ldl";
346 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
347 $config{MAKEPROG} = "make";
365 opendir(DIRHANDLE, "src/modules");
366 foreach $name (sort readdir(DIRHANDLE)) {
367 if ($name =~ /^m_(.+)\.cpp$/)
377 print "Writing \033[1;32minspircd_config.h\033[0m\n";
378 # First File.. inspircd_config.h
379 chomp(my $incos = `uname -n -s -r`);
380 chomp(my $version = `sh ./src/version.sh`);
381 open(FILEHANDLE, "> include/inspircd_config.h");
382 print FILEHANDLE <<EOF;
383 /* Auto generated by configure, do not modify! */
384 #define SYSLOG_FACILITY LOG_DAEMON
385 #define SYSLOG_LEVEL LOG_NOTICE
386 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
387 #define MOD_PATH "$config{MODULE_DIR}"
388 #define VERSION "$version"
389 #define MAXCLIENTS $config{MAX_CLIENT}
390 #define NICKMAX $config{NICK_LENGT}
391 #define CHANMAX $config{CHAN_LENGT}
392 #define MAXCHANS $config{MAX_CHANNE}
393 #define MAXMODES $config{MAXI_MODES}
394 #define OPTIMISATION $config{OPTIMITEMP}
395 #define SYSTEM "$incos"
399 if ($config{GCCVER} > 3) {
400 print FILEHANDLE "#define GCC3\n";
401 print FILEHANDLE "#define GCC34\n";
405 if ($config{GCCVER} == 3) {
406 print FILEHANDLE "#define GCC3\n";
407 if ($config{GCC34} > 3) {
408 print FILEHANDLE "#define GCC34\n";
412 if ($config{HAS_STRLCPY} eq "true") {
413 print FILEHANDLE "#define HAS_STRLCPY\n";
415 if ($config{USE_KQUEUE} eq "y") {
416 print FILEHANDLE "#define USE_KQUEUE\n";
420 # Create a Modules List..
422 foreach $i (@modlist)
424 $modules .= "m_".$i.".so ";
426 chomp($modules); # Remove Redundant whitespace..
429 # Write all .in files.
432 opendir(DIRHANDLE, $this);
433 foreach $name (sort readdir(DIRHANDLE)) {
434 if ($name =~ /^\.(.+)\.inc$/)
437 # All .name.inc files need parsing!
439 open(FILEHANDLE, ".$file.inc");
440 while (<FILEHANDLE>) {
445 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
446 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
447 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
448 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
449 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
450 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
451 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
452 $tmp =~ s/\@MODULES\@/$modules/;
454 print "Writing \033[1;32m$file\033[0m\n";
455 open(FILEHANDLE, ">$file");
456 print FILEHANDLE $tmp;
461 # Make inspircd executable!
462 chmod 0744, 'inspircd';
465 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
466 open(FILEHANDLE, ">src/modules/Makefile");
467 print FILEHANDLE <<EOF;
468 # (C) ChatSpike development team
469 # Makefile by <Craig\@ChatSpike.net>
470 # Many Thanks to Andrew Church <achurch\@achurch.org>
471 # for assisting with making this work right.
473 # Automatically Generated by ./configure to add a modules
474 # please run ./configure --update
480 # Create a Modules List..
483 foreach $i (@modlist)
485 $flags = getcompilerflags("src/modules/m_".$i.".cpp");
486 print FILEHANDLE <<EOCHEESE;
487 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
488 \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
489 \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
490 cp m_$i.so \$(MODPATH)/
491 chmod 0700 \$(MODPATH)/m_$i.so
497 sub getcompilerflags {
501 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
511 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";
512 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";
513 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";
514 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";
515 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";
516 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";
517 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";
518 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
521 sub resolve_directory {
523 return File::Spec->rel2abs($_[0]);
527 my ($flag,$prompt) = @_;
528 print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
529 chomp($tmp = <STDIN>);
530 if ($tmp eq "") { $tmp = $config{$flag} }
532 if (($tmp eq "") || ($tmp =~ /^y/i)) {
533 $config{$flag} = "y";
535 $config{$flag} = "n";