]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
*** empty log message ***
[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}         = "32";                                             # Default Nick Length
26 $config{CHAN_LENGT}         = "64";                                             # Default Channel Name Length
27 $config{MAX_CHANNE}         = "20";                                             # Default Max. Channels per user..
28 $config{MAXI_MODES}         = "20";                                             # Default Max. Number of Modes set at once.
29 $config{HAS_STRLCPY}        = "false";                                          # strlcpy Check.
30 $config{USE_KQUEUE}         = "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 my $continue = 0;
245 while (!$continue) {
246   print "What is the Maximum number of mode changes in one line?\n";
247   print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
248   chomp($var = <STDIN>);
249   if ($var eq "") { $var = $config{MAXI_MODES}; }
250   if ($var =~ /^\d+$/) {
251     # We don't care what the number is, set it and be on our way.
252     $config{MAXI_MODES} = $var;
253     $continue = 1;
254     print "\n";
255   } else {
256     print "You must enter a number in this field. Please try again.\n\n";
257   }
258 }
259
260 # Code Optimisation
261 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
262 The InspIRCd Team will _NOT_ support any bug reports above 0.
263 Also note, the IRCd behaviour will be different depending on this value.
264 Please read the documentation for more information.
265
266 The Higher the number, the more optimised your binary will be. This value will default to 0
267 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
268 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
269 chomp($var = <STDIN>);
270 if ($var eq "") {
271   $var = $config{OPTIMITEMP};
272 }
273
274 if ($var eq "1") {
275   $config{OPTIMITEMP} = 1;
276   $config{OPTIMISATI} = "-O";
277 } elsif ($var eq "2") {
278   $config{OPTIMITEMP} = 2;
279   $config{OPTIMISATI} = "-O2";
280 } elsif ($var eq "3") {
281   $config{OPTIMITEMP} = 3;
282   $config{OPTIMISATI} = "-O3";
283 } else {
284   $config{OPTIMITEMP} = 0;
285   $config{OPTIMISATI} = "-g";
286 }
287
288 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
289 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
290 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
291 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
292 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
293 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
294 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
295 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
296 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
297 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
298 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
299 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n\n";
300
301 makecache();
302 writefiles();
303
304 print "\n\n";
305 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
306 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
307 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
308         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";
309 }
310 if ($config{OSNAME} =~ /CYGWIN/) {
311         print <<FOO;
312 \033[1;32mWARNING!\033[0m CYGWIN does not properly support shared modules,
313 so modules will be compiled statically into the core of the ircd. The modules
314 will act like they are being loaded from disk and being unloaded from RAM,
315 however they are in fact being enabled and disabled similar to features in
316 other ircds.
317 FOO
318 }
319
320 ################################################################################
321 #                              HELPER FUNCTIONS                                #
322 ################################################################################
323 sub getcache {
324   # Retrieves the .config.cache file, and loads values into the main config hash.
325   open(CACHE, ".config.cache") or return undef;
326   while (<CACHE>) {
327     chomp;
328
329     # Ignore Blank lines, and comments..
330     next if /^\s*$/;
331     next if /^\s*#/;
332
333     my ($key, $value) = split("=", $_);
334     $value =~ /^\"(.*)\"$/;
335     # Do something with data here!
336     $config{$key} = $1;
337   }
338   close(CONFIG);
339   return "true";
340 }
341
342 sub makecache {
343   # Dump the contents of %config
344   print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
345   open(FILEHANDLE, ">.config.cache");
346   foreach $key (keys %config)
347   {
348     print FILEHANDLE "$key=\"$config{$key}\"\n";
349   }
350   close(FILEHANDLE);
351 }
352
353 sub dir_check {
354   my ($desc, $hash_key) = @_;
355   my $complete = 0;
356   while (!$complete) {
357     print "In what directory $desc?\n";
358     print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
359     chomp($var = <STDIN>);
360     if ($var eq "") { $var = $config{$hash_key}; }
361     if ($var =~ /^\~\/(.+)$/) {
362         # Convert it to a full path..
363         $var = resolve_directory($ENV{HOME} . "/" . $1);
364     }
365     if (substr($var,0,1) ne "/")
366     {
367         # Assume relative Path was given.. fill in the rest.
368         $var = $this . "/$var";
369     }
370     $var = resolve_directory($var); 
371     if (! -e $var) {
372       print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
373       chomp($tmp = <STDIN>);
374       if (($tmp eq "") || ($tmp =~ /^y/i)) {
375         # Attempt to Create the Dir..
376         $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
377         if ($chk != 0) {
378           print "Unable to create directory. ($var)\n\n";
379           # Restart Loop..
380           next;
381         }
382       } else {
383         # They said they don't want to create, and we can't install there.
384         print "\n\n";
385         next;
386       }
387     } else {
388       if (!is_dir($var)) {
389         # Target exists, but is not a directory.
390         print "File $var exists, but is not a directory.\n\n";
391         next;
392       }
393     }
394     # Either Dir Exists, or was created fine.
395     $config{$hash_key} = $var;
396     $complete = 1;
397     print "\n";
398   }
399 }
400
401 sub getosflags {
402   if ($config{OSNAME} =~ /BSD$/) {
403     $config{LDLIBS} = "-Ldl";
404     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
405     $config{MAKEPROG} = "gmake";
406     if ($config{OSNAME} eq "OpenBSD") {
407         chomp($foo = `eg++ -dumpversion | cut -c 1`);
408         # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
409         # if theyre not running this, configure lets the build continue but they probably wont manage to
410         # compile as this standard version is 2.95.3!
411         if ($foo ne "") {
412                 $config{CC} = "eg++";
413                 chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change
414                 chomp($config{GCC34}        = `eg++ -dumpversion | cut -c 3`); # the compiler path
415         }
416     }
417   } else {
418     $config{LDLIBS} = "-ldl";
419     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
420     $config{MAKEPROG} = "make";
421     if ($config{OSNAME} =~ /CYGWIN/) {
422        $config{FLAGS}  = "-frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
423        $config{LDLIBS} = "";
424        $config{MAKEPROG} = "/usr/bin/make";
425        $config{MAKEORDER} = "mods ircd config bininst";
426        $config{STATICLIBS} = "modules/mods.a";
427        $config{STATIC_LINK} = "yes";
428     }
429   }
430   if ($config{OSNAME} =~ /SunOS/) {
431     # solaris/sunos needs these
432     # socket = bsd sockets api
433     # nsl = dns stuff
434     # rt = POSIX realtime extensions
435     # resolv = inet_aton only (why isnt this in nsl?!)
436     $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
437   }
438 }
439
440 sub is_dir {
441   my ($path) = @_;
442   if (chdir($path)) {
443     chdir($this);
444     return 1;
445   } else {
446     # Just in case..
447     chdir($this);
448     return 0;
449   }
450 }
451
452 sub getmodules {
453   my $i = 0;
454   opendir(DIRHANDLE, "src/modules");
455   foreach $name (sort readdir(DIRHANDLE)) {
456     if ($name =~ /^m_(.+)\.cpp$/)
457     {
458       $mod = $1;
459       if ($mod !~ /_static$/) {
460               $modlist[$i++] = $mod;
461       }
462     }
463   }
464   closedir(DIRHANDLE);
465 }
466
467 sub writefiles {
468
469   print "Writing \033[1;32minspircd_config.h\033[0m\n";
470   # First File.. inspircd_config.h
471   chomp(my $incos = `uname -n -s -r`);
472   chomp(my $version = `sh ./src/version.sh`);
473   open(FILEHANDLE, ">include/inspircd_config.h");
474   print FILEHANDLE <<EOF;
475 /* Auto generated by configure, do not modify! */
476 #define SYSLOG_FACILITY LOG_DAEMON
477 #define SYSLOG_LEVEL LOG_NOTICE
478 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
479 #define MOD_PATH "$config{MODULE_DIR}"
480 #define VERSION "$version"
481 #define MAXCLIENTS $config{MAX_CLIENT}
482 #define NICKMAX $config{NICK_LENGT}
483 #define CHANMAX $config{CHAN_LENGT}
484 #define MAXCHANS $config{MAX_CHANNE}
485 #define MAXMODES $config{MAXI_MODES}
486 #define OPTIMISATION $config{OPTIMITEMP}
487 #define SYSTEM "$incos"
488 #define MAXBUF 514
489 EOF
490
491   if ($config{OSNAME} =~ /SunOS/) {
492     print FILEHANDLE "#define IS_SOLARIS\n";
493   }
494   if ($config{OSNAME} =~ /CYGWIN/) {
495     print FILEHANDLE "#define IS_CYGWIN\n";
496   }
497   if ($config{STATIC_LINK} eq "yes") {
498     print FILEHANDLE "#define STATIC_LINK\n";
499   }
500   if ($config{GCCVER} > 3) {
501     print FILEHANDLE "#define GCC3\n";
502     print FILEHANDLE "#define GCC34\n";
503   }
504   else
505   {
506     if ($config{GCCVER} == 3) {
507       print FILEHANDLE "#define GCC3\n";
508       if ($config{GCC34} > 3) {
509         print FILEHANDLE "#define GCC34\n";
510       }
511     }
512   }
513   if ($config{HAS_STRLCPY} eq "true") {
514     print FILEHANDLE "#define HAS_STRLCPY\n";
515   }
516   my $use_hiperf = 0;
517   if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
518     print FILEHANDLE "#define USE_KQUEUE\n";
519     $use_hiperf = 1;
520   }
521   if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
522     print FILEHANDLE "#define USE_EPOLL\n";
523     $use_hiperf = 1;
524   }
525   # user didn't choose either epoll or select for their OS.
526   # default them to USE_SELECT (ewwy puke puke)
527   if (!$use_hiperf) {
528     print FILEHANDLE "#define USE_SELECT\n";
529   }
530   close(FILEHANDLE);
531
532   # Create a Modules List..
533   my $modules = "";
534   foreach $i (@modlist)
535   {
536     if ($config{OSNAME} =~ /CYGWIN/) {
537         $modules .= "m_".$i.".o ";
538     }
539     else {
540         $modules .= "m_".$i.".so ";
541     }
542   }
543   chomp($modules);   # Remove Redundant whitespace..
544
545
546   # Write all .in files.
547   my $tmp = "";
548   my $file = "";
549   my $exe = "inspircd";
550
551   if ($config{OSNAME} =~ /CYGWIN/) {
552     $exe = "inspircd.exe";
553   }
554
555   opendir(DIRHANDLE, $this);
556   foreach $name (sort readdir(DIRHANDLE)) {
557     if ($name =~ /^\.(.+)\.inc$/)
558     {
559       $file = $1;
560       # All .name.inc files need parsing!
561       $tmp = "";
562       open(FILEHANDLE, ".$file.inc");
563       while (<FILEHANDLE>) {
564         $tmp .= $_;
565       }
566       close(FILEHANDLE);
567
568       $tmp =~ s/\@CC\@/$config{CC}/;
569       $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
570       $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
571       $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
572       $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
573       $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
574       $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
575       $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
576       $tmp =~ s/\@MODULES\@/$modules/;
577       $tmp =~ s/\@EXECUTABLE\@/$exe/;
578       $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
579       $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
580
581       print "Writing \033[1;32m$file\033[0m\n";
582       open(FILEHANDLE, ">$file");
583       print FILEHANDLE $tmp;
584     }
585   }
586   closedir(DIRHANDLE);
587
588   # Make inspircd executable!
589   chmod 0744, 'inspircd';
590
591   if ($config{OSNAME} =~ /CYGWIN/) {
592         print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
593         write_static_makefile();
594   }
595   else {
596         print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
597         write_dynamic_makefile();
598   }
599
600
601   # Modules Makefile..
602   print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
603   open(FILEHANDLE, ">src/modules/Makefile");
604   print FILEHANDLE <<EOF;
605 # (C) ChatSpike development team
606 # Makefile by <Craig\@ChatSpike.net>
607 # Many Thanks to Andrew Church <achurch\@achurch.org>
608 #    for assisting with making this work right.
609 #
610 # Automatically Generated by ./configure to add a modules
611 # please run ./configure --update
612
613 all: \$(MODULES)
614
615 EOF
616
617   # Create a Modules List..
618   my $modules = "";
619   my $flags = "";
620   if ($config{OSNAME} =~ /CYGWIN/) {
621      open(MODLIST,">include/modlist.h");
622      print MODLIST <<HEADER;
623 // Generated automatically by configure. DO NOT EDIT!
624
625 #ifndef __SYMBOLS__H_CONFIGURED__
626 #define __SYMBOLS__H_CONFIGURED__
627
628 HEADER
629      foreach $i (@modlist) {
630         if ($i !~ /_static$/) {
631                 print MODLIST "extern \"C\" void * $i\_init (void);\n";
632         }
633      }
634      print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
635   }
636   foreach $i (@modlist)
637   {
638     if ($i !~ /_static$/) {
639      $flags = getcompilerflags("src/modules/m_".$i.".cpp");
640      if ($config{OSNAME} =~ /CYGWIN/) {
641         print FILEHANDLE <<EOCHEESE;
642 m_$i.o: m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
643         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i\_static.cpp
644         mv m_$i\_static.o ../m_$i.o
645
646 EOCHEESE
647         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
648         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
649         open(MUNGED,">src/modules/m_".$i."_static.cpp") or die("Could not create m_".$i."_static.cpp");
650         while (chomp($a = <MODULE>)) { 
651                 $a =~ s/init_module/$i\_init/g;
652                 $a =~ s/Srv/$i\Srv/g;
653                 print MUNGED "$a\n";
654         }
655         close(MODULE);
656         close(MUNGED);
657         print MODLIST <<EOENT;
658 {"m_$i.so",\&$i\_init},
659 EOENT
660         print "done\n";
661      }
662      else {
663          print FILEHANDLE <<EOCHEESE;
664 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
665         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
666         \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
667         cp m_$i.so \$(MODPATH)/
668         chmod 0700 \$(MODPATH)/m_$i.so
669
670 EOCHEESE
671       }
672    }
673   }
674   if ($config{OSNAME} =~ /CYGWIN/) {
675      print MODLIST "{0}};\n\n#endif\n";
676      close(MODLIST);
677   }
678 }
679
680 sub getcompilerflags {
681   my ($file) = @_;
682   open(FLAGS, $file);
683   while (<FLAGS>) {
684     if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
685       close(FLAGS);
686       return $1;
687     }
688   }
689   close(FLAGS);
690   return undef;
691 }
692
693 sub show_splash {
694   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";
695   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";
696   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";
697   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";
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::::::: \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:\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::\n";
701   print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
702 }
703
704 sub resolve_directory {
705         use File::Spec;
706         return File::Spec->rel2abs($_[0]);
707 }
708
709 sub yesno {
710         my ($flag,$prompt) = @_;
711         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
712         chomp($tmp = <STDIN>);
713         if ($tmp eq "") { $tmp = $config{$flag} }
714
715         if (($tmp eq "") || ($tmp =~ /^y/i)) {
716                 $config{$flag} = "y";
717         } else {
718                 $config{$flag} = "n";
719         }
720         return;
721 }
722
723
724 sub write_static_makefile {
725         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
726         print FH <<EOM;
727 # Insp Makefile :p
728 #
729 # (C) ChatSpike development team
730 # Makefile by <Craig\@ChatSpike.net>
731 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
732 #
733
734 CC = im a cheezeball
735
736 CXXFLAGS = -I../include \${FLAGS}
737
738 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
739
740 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h
741         \$(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)
742
743 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
744         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
745
746 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
747         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
748
749 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
750         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
751
752 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
753         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
754
755 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
756         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
757
758 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
759         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
760
761 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
762         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
763
764 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
765         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
766
767 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
768         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_util.cpp
769
770 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
771         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_io.cpp
772
773 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
774         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c connection.cpp
775
776 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
777         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
778
779 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
780         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
781
782 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
783         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dnsqueue.cpp
784
785 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
786         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
787
788 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
789         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
790
791 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
792         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
793
794 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
795         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
796
797 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
798         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c servers.cpp
799
800
801 EOM
802 close(FH);
803 }
804
805 sub write_dynamic_makefile {
806         open(FH,">src/Makefile") or die("Could not write src/Makefile");
807         print FH <<EOM;
808 # Insp Makefile :p
809 #
810 # (C) ChatSpike development team
811 # Makefile by <Craig\@ChatSpike.net>
812 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
813 #
814
815 CC = im a cheezeball
816
817 CXXFLAGS = -I../include \${FLAGS}
818
819 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
820
821 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h
822         \$(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
823
824 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
825         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
826         \$(CC) -shared -o libIRCDhash.so hashcomp.o
827
828 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
829         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
830         \$(CC) -shared -o libIRCDhelper.so helperfuncs.o
831
832 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
833         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
834         \$(CC) -shared -o libIRCDchannels.so channels.o
835
836 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
837         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
838         \$(CC) -shared -o libIRCDmode.so mode.o
839
840 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
841         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
842         \$(CC) -shared -o libIRCDxline.so xline.o
843
844 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
845         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
846         \$(CC) -shared -o libIRCDstring.so inspstring.o
847
848 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
849         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
850         \$(CC) -shared -o libIRCDasyncdns.so dns.o
851
852 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
853         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
854         \$(CC) -shared -o libIRCDbase.so base.o
855
856 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
857         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_util.cpp
858         \$(CC) -shared -o libIRCDutil.so inspircd_util.o
859
860 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
861         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd_io.cpp
862         \$(CC) -shared -o libIRCDio.so inspircd_io.o
863
864 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
865         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c connection.cpp
866         \$(CC) -shared -o libIRCDconnection.so connection.o
867
868 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
869         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
870         \$(CC) -shared -o libIRCDmessage.so message.o
871
872 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
873         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
874         \$(CC) -shared -o libIRCDcommands.so commands.o
875
876 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
877         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dnsqueue.cpp
878         \$(CC) -shared -o libIRCDdnsqueue.so dnsqueue.o
879
880 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
881         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
882         \$(CC) -shared -o libIRCDdynamic.so dynamic.o
883
884 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
885         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
886         \$(CC) -shared -o libIRCDusers.so users.o
887
888 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
889         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
890         \$(CC) -shared -o libIRCDmodules.so modules.o
891
892 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
893         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
894         \$(CC) -shared -o libIRCDwildcard.so wildcard.o
895
896 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
897         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c servers.cpp
898         \$(CC) -shared -o libIRCDservers.so servers.o
899
900 EOM
901 close(FH);
902 }