]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Merge in nenolod's unified build patch from bug #413, thanks
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2 ###################################################
3 # InspIRCd Configuration Script
4 #
5 # Copyright 2002-2007 The InspIRCd Development Team
6 #  http://www.inspircd.org/wiki/index.php/Credits
7 #
8 # Licensed under GPL, please see the COPYING file
9 # for more information
10 #
11 # $Id$
12 #
13 ###################################################
14
15 require 5.8.0;
16 use Socket;
17 use Cwd;
18 use Getopt::Long;
19
20 # Utility functions for our buildsystem
21 use make::utilities;
22 use make::configure;
23 use make::gnutlscert;
24 use make::opensslcert;
25
26 GetOptions (
27         'enable-gnutls' => \$opt_use_gnutls,
28         'rebuild' => \$opt_rebuild,
29         'enable-openssl' => \$opt_use_openssl,
30         'disable-interactive' => \$opt_nointeractive,
31         'with-nick-length=i' => \$opt_nick_length,
32         'with-channel-length=i' => \$opt_chan_length,
33         'with-max-clients=i' => \$opt_maxclients,
34         'enable-ports' => \$opt_ports,
35         'enable-epoll' => \$opt_epoll,
36         'enable-kqueue' => \$opt_kqueue,
37         'disable-ports' => \$opt_noports,
38         'disable-epoll' => \$opt_noepoll,
39         'disable-kqueue' => \$opt_nokqueue,
40         'enable-ipv6' => \$opt_ipv6,
41         'enable-remote-ipv6' => \$opt_ipv6links,
42         'disable-remote-ipv6' => \$opt_noipv6links,
43         'with-cc=s' => \$opt_cc,
44         'with-ident-length=i' => \$opt_ident,
45         'with-quit-length=i' => \$opt_quit,
46         'with-topic-length=i' => \$opt_topic,
47         'with-maxbuf=i' => \$opt_maxbuf,
48         'with-kick-length=i' => \$opt_kick,
49         'with-gecos-length=i' => \$opt_gecos,
50         'with-away-length=i' => \$opt_away,
51         'with-max-modes=i' => \$opt_modes,
52         'prefix=s' => \$opt_base_dir,
53         'config-dir=s' => \$opt_config_dir,
54         'module-dir=s' => \$opt_module_dir,
55         'binary-dir=s' => \$opt_binary_dir,
56         'library-dir=s' => \$opt_library_dir,
57         'disable-debuginfo' => sub { $opt_disable_debug = 1 },
58         'help'  => sub { showhelp(); },
59         'modupdate' => sub { modupdate(); },
60         'update' => sub { update(); },
61         'svnupdate' => sub { svnupdate(); },
62         'clean' => sub { clean(); },
63 );
64
65 my $non_interactive = (
66         (defined $opt_library_dir) ||
67         (defined $opt_base_dir) ||
68         (defined $opt_config_dir) ||
69         (defined $opt_module_dir) ||
70         (defined $opt_base_dir) ||
71         (defined $opt_binary_dir) ||
72         (defined $opt_nointeractive) ||
73         (defined $opt_away) ||
74         (defined $opt_gecos) ||
75         (defined $opt_kick) ||
76         (defined $opt_maxclients) ||
77         (defined $opt_modes) ||
78         (defined $opt_topic) ||
79         (defined $opt_quit) ||
80         (defined $opt_ident) ||
81         (defined $opt_cc) ||
82         (defined $opt_ipv6) ||
83         (defined $opt_ipv6links) ||
84         (defined $opt_noipv6links) ||
85         (defined $opt_kqueue) ||
86         (defined $opt_epoll) ||
87         (defined $opt_ports) ||
88         (defined $opt_maxchans) ||
89         (defined $opt_opermaxchans) ||
90         (defined $opt_chan_length) ||
91         (defined $opt_nick_length) ||
92         (defined $opt_use_openssl) ||
93         (defined $opt_nokqueue) ||
94         (defined $opt_noepoll) ||
95         (defined $opt_noports) ||
96         (defined $opt_maxbuf) ||
97         (defined $opt_use_gnutls)
98 );
99 my $interactive = !$non_interactive;
100
101
102 chomp($topdir = getcwd());
103 $this = resolve_directory($topdir);                                             # PWD, Regardless.
104 @modlist = ();                                                                  # Declare for Module List..
105 %config = ();                                                                   # Initiate Configuration Hash..
106 $config{ME}              = resolve_directory($topdir);                          # Present Working Directory
107
108 $config{BASE_DIR}          = $config{ME};
109
110 if (defined $opt_base_dir)
111 {
112         $config{BASE_DIR} = $opt_base_dir;
113 }
114
115 $config{CONFIG_DIR}      = resolve_directory($config{BASE_DIR}."/conf");        # Configuration Directory
116 $config{MODULE_DIR}      = resolve_directory($config{BASE_DIR}."/modules");     # Modules Directory
117 $config{BINARY_DIR}      = resolve_directory($config{BASE_DIR}."/bin");         # Binary Directory
118 $config{LIBRARY_DIR}    = resolve_directory($config{BASE_DIR}."/lib");          # Library Directory
119
120 if (defined $opt_config_dir)
121 {
122         $config{CONFIG_DIR} = $opt_config_dir;
123 }
124 if (defined $opt_module_dir)
125 {
126         $config{MODULE_DIR} = $opt_module_dir;
127 }
128 if (defined $opt_binary_dir)
129 {
130         $config{BINARY_DIR} = $opt_binary_dir;
131 }
132 if (defined $opt_library_dir)
133 {
134         $config{LIBRARY_DIR} = $opt_library_dir;
135 }
136 chomp($config{HAS_GNUTLS}   = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
137 chomp($config{HAS_OPENSSL}  = `pkg-config --modversion openssl 2>/dev/null`);           # Openssl version
138 chomp($gnutls_ver = $config{HAS_GNUTLS});
139 chomp($openssl_ver = $config{HAS_OPENSSL});
140 $config{USE_GNUTLS}         = "n";
141 if (defined $opt_use_gnutls)
142 {
143         $config{USE_GNUTLS} = "y";                                      # Use gnutls.
144 }
145 $config{USE_OPENSSL}    = "n";                                          # Use openssl.
146 if (defined $opt_use_openssl)
147 {
148         $config{USE_OPENSSL} = "y";
149 }
150
151 # no, let's not change these.
152 $config{OPTIMITEMP}      = "0";                                         # Default Optimisation Value
153 if (!defined $opt_disable_debug)
154 {
155         $config{OPTIMISATI}      = "-g1";                               # Optimisation Flag
156 }
157 else
158 {
159         $config{OPTIMISATI}      = "-O2";                               # DEBUGGING OFF!
160 }
161
162 $config{NICK_LENGT}      = "31";                                        # Default Nick Length
163 if (defined $opt_nick_length)
164 {
165         $config{NICK_LENGT} = $opt_nick_length;
166 }
167 $config{CHAN_LENGT}      = "64";                                        # Default Channel Name Length
168 if (defined $opt_chan_length)
169 {
170         $config{CHAN_LENGT} = $opt_chan_length;
171 }
172 $config{MAXI_MODES}      = "20";                                        # Default Max. Number of Modes set at once.
173 if (defined $opt_modes)
174 {
175         $config{MAXI_MODES} = $opt_modes;
176 }
177 $config{HAS_STRLCPY}    = "false";                                      # strlcpy Check.
178 $config{HAS_STDINT}      = "false";                                     # stdint.h check
179 $config{USE_KQUEUE}      = "y";                                         # kqueue enabled
180 if (defined $opt_kqueue)
181 {
182         $config{USE_KQUEUE} = "y";
183 }
184 if (defined $opt_nokqueue)
185 {
186         $config{USE_KQUEUE} = "n";
187 }
188 $config{USE_EPOLL}        = "y";                                        # epoll enabled
189 if (defined $opt_epoll)
190 {
191         $config{USE_EPOLL} = "y";
192 }
193 if (defined $opt_noepoll)
194 {
195         $config{USE_EPOLL} = "n";
196 }
197 $config{USE_PORTS}        = "y";                                        # epoll enabled
198 if (defined $opt_ports)
199 {
200         $config{USE_PORTS} = "y";
201 }
202 if (defined $opt_noports)
203 {
204         $config{USE_PORTS} = "n";
205 }
206 $config{IPV6}          = "n";                                           # IPv6 support (experimental)
207 if (defined $opt_ipv6)
208 {
209         $config{IPV6} = "y";
210 }
211 $config{SUPPORT_IP6LINKS}   = "y";                                      # IPv4 supporting IPv6 links (experimental)
212 if (defined $opt_ipv6links)
213 {
214         $config{SUPPORT_IP6LINKS} = "y";
215 }
216 if (defined $opt_noipv6links)
217 {
218         $config{SUPPORT_IP6LINKS} = "n";
219 }
220 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                   # FD Limit
221 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`);                # Hard FD Limit
222 chomp($config{GCCVER}       = `g++ -dumpversion | cut -c 1`);           # Major GCC Version
223 $config{_SOMAXCONN} = SOMAXCONN;                                        # Max connections in accept queue
224 $config{OSNAME}             = $^O;                                      # Operating System Name
225 $config{IS_DARWIN}          = "NO";                                     # Is OSX?
226 $config{STARTSCRIPT}          = "inspircd";                     # start script?
227 $config{DESTINATION}          = "BASE";                         # Is target path.
228 $config{EXTRA_DIR}          = "";                                               # Is empty.
229 if ($config{OSNAME} =~ /darwin/i)
230 {
231         $config{IS_DARWIN} = "YES";
232         $config{STARTSCRIPT}          = "org.inspircd.plist";           # start script for OSX.
233         $config{DESTINATION}          = "LAUNCHDPATH";                          # Is OSX target.
234         $config{EXTRA_DIR}            = " launchd_dir";                         # Is OSX specific path.
235 }
236 $config{CC}                 = "g++";                                            # C++ compiler
237 if (defined $opt_cc)
238 {
239         $config{CC} = $opt_cc;
240 }
241 $exec = $config{CC} . " -dumpversion | cut -c 1";
242 chomp($config{GCCVER}           = `$exec`);                             # Major GCC Version
243 $config{MAKEORDER}              = "ircd mods";                          # build order
244 $config{MAX_IDENT}              = "12";                                 # max ident size
245 $config{MAX_QUIT}               = "255";                                # max quit message size
246 $config{MAX_TOPIC}              = "307";                                # max topic size
247 $config{MAX_KICK}               = "255";                                # max kick message size
248 $config{MAX_GECOS}              = "128";                                # max GECOS size
249 $config{MAX_AWAY}               = "200";                                # max AWAY size
250 $config{MAXBUF}                 = "512";                                # Max buffer size
251 if (defined $opt_ident)
252 {
253         $config{MAX_IDENT} = $opt_ident;
254 }
255 if (defined $opt_quit)
256 {
257         $config{MAX_QUIT} = $opt_quit;
258 }
259 if (defined $opt_topic)
260 {
261         $config{MAX_TOPIC} = $opt_topic;
262 }
263 if (defined $opt_kick)
264 {
265         $config{MAX_KICK} = $opt_kick;
266 }
267 if (defined $opt_gecos)
268 {
269         $config{MAX_GECOS} = $opt_gecos;
270 }
271 if (defined $opt_away)
272 {
273         $config{MAX_AWAY} = $opt_away;
274 }
275
276 $config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/;
277 $config{HAS_OPENSSL} = $1;
278
279 if ($config{GCCVER} eq "") {
280         print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
281         exit;
282 }
283
284 if (!$config{MAX_CLIENT_T}) { 
285         $config{MAX_CLIENT_T} = 1024;                            # Set a reasonable 'Default'
286         $fd_scan_fail = "true";                                # Used Later
287 }
288
289 # Get and Set some important vars..
290 getmodules();
291
292 sub clean
293 {
294         system("rm -rf .config.cache");
295 }
296
297 sub update
298 {
299         eval {
300                 chomp($topdir = getcwd());
301                 $this = resolve_directory($topdir);                                          # PWD, Regardless.
302                 getmodules();
303                 # Does the cache file exist?
304                 if (!getcache()) {
305                         # No, No it doesn't.. *BASH*
306                         print "You have not run ./configure before. Please do this before trying to run the update script.\n";
307                         exit 0;
308                 } else {
309                         # We've Loaded the cache file and all our variables..
310                         print "Updating Files..\n";
311                         getosflags();
312                         if ($opt_disable_debug == 1)
313                         {
314                                 print "Disabling debug information (-g).\n";
315                                 $config{OPTIMISATI} = "";
316                                 getosflags();
317                         }
318                         $has_epoll = $config{HAS_EPOLL};
319                         $has_ports = $config{HAS_PORTS};
320                         $has_kqueue = $config{HAS_KQUEUE};
321                         writefiles(1);
322                         makecache();
323                         print "Complete.\n";
324                         exit;
325                 }
326         };
327         if ($@)
328         {
329                 print "Configure update failed: $@\n";
330         }
331         exit;
332 }
333
334 sub modupdate
335 {
336         eval {
337                 chomp($topdir = getcwd());
338                 $this = resolve_directory($topdir);                                          # PWD, Regardless.
339                 getmodules();
340                 # Does the cache file exist?
341                 if (!getcache()) {
342                         # No, No it doesn't.. *BASH*
343                         print "You have not run ./configure before. Please do this before trying to run the update script.\n";
344                         exit 0;
345                 } else {
346                         # We've Loaded the cache file and all our variables..
347                         print "Updating Files..\n";
348                         getosflags();
349                         $has_epoll = $config{HAS_EPOLL};
350                         $has_ports = $config{HAS_PORTS};
351                         $has_kqueue = $config{HAS_KQUEUE};
352                         writefiles(0);
353                         makecache();
354                         print "Complete.\n";
355                         exit;
356                 }
357         };
358         if ($@)
359         {
360                 print "Module update failed: $@\n";
361         }
362         exit;
363 }
364
365
366
367 sub svnupdate
368 {
369         my $fail = 0;
370         open(FH,"<.svn/entries") or $fail = 1;
371         if ($fail) {
372                 print "This is not an SVN copy of InspIRCd.\n";
373                 exit;
374         }
375         else
376         {
377                 close(FH);
378         }
379         system("svn update");
380         system("perl configure -update");
381         if (defined $opt_rebuild) {
382                 system("make install");
383         }
384         exit;
385 }
386
387 print "Running non-interactive configure...\n" unless $interactive;
388 print "Checking for cache from previous configure... ";
389 print ((!getcache()) ? "not found\n" : "found\n");
390 print "Checking operating system version... ";
391 print getosflags() . "\n";
392
393 if (defined $opt_maxclients)
394 {
395         $config{MAX_CLIENT} = $opt_maxclients;
396 }
397
398 if (!$config{MAX_CLIENT}) { 
399         # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
400         # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
401         # higher than the found value" :))
402         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
403 }
404
405 printf "Checking if stdint.h exists... ";
406 $config{HAS_STDINT} = "true";
407 my $fail = 0;
408 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
409 if ($config{HAS_STDINT} eq "true") {
410         close(STDINT);
411 }
412 print "yes\n" if $config{HAS_STDINT} eq "true";
413 print "no\n" if $config{HAS_STDINT} eq "false";
414
415
416 printf "Checking if strlcpy exists... ";
417 # Perform the strlcpy() test..
418 $config{HAS_STRLCPY} = "false";
419 my $fail = 0;
420 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
421 if (!$fail) {
422         while (chomp($line = <STRLCPY>)) {
423                 # try and find the delcaration of:
424                 # size_t strlcpy(...)
425                 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
426                         $config{HAS_STRLCPY} = "true";
427                 }
428         }
429         close(STRLCPY);
430 }
431 print "yes\n" if $config{HAS_STRLCPY} eq "true";
432 print "no\n" if $config{HAS_STRLCPY} eq "false";
433
434
435 printf "Checking if kqueue exists... ";
436 $has_kqueue = 0;
437 $fail = 0;
438 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
439 if (!$fail) {
440         while (chomp($line = <KQUEUE>)) {
441                 # try and find the delcaration of:
442                 # int kqueue(void);
443                 if ($line =~ /int(\0x9|\s)+kqueue/) {
444                         $has_kqueue = 1;
445                 }
446         }
447         close(KQUEUE);
448 }
449 print "yes\n" if $has_kqueue == 1;
450 print "no\n" if $has_kqueue == 0;
451
452 printf "Checking if epoll exists... ";
453 $has_epoll = 0;
454 $fail = 0;
455 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
456 if (!$fail) {
457         $has_epoll = 1;
458         close(EPOLL);
459 }
460 if ($has_epoll) {
461         my $kernel = `uname -r`;
462         chomp($kernel);
463         if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
464                 $has_epoll = 0;
465         }
466         else
467         {
468                 # Suggestion from nenolod, weed out odd systems which have glibc built
469                 # against 2.4 kernels (ick)
470                 my $kernel_arch = `uname -p`;
471                 chomp($kernel_arch);
472                 $libcv = 0.0;
473                 $kernelv = 0.0;
474                 if ($kernel_arch =~ /x86_64/) {
475                         open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
476                 }
477                 else {
478                         open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
479                 }
480                 if ($has_epoll)
481                 {
482                         while (chomp($line = <FH>))
483                         {
484                                 if ($line =~ /GNU C Library .* version (.*?) /)
485                                 {
486                                         $libcv = $1;
487                                         $libcv =~  /(\d+\.\d+)/;
488                                         $libcv = $1;
489                                 }
490                                 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
491                                 {
492                                         $kernelv = $1;
493                                         # Fix for some retarded libc builds, strip off >> and << etc.
494                                         $kernelv =~ /(\d+\.\d+)/;
495                                         $kernelv = $1;
496                                 }
497                         }
498                         close FH;
499                         if ($libcv < 2.3)
500                         {
501                                 $has_epoll = 0;
502                                 printf "libc too old: $libcv... ";
503                         }
504                         if ($kernelv < 2.6)
505                         {
506                                 $has_epoll = 0;
507                                 printf "libc built against older kernel $kernelv... ";
508                         }
509                 }
510         }
511 }
512 print "yes\n" if $has_epoll == 1;
513 print "no\n" if $has_epoll == 0;
514
515 printf "Checking if Solaris I/O completion ports are available... ";
516 $has_ports = 0;
517 my $system = `uname -s`;
518 chomp ($system);
519 $has_ports = 1 if ($system eq "SunOS");
520
521 if ($has_ports) {
522         my $kernel = `uname -r`;
523         chomp($kernel);
524         if (($kernel !~ /^5\.1./)) {
525                 $has_ports = 0;
526         }
527 }
528 print "yes\n" if $has_ports == 1;
529 print "no\n" if $has_ports == 0;
530
531 $config{HAS_EPOLL} = $has_epoll;
532 $config{HAS_KQUEUE} = $has_kqueue; 
533
534 printf "Checking for libgnutls... ";
535 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
536         print "yes\n";
537         $config{HAS_GNUTLS} = "y";
538 } else {
539         print "no\n";
540         $config{HAS_GNUTLS} = "n";
541 }
542
543 printf "Checking for openssl... ";
544 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
545         print "yes\n";
546         $config{HAS_OPENSSL} = "y";
547 } else {
548         print "no\n";
549         $config{HAS_OPENSSL} = "n";
550 }
551
552 printf "Checking if you are running an ancient, unsupported OS... ";
553 if ($config{OSNAME} =~ /FreeBSD/i)
554 {
555         $version = `uname -r`;
556         if ($version =~ /^4\./)
557         {
558                 $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
559                 if ($foundit > 0)
560                 {
561                         # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
562                         $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
563                         print "yes\n";
564                 }
565                 else
566                 {
567                         print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
568                 }
569         }
570         else
571         {
572                 $config{CRAQ} = " ";
573                 print "no ($version)\n";
574         }
575 }
576 else
577 {
578         $config{CRAQ} = " ";
579         print "no ($config{OSNAME})\n";
580 }
581
582 ################################################################################
583 #                         BEGIN INTERACTIVE PART                              #
584 ################################################################################
585
586 # Clear the Screen..
587 if ($interactive)
588 {
589         system("clear");
590         $wholeos = $^O;
591
592         my $rev = getrevision();
593         # Display Introduction Message..
594         print "
595 Welcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)
596 \033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m
597
598 *** If you are unsure of any of these values, leave it blank for    ***
599 *** standard settings that will work, and your server will run      ***
600 *** using them. Please consult your IRC network admin if in doubt.  ***
601
602 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
603 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
604 dir, otherwise you won't have a config file!
605
606 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos)
607 Maximum file descriptors: \033[1;32m$config{MAX_CLIENT_T}\033[0m
608 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
609         if ($rev eq "r0") {
610                 print " (Non-SVN build)";
611         }
612         print ".\n\n";
613
614         $config{CHANGE_COMPILER} = "n";
615         print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
616
617         while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
618                 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
619 should NOT be used. You should probably specify a newer compiler.\n\n";
620                 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
621                 if ($config{CHANGE_COMPILER} =~ /y/i) {
622                         print "What command do you want to use to invoke your compiler?\n";
623                         print "[\033[1;32m$config{CC}\033[0m] -> ";
624                         chomp($config{CC} = <STDIN>);
625                         if ($config{CC} eq "") {
626                                 $config{CC} = "g++";
627                         }
628                         chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
629                         if ($foo ne "") {
630                                 chomp($config{GCCVER}       = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
631                                 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
632                                 if ($config{GCCVER} < 3) {
633                                         print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
634                                 }
635                         }
636                         else {
637                                 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
638                         }
639                 }
640         }
641
642         print "\n";
643
644         # Directory Settings..
645         my $tmpbase = $config{BASE_DIR};
646         dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
647         if ($tmpbase ne $config{BASE_DIR}) {
648                 $config{CONFIG_DIR}      = resolve_directory($config{BASE_DIR}."/conf");           # Configuration Dir
649                 $config{MODULE_DIR}      = resolve_directory($config{BASE_DIR}."/modules");     # Modules Directory
650                 $config{BINARY_DIR}      = resolve_directory($config{BASE_DIR}."/bin");     # Binary Directory
651                 $config{LIBRARY_DIR}    = resolve_directory($config{BASE_DIR}."/lib");      # Library Directory
652         }
653
654         dir_check("are the configuration files", "CONFIG_DIR");
655         dir_check("are the modules to be compiled to", "MODULE_DIR");
656         dir_check("is the IRCd binary to be placed", "BINARY_DIR");
657         dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
658
659         if ($has_kqueue) {
660                 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?");
661                 print "\n";
662         }
663         if ($has_epoll) {
664                 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?");
665                 print "\n";
666         }
667         if ($has_ports) {
668                 yesno(USE_PORTS,"You are running Solaris 10.\nWould you like to enable I/O completion ports support?\nThis is likely to increase performance.\nIf you are unsure, answer yes.\n\nEnable support for I/O completion ports?");
669                 print "\n";
670         }
671         $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
672         if (!$chose_hiperf) {
673                 print "No high-performance socket engines are available, or you chose\n";
674                 print "not to enable one. Defaulting to select() engine.\n\n";
675         }
676
677         yesno(IPV6,"Would you like to build InspIRCd with IPv6 support?");
678         print "\n";
679
680         if ($config{IPV6} eq "y") {
681                 print "You have chosen to build an \033[1;32mIPV6-enabled\033[0m server.\nTo accept IPV4 users, you can still use IPV4 addresses\nin your port bindings..\n\n";
682                 $config{SUPPORT_IP6LINKS} = "y";
683         } else {
684                 yesno(SUPPORT_IP6LINKS,"You have chosen to build an \033[1;32mIPV4-only\033[0m server.\nWould you like to enable support for linking to IPV6-enabled\nInspIRCd servers?\nIf you are using a recent operating\nsystem and are unsure, answer yes.\nIf you answer 'no' here, your InspIRCd server will be unable\nto parse IPV6 addresses (e.g. for CIDR bans)");
685                 print "\n";
686         }
687
688         if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
689                 print "I have detected both \033[1;32mGnuTLS\033[0m and \033[1;32mOpenSSL\033[0m on your system.\n";
690                 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
691                 print "instead, you should enable the OpenSSL module yourself\n";
692                 print "by copying it from src/modules/extra to src/modules.\n\n";
693                 print "Detected GnuTLS version: \033[1;32m" . $gnutls_ver . "\033[0m\n";
694                 print "Detected OpenSSL version: \033[1;32m" . $openssl_ver . "\033[0m\n\n";
695         }
696
697         if ($config{HAS_GNUTLS} eq "y") {
698                 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
699                 if ($config{USE_GNUTLS} eq "y") {
700                         print "\nUsing GnuTLS SSL module.\n";
701                 }
702         } elsif ($config{HAS_OPENSSL} eq "y") {
703                         yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
704         if ($config{USE_OPENSSL} eq "y") {
705                         print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
706                 }
707         }
708         else {
709                 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\nyou intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
710         }
711
712         print "\nThe following questions will ask you for various figures relating\n";
713         print "To your IRCd install. Please note that these should usually be left\n";
714         print "as defaults unless you have a real reason to change them. If they\n";
715         print "changed, then the values must be identical on all servers on your\n";
716         print "network, or malfunctions and/or crashes may occur, with the exception\n";
717         print "of the 'maximum number of clients' setting which may be different on\n";
718         print "different servers on the network.\n\n";
719
720         # File Descriptor Settings..
721         promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
722         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
723         $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
724
725         promptnumeric("length of nicknames", "NICK_LENGT");
726         promptnumeric("length of channel names", "CHAN_LENGT");
727         promptnumeric("number of mode changes in one line", "MAXI_MODES");
728         promptnumeric("length of an ident (username)", "MAX_IDENT");
729         promptnumeric("length of a quit message", "MAX_QUIT");
730         promptnumeric("length of a channel topic", "MAX_TOPIC");
731         promptnumeric("length of a kick message", "MAX_KICK");
732         promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
733         promptnumeric("length of an away message", "MAX_AWAY");
734 }
735
736 dumphash();
737
738 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
739 {
740         print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
741         exit(0);
742 }
743 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
744 {
745         print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
746         exit(0);
747 }
748
749 if ($config{USE_GNUTLS} eq "y") {
750         $failed = 0;
751         open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
752         close(TMP);
753         if ($failed) {
754                 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
755                 chdir("src/modules");
756                 system("ln -s extra/m_ssl_gnutls.cpp");
757                 chdir("../..");
758         }
759         getmodules();
760         if ($interactive)
761         {
762                 $failed = 0;
763                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
764                 close(TMP);
765                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
766                 close(TMP);
767                 if ($failed) {
768                         print "SSL Certificates Not found, Generating.. \n\n
769 *************************************************************
770 * Generating the Private Key may take some time, go grab a  *
771 * Coffee. Even better, to generate some more entropy if it  *
772 * is taking a while, open another console and type du / a   *
773 * few times and get that HD going :) Then answer the        *
774 * Questions which follow. If you are unsure, just hit enter *
775 *************************************************************\n\n";
776                         $failed = make_gnutls_cert();
777                         if ($failed) {
778                                 print "\n\033[1;32mCertificate generation failed!\033[0m\n\n";
779                         } else {
780                                 print "\nCertificate generation complete, copying to config directory... ";
781                                 system("mv key.pem $config{CONFIG_DIR}/key.pem");
782                                 system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
783                                 print "Done.\n\n";
784                         }
785                 }
786                 else {
787                         print "SSL Certificates found, skipping.\n\n";
788                 }
789         }
790         else
791         {
792                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
793         }
794 } elsif ($config{USE_OPENSSL} eq "y") {
795         $failed = 0;
796         open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
797         close(TMP);
798         if ($failed) {
799                 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
800                 chdir("src/modules");
801                 system("ln -s extra/m_ssl_openssl.cpp");
802                 chdir("../..");
803         }
804         getmodules();
805         $failed = 0;
806         if ($interactive)
807         {
808                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
809                 close(TMP);
810                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
811                 close(TMP);
812                 if ($failed) {
813                         print "SSL Certificates Not found, Generating.. \n\n
814 *************************************************************
815 * Generating the certificates may take some time, go grab a *
816 * coffee, or something.                                     *
817 *************************************************************\n\n";
818                         make_openssl_cert();
819                         print "\nCertificate generation complete, copying to config directory... ";
820                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
821                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
822                         system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
823                         print "Done.\n\n";
824                 } else {
825                         print "SSL Certificates found, skipping.\n\n"
826                 }
827         }
828         else
829         {
830                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
831         }
832 }
833 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
834         print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
835 }
836
837 getosflags();
838 writefiles(1);
839 makecache();
840
841 print "\n\n";
842 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
843 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
844         print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
845         print "load the required modules in your config. This configure process\n";
846         print "has just prepared these modules to be compiled for you, and has not\n";
847         print "configured them to be compiled into the core of the ircd.\n";
848 }
849 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
850 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
851         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";
852 }
853
854 if ($config{GCCVER} < "3") {
855         print <<FOO2;
856 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
857 GCC 2.x series compilers only had partial (read as broken) C++ support, and
858 your compile will most likely fail horribly! If you have any problems, do NOT
859 report them to the bugtracker or forums without first upgrading your compiler
860 to a newer 3.x or 4.x (or whatever is available currently) version.
861 FOO2
862 }
863
864 ################################################################################
865 #                             HELPER FUNCTIONS                          #
866 ################################################################################
867 sub getcache {
868         # Retrieves the .config.cache file, and loads values into the main config hash.
869         open(CACHE, ".config.cache") or return 0;
870         while (<CACHE>) {
871                 chomp;
872                 # Ignore Blank lines, and comments..
873                 next if /^\s*$/;
874                 next if /^\s*#/;
875                 my ($key, $value) = split("=", $_, 2);
876                 $value =~ /^\"(.*)\"$/;
877                 # Do something with data here!
878                 $config{$key} = $1;
879         }
880         close(CONFIG);
881         return 1;
882 }
883
884 sub makecache {
885         # Dump the contents of %config
886         print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
887         open(FILEHANDLE, ">.config.cache");
888         foreach $key (keys %config) {
889                 print FILEHANDLE "$key=\"$config{$key}\"\n";
890         }
891         close(FILEHANDLE);
892 }
893
894 sub dir_check {
895         my ($desc, $hash_key) = @_;
896         my $complete = 0;
897         while (!$complete) {
898                 print "In what directory $desc?\n";
899                 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
900                 chomp($var = <STDIN>);
901                 if ($var eq "") {
902                         $var = $config{$hash_key};
903                 }
904                 if ($var =~ /^\~\/(.+)$/) {
905                         # Convert it to a full path..
906                         $var = resolve_directory($ENV{HOME} . "/" . $1);
907                 }
908                 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
909                 {
910                         # Assume relative Path was given.. fill in the rest.
911                         $var = $this . "/$var";
912                 }
913                 
914                 $var = resolve_directory($var); 
915                 if (! -e $var) {
916                         print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
917                         chomp($tmp = <STDIN>);
918                         if (($tmp eq "") || ($tmp =~ /^y/i)) {
919                                 # Attempt to Create the Dir..
920                                 
921                                 system("mkdir -p \"$var\" >> /dev/null 2>&1");
922                                 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
923                                 if ($chk != 0) {
924                                         print "Unable to create directory. ($var)\n\n";
925                                         # Restart Loop..
926                                         next;
927                                 }
928                         } else {
929                                 # They said they don't want to create, and we can't install there.
930                                 print "\n\n";
931                                 next;
932                         }
933                 } else {
934                         if (!is_dir($var)) {
935                                 # Target exists, but is not a directory.
936                                 print "File $var exists, but is not a directory.\n\n";
937                                 next;
938                         }
939                 }
940                 # Either Dir Exists, or was created fine.
941                 $config{$hash_key} = $var;
942                 $complete = 1;
943                 print "\n";
944         }
945 }
946
947 sub getosflags {
948
949         $config{LDLIBS} = "-lstdc++";
950         $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
951         $config{DEVELOPER} = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated -g";
952         $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared";
953         $config{MAKEPROG} = "make";
954
955         if ($config{OSNAME} =~ /darwin/i) {
956                 $config{FLAGS}  = "-DDARWIN -frtti -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
957                 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
958                 $config{LDLIBS} = "-ldl -lstdc++";
959         }
960
961         if ($config{OSNAME} =~ /OpenBSD/i) {
962                 $config{MAKEPROG} = "gmake";
963                 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
964                 chomp($foo = `eg++ -dumpversion | cut -c 1`);
965                 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
966                 # if theyre not running this, configure lets the build continue but they probably wont manage to
967                 # compile as this standard version is 2.95.3!
968                 if ($foo ne "") {
969                         $config{CC} = "eg++";
970                         chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
971                 }
972                 return "OpenBSD";
973         }
974
975         if ($config{OSNAME} =~ /Linux/i) {
976                 $config{LDLIBS} = "-ldl -lstdc++";
977                 $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
978                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
979                 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
980                 $config{MAKEPROG} = "make";
981         }
982
983         if ($config{OSNAME} =~ /FreeBSD/i) {
984                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
985                 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
986         }
987
988         if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
989         {
990                 # solaris/sunos needs these
991                 # socket = bsd sockets api
992                 # nsl = dns stuff
993                 # rt = POSIX realtime extensions
994                 # resolv = inet_aton only (why isnt this in nsl?!)
995                 $config{MAKEPROG} = "gmake";
996                 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv";
997                 return "Solaris";
998         }
999         
1000         if($config{OSNAME} =~ /MINGW32/i)
1001         {
1002                 # All code is position-independent on windows
1003                 $config{FLAGS} =~ s/-fPIC //;
1004                 return "MinGW";
1005         }
1006
1007         return $config{OSNAME};
1008 }
1009
1010 sub writefiles {
1011         my($writeheader) = @_;
1012         # First File.. inspircd_config.h
1013         chomp(my $incos = `uname -n -s -r`);
1014         chomp($version = `sh src/version.sh`);
1015         chomp(my $revision2 = getrevision());
1016         if ($writeheader == 1)
1017         {
1018                 print "Writing \033[1;32minspircd_config.h\033[0m\n";
1019                 open(FILEHANDLE, ">include/inspircd_config.h");
1020                 my $NL = $config{NICK_LENGT}+1;
1021                 my $CL = $config{CHAN_LENGT}+1;
1022                 print FILEHANDLE <<EOF;
1023 /* Auto generated by configure, do not modify! */
1024 #ifndef __CONFIGURATION_AUTO__
1025 #define __CONFIGURATION_AUTO__
1026
1027 /* this is for windows support. */
1028 #define CoreExport /**/
1029 #define DllExport /**/
1030
1031 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1032 #define MOD_PATH "$config{MODULE_DIR}"
1033 #define VERSION "$version"
1034 #define REVISION "$revision2"
1035 #define MAXCLIENTS $config{MAX_CLIENT}
1036 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1037 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1038 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1039 #define NICKMAX $NL
1040 #define CHANMAX $CL
1041 #define MAXMODES $config{MAXI_MODES}
1042 #define IDENTMAX $config{MAX_IDENT}
1043 #define MAXQUIT $config{MAX_QUIT}
1044 #define MAXTOPIC $config{MAX_TOPIC}
1045 #define MAXKICK $config{MAX_KICK}
1046 #define MAXGECOS $config{MAX_GECOS}
1047 #define MAXAWAY $config{MAX_AWAY}
1048 #define OPTIMISATION $config{OPTIMITEMP}
1049 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1050 #define SYSTEM "$incos"
1051 EOF
1052 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1053
1054                 if ($config{OSNAME} =~ /SunOS/i) {
1055                         print FILEHANDLE "#define IS_SOLARIS\n";
1056                 }
1057                 if ($config{OSNAME} =~ /MINGW32/i) {
1058                         print FILEHANDLE "#define IS_MINGW\n";
1059                 }
1060                 if ($config{GCCVER} >= 3) {
1061                         print FILEHANDLE "#define GCC3\n";
1062                 }
1063                 if ($config{HAS_STRLCPY} eq "true") {
1064                         print FILEHANDLE "#define HAS_STRLCPY\n";
1065                 }
1066                 if ($config{HAS_STDINT} eq "true") {
1067                         print FILEHANDLE "#define HAS_STDINT\n";
1068                 }
1069                 if ($config{IPV6} =~ /y/i) {
1070                         print FILEHANDLE "#define IPV6\n";
1071                 }
1072                 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1073                         print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1074                 }
1075                 my $use_hiperf = 0;
1076                 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1077                         print FILEHANDLE "#define USE_KQUEUE\n";
1078                         $se = "socketengine_kqueue";
1079                         $use_hiperf = 1;
1080                 }
1081                 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1082                         print FILEHANDLE "#define USE_EPOLL\n";
1083                         $se = "socketengine_epoll";
1084                         $use_hiperf = 1;
1085                 }
1086                 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1087                         print FILEHANDLE "#define USE_PORTS\n";
1088                         $se = "socketengine_ports";
1089                         $use_hiperf = 1;
1090                 }
1091                 # user didn't choose either epoll or select for their OS.
1092                 # default them to USE_SELECT (ewwy puke puke)
1093                 if (!$use_hiperf) {
1094                         print FILEHANDLE "#define USE_SELECT\n";
1095                         $se = "socketengine_select";
1096                 }
1097                 print FILEHANDLE "\n#endif\n";
1098                 close(FILEHANDLE);
1099         }
1100
1101         if ($writeheader)
1102         {
1103                 open(FILEHANDLE, ">include/inspircd_se_config.h");
1104                 print FILEHANDLE <<EOF;
1105 /* Auto generated by configure, do not modify or commit to svn! */
1106 #ifndef __CONFIGURATION_SOCKETENGINE__
1107 #define __CONFIGURATION_SOCKETENGINE__
1108
1109 #include "$se.h"
1110
1111 #endif
1112 EOF
1113                 close(FILEHANDLE);
1114         }
1115
1116
1117         # Create a Modules List..
1118         my $modules = "";
1119         foreach $i (@modlist)
1120         {
1121                 $modules .= "m_".$i.".so ";
1122         }
1123         chomp($modules);   # Remove Redundant whitespace..
1124
1125         opendir(DIRHANDLE, "src/modules");
1126         foreach $name (sort readdir(DIRHANDLE)) {
1127                 if ($name =~ /^m_(.+?)$/) {
1128                         if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1129                                 closedir(MDIRHANDLE);
1130                                 $modules .= "$name.so ";
1131                         }
1132                 }
1133         }
1134         closedir(DIRHANDLE);
1135
1136
1137         # Write all .in files.
1138         my $tmp = "";
1139         my $file = "";
1140         my $exe = "inspircd";
1141
1142         opendir(DIRHANDLE, $this);
1143
1144         # Do this once here, and cache it in the .*.inc files,
1145         # rather than attempting to read src/version.sh from
1146         # compiled code -- we might not have the source to hand.
1147         # Fix for bug#177 by Brain.
1148
1149         chomp(my $version = `sh ./src/version.sh`);
1150         chomp(my $revision = getrevision());
1151         $version = "$version(r$revision)";
1152
1153         my $LIBEXT = "so";
1154         if ($config{IS_DARWIN} eq "YES")
1155         {
1156                 $LIBEXT = "dylib";
1157         }
1158         # We can actually parse any file starting with . and ending with .inc,
1159         # but right now we only parse .inspircd.inc to form './inspircd'
1160
1161         foreach $name (sort readdir(DIRHANDLE)) {
1162                 if ($name =~ /^\.(.+)\.inc$/) {
1163                         $file = $1;
1164
1165                         # Bug #353, omit this on non-darwin
1166                         next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1167
1168                         # All .name.inc files need parsing!
1169                         $tmp = "";
1170                         open(FILEHANDLE, ".$file.inc");
1171                         while (<FILEHANDLE>) {
1172                                 $tmp .= $_;
1173                         }
1174                         close(FILEHANDLE);
1175
1176                         $tmp =~ s/\@CC\@/$config{CC}/;
1177                         $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1178                         $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1179                         $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/;
1180                         $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1181                         $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1182                         $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1183                         $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1184                         $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1185                         $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1186                         $tmp =~ s/\@LIBRARY_EXT\@/$LIBEXT/;
1187                         $tmp =~ s/\@MODULES\@/$modules/;
1188                         $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/;
1189                         $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/;
1190                         $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/;
1191                         $tmp =~ s/\@EXECUTABLE\@/$exe/;
1192                         $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1193                         $tmp =~ s/\@VERSION\@/$version/;
1194
1195                         print "Writing \033[1;32m$file\033[0m\n";
1196                         open(FILEHANDLE, ">$file");
1197                         print FILEHANDLE $tmp;
1198                 }
1199         }
1200         closedir(DIRHANDLE);
1201
1202         # Make inspircd executable!
1203         chmod 0744, 'inspircd';
1204
1205         print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1206         write_dynamic_makefile();
1207         write_dynamic_modules_makefile();
1208 }
1209
1210 sub write_dynamic_modules_makefile {
1211         # Modules Makefile..
1212         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1213         open(FILEHANDLE, ">src/modules/Makefile");
1214
1215 ###
1216 # Module Makefile Header
1217 ###
1218         print FILEHANDLE <<EOF;
1219 ###################################################
1220 # Copyright 2002-2007 The InspIRCd Development Team
1221 #  http://www.inspircd.org/wiki/index.php/Credits
1222 #
1223 # Thanks to Andrew Church <achurch\@achurch.org>
1224 #   for assisting with making this work right.
1225 #
1226 # Automatically Generated by ./configure to add a
1227 #  modules please run ./configure -modupdate
1228 ###################################################
1229
1230 all: \$(MODULES)
1231
1232 EOF
1233
1234 if ($config{OSNAME} =~ /darwin/) {
1235                 print FILEHANDLE <<EOCHEESE;
1236
1237 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) -bundle
1238
1239 EOCHEESE
1240 } else {
1241                 print FILEHANDLE <<EOCHEESE;
1242
1243 PICLDFLAGS = -fPIC -DPIC -shared \$(FLAGS)
1244
1245 EOCHEESE
1246 }
1247
1248         ###
1249         # End Module Makefile Header
1250         ###
1251
1252         # Create a Modules List..
1253         my $modules = "";
1254         my $cmflags = "";
1255         my $liflags = "";
1256         my $crud = "";
1257
1258         foreach $i (@modlist) {
1259                 ###
1260                 # Write Entry to the MakeFile
1261                 ###
1262                 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1263                 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1264                 $deps = getdependencies("src/modules/m_".$i.".cpp");
1265         
1266                 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1267         
1268                 print FILEHANDLE <<EOCHEESE;
1269 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $deps
1270         \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1271 EOCHEESE
1272                 $crud = $crud . "       install -m \$(INSTMODE) m_$i.so \$(MODPATH)\n";
1273 ###
1274                 # End Write Entry to the MakeFile
1275                 ###
1276         }
1277
1278         opendir(DIRHANDLE, "src/modules");
1279         foreach $name (sort readdir(DIRHANDLE)) {
1280                 if ($name =~ /^m_(.+?)$/) {
1281                         $mfrules = "";
1282                         $mobjs = "";
1283                         $mliflags = "";
1284                         $mfcount = 0;
1285                         # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1286                         if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1287                                 read_module_directory("src/modules/$name", $name);
1288                                 print "Composing Makefile rules for directory \033[1;32m$name\033[0m... (\033[1;32m$mfcount files found\033[0m)\n";
1289                                 print FILEHANDLE "$name.so: ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $mobjs\n"; 
1290                                 if ($config{IS_DARWIN} eq "YES") {
1291                                         print FILEHANDLE "      \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n"; 
1292                                 } else {
1293                                         print FILEHANDLE "      \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1294                                 }
1295                                 print FILEHANDLE "\n$mfrules\n";
1296                                 closedir(MDIRHANDLE);
1297                                 $crud = $crud . "       install -m \$(INSTMODE) $name.so \$(MODPATH)\n";
1298                         }
1299                 }
1300         }
1301         closedir(DIRHANDLE);
1302
1303         print FILEHANDLE "modinst:\n    \@echo \"Installing modules...\"\n" . $crud;
1304 }
1305
1306 sub read_module_directory {
1307         my ($dpath, $reldpath) = @_;
1308         
1309         if (opendir(MDIRHANDLE, $dpath) == 0) {
1310                 return;
1311         }
1312         
1313         foreach $fname (sort readdir(MDIRHANDLE)) {
1314                 if ($fname =~ /\.cpp$/) {
1315                         $cmflags = getcompilerflags("$dpath/$fname");
1316                         $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1317                         $deps = getdependencies("$dpath/$fname");
1318                         $oname = $fname;
1319                         $oname =~ s/\.cpp$/.o/g;
1320                         $mfrules = $mfrules .  "$reldpath/$oname: $reldpath/$fname ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $deps\n";
1321                         $mfrules = $mfrules .  "        \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1322                         $mobjs = $mobjs . " $reldpath/$oname";
1323                         $mfcount++;
1324                 }
1325                 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1326                         read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1327                 }
1328         }
1329 }
1330
1331 sub write_dynamic_makefile {
1332
1333         my $i = 0;
1334         my @cmdlist = ();
1335         opendir(DIRHANDLE, "src");
1336         foreach $name (sort readdir(DIRHANDLE)) {
1337                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1338                         $cmdlist[$i++] = $1;
1339                 }
1340         }
1341         closedir(DIRHANDLE);
1342
1343         my $cmdobjs = "";
1344         my $srcobjs = "";
1345         foreach my $cmd (@cmdlist) {
1346                 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1347                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1348         }
1349
1350         $se = "socketengine_select";
1351         if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1352                 $se = "socketengine_kqueue";
1353         }
1354         elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1355                 $se = "socketengine_epoll";
1356         }
1357         elsif (($has_ports) && ($config{USE_PORTS} eq "y")) {
1358                 $se = "socketengine_ports";
1359         }
1360
1361         $freebsd4libs = $config{CRAQ};
1362
1363         open(FH,">src/Makefile") or die("Could not write src/Makefile");
1364         print FH <<EOM;
1365 ###################################################
1366 # Copyright 2002-2007 The InspIRCd Development Team
1367 #  http://www.inspircd.org/wiki/index.php/Credits
1368 #
1369 # Thanks to Andrew Church <achurch\@achurch.org>
1370 #  for assisting with making this work right.
1371 #
1372 # This file is automagically generated by configure 
1373 # Any changes made will be lost on ./configure         
1374 ###################################################
1375
1376 CC = im a cheezeball
1377
1378 CXXFLAGS = -I../include \${FLAGS}
1379 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1380 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1381
1382 EOM
1383
1384 if ($config{IS_DARWIN} eq "YES") {
1385         print FH <<EOM;
1386 all: libIRCDtimer.dylib libIRCDcull_list.dylib libIRCDuserprocess.dylib libIRCDsocketengine.dylib libIRCDsocket.dylib libIRCDhash.dylib libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDcommand_parse.dylib libIRCDsnomasks.dylib libIRCDserver.dylib libIRCDfilelogger.dylib inspircd
1387
1388 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h $cmdobjs libIRCDtimer.dylib libIRCDcull_list.dylib libIRCDuserprocess.dylib libIRCDsocketengine.dylib libIRCDsocket.dylib libIRCDhash.dylib libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDsnomasks.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDcommand_parse.dylib libIRCDserver.dylib libIRCDfilelogger.dylib
1389         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp
1390         \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o libIRCDchannels.dylib libIRCDmode.dylib libIRCDxline.dylib libIRCDstring.dylib libIRCDasyncdns.dylib libIRCDbase.dylib libIRCDconfigreader.dylib libIRCDinspsocket.dylib libIRCDcommands.dylib libIRCDdynamic.dylib libIRCDusers.dylib libIRCDmodules.dylib libIRCDwildcard.dylib libIRCDhelper.dylib libIRCDhash.dylib libIRCDsocket.dylib libIRCDsocketengine.dylib libIRCDuserprocess.dylib libIRCDcull_list.dylib libIRCDcommand_parse.dylib libIRCDtimer.dylib libIRCDsnomasks.dylib libIRCDserver.dylib libIRCDfilelogger.dylib
1391
1392 libIRCDsocketengine.dylib: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1393         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp
1394         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $se.cpp
1395         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsocketengine.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsocketengine.dylib socketengine.o $se.o
1396
1397 libIRCDsnomasks.dylib: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1398         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1399         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsnomasks.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsnomasks.dylib snomasks.o
1400
1401 libIRCDcommand_parse.dylib: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1402         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1403         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcommand_parse.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcommand_parse.dylib command_parse.o
1404
1405 libIRCDcull_list.dylib: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1406         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1407         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcull_list.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcull_list.dylib cull_list.o
1408
1409 libIRCDuserprocess.dylib: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1410         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1411         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDuserprocess.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDuserprocess.dylib userprocess.o
1412
1413 libIRCDhash.dylib: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1414         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1415         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDhash.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDhash.dylib hashcomp.o
1416
1417 libIRCDhelper.dylib: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1418         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1419         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDhelper.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDhelper.dylib helperfuncs.o
1420
1421 libIRCDchannels.dylib: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1422         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1423         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDchannels.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDchannels.dylib channels.o
1424
1425 libIRCDmode.dylib: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1426         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1427         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1428         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDmode.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDmode.dylib mode.o modes/modeclasses.a
1429
1430 libIRCDxline.dylib: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1431         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1432         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDxline.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDxline.dylib xline.o
1433
1434 libIRCDstring.dylib: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1435         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1436         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDstring.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDstring.dylib inspstring.o
1437
1438 libIRCDasyncdns.dylib: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1439         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1440         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDasyncdns.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDasyncdns.dylib dns.o
1441
1442 libIRCDbase.dylib: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1443         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1444         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDbase.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDbase.dylib base.o
1445
1446 libIRCDconfigreader.dylib: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1447         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1448         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDconfigreader.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDconfigreader.dylib configreader.o
1449
1450 libIRCDcommands.dylib: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1451         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1452         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDcommands.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDcommands.dylib commands.o
1453
1454 libIRCDdynamic.dylib: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1455         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1456         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDdynamic.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDdynamic.dylib dynamic.o
1457
1458 libIRCDusers.dylib: 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/timer.h
1459         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1460         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDusers.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDusers.dylib users.o
1461
1462 libIRCDmodules.dylib: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1463         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1464         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDmodules.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDmodules.dylib modules.o
1465
1466 libIRCDwildcard.dylib: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1467         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1468         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDwildcard.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDwildcard.dylib wildcard.o
1469
1470 libIRCDsocket.dylib: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1471         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1472         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDsocket.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDsocket.dylib socket.o
1473
1474 libIRCDinspsocket.dylib: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1475         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1476         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDinspsocket.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDinspsocket.dylib inspsocket.o
1477
1478 libIRCDtimer.dylib: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1479         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1480         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDtimer.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDtimer.dylib timer.o
1481
1482 libIRCDserver.dylib: server.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1483         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c server.cpp
1484         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDserver.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDserver.dylib server.o
1485
1486 libIRCDfilelogger.dylib: filelogger.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1487         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c filelogger.cpp
1488         \$(CC) -pipe -install_name $config{LIBRARY_DIR}/libIRCDfilelogger.dylib -dynamiclib -twolevel_namespace -undefined dynamic_lookup -o libIRCDfilelogger.dylib filelogger.o
1489
1490 EOM
1491
1492 } else {
1493
1494         print FH <<EOM;
1495 all: libIRCDtimer.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so libIRCDsnomasks.so libIRCDserver.so libIRCDfilelogger.so inspircd
1496
1497 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h libIRCDtimer.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so $cmdobjs libIRCDsnomasks.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so libIRCDserver.so libIRCDfilelogger.so
1498         \$(CC) -pipe -I../include -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so libIRCDuserprocess.so libIRCDcull_list.so libIRCDcommand_parse.so libIRCDtimer.so libIRCDsnomasks.so libIRCDserver.so libIRCDfilelogger.so
1499
1500 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1501         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1502         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1503
1504 libIRCDsnomasks.so: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1505         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1506         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1507
1508 libIRCDcommand_parse.so: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1509         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1510         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1511
1512 libIRCDcull_list.so: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1513         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1514         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1515
1516 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1517         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1518         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1519
1520 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1521         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1522         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1523
1524 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1525         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1526         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1527
1528 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1529         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1530         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1531
1532 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 \$(RELCPPFILES)
1533         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1534         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1535         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1536
1537 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 ../include/timer.h
1538         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1539         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1540
1541 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
1542         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1543         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1544
1545 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 ../include/timer.h
1546         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1547         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1548
1549 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1550         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1551         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1552
1553 libIRCDconfigreader.so: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1554         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1555         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1556
1557 libIRCDcommands.so: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1558         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1559         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o
1560
1561 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
1562         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1563         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1564
1565 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/timer.h
1566         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1567         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1568
1569 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 ../include/timer.h
1570         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1571         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1572
1573 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
1574         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1575         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1576
1577 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1578         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1579         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1580
1581 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1582         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1583         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1584
1585 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h ../include/timer.h
1586         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1587         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1588
1589 libIRCDserver.so: server.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1590         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c server.cpp
1591         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDserver.so server.o
1592
1593 libIRCDfilelogger.so: filelogger.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1594         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c filelogger.cpp
1595         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDfilelogger.so filelogger.o
1596
1597 EOM
1598 }
1599         foreach my $cmd (@cmdlist) {
1600                 print FH <<ITEM;
1601 cmd_$cmd.so: cmd_$cmd.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/commands/cmd_$cmd.h
1602         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1603         \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o
1604
1605 ITEM
1606         }
1607         close(FH);
1608 }
1609