]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Fixed nicklength perpetually increasing on each run (reported by katsklaw)
[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 chomp($topdir = `pwd`);
15 $this = resolve_directory($topdir);                                             # PWD, Regardless.
16 @modlist = ();                                                                  # Declare for Module List..
17 %config = ();                                                                   # Initiate Configuration Hash..
18 $config{ME}                 = resolve_directory($topdir);                       # Present Working Directory
19 $config{CONFIG_DIR}         = resolve_directory($config{ME}."/conf");           # Configuration Directory
20 $config{MODULE_DIR}         = resolve_directory($config{ME}."/modules");        # Modules Directory
21 $config{BINARY_DIR}         = resolve_directory($config{ME}."/bin");            # Binary Directory
22 $config{LIBRARY_DIR}        = resolve_directory($config{ME}."/lib");            # Library Directory
23 $config{OPTIMITEMP}         = "0";                                              # Default Optimisation Value
24 $config{OPTIMISATI}         = "-g";                                             # Optimisation Flag
25 $config{NICK_LENGT}         = "31";                                             # 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}         = "y";                                              # kqueue enabled
31 $config{USE_EPOLL}          = "y";                                              # epoll enabled
32 $config{STATIC_LINK}        = "no";                                             # are doing static modules?
33 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                           # FD Limit
34 chomp($config{GCCVER}       = `gcc -dumpversion | cut -c 1`);                   # Major GCC Version
35 chomp($config{GCC34}        = `gcc -dumpversion | cut -c 3`);                   # Minor GCC Version
36 chomp($config{OSNAME}       = `/bin/uname`);                                    # Operating System Name
37 $config{CC}                 = "g++";                                            # C++ compiler
38 $config{MAKEORDER}          = "ircd mods config bininst";                       # build order
39 $config{STATICLIBS}         = "";                                               # library archive path
40
41 if ((!$config{OSNAME}) || ($config{OSNAME} eq "")) {
42   chomp($config{OSNAME} = `/usr/bin/uname`);
43   if ((!$config{OSNAME}) || ($config{OSNAME} eq "")){
44         $config{OSNAME} = "Unknown";
45   }
46 }
47
48 if (!$config{MAX_CLIENT_T}) { 
49   $config{MAX_CLIENT_T} = 1024;                                 # Set a reasonable 'Default'
50   $fd_scan_fail = "true";                                       # Used Later
51 }
52
53 # Get and Set some important vars..
54 getmodules();
55
56 my $arg = $ARGV[0];                                             # Do Some Argument Checks..
57 if ($arg eq "-clean") { `rm -rf .config.cache`; }               # Remove the config.cache file.
58
59 if ($arg eq "-update") {
60   # Does the cache file exist?
61   if (!getcache()) {
62     # No, No it doesn't.. *BASH*
63     print "You have not run ./configure before. Please do this before trying to run the update script.\n";
64     exit 0;
65   } else {
66     # We've Loaded the cache file and all our variables..
67     print "Updating Files..\n";
68     getosflags();
69     $has_epoll = $config{HAS_EPOLL};
70     $has_kqueue = $config{HAS_KQUEUE};
71     writefiles();
72     print "Complete.\n";
73     exit;
74   }
75 }
76
77 print "Checking for cache from previous configure...\n";
78 getcache();
79 print "Checking operating system version...\n";
80 getosflags();
81
82 if (!$config{MAX_CLIENT}) { 
83   # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
84   # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
85   # higher than the found value" :))
86   $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
87 }
88
89 printf "Checking if strlcpy exists... ";
90 # Perform the strlcpy() test..
91 $config{HAS_STRLCPY} = "false";
92 my $fail = 0;
93 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
94 if (!$fail)
95 {
96         while (chomp($line = <STRLCPY>))
97         {
98                 # try and find the delcaration of:
99                 # size_t strlcpy(...)
100                 if ($line =~ /size_t(\0x9|\s)+strlcpy/)
101                 {
102                         $config{HAS_STRLCPY} = "true";
103                 }
104         }
105         close(STRLCPY);
106 }
107 print "yes\n" if $config{HAS_STRLCPY} eq "true";
108 print "no\n" if $config{HAS_STRLCPY} eq "false";
109
110 printf "Checking if kqueue exists... ";
111 $has_kqueue = 0;
112 $fail = 0;
113 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
114 if (!$fail)
115 {
116         while (chomp($line = <KQUEUE>))
117         {
118                 # try and find the delcaration of:
119                 # int kqueue(void);
120                 if ($line =~ /int(\0x9|\s)+kqueue/)
121                 {
122                         $has_kqueue = 1;
123                 }
124         }
125         close(KQUEUE);
126 }
127 print "yes\n" if $has_kqueue == 1;
128 print "no\n" if $has_kqueue == 0;
129
130 printf "Checking if epoll exists... ";
131 $has_epoll = 0;
132 $fail = 0;
133 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
134 if (!$fail)
135 {
136         while (chomp($line = <EPOLL>))
137         {
138                 # try and find the declaration of:
139                 # extern int epoll_create (int __size) __THROW;
140                 if (($line =~ /int(\0x9|\s)+epoll_create(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+epoll_create\(/))
141                 {
142                         $has_epoll = 1;
143                 }
144         }
145         close(EPOLL);
146 }
147 print "yes\n" if $has_epoll == 1;
148 print "no\n" if $has_epoll == 0;
149
150 if ($config{OSNAME} =~ /CYGWIN/) {
151         $config{HAS_STRLCPY} = "true";
152 }
153
154 $config{HAS_EPOLL} = $has_epoll;
155 $config{HAS_KQUEUE} = $has_kqueue; 
156
157 ################################################################################
158 #                          BEGIN INTERACTIVE PART                              #
159 ################################################################################
160
161 # Clear the Screen..
162 system("clear");
163 # Display Splash Logo..
164 show_splash();
165 chomp($wholeos = `uname -mnr`);
166
167 # Display Introduction Message..
168 print "
169 Welcome to the InspIRCd Configuration program!
170
171 *** If you are unsure of any of these values, leave it blank for    ***
172 *** standard settings that will work, and your server will run      ***
173 *** using them. If you are running this server as part of a         ***
174 *** larger network, you must consult with your network admins       ***
175 *** for the proper values to use, or server links will be unstable! ***
176
177 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
178 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
179 dir, otherwise you won't have a config file!
180
181 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
182
183 # Directory Settings..
184 dir_check("are the configuration files", "CONFIG_DIR");
185 dir_check("are the modules to be compiled to", "MODULE_DIR");
186 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
187 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
188
189 if ($has_kqueue) {
190         yesno(USE_KQUEUE,"You are running a BSD operating system, and kqueue\nwas detected. Would you like to enable kqueue support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable kqueue?");
191 }
192 if ($has_epoll) {
193         yesno(USE_EPOLL,"You are running a Linux 2.6+ operating system, and epoll\nwas detected. Would you like to enable epoll support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable epoll?");
194 }
195 $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
196 if (!$chose_hiperf)
197 {
198         print "No high-performance socket engines are available, or you chose\n";
199         print "not to enable one. Defaulting to select() engine.\n\n";
200 }
201
202 # File Descriptor Settings..
203 my $continue = 0;
204 while (!$continue) {
205   print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
206   print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
207   chomp($var = <STDIN>);
208   if ($var eq "") { $var = $config{MAX_CLIENT}; }
209   if ($var =~ /^\d+$/) {
210     if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
211       # Client has entered a larger number than the 'discovered' value
212       # Confirm.
213       print "WARNING: Our scans have indicated that you are attempting
214 to use more sockets than there are avaliable. Are you sure
215 you wish to do this? It may cause the IRCd to malfunction [y/n]
216 [\033[1;32mn\033[0m] -> $c";
217       chomp($tmp = <STDIN>);
218       if ($tmp ne "y") {
219         print "Please enter the correct value.\n\n";
220         next;
221       }
222     }
223   } else {
224     print "You must enter a number in this field. Please try again.\n\n";
225     next;
226   }
227   # If we get here, we should be good to go.
228   $config{MAX_CLIENT} = $var;
229   $continue = 1;
230   print "\n";
231 }
232
233 my $continue = 0;
234 while (!$continue) {
235   print "What is the Maximum length of nicknames?\n";
236   print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
237   chomp($var = <STDIN>);
238   if ($var eq "") { $var = $config{NICK_LENGT}; } else { $var++; }
239   if ($var =~ /^\d+$/) {
240     # We don't care what the number is, set it and be on our way.
241     $config{NICK_LENGT} = $var;
242     $continue = 1;
243     print "\n";
244   } else {
245     print "You must enter a number in this field. Please try again.\n\n";
246   }
247 }
248
249 my $continue = 0;
250 while (!$continue) {
251   print "What is the Maximum number of mode changes in one line?\n";
252   print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
253   chomp($var = <STDIN>);
254   if ($var eq "") { $var = $config{MAXI_MODES}; }
255   if ($var =~ /^\d+$/) {
256     # We don't care what the number is, set it and be on our way.
257     $config{MAXI_MODES} = $var;
258     $continue = 1;
259     print "\n";
260   } else {
261     print "You must enter a number in this field. Please try again.\n\n";
262   }
263 }
264
265 # Code Optimisation
266 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
267 The InspIRCd Team will _NOT_ support any bug reports above 0.
268 Also note, the IRCd behaviour will be different depending on this value.
269 Please read the documentation for more information.
270
271 The Higher the number, the more optimised your binary will be. This value will default to 0
272 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
273 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
274 chomp($var = <STDIN>);
275 if ($var eq "") {
276   $var = $config{OPTIMITEMP};
277 }
278
279 if ($var eq "1") {
280   $config{OPTIMITEMP} = 1;
281   $config{OPTIMISATI} = "-O";
282 } elsif ($var eq "2") {
283   $config{OPTIMITEMP} = 2;
284   $config{OPTIMISATI} = "-O2";
285 } elsif ($var eq "3") {
286   $config{OPTIMITEMP} = 3;
287   $config{OPTIMISATI} = "-O3";
288 } else {
289   $config{OPTIMITEMP} = 0;
290   $config{OPTIMISATI} = "-g";
291 }
292
293 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
294 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
295 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
296 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
297 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
298 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
299 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
300 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
301 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
302 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
303 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
304 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n\n";
305
306 makecache();
307 writefiles();
308
309 print "\n\n";
310 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
311 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
312 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
313         print "\033[1;32mWARNING!\033[0m You are running OpenBSD but you are using the base gcc package\nrather than eg++. This compile will most likely fail, but i'm letting you\ngo ahead with it anyway, just in case i'm wrong :-)\n";
314 }
315 if ($config{OSNAME} =~ /CYGWIN/) {
316         print <<FOO;
317 \033[1;32mWARNING!\033[0m CYGWIN does not properly support shared modules,
318 so modules will be compiled statically into the core of the ircd. The modules
319 will act like they are being loaded from disk and being unloaded from RAM,
320 however they are in fact being enabled and disabled similar to features in
321 other ircds.
322 FOO
323 }
324
325 ################################################################################
326 #                              HELPER FUNCTIONS                                #
327 ################################################################################
328 sub getcache {
329   # Retrieves the .config.cache file, and loads values into the main config hash.
330   open(CACHE, ".config.cache") or return undef;
331   while (<CACHE>) {
332     chomp;
333
334     # Ignore Blank lines, and comments..
335     next if /^\s*$/;
336     next if /^\s*#/;
337
338     my ($key, $value) = split("=", $_);
339     $value =~ /^\"(.*)\"$/;
340     # Do something with data here!
341     $config{$key} = $1;
342   }
343   close(CONFIG);
344   return "true";
345 }
346
347 sub makecache {
348   # Dump the contents of %config
349   print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
350   open(FILEHANDLE, ">.config.cache");
351   foreach $key (keys %config)
352   {
353     print FILEHANDLE "$key=\"$config{$key}\"\n";
354   }
355   close(FILEHANDLE);
356 }
357
358 sub dir_check {
359   my ($desc, $hash_key) = @_;
360   my $complete = 0;
361   while (!$complete) {
362     print "In what directory $desc?\n";
363     print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
364     chomp($var = <STDIN>);
365     if ($var eq "") { $var = $config{$hash_key}; }
366     if ($var =~ /^\~\/(.+)$/) {
367         # Convert it to a full path..
368         $var = resolve_directory($ENV{HOME} . "/" . $1);
369     }
370     if (substr($var,0,1) ne "/")
371     {
372         # Assume relative Path was given.. fill in the rest.
373         $var = $this . "/$var";
374     }
375     $var = resolve_directory($var); 
376     if (! -e $var) {
377       print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
378       chomp($tmp = <STDIN>);
379       if (($tmp eq "") || ($tmp =~ /^y/i)) {
380         # Attempt to Create the Dir..
381         $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
382         if ($chk != 0) {
383           print "Unable to create directory. ($var)\n\n";
384           # Restart Loop..
385           next;
386         }
387       } else {
388         # They said they don't want to create, and we can't install there.
389         print "\n\n";
390         next;
391       }
392     } else {
393       if (!is_dir($var)) {
394         # Target exists, but is not a directory.
395         print "File $var exists, but is not a directory.\n\n";
396         next;
397       }
398     }
399     # Either Dir Exists, or was created fine.
400     $config{$hash_key} = $var;
401     $complete = 1;
402     print "\n";
403   }
404 }
405
406 sub getosflags {
407   if ($config{OSNAME} =~ /BSD$/) {
408     $config{LDLIBS} = "-Ldl";
409     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
410     $config{MAKEPROG} = "gmake";
411     if ($config{OSNAME} eq "OpenBSD") {
412         chomp($foo = `eg++ -dumpversion | cut -c 1`);
413         # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
414         # if theyre not running this, configure lets the build continue but they probably wont manage to
415         # compile as this standard version is 2.95.3!
416         if ($foo ne "") {
417                 $config{CC} = "eg++";
418                 chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change
419                 chomp($config{GCC34}        = `eg++ -dumpversion | cut -c 3`); # the compiler path
420         }
421     }
422   } else {
423     $config{LDLIBS} = "-ldl";
424     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
425     $config{MAKEPROG} = "make";
426     if ($config{OSNAME} =~ /CYGWIN/) {
427        $config{FLAGS}  = "-frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
428        $config{LDLIBS} = "";
429        $config{MAKEPROG} = "/usr/bin/make";
430        $config{MAKEORDER} = "mods ircd config bininst";
431        $config{STATICLIBS} = "modules/mods.a";
432        $config{STATIC_LINK} = "yes";
433     }
434   }
435   if ($config{OSNAME} =~ /SunOS/) {
436     # solaris/sunos needs these
437     # socket = bsd sockets api
438     # nsl = dns stuff
439     # rt = POSIX realtime extensions
440     # resolv = inet_aton only (why isnt this in nsl?!)
441     $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
442   }
443 }
444
445 sub is_dir {
446   my ($path) = @_;
447   if (chdir($path)) {
448     chdir($this);
449     return 1;
450   } else {
451     # Just in case..
452     chdir($this);
453     return 0;
454   }
455 }
456
457 sub getmodules {
458   my $i = 0;
459   opendir(DIRHANDLE, "src/modules");
460   foreach $name (sort readdir(DIRHANDLE)) {
461     if ($name =~ /^m_(.+)\.cpp$/)
462     {
463       $mod = $1;
464       if ($mod !~ /_static$/) {
465               $modlist[$i++] = $mod;
466       }
467     }
468   }
469   closedir(DIRHANDLE);
470 }
471
472 sub writefiles {
473
474   print "Writing \033[1;32minspircd_config.h\033[0m\n";
475   # First File.. inspircd_config.h
476   chomp(my $incos = `uname -n -s -r`);
477   chomp(my $version = `sh ./src/version.sh`);
478   open(FILEHANDLE, ">include/inspircd_config.h");
479   print FILEHANDLE <<EOF;
480 /* Auto generated by configure, do not modify! */
481 #define SYSLOG_FACILITY LOG_DAEMON
482 #define SYSLOG_LEVEL LOG_NOTICE
483 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
484 #define MOD_PATH "$config{MODULE_DIR}"
485 #define VERSION "$version"
486 #define MAXCLIENTS $config{MAX_CLIENT}
487 #define NICKMAX $config{NICK_LENGT}
488 #define CHANMAX $config{CHAN_LENGT}
489 #define MAXCHANS $config{MAX_CHANNE}
490 #define MAXMODES $config{MAXI_MODES}
491 #define OPTIMISATION $config{OPTIMITEMP}
492 #define SYSTEM "$incos"
493 #define MAXBUF 514
494 EOF
495
496   if ($config{OSNAME} =~ /SunOS/) {
497     print FILEHANDLE "#define IS_SOLARIS\n";
498   }
499   if ($config{OSNAME} =~ /CYGWIN/) {
500     print FILEHANDLE "#define IS_CYGWIN\n";
501   }
502   if ($config{STATIC_LINK} eq "yes") {
503     print FILEHANDLE "#define STATIC_LINK\n";
504   }
505   if ($config{GCCVER} > 3) {
506     print FILEHANDLE "#define GCC3\n";
507     print FILEHANDLE "#define GCC34\n";
508   }
509   else
510   {
511     if ($config{GCCVER} == 3) {
512       print FILEHANDLE "#define GCC3\n";
513       if ($config{GCC34} > 3) {
514         print FILEHANDLE "#define GCC34\n";
515       }
516     }
517   }
518   if ($config{HAS_STRLCPY} eq "true") {
519     print FILEHANDLE "#define HAS_STRLCPY\n";
520   }
521   my $use_hiperf = 0;
522   if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
523     print FILEHANDLE "#define USE_KQUEUE\n";
524     $use_hiperf = 1;
525   }
526   if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
527     print FILEHANDLE "#define USE_EPOLL\n";
528     $use_hiperf = 1;
529   }
530   # user didn't choose either epoll or select for their OS.
531   # default them to USE_SELECT (ewwy puke puke)
532   if (!$use_hiperf) {
533     print FILEHANDLE "#define USE_SELECT\n";
534   }
535   close(FILEHANDLE);
536
537   # Create a Modules List..
538   my $modules = "";
539   foreach $i (@modlist)
540   {
541     if ($config{OSNAME} =~ /CYGWIN/) {
542         $modules .= "m_".$i.".o ";
543     }
544     else {
545         $modules .= "m_".$i.".so ";
546     }
547   }
548   chomp($modules);   # Remove Redundant whitespace..
549
550
551   # Write all .in files.
552   my $tmp = "";
553   my $file = "";
554   my $exe = "inspircd";
555
556   if ($config{OSNAME} =~ /CYGWIN/) {
557     $exe = "inspircd.exe";
558   }
559
560   opendir(DIRHANDLE, $this);
561   foreach $name (sort readdir(DIRHANDLE)) {
562     if ($name =~ /^\.(.+)\.inc$/)
563     {
564       $file = $1;
565       # All .name.inc files need parsing!
566       $tmp = "";
567       open(FILEHANDLE, ".$file.inc");
568       while (<FILEHANDLE>) {
569         $tmp .= $_;
570       }
571       close(FILEHANDLE);
572
573       $tmp =~ s/\@CC\@/$config{CC}/;
574       $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
575       $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
576       $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
577       $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
578       $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
579       $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
580       $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
581       $tmp =~ s/\@MODULES\@/$modules/;
582       $tmp =~ s/\@EXECUTABLE\@/$exe/;
583       $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
584       $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
585
586       print "Writing \033[1;32m$file\033[0m\n";
587       open(FILEHANDLE, ">$file");
588       print FILEHANDLE $tmp;
589     }
590   }
591   closedir(DIRHANDLE);
592
593   # Make inspircd executable!
594   chmod 0744, 'inspircd';
595
596   if ($config{OSNAME} =~ /CYGWIN/) {
597         print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
598         write_static_makefile();
599   }
600   else {
601         print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
602         write_dynamic_makefile();
603   }
604
605
606   # Modules Makefile..
607   print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
608   open(FILEHANDLE, ">src/modules/Makefile");
609   print FILEHANDLE <<EOF;
610 # (C) ChatSpike development team
611 # Makefile by <Craig\@ChatSpike.net>
612 # Many Thanks to Andrew Church <achurch\@achurch.org>
613 #    for assisting with making this work right.
614 #
615 # Automatically Generated by ./configure to add a modules
616 # please run ./configure --update
617
618 all: \$(MODULES)
619
620 EOF
621
622   # Create a Modules List..
623   my $modules = "";
624   my $flags = "";
625   if ($config{OSNAME} =~ /CYGWIN/) {
626      open(MODLIST,">include/modlist.h");
627      print MODLIST <<HEADER;
628 // Generated automatically by configure. DO NOT EDIT!
629
630 #ifndef __SYMBOLS__H_CONFIGURED__
631 #define __SYMBOLS__H_CONFIGURED__
632
633 HEADER
634      foreach $i (@modlist) {
635         if ($i !~ /_static$/) {
636                 print MODLIST "extern \"C\" void * $i\_init (void);\n";
637         }
638      }
639      print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
640   }
641   foreach $i (@modlist)
642   {
643     if ($i !~ /_static$/) {
644      $flags = getcompilerflags("src/modules/m_".$i.".cpp");
645      if ($config{OSNAME} =~ /CYGWIN/) {
646         print FILEHANDLE <<EOCHEESE;
647 m_$i.o: m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
648         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i\_static.cpp
649         mv m_$i\_static.o ../m_$i.o
650
651 EOCHEESE
652         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
653         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
654         open(MUNGED,">src/modules/m_".$i."_static.cpp") or die("Could not create m_".$i."_static.cpp");
655         while (chomp($a = <MODULE>)) { 
656                 $a =~ s/init_module/$i\_init/g;
657                 $a =~ s/Srv/$i\Srv/g;
658                 print MUNGED "$a\n";
659         }
660         close(MODULE);
661         close(MUNGED);
662         print MODLIST <<EOENT;
663 {"m_$i.so",\&$i\_init},
664 EOENT
665         print "done\n";
666      }
667      else {
668          print FILEHANDLE <<EOCHEESE;
669 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
670         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
671         \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
672         @-rm -f \$(MODPATH)/m_$i.so
673         cp m_$i.so \$(MODPATH)/
674         chmod 0700 \$(MODPATH)/m_$i.so
675
676 EOCHEESE
677       }
678    }
679   }
680   if ($config{OSNAME} =~ /CYGWIN/) {
681      print MODLIST "{0}};\n\n#endif\n";
682      close(MODLIST);
683   }
684 }
685
686 sub getcompilerflags {
687   my ($file) = @_;
688   open(FLAGS, $file);
689   while (<FLAGS>) {
690     if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
691       close(FLAGS);
692       return $1;
693     }
694   }
695   close(FLAGS);
696   return undef;
697 }
698
699 sub show_splash {
700   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";
701   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";
702   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";
703   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";
704   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";
705   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";
706   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";
707   print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
708 }
709
710 sub resolve_directory {
711         use File::Spec;
712         return File::Spec->rel2abs($_[0]);
713 }
714
715 sub yesno {
716         my ($flag,$prompt) = @_;
717         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
718         chomp($tmp = <STDIN>);
719         if ($tmp eq "") { $tmp = $config{$flag} }
720
721         if (($tmp eq "") || ($tmp =~ /^y/i)) {
722                 $config{$flag} = "y";
723         } else {
724                 $config{$flag} = "n";
725         }
726         return;
727 }
728
729
730 sub write_static_makefile {
731         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
732         print FH <<EOM;
733 # Insp Makefile :p
734 #
735 # (C) ChatSpike development team
736 # Makefile by <Craig\@ChatSpike.net>
737 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
738 #
739
740 CC = im a cheezeball
741
742 CXXFLAGS = -I../include \${FLAGS}
743
744 all: hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o connection.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o servers.o helperfuncs.o \$(MODULES) inspircd.exe
745
746 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h
747         \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o connection.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o servers.o helperfuncs.o hashcomp.o \$(MODULES)
748
749 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
750         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
751
752 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
753         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
754
755 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
756         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
757
758 mode.o: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
759         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
760
761 xline.o: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
762         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
763
764 inspstring.o: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
765         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
766
767 dns.o: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
768         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
769
770 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
771         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
772
773 inspircd_util.o: inspircd_util.cpp ../include/base.h ../include/inspircd_util.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
774         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_util.cpp
775
776 inspircd_io.o: inspircd_io.cpp ../include/base.h ../include/inspircd_io.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
777         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_io.cpp
778
779 connection.o: connection.cpp ../include/base.h ../include/connection.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
780         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c connection.cpp
781
782 message.o: message.cpp ../include/base.h ../include/message.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
783         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
784
785 commands.o: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
786         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
787
788 dnsqueue.o: dnsqueue.cpp ../include/base.h ../include/dnsqueue.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
789         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dnsqueue.cpp
790
791 dynamic.o: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
792         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
793
794 users.o: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/connection.h
795         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
796
797 modules.o: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
798         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
799
800 wildcard.o: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
801         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
802
803 servers.o: servers.cpp ../include/base.h ../include/servers.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/connection.h
804         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c servers.cpp
805
806
807 EOM
808 close(FH);
809 }
810
811 sub write_dynamic_makefile {
812         open(FH,">src/Makefile") or die("Could not write src/Makefile");
813         print FH <<EOM;
814 # Insp Makefile :p
815 #
816 # (C) ChatSpike development team
817 # Makefile by <Craig\@ChatSpike.net>
818 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
819 #
820
821 CC = im a cheezeball
822
823 CXXFLAGS = -I../include \${FLAGS}
824
825 all: libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDconnection.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDservers.so libIRCDhelper.so inspircd
826
827 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h
828         \$(CC) -I../include \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDconnection.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDservers.so libIRCDhelper.so libIRCDhash.so
829
830 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
831         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
832         \$(CC) -shared -o libIRCDhash.so hashcomp.o
833
834 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
835         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
836         \$(CC) -shared -o libIRCDhelper.so helperfuncs.o
837
838 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
839         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
840         \$(CC) -shared -o libIRCDchannels.so channels.o
841
842 libIRCDmode.so: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
843         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
844         \$(CC) -shared -o libIRCDmode.so mode.o
845
846 libIRCDxline.so: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
847         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
848         \$(CC) -shared -o libIRCDxline.so xline.o
849
850 libIRCDstring.so: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
851         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
852         \$(CC) -shared -o libIRCDstring.so inspstring.o
853
854 libIRCDasyncdns.so: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
855         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
856         \$(CC) -shared -o libIRCDasyncdns.so dns.o
857
858 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
859         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
860         \$(CC) -shared -o libIRCDbase.so base.o
861
862 libIRCDutil.so: inspircd_util.cpp ../include/base.h ../include/inspircd_util.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
863         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_util.cpp
864         \$(CC) -shared -o libIRCDutil.so inspircd_util.o
865
866 libIRCDio.so: inspircd_io.cpp ../include/base.h ../include/inspircd_io.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
867         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_io.cpp
868         \$(CC) -shared -o libIRCDio.so inspircd_io.o
869
870 libIRCDconnection.so: connection.cpp ../include/base.h ../include/connection.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
871         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c connection.cpp
872         \$(CC) -shared -o libIRCDconnection.so connection.o
873
874 libIRCDmessage.so: message.cpp ../include/base.h ../include/message.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
875         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
876         \$(CC) -shared -o libIRCDmessage.so message.o
877
878 libIRCDcommands.so: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
879         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
880         \$(CC) -shared -o libIRCDcommands.so commands.o
881
882 libIRCDdnsqueue.so: dnsqueue.cpp ../include/base.h ../include/dnsqueue.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
883         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dnsqueue.cpp
884         \$(CC) -shared -o libIRCDdnsqueue.so dnsqueue.o
885
886 libIRCDdynamic.so: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
887         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
888         \$(CC) -shared -o libIRCDdynamic.so dynamic.o
889
890 libIRCDusers.so: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/connection.h
891         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
892         \$(CC) -shared -o libIRCDusers.so users.o
893
894 libIRCDmodules.so: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
895         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
896         \$(CC) -shared -o libIRCDmodules.so modules.o
897
898 libIRCDwildcard.so: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
899         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
900         \$(CC) -shared -o libIRCDwildcard.so wildcard.o
901
902 libIRCDservers.so: servers.cpp ../include/base.h ../include/servers.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/connection.h
903         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c servers.cpp
904         \$(CC) -shared -o libIRCDservers.so servers.o
905
906 EOM
907 close(FH);
908 }