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