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