]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Added another check for 'NoServerUline' type thing.
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2 # InspIRCd Configuration Script
3 #
4 # Copyright 2003 The ChatSpike Development Team
5 # <brain@chatspike.net>
6 # <Craig@chatspike.net>
7 #
8 # [14:21] Brain: <matrix impression> i know perl-fu!
9 #
10 # $Id$
11 #
12 ########################################
13
14
15 $this = $ENV{PWD};                                              # PWD, Regardless.
16 @modlist = ();                                                  # Declare for Module List..
17 %config = ();                                                   # Initiate Configuration Hash..
18 $config{ME}                 = $ENV{PWD};                        # Present Working Directory
19 $config{CONFIG_DIR}         = $ENV{PWD}."/conf";                # Configuration Directory
20 $config{MODULE_DIR}         = $ENV{PWD}."/modules";             # Modules Directory
21 $config{BINARY_DIR}         = $ENV{PWD}."/bin";                 # Binary Directory
22 $config{OPTIMITEMP}         = "0";                              # Default Optimisation Value
23 $config{OPTIMISATI}         = "-g";                             # Optimisation Flag
24 $config{NICK_LENGT}         = "32";                             # Default Nick Length
25 $config{CHAN_LENGT}         = "64";                             # Default Channel Name Length
26 $config{MAX_CHANNE}         = "20";                             # Default Max. Channels per user..
27 $config{MAXI_MODES}         = "20";                             # Default Max. Number of Modes set at once.
28 $config{HAS_STRLCPY}        = "false";                          # strlcpy Check.
29 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);           # FD Limit
30 chomp($config{GCCVER}       = `gcc -dumpversion | cut -c 1`);   # Major GCC Version
31 chomp($config{GCC34}        = `gcc -dumpversion | cut -c 3`);   # Minor GCC Version
32 chomp($config{OSNAME}       = `uname -s`);                      # Operating System Name
33
34 if (!$config{OSNAME}) {
35   $config{OSNAME} = "Unknown";                                  # For use when uname fails.
36 }
37
38 if (!$config{MAX_CLIENT_T}) { 
39   $config{MAX_CLIENT_T} = 1024;                                 # Set a reasonable 'Default'
40   $fd_scan_fail = "true";                                       # Used Later
41 }
42
43 # Get and Set some important vars..
44 getmodules();
45
46 my $arg = $ARGV[0];                                             # Do Some Argument Checks..
47 if ($arg eq "-clean") { `rm -rf .config.cache`; }               # Remove the config.cache file.
48
49 if ($arg eq "-update") {
50   # Does the cache file exist?
51   if (!getcache()) {
52     # No, No it doesn't.. *BASH*
53     print "You have not run ./configure before. Please do this before trying to run the update script.\n";
54     exit 0;
55   } else {
56     # We've Loaded the cache file and all our variables..
57     print "Updating Files..\n";
58     getosflags();
59     writefiles();
60     print "Complete.\n";
61     exit;
62   }
63 }
64
65
66 getcache();
67 getosflags();
68
69 if (!$config{MAX_CLIENT}) { 
70   # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
71   # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
72   # higher than the found value" :))
73   $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
74 }
75
76 # Perform the strlcpy() test..
77 open(STRLCPY, ">.test.cpp");
78 print STRLCPY "#include <string.h>
79 #include <stdio.h>
80 int main() { char a[10]; char b[10]; strlcpy(a,b,10); printf(\"%d\\n\",9); }\n";
81 close(STRLCPY);
82
83 # Build the Binary..
84 system("g++ -o .test .test.cpp 2>&1");
85
86 # Was the build succesful?
87 if (-e ".test") {
88   $config{HAS_STRLCPY} = "true";
89   system("rm -f .test .test.cpp");
90 }
91
92 ################################################################################
93 #                          BEGIN INTERACTIVE PART                              #
94 ################################################################################
95
96 # Clear the Screen..
97 system("clear");
98 # Display Splash Logo..
99 show_splash();
100 chomp($wholeos = `uname -mnr`);
101
102 # Display Introduction Message..
103 print "
104 Welcome to the InspIRCd Configuration program!
105
106 *** If you are unsure of any of these values, leave it blank for    ***
107 *** standard settings that will work, and your server will run      ***
108 *** using them. If you are running this server as part of a         ***
109 *** larger network, you must consult with your network admins       ***
110 *** for the proper values to use, or server links will be unstable! ***
111
112 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
113 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
114 dir, otherwise you won't have a config file!
115
116 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
117
118 # Directory Settings..
119 dir_check("are the configuration files", "CONFIG_DIR");
120 dir_check("are the modules to be compiled to", "MODULE_DIR");
121 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
122
123 # File Descriptor Settings..
124 my $continue = 0;
125 while (!$continue) {
126   print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
127   print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
128   chomp($var = <STDIN>);
129   if ($var eq "") { $var = $config{MAX_CLIENT}; }
130   if ($var =~ /^\d+$/) {
131     if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
132       # Client has entered a larger number than the 'discovered' value
133       # Confirm.
134       print "WARNING: Our scans have indicated that you are attempting
135 to use more sockets than there are avaliable. Are you sure
136 you wish to do this? It may cause the IRCd to malfunction [y/n]
137 [\033[1;32mn\033[0m] -> $c";
138       chomp($tmp = <STDIN>);
139       if ($tmp ne "y") {
140         print "Please enter the correct value.\n\n";
141         next;
142       }
143     }
144   } else {
145     print "You must enter a number in this field. Please try again.\n\n";
146     next;
147   }
148   # If we get here, we should be good to go.
149   $config{MAX_CLIENT} = $var;
150   $continue = 1;
151   print "\n";
152 }
153
154 my $continue = 0;
155 while (!$continue) {
156   print "What is the Maximum length of nicknames?\n";
157   print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
158   chomp($var = <STDIN>);
159   if ($var eq "") { $var = $config{NICK_LENGT}; }
160   if ($var =~ /^\d+$/) {
161     # We don't care what the number is, set it and be on our way.
162     $config{NICK_LENGT} = $var;
163     $continue = 1;
164     print "\n";
165   } else {
166     print "You must enter a number in this field. Please try again.\n\n";
167   }
168 }
169
170 my $continue = 0;
171 while (!$continue) {
172   print "What is the Maximum number of mode changes in one line?\n";
173   print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
174   chomp($var = <STDIN>);
175   if ($var eq "") { $var = $config{MAXI_MODES}; }
176   if ($var =~ /^\d+$/) {
177     # We don't care what the number is, set it and be on our way.
178     $config{MAXI_MODES} = $var;
179     $continue = 1;
180     print "\n";
181   } else {
182     print "You must enter a number in this field. Please try again.\n\n";
183   }
184 }
185
186 # Code Optimisation
187 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
188 The InspIRCd Team will _NOT_ support any bug reports above 0.
189 Also note, the IRCd behaviour will be different depending on this value.
190 Please read the documentation for more information.
191
192 The Higher the number, the more optimised your binary will be. This value will default to 0
193 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
194 print "[\033[1;32m0\033[0m] -> ";
195 chomp($var = <STDIN>);
196 if ($var == 1) {
197   $config{OPTIMITEMP} = 1;
198   $config{OPTIMISATI} = "-O";
199 } elsif ($var == 2) {
200   $config{OPTIMITEMP} = 2;
201   $config{OPTIMISATI} = "-O2";
202 } elsif ($var == 3) {
203   $config{OPTIMITEMP} = 3;
204   $config{OPTIMISATI} = "-O3";
205 } else {
206   $config{OPTIMITEMP} = 0;
207   $config{OPTIMISATI} = "-g";
208 }
209
210 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
211 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
212 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
213 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
214 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
215 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
216 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
217 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
218 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
219 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n\n";
220
221 makecache();
222 writefiles();
223
224 print "\n\n";
225 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
226 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
227
228 ################################################################################
229 #                              HELPER FUNCTIONS                                #
230 ################################################################################
231 sub getcache {
232   # Retrieves the .config.cache file, and loads values into the main config hash.
233   open(CACHE, ".config.cache") or return undef;
234   while (<CACHE>) {
235     chomp;
236
237     # Ignore Blank lines, and comments..
238     next if /^\s*$/;
239     next if /^\s*#/;
240
241     my ($key, $value) = split("=", $_);
242     $value =~ /^\"(.*)\"$/;
243     # Do something with data here!
244     $config{$key} = $1;
245   }
246   close(CONFIG);
247   return "true";
248 }
249
250 sub makecache {
251   # Dump the contents of %config
252   print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
253   open(FILEHANDLE, ">.config.cache");
254   foreach $key (keys %config)
255   {
256     print FILEHANDLE "$key=\"$config{$key}\"\n";
257   }
258   close(FILEHANDLE);
259 }
260
261 sub dir_check {
262   my ($desc, $hash_key) = @_;
263   my $complete = 0;
264   while (!$complete) {
265     print "In what directory $desc?\n";
266     print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
267     chomp($var = <STDIN>);
268     if ($var eq "") { $var = $config{$hash_key}; }
269     if (substr($var,0,1) ne "/")
270     {
271         # Assume relative Path was given.. fill in the rest.
272         $var = $this . "/$var";
273     }
274     if (substr($var, 0, 1) eq "~") {
275         # Convert it to a full path..
276         
277         $var = $this . substr(1,0);
278     } 
279     if (! -e $var) {
280       print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
281       chomp($tmp = <STDIN>);
282       if (($tmp eq "") || ($tmp = "y")) {
283         # Attempt to Create the Dir..
284         $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
285         if ($chk != 0) {
286           print "Unable to create directory. ($var)\n\n";
287           # Restart Loop..
288           next;
289         }
290       } else {
291         # They said they don't want to create, and we can't install there.
292         print "\n\n";
293         next;
294       }
295     } else {
296       if (!is_dir($var)) {
297         # Target exists, but is not a directory.
298         print "File $var exists, but is not a directory.\n\n";
299         next;
300       }
301     }
302     # Either Dir Exists, or was created fine.
303     $config{$hash_key} = $var;
304     $complete = 1;
305     print "\n";
306   }
307 }
308
309 sub getosflags {
310   if ($config{OSNAME} eq "FreeBSD") {
311     $config{LDLIBS} = "-Ldl";
312     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual -g";
313     $config{MAKEPROG} = "gmake";
314   } else {
315     $config{LDLIBS} = "-ldl";
316     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual -g";
317     $config{MAKEPROG} = "make";
318   }
319 }
320
321 sub is_dir {
322   my ($path) = @_;
323   if (chdir($path)) {
324     chdir($this);
325     return 1;
326   } else {
327     # Just in case..
328     chdir($this);
329     return 0;
330   }
331 }
332
333 sub getmodules {
334   my $i = 0;
335   opendir(DIRHANDLE, "src/modules");
336   foreach $name (sort readdir(DIRHANDLE)) {
337     if ($name =~ /^m_(.+)\.cpp$/)
338     {
339       $modlist[$i++] = $1;
340     }
341   }
342   closedir(DIRHANDLE);
343 }
344
345 sub writefiles {
346
347   print "Writing \033[1;32minspircd_config.h\033[0m\n";
348   # First File.. inspircd_config.h
349   chomp(my $incos = `uname -n -s -r`);
350   chomp(my $version = `sh ./src/version.sh`);
351   open(FILEHANDLE, "> include/inspircd_config.h");
352   print FILEHANDLE <<EOF;
353 /* Auto generated by configure, do not modify! */
354 #define SYSLOG_FACILITY LOG_DAEMON
355 #define SYSLOG_LEVEL LOG_NOTICE
356 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
357 #define MOD_PATH "$config{MODULE_DIR}"
358 #define VERSION "$version"
359 #define MAXCLIENTS $config{MAX_CLIENT}
360 #define NICKMAX $config{NICK_LENGT}
361 #define CHANMAX $config{CHAN_LENGT}
362 #define MAXCHANS $config{MAX_CHANNE}
363 #define MAXMODES $config{MAXI_MODES}
364 #define OPTIMISATION $config{OPTIMITEMP}
365 #define SYSTEM "$incos"
366 #define MAXBUF 514
367 EOF
368
369   if ($config{GCCVER} > 3) {
370     print FILEHANDLE "#define GCC3\n";
371     print FILEHANDLE "#define GCC34\n";
372   }
373   else
374   {
375     if ($config{GCCVER} == 3) {
376       print FILEHANDLE "#define GCC3\n";
377       if ($config{GCC34} > 3) {
378         print FILEHANDLE "#define GCC34\n";
379       }
380     }
381   }
382   if ($config{HAS_STRLCPY} eq "true") {
383     print FILEHANDLE "#define HAS_STRLCPY\n";
384   }
385   close(FILEHANDLE);
386
387   # Create a Modules List..
388   my $modules = "";
389   foreach $i (@modlist)
390   {
391     $modules .= "m_".$i.".so ";
392   }
393   chomp($modules);   # Remove Redundant whitespace..
394
395
396   # Write all .in files.
397   my $tmp = "";
398   my $file = "";
399   opendir(DIRHANDLE, $this);
400   foreach $name (sort readdir(DIRHANDLE)) {
401     if ($name =~ /^\.(.+)\.inc$/)
402     {
403       $file = $1;
404       # All .name.inc files need parsing!
405       $tmp = "";
406       open(FILEHANDLE, ".$file.inc");
407       while (<FILEHANDLE>) {
408         $tmp .= $_;
409       }
410       close(FILEHANDLE);
411
412       $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
413       $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
414       $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
415       $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
416       $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
417       $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
418       $tmp =~ s/\@MODULES\@/$modules/;
419
420       print "Writing \033[1;32m$file\033[0m\n";
421       open(FILEHANDLE, ">$file");
422       print FILEHANDLE $tmp;
423     }
424   }
425   closedir(DIRHANDLE);
426
427   # Make inspircd executable!
428   chmod 0744, 'inspircd';
429
430   # Modules Makefile..
431   print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
432   open(FILEHANDLE, ">src/modules/Makefile");
433   print FILEHANDLE <<EOF;
434 # (C) ChatSpike development team
435 # Makefile by <Craig\@ChatSpike.net>
436 # Many Thanks to Andrew Church <achurch\@achurch.org>
437 #    for assisting with making this work right.
438 #
439 # Automatically Generated by ./configure to add a modules
440 # please run ./configure --update
441
442 all: \$(MODULES)
443
444 EOF
445
446   # Create a Modules List..
447   my $modules = "";
448   my $flags = "";
449   foreach $i (@modlist)
450   {
451     $flags = getcompilerflags("src/modules/m_".$i.".cpp");
452     print FILEHANDLE <<EOCHEESE;
453 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
454         \$(CC) -I../../include \$(FLAGS) -shared $flags -o m_$i.so m_$i.cpp
455         \@cp m_$i.so \$(MODPATH)/
456
457 EOCHEESE
458   }
459 }
460
461 sub getcompilerflags {
462   my ($file) = @_;
463   open(FLAGS, $file);
464   while (<FLAGS>) {
465     if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
466       close(FLAGS);
467       return $1;
468     }
469   }
470   close(FLAGS);
471   return undef;
472 }
473
474 sub show_splash {
475   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";
476   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";
477   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";
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::::::: \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:\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:::: \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::\n";
482   print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
483 }