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 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
31 chomp($config{GCCVER} = `gcc -dumpversion | cut -c 1`); # Major GCC Version
32 chomp($config{GCC34} = `gcc -dumpversion | cut -c 3`); # Minor GCC Version
33 chomp($config{OSNAME} = `uname -s`); # Operating System Name
35 if (!$config{OSNAME}) {
36 $config{OSNAME} = "Unknown"; # For use when uname fails.
39 if (!$config{MAX_CLIENT_T}) {
40 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
41 $fd_scan_fail = "true"; # Used Later
44 # Get and Set some important vars..
47 my $arg = $ARGV[0]; # Do Some Argument Checks..
48 if ($arg eq "-clean") { `rm -rf .config.cache`; } # Remove the config.cache file.
50 if ($arg eq "-update") {
51 # Does the cache file exist?
53 # No, No it doesn't.. *BASH*
54 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
57 # We've Loaded the cache file and all our variables..
58 print "Updating Files..\n";
70 if (!$config{MAX_CLIENT}) {
71 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
72 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
73 # higher than the found value" :))
74 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
77 # Perform the strlcpy() test..
78 open(STRLCPY, ">.test.cpp");
79 print STRLCPY "#include <string.h>
81 int main() { char a[10]; char b[10]; strlcpy(a,b,10); printf(\"%d\\n\",9); }\n";
85 system("g++ -o .test .test.cpp 2>&1");
87 # Was the build succesful?
89 $config{HAS_STRLCPY} = "true";
90 system("rm -f .test .test.cpp");
93 ################################################################################
94 # BEGIN INTERACTIVE PART #
95 ################################################################################
99 # Display Splash Logo..
101 chomp($wholeos = `uname -mnr`);
103 # Display Introduction Message..
105 Welcome to the InspIRCd Configuration program!
107 *** If you are unsure of any of these values, leave it blank for ***
108 *** standard settings that will work, and your server will run ***
109 *** using them. If you are running this server as part of a ***
110 *** larger network, you must consult with your network admins ***
111 *** for the proper values to use, or server links will be unstable! ***
113 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
114 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
115 dir, otherwise you won't have a config file!
117 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
119 # Directory Settings..
120 dir_check("are the configuration files", "CONFIG_DIR");
121 dir_check("are the modules to be compiled to", "MODULE_DIR");
122 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
123 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
125 # File Descriptor Settings..
128 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
129 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
130 chomp($var = <STDIN>);
131 if ($var eq "") { $var = $config{MAX_CLIENT}; }
132 if ($var =~ /^\d+$/) {
133 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
134 # Client has entered a larger number than the 'discovered' value
136 print "WARNING: Our scans have indicated that you are attempting
137 to use more sockets than there are avaliable. Are you sure
138 you wish to do this? It may cause the IRCd to malfunction [y/n]
139 [\033[1;32mn\033[0m] -> $c";
140 chomp($tmp = <STDIN>);
142 print "Please enter the correct value.\n\n";
147 print "You must enter a number in this field. Please try again.\n\n";
150 # If we get here, we should be good to go.
151 $config{MAX_CLIENT} = $var;
158 print "What is the Maximum length of nicknames?\n";
159 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
160 chomp($var = <STDIN>);
161 if ($var eq "") { $var = $config{NICK_LENGT}; }
162 if ($var =~ /^\d+$/) {
163 # We don't care what the number is, set it and be on our way.
164 $config{NICK_LENGT} = $var;
168 print "You must enter a number in this field. Please try again.\n\n";
174 print "What is the Maximum number of mode changes in one line?\n";
175 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
176 chomp($var = <STDIN>);
177 if ($var eq "") { $var = $config{MAXI_MODES}; }
178 if ($var =~ /^\d+$/) {
179 # We don't care what the number is, set it and be on our way.
180 $config{MAXI_MODES} = $var;
184 print "You must enter a number in this field. Please try again.\n\n";
189 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
190 The InspIRCd Team will _NOT_ support any bug reports above 0.
191 Also note, the IRCd behaviour will be different depending on this value.
192 Please read the documentation for more information.
194 The Higher the number, the more optimised your binary will be. This value will default to 0
195 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
196 print "[\033[1;32m0\033[0m] -> ";
197 chomp($var = <STDIN>);
199 $config{OPTIMITEMP} = 1;
200 $config{OPTIMISATI} = "-O";
201 } elsif ($var == 2) {
202 $config{OPTIMITEMP} = 2;
203 $config{OPTIMISATI} = "-O2";
204 } elsif ($var == 3) {
205 $config{OPTIMITEMP} = 3;
206 $config{OPTIMISATI} = "-O3";
208 $config{OPTIMITEMP} = 0;
209 $config{OPTIMISATI} = "-g";
212 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
213 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
214 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
215 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
216 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
217 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
218 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
219 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
220 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
221 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
227 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
228 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
230 ################################################################################
232 ################################################################################
234 # Retrieves the .config.cache file, and loads values into the main config hash.
235 open(CACHE, ".config.cache") or return undef;
239 # Ignore Blank lines, and comments..
243 my ($key, $value) = split("=", $_);
244 $value =~ /^\"(.*)\"$/;
245 # Do something with data here!
253 # Dump the contents of %config
254 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
255 open(FILEHANDLE, ">.config.cache");
256 foreach $key (keys %config)
258 print FILEHANDLE "$key=\"$config{$key}\"\n";
264 my ($desc, $hash_key) = @_;
267 print "In what directory $desc?\n";
268 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
269 chomp($var = <STDIN>);
270 if ($var eq "") { $var = $config{$hash_key}; }
271 if ($var =~ /^\~\/(.+)$/) {
272 # Convert it to a full path..
273 $var = resolve_directory($ENV{HOME} . "/" . $1);
275 if (substr($var,0,1) ne "/")
277 # Assume relative Path was given.. fill in the rest.
278 $var = $this . "/$var";
280 $var = resolve_directory($var);
282 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
283 chomp($tmp = <STDIN>);
284 if (($tmp eq "") || ($tmp =~ /^y/i)) {
285 # Attempt to Create the Dir..
286 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
288 print "Unable to create directory. ($var)\n\n";
293 # They said they don't want to create, and we can't install there.
299 # Target exists, but is not a directory.
300 print "File $var exists, but is not a directory.\n\n";
304 # Either Dir Exists, or was created fine.
305 $config{$hash_key} = $var;
312 if ($config{OSNAME} eq "FreeBSD") {
313 $config{LDLIBS} = "-Ldl";
314 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual -g";
315 $config{MAKEPROG} = "gmake";
317 $config{LDLIBS} = "-ldl";
318 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual -g";
319 $config{MAKEPROG} = "make";
337 opendir(DIRHANDLE, "src/modules");
338 foreach $name (sort readdir(DIRHANDLE)) {
339 if ($name =~ /^m_(.+)\.cpp$/)
349 print "Writing \033[1;32minspircd_config.h\033[0m\n";
350 # First File.. inspircd_config.h
351 chomp(my $incos = `uname -n -s -r`);
352 chomp(my $version = `sh ./src/version.sh`);
353 open(FILEHANDLE, "> include/inspircd_config.h");
354 print FILEHANDLE <<EOF;
355 /* Auto generated by configure, do not modify! */
356 #define SYSLOG_FACILITY LOG_DAEMON
357 #define SYSLOG_LEVEL LOG_NOTICE
358 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
359 #define MOD_PATH "$config{MODULE_DIR}"
360 #define VERSION "$version"
361 #define MAXCLIENTS $config{MAX_CLIENT}
362 #define NICKMAX $config{NICK_LENGT}
363 #define CHANMAX $config{CHAN_LENGT}
364 #define MAXCHANS $config{MAX_CHANNE}
365 #define MAXMODES $config{MAXI_MODES}
366 #define OPTIMISATION $config{OPTIMITEMP}
367 #define SYSTEM "$incos"
371 if ($config{GCCVER} > 3) {
372 print FILEHANDLE "#define GCC3\n";
373 print FILEHANDLE "#define GCC34\n";
377 if ($config{GCCVER} == 3) {
378 print FILEHANDLE "#define GCC3\n";
379 if ($config{GCC34} > 3) {
380 print FILEHANDLE "#define GCC34\n";
384 if ($config{HAS_STRLCPY} eq "true") {
385 print FILEHANDLE "#define HAS_STRLCPY\n";
389 # Create a Modules List..
391 foreach $i (@modlist)
393 $modules .= "m_".$i.".so ";
395 chomp($modules); # Remove Redundant whitespace..
398 # Write all .in files.
401 opendir(DIRHANDLE, $this);
402 foreach $name (sort readdir(DIRHANDLE)) {
403 if ($name =~ /^\.(.+)\.inc$/)
406 # All .name.inc files need parsing!
408 open(FILEHANDLE, ".$file.inc");
409 while (<FILEHANDLE>) {
414 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
415 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
416 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
417 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
418 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
419 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
420 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
421 $tmp =~ s/\@MODULES\@/$modules/;
423 print "Writing \033[1;32m$file\033[0m\n";
424 open(FILEHANDLE, ">$file");
425 print FILEHANDLE $tmp;
430 # Make inspircd executable!
431 chmod 0744, 'inspircd';
434 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
435 open(FILEHANDLE, ">src/modules/Makefile");
436 print FILEHANDLE <<EOF;
437 # (C) ChatSpike development team
438 # Makefile by <Craig\@ChatSpike.net>
439 # Many Thanks to Andrew Church <achurch\@achurch.org>
440 # for assisting with making this work right.
442 # Automatically Generated by ./configure to add a modules
443 # please run ./configure --update
449 # Create a Modules List..
452 foreach $i (@modlist)
454 $flags = getcompilerflags("src/modules/m_".$i.".cpp");
455 print FILEHANDLE <<EOCHEESE;
456 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
457 \$(CC) -I../../include \$(FLAGS) -shared $flags -o m_$i.so m_$i.cpp
458 \@cp m_$i.so \$(MODPATH)/
464 sub getcompilerflags {
468 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
478 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";
479 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";
480 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";
481 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";
482 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";
483 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";
484 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";
485 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
488 sub resolve_directory {
490 return File::Spec->rel2abs($_[0]);