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";
96 ################################################################################
97 # BEGIN INTERACTIVE PART #
98 ################################################################################
102 # Display Splash Logo..
104 chomp($wholeos = `uname -mnr`);
106 # Display Introduction Message..
108 Welcome to the InspIRCd Configuration program!
110 *** If you are unsure of any of these values, leave it blank for ***
111 *** standard settings that will work, and your server will run ***
112 *** using them. If you are running this server as part of a ***
113 *** larger network, you must consult with your network admins ***
114 *** for the proper values to use, or server links will be unstable! ***
116 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
117 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
118 dir, otherwise you won't have a config file!
120 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
122 # Directory Settings..
123 dir_check("are the configuration files", "CONFIG_DIR");
124 dir_check("are the modules to be compiled to", "MODULE_DIR");
125 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
126 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
128 if ($config{OSNAME} =~ /BSD$/) {
129 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?");
132 # File Descriptor Settings..
135 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
136 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
137 chomp($var = <STDIN>);
138 if ($var eq "") { $var = $config{MAX_CLIENT}; }
139 if ($var =~ /^\d+$/) {
140 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
141 # Client has entered a larger number than the 'discovered' value
143 print "WARNING: Our scans have indicated that you are attempting
144 to use more sockets than there are avaliable. Are you sure
145 you wish to do this? It may cause the IRCd to malfunction [y/n]
146 [\033[1;32mn\033[0m] -> $c";
147 chomp($tmp = <STDIN>);
149 print "Please enter the correct value.\n\n";
154 print "You must enter a number in this field. Please try again.\n\n";
157 # If we get here, we should be good to go.
158 $config{MAX_CLIENT} = $var;
165 print "What is the Maximum length of nicknames?\n";
166 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
167 chomp($var = <STDIN>);
168 if ($var eq "") { $var = $config{NICK_LENGT}; }
169 if ($var =~ /^\d+$/) {
170 # We don't care what the number is, set it and be on our way.
171 $config{NICK_LENGT} = $var;
175 print "You must enter a number in this field. Please try again.\n\n";
181 print "What is the Maximum number of mode changes in one line?\n";
182 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
183 chomp($var = <STDIN>);
184 if ($var eq "") { $var = $config{MAXI_MODES}; }
185 if ($var =~ /^\d+$/) {
186 # We don't care what the number is, set it and be on our way.
187 $config{MAXI_MODES} = $var;
191 print "You must enter a number in this field. Please try again.\n\n";
196 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
197 The InspIRCd Team will _NOT_ support any bug reports above 0.
198 Also note, the IRCd behaviour will be different depending on this value.
199 Please read the documentation for more information.
201 The Higher the number, the more optimised your binary will be. This value will default to 0
202 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
203 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
204 chomp($var = <STDIN>);
206 $var = $config{OPTIMITEMP};
210 $config{OPTIMITEMP} = 1;
211 $config{OPTIMISATI} = "-O";
212 } elsif ($var eq "2") {
213 $config{OPTIMITEMP} = 2;
214 $config{OPTIMISATI} = "-O2";
215 } elsif ($var eq "3") {
216 $config{OPTIMITEMP} = 3;
217 $config{OPTIMISATI} = "-O3";
219 $config{OPTIMITEMP} = 0;
220 $config{OPTIMISATI} = "-g";
223 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
224 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
225 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
226 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
227 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
228 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
229 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
230 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
231 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
232 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
238 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
239 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
241 ################################################################################
243 ################################################################################
245 # Retrieves the .config.cache file, and loads values into the main config hash.
246 open(CACHE, ".config.cache") or return undef;
250 # Ignore Blank lines, and comments..
254 my ($key, $value) = split("=", $_);
255 $value =~ /^\"(.*)\"$/;
256 # Do something with data here!
264 # Dump the contents of %config
265 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
266 open(FILEHANDLE, ">.config.cache");
267 foreach $key (keys %config)
269 print FILEHANDLE "$key=\"$config{$key}\"\n";
275 my ($desc, $hash_key) = @_;
278 print "In what directory $desc?\n";
279 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
280 chomp($var = <STDIN>);
281 if ($var eq "") { $var = $config{$hash_key}; }
282 if ($var =~ /^\~\/(.+)$/) {
283 # Convert it to a full path..
284 $var = resolve_directory($ENV{HOME} . "/" . $1);
286 if (substr($var,0,1) ne "/")
288 # Assume relative Path was given.. fill in the rest.
289 $var = $this . "/$var";
291 $var = resolve_directory($var);
293 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
294 chomp($tmp = <STDIN>);
295 if (($tmp eq "") || ($tmp =~ /^y/i)) {
296 # Attempt to Create the Dir..
297 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
299 print "Unable to create directory. ($var)\n\n";
304 # They said they don't want to create, and we can't install there.
310 # Target exists, but is not a directory.
311 print "File $var exists, but is not a directory.\n\n";
315 # Either Dir Exists, or was created fine.
316 $config{$hash_key} = $var;
323 if ($config{OSNAME} eq "FreeBSD") {
324 $config{LDLIBS} = "-Ldl";
325 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
326 $config{MAKEPROG} = "gmake";
328 $config{LDLIBS} = "-ldl";
329 $config{FLAGS} = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
330 $config{MAKEPROG} = "make";
348 opendir(DIRHANDLE, "src/modules");
349 foreach $name (sort readdir(DIRHANDLE)) {
350 if ($name =~ /^m_(.+)\.cpp$/)
360 print "Writing \033[1;32minspircd_config.h\033[0m\n";
361 # First File.. inspircd_config.h
362 chomp(my $incos = `uname -n -s -r`);
363 chomp(my $version = `sh ./src/version.sh`);
364 open(FILEHANDLE, "> include/inspircd_config.h");
365 print FILEHANDLE <<EOF;
366 /* Auto generated by configure, do not modify! */
367 #define SYSLOG_FACILITY LOG_DAEMON
368 #define SYSLOG_LEVEL LOG_NOTICE
369 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
370 #define MOD_PATH "$config{MODULE_DIR}"
371 #define VERSION "$version"
372 #define MAXCLIENTS $config{MAX_CLIENT}
373 #define NICKMAX $config{NICK_LENGT}
374 #define CHANMAX $config{CHAN_LENGT}
375 #define MAXCHANS $config{MAX_CHANNE}
376 #define MAXMODES $config{MAXI_MODES}
377 #define OPTIMISATION $config{OPTIMITEMP}
378 #define SYSTEM "$incos"
382 if ($config{GCCVER} > 3) {
383 print FILEHANDLE "#define GCC3\n";
384 print FILEHANDLE "#define GCC34\n";
388 if ($config{GCCVER} == 3) {
389 print FILEHANDLE "#define GCC3\n";
390 if ($config{GCC34} > 3) {
391 print FILEHANDLE "#define GCC34\n";
395 if ($config{HAS_STRLCPY} eq "true") {
396 print FILEHANDLE "#define HAS_STRLCPY\n";
398 if ($config{USE_KQUEUE} eq "y") {
399 print FILEHANDLE "#define USE_KQUEUE\n";
403 # Create a Modules List..
405 foreach $i (@modlist)
407 $modules .= "m_".$i.".so ";
409 chomp($modules); # Remove Redundant whitespace..
412 # Write all .in files.
415 opendir(DIRHANDLE, $this);
416 foreach $name (sort readdir(DIRHANDLE)) {
417 if ($name =~ /^\.(.+)\.inc$/)
420 # All .name.inc files need parsing!
422 open(FILEHANDLE, ".$file.inc");
423 while (<FILEHANDLE>) {
428 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
429 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
430 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
431 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
432 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
433 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
434 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
435 $tmp =~ s/\@MODULES\@/$modules/;
437 print "Writing \033[1;32m$file\033[0m\n";
438 open(FILEHANDLE, ">$file");
439 print FILEHANDLE $tmp;
444 # Make inspircd executable!
445 chmod 0744, 'inspircd';
448 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
449 open(FILEHANDLE, ">src/modules/Makefile");
450 print FILEHANDLE <<EOF;
451 # (C) ChatSpike development team
452 # Makefile by <Craig\@ChatSpike.net>
453 # Many Thanks to Andrew Church <achurch\@achurch.org>
454 # for assisting with making this work right.
456 # Automatically Generated by ./configure to add a modules
457 # please run ./configure --update
463 # Create a Modules List..
466 foreach $i (@modlist)
468 $flags = getcompilerflags("src/modules/m_".$i.".cpp");
469 print FILEHANDLE <<EOCHEESE;
470 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
471 \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
472 \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
473 cp m_$i.so \$(MODPATH)/
474 chmod 0700 \$(MODPATH)/m_$i.so
480 sub getcompilerflags {
484 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
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::\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... \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:::: \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:\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:::: \033[1;33m##\033[0m:\n";
499 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";
500 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";
501 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
504 sub resolve_directory {
506 return File::Spec->rel2abs($_[0]);
510 my ($flag,$prompt) = @_;
511 print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
512 chomp($tmp = <STDIN>);
513 if ($tmp eq "") { $tmp = $config{$flag} }
515 if (($tmp eq "") || ($tmp =~ /^y/i)) {
516 $config{$flag} = "y";
518 $config{$flag} = "n";