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