]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Avoid no such nick on non oper attempting to view modes of a user.
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2
3 # InspIRCd Configuration Script
4 #
5 # Copyright 2002-2006 The ChatSpike Development Team
6 # <brain@chatspike.net>
7 # <Craig@chatspike.net>
8 #
9 # [14:21] Brain: <matrix impression> i know perl-fu!
10 #
11 # $Id$
12 #
13 ########################################
14
15
16 require 5.6.0;
17 use Cwd;
18 use Getopt::Long;
19
20 GetOptions (
21         'enable-gnutls' => \$opt_use_gnutls,
22         'enable-openssl' => \$opt_use_openssl,
23         'disable-interactive' => \$opt_nointeractive,
24         'with-nick-length=i' => \$opt_nick_length,
25         'with-channel-length=i' => \$opt_chan_length,
26         'with-max-channels=i' => \$opt_maxchans,
27         'with-max-oper-channels=i' => \$opt_opermaxchans,
28         'with-max-clients' => \$opt_maxclients,
29         'enable-epoll' => \$opt_epoll,
30         'enable-kqueue' => \$opt_kqueue,
31         'disable-epoll' => \$opt_noepoll,
32         'disable-kqueue' => \$opt_nokqueue,
33         'enable-ipv6' => \$opt_ipv6,
34         'enable-remote-ipv6' => \$opt_ipv6links,
35         'disable-remote-ipv6' => \$opt_noipv6links,
36         'with-cc=s' => \$opt_cc,
37         'with-ident-length=i' => \$opt_ident,
38         'with-quit-length=i' => \$opt_quit,
39         'with-topic-length=i' => \$opt_topic,
40         'with-kick-length=i' => \$opt_kick,
41         'with-gecos-length=i' => \$opt_gecos,
42         'with-away-length=i' => \$opt_away,
43         'with-max-modes=i' => \$opt_modes,
44         'prefix=s' => \$opt_base_dir,
45         'config-dir=s' => \$opt_config_dir,
46         'module-dir=s' => \$opt_module_dir,
47         'binary-dir=s' => \$opt_binary_dir,
48         'library-dir=s' => \$opt_library_dir,
49         'disable-debuginfo' => sub { $opt_disable_debug = 1 },
50         'help'  => sub { showhelp(); },
51         'modupdate' => sub { modupdate(); },
52         'update' => sub { update(); },
53         'svnupdate' => sub { svnupdate(); },
54         'clean' => sub { clean(); },
55 );
56
57 my $non_interactive = (
58         (defined $opt_library_dir) ||
59         (defined $opt_base_dir) ||
60         (defined $opt_config_dir) ||
61         (defined $opt_module_dir) ||
62         (defined $opt_base_dir) ||
63         (defined $opt_binary_dir) ||
64         (defined $opt_nointeractive) ||
65         (defined $opt_away) ||
66         (defined $opt_gecos) ||
67         (defined $opt_kick) ||
68         (defined $opt_maxclients) ||
69         (defined $opt_modes) ||
70         (defined $opt_topic) ||
71         (defined $opt_quit) ||
72         (defined $opt_ident) ||
73         (defined $opt_cc) ||
74         (defined $opt_ipv6) ||
75         (defined $opt_ipv6links) ||
76         (defined $opt_noipv6links) ||
77         (defined $opt_kqueue) ||
78         (defined $opt_epoll) ||
79         (defined $opt_maxchans) ||
80         (defined $opt_opermaxchans) ||
81         (defined $opt_chan_length) ||
82         (defined $opt_nick_length) ||
83         (defined $opt_use_openssl) ||
84         (defined $opt_nokqueue) ||
85         (defined $opt_noepoll) ||
86         (defined $opt_use_gnutls)
87 );
88 my $interactive = !$non_interactive;
89
90
91 chomp($topdir = getcwd());
92 $this = resolve_directory($topdir);                                             # PWD, Regardless.
93 @modlist = ();                                                                  # Declare for Module List..
94 %config = ();                                                                   # Initiate Configuration Hash..
95 $config{ME}                 = resolve_directory($topdir);                       # Present Working Directory
96
97 $config{BASE_DIR}           = $config{ME};
98
99 if (defined $opt_base_dir)
100 {
101         $config{BASE_DIR} = $opt_base_dir;
102 }
103
104 $config{CONFIG_DIR}         = resolve_directory($config{BASE_DIR}."/conf");             # Configuration Directory
105 $config{MODULE_DIR}         = resolve_directory($config{BASE_DIR}."/modules");          # Modules Directory
106 $config{BINARY_DIR}         = resolve_directory($config{BASE_DIR}."/bin");              # Binary Directory
107 $config{LIBRARY_DIR}        = resolve_directory($config{BASE_DIR}."/lib");              # Library Directory
108
109 if (defined $opt_config_dir)
110 {
111         $config{CONFIG_DIR} = $opt_config_dir;
112 }
113 if (defined $opt_module_dir)
114 {
115         $config{MODULE_DIR} = $opt_module_dir;
116 }
117 if (defined $opt_binary_dir)
118 {
119         $config{BINARY_DIR} = $opt_binary_dir;
120 }
121 if (defined $opt_library_dir)
122 {
123         $config{LIBRARY_DIR} = $opt_library_dir;
124 }
125 chomp($config{HAS_GNUTLS}   = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
126 chomp($config{HAS_OPENSSL}  = `openssl version 2>/dev/null`);                   # Openssl version
127 $config{USE_GNUTLS}         = "n";
128 if (defined $opt_use_gnutls)
129 {
130         $config{USE_GNUTLS} = "y";                                              # Use gnutls.
131 }
132 $config{USE_OPENSSL}        = "n";                                              # Use openssl.
133 if (defined $opt_use_openssl)
134 {
135         $config{USE_OPENSSL} = "y";
136 }
137
138 # no, let's not change these.
139 $config{OPTIMITEMP}         = "0";                                              # Default Optimisation Value
140 if (!defined $opt_disable_debug)
141 {
142         $config{OPTIMISATI}         = "-g";                                     # Optimisation Flag
143 }
144 else
145 {
146         $config{OPTIMISATI}         = "";                                       # DEBUGGING OFF!
147 }
148
149 $config{NICK_LENGT}         = "31";                                             # Default Nick Length
150 if (defined $opt_nick_length)
151 {
152         $config{NICK_LENGT} = $opt_nick_length;
153 }
154 $config{CHAN_LENGT}         = "64";                                             # Default Channel Name Length
155 if (defined $opt_chan_length)
156 {
157         $config{CHAN_LENGT} = $opt_chan_length;
158 }
159 $config{MAX_CHANNE}         = "20";                                             # Default Max. Channels per user
160 if (defined $opt_maxchans)
161 {
162         $config{MAX_CHANNE} = $opt_maxchans;
163 }
164 $config{MAX_OPERCH}         = "60";                                             # Default Max. Channels per oper
165 if (defined $opt_opermaxchans)
166 {
167         $config{MAX_OPERCH} = $opt_opermaxchans;
168 }
169 $config{MAXI_MODES}         = "20";                                             # Default Max. Number of Modes set at once.
170 if (defined $opt_modes)
171 {
172         $config{MAXI_MODES} = $opt_modes;
173 }
174 $config{HAS_STRLCPY}        = "false";                                          # strlcpy Check.
175 $config{HAS_STDINT}         = "false";                                          # stdint.h check
176 $config{USE_KQUEUE}         = "y";                                              # kqueue enabled
177 if (defined $opt_kqueue)
178 {
179         $config{USE_KQUEUE} = "y";
180 }
181 if (defined $opt_nokqueue)
182 {
183         $config{USE_KQUEUE} = "n";
184 }
185 $config{USE_EPOLL}          = "y";                                              # epoll enabled
186 if (defined $opt_epoll)
187 {
188         $config{USE_EPOLL} = "y";
189 }
190 if (defined $opt_noepoll)
191 {
192         $config{USE_EPOLL} = "n";
193 }
194 $config{IPV6}               = "n";                                              # IPv6 support (experimental)
195 if (defined $opt_ipv6)
196 {
197         $config{IPV6} = "y";
198 }
199 $config{SUPPORT_IP6LINKS}   = "y";                                              # IPv4 supporting IPv6 links (experimental)
200 if (defined $opt_ipv6links)
201 {
202         $config{SUPPORT_IP6LINKS} = "y";
203 }
204 if (defined $opt_noipv6links)
205 {
206         $config{SUPPORT_IP6LINKS} = "n";
207 }
208 $config{STATIC_LINK}        = "no";                                             # are doing static modules?
209 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                           # FD Limit
210 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`);                        # Hard FD Limit
211 chomp($config{GCCVER}       = `g++ -dumpversion | cut -c 1`);                   # Major GCC Version
212 $config{OSNAME}             = $^O;                                              # Operating System Name
213 $config{CC}                 = "g++";                                            # C++ compiler
214 if (defined $opt_cc)
215 {
216         $config{CC} = $opt_cc;
217 }
218 $exec = $config{CC} . " -dumpversion | cut -c 1";
219 chomp($config{GCCVER}       = `$exec`);                                         # Major GCC Version
220 $config{MAKEORDER}          = "ircd mods";                                      # build order
221 $config{STATICLIBS}         = "";                                               # library archive path
222 $config{MAX_IDENT}          = "12";                                             # max ident size
223 $config{MAX_QUIT}           = "255";                                            # max quit message size
224 $config{MAX_TOPIC}          = "307";                                            # max topic size
225 $config{MAX_KICK}           = "255";                                            # max kick message size
226 $config{MAX_GECOS}          = "128";                                            # max GECOS size
227 $config{MAX_AWAY}           = "200";                                            # max AWAY size
228 if (defined $opt_ident)
229 {
230         $config{MAX_IDENT} = $opt_ident;
231 }
232 if (defined $opt_quit)
233 {
234         $config{MAX_QUIT} = $opt_quit;
235 }
236 if (defined $opt_topic)
237 {
238         $config{MAX_TOPIC} = $opt_topic;
239 }
240 if (defined $opt_kick)
241 {
242         $config{MAX_KICK} = $opt_kick;
243 }
244 if (defined $opt_gecos)
245 {
246         $config{MAX_GECOS} = $opt_gecos;
247 }
248 if (defined $opt_away)
249 {
250         $config{MAX_AWAY} = $opt_away;
251 }
252
253 $no_svn = 0;
254
255 $config{HAS_OPENSSL} =~ /OpenSSL ([-[:digit:].]+)([a-z])?(\-[a-z][0-9])? (\w{3}|[0-9]+) (\w{3}|[0-9]+) [0-9]{4}/;
256 $config{HAS_OPENSSL} = $1;
257
258 if ($config{GCCVER} eq "") {
259         print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
260         exit;
261 }
262
263 # Minihack! Convert Cygwin to 'Cyg-Static' so i can
264 # Keep my dynamic module experiments here for later
265 # concideration!
266
267 if ($config{OSNAME} =~ /CYGWIN/i)
268 {
269         $config{OSNAME} = "CYG-STATIC";
270 }
271
272 if (!$config{MAX_CLIENT_T}) { 
273         $config{MAX_CLIENT_T} = 1024;                                 # Set a reasonable 'Default'
274         $fd_scan_fail = "true";                                       # Used Later
275 }
276
277 # Get and Set some important vars..
278 getmodules();
279
280 sub clean
281 {
282         if ($arg eq "-clean") {
283                 system("rm -rf .config.cache");
284         }
285 }
286
287 sub update
288 {
289         chomp($topdir = getcwd());
290         $this = resolve_directory($topdir);                                             # PWD, Regardless.
291         getmodules();
292         # Does the cache file exist?
293         if (!getcache()) {
294                 # No, No it doesn't.. *BASH*
295                 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
296                 exit 0;
297         } else {
298                 # We've Loaded the cache file and all our variables..
299                 print "Updating Files..\n";
300                 getosflags();
301                 if ($opt_disable_debug == 1)
302                 {
303                         print "Disabling debug information (-g).\n";
304                         $config{OPTIMISATI} = "";
305                         getosflags();
306                 }
307                 $has_epoll = $config{HAS_EPOLL};
308                 $has_kqueue = $config{HAS_KQUEUE};
309                 writefiles(1);
310                 print "Complete.\n";
311                 exit;
312         }
313 }
314
315 sub modupdate
316 {
317         chomp($topdir = getcwd());
318         $this = resolve_directory($topdir);                                             # PWD, Regardless.
319         getmodules();
320         # Does the cache file exist?
321         if (!getcache()) {
322                 # No, No it doesn't.. *BASH*
323                 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
324                 exit 0;
325         } else {
326                 # We've Loaded the cache file and all our variables..
327                 print "Updating Files..\n";
328                 getosflags();
329                 $has_epoll = $config{HAS_EPOLL};
330                 $has_kqueue = $config{HAS_KQUEUE};
331                 writefiles(0);
332                 print "Complete.\n";
333                 exit;
334         }
335 }
336
337
338
339 sub svnupdate
340 {
341         my $fail = 0;
342         open(FH,"<.svn/entries") or $fail = 1;
343         if ($fail) {
344                 print "This is not an SVN copy of InspIRCd.\n";
345                 exit;
346         }
347         system("svn update");
348         system("perl configure -update");
349         if ($ARGV[1] eq "rebuild") {
350                 system("make install");
351         }
352         exit;
353 }
354
355 print "Running non-interactive configure...\n" unless $interactive;
356 print "Checking for cache from previous configure... ";
357 print ((getcache() eq "true") ? "found\n" : "not found\n");
358 print "Checking operating system version... ";
359 print getosflags() . "\n";
360
361 if (defined $opt_maxclients)
362 {
363         $config{MAX_CLIENT} = $opt_maxclients;
364 }
365
366 if (!$config{MAX_CLIENT}) { 
367         # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
368         # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
369         # higher than the found value" :))
370         $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
371 }
372
373 printf "Checking if stdint.h exists... ";
374 $config{HAS_STDINT} = "true";
375 my $fail = 0;
376 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
377 if ($config{HAS_STDINT} eq "true") {
378         close(STDINT);
379 }
380 print "yes\n" if $config{HAS_STDINT} eq "true";
381 print "no\n" if $config{HAS_STDINT} eq "false";
382
383
384 printf "Checking if strlcpy exists... ";
385 # Perform the strlcpy() test..
386 $config{HAS_STRLCPY} = "false";
387 my $fail = 0;
388 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
389 if (!$fail) {
390         while (chomp($line = <STRLCPY>)) {
391                 # try and find the delcaration of:
392                 # size_t strlcpy(...)
393                 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
394                         $config{HAS_STRLCPY} = "true";
395                 }
396         }
397         close(STRLCPY);
398 }
399 print "yes\n" if $config{HAS_STRLCPY} eq "true";
400 print "no\n" if $config{HAS_STRLCPY} eq "false";
401
402
403 printf "Checking if kqueue exists... ";
404 $has_kqueue = 0;
405 $fail = 0;
406 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
407 if (!$fail) {
408         while (chomp($line = <KQUEUE>)) {
409                 # try and find the delcaration of:
410                 # int kqueue(void);
411                 if ($line =~ /int(\0x9|\s)+kqueue/) {
412                         $has_kqueue = 1;
413                 }
414         }
415         close(KQUEUE);
416 }
417 print "yes\n" if $has_kqueue == 1;
418 print "no\n" if $has_kqueue == 0;
419
420 printf "Checking if epoll exists... ";
421 $has_epoll = 0;
422 $fail = 0;
423 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
424 if (!$fail) {
425         $has_epoll = 1;
426         close(EPOLL);
427 }
428 if ($has_epoll) {
429         my $kernel = `uname -r`;
430         chomp($kernel);
431         if (($kernel =~ /2\.0/) || ($kernel =~ /2\.2/) || ($kernel =~ /2\.4/)) {
432                 $has_epoll = 0;
433         }
434 }
435 print "yes\n" if $has_epoll == 1;
436 print "no\n" if $has_epoll == 0;
437
438 if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) {
439         $config{HAS_STRLCPY} = "true";
440 }
441
442 $config{HAS_EPOLL} = $has_epoll;
443 $config{HAS_KQUEUE} = $has_kqueue; 
444
445 printf "Checking for libgnutls... ";
446 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
447         print "yes\n";
448         $config{HAS_GNUTLS} = "y";
449 } else {
450         print "no\n";
451         $config{HAS_GNUTLS} = "n";
452 }
453
454 printf "Checking for openssl... ";
455 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
456         print "yes\n";
457         $config{HAS_OPENSSL} = "y";
458 } else {
459         print "no\n";
460         $config{HAS_OPENSSL} = "n";
461 }
462
463 ################################################################################
464 #                          BEGIN INTERACTIVE PART                              #
465 ################################################################################
466
467 # Clear the Screen..
468 if ($interactive)
469 {
470         system("clear");
471         $wholeos = $^O;
472
473         my $rev = getrevision();
474         # Display Introduction Message..
475         print "
476 Welcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)
477 \033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m
478
479 *** If you are unsure of any of these values, leave it blank for    ***
480 *** standard settings that will work, and your server will run      ***
481 *** using them. Please consult your IRC network admin if in doubt.  ***
482
483 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
484 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
485 dir, otherwise you won't have a config file!
486
487 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos)
488 Maximum file descriptors: \033[1;32m$config{MAX_CLIENT_T}\033[0m
489 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
490         if ($rev eq "r0") {
491                 print " (Non-SVN build)";
492         }
493         print ".\n\n";
494
495         $config{CHANGE_COMPILER} = "n";
496         print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
497
498         while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
499                 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
500 should NOT be used. You should probably specify a newer compiler.\n\n";
501                 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
502                 if ($config{CHANGE_COMPILER} =~ /y/i) {
503                         print "What command do you want to use to invoke your compiler?\n";
504                         print "[\033[1;32m$config{CC}\033[0m] -> ";
505                         chomp($config{CC} = <STDIN>);
506                         if ($config{CC} eq "") {
507                                 $config{CC} = "g++";
508                         }
509                         chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
510                         if ($foo ne "") {
511                                 chomp($config{GCCVER}       = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
512                                 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
513                                 if ($config{GCCVER} < 3) {
514                                         print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
515                                 }
516                         }
517                         else {
518                                 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
519                         }
520                 }
521         }
522
523         print "\n";
524
525         # Directory Settings..
526         my $tmpbase = $config{BASE_DIR};
527         dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
528         if ($tmpbase ne $config{BASE_DIR}) {
529                 $config{CONFIG_DIR}         = resolve_directory($config{BASE_DIR}."/conf");           # Configuration Dir
530                 $config{MODULE_DIR}         = resolve_directory($config{BASE_DIR}."/modules");        # Modules Directory
531                 $config{BINARY_DIR}         = resolve_directory($config{BASE_DIR}."/bin");            # Binary Directory
532                 $config{LIBRARY_DIR}        = resolve_directory($config{BASE_DIR}."/lib");            # Library Directory
533         }
534
535         dir_check("are the configuration files", "CONFIG_DIR");
536         dir_check("are the modules to be compiled to", "MODULE_DIR");
537         dir_check("is the IRCd binary to be placed", "BINARY_DIR");
538         dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
539
540         if ($has_kqueue) {
541                 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?");
542                 print "\n";
543         }
544         if ($has_epoll) {
545                 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?");
546                 print "\n";
547         }
548         $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
549         if (!$chose_hiperf) {
550                 print "No high-performance socket engines are available, or you chose\n";
551                 print "not to enable one. Defaulting to select() engine.\n\n";
552         }
553
554         yesno(IPV6,"Would you like to build InspIRCd with IPv6 support?");
555         print "\n";
556
557         if ($config{IPV6} eq "y") {
558                 print "You have chosen to build an \033[1;32mIPV6-only\033[0m server.\nTo accept IPV4 users, you must use the '::ffff:' notation of addresses.\n\n";
559                 $config{SUPPORT_IP6LINKS} = "y";
560         } else {
561                 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 which are using '::ffff:' notation?\nIf you are using a recent operating\nsystem and are unsure, answer yes.");
562                 print "\n";
563         }
564
565         if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
566                 print "I have detected both GnuTLS and OpenSSL on your system.\n";
567                 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
568                 print "instead, you should enable the OpenSSL module yourself\n";
569                 print "by copying it from src/modules/extra to src/modules.\n\n";
570         }
571
572         if ($config{HAS_GNUTLS} eq "y") {
573                 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
574                 if ($config{USE_GNUTLS} eq "y") {
575                         print "\nUsing GnuTLS SSL module.\n";
576                 }
577         } elsif ($config{HAS_OPENSSL} eq "y") {
578                         yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
579         if ($config{USE_OPENSSL} eq "y") {
580                         print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
581                 }
582         }
583
584         print "\nThe following questions will ask you for various figures relating\n";
585         print "To your IRCd install. Please note that these should usually be left\n";
586         print "as defaults unless you have a real reason to change them. If they\n";
587         print "changed, then the values must be identical on all servers on your\n";
588         print "network, or malfunctions and/or crashes may occur, with the exception\n";
589         print "of the 'maximum number of clients' setting which may be different on\n";
590         print "different servers on the network.\n\n";
591
592         # File Descriptor Settings..
593         my $continue = 0;
594         while (!$continue) {
595                 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
596                 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
597                 chomp($var = <STDIN>);
598                 if ($var eq "") {
599                         $var = $config{MAX_CLIENT};
600                 }
601                 if ($var =~ /^\d+$/) {
602                         if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_fail ne "true")) {
603                                 # Client has entered a larger number than the 'discovered' value
604                                 # Confirm.
605                                 print "WARNING: Our scans have indicated that you are attempting
606 to use more sockets than there are avaliable. Are you sure
607 you wish to do this? It may cause the IRCd to malfunction [y/n]
608 [\033[1;32mn\033[0m] -> $c";
609                                 chomp($tmp = <STDIN>);
610                                 if ($tmp ne "y") {
611                                         print "Please enter the correct value.\n\n";
612                                         next;
613                                 }
614                         }
615                 } else {
616                         print "You must enter a number in this field. Please try again.\n\n";
617                         next;
618                 }
619                 # If we get here, we should be good to go.
620                 $config{MAX_CLIENT} = $var;
621                 $config{MAX_DESCRIPTORS} = $var;
622                 $continue = 1;
623                 print "\n";
624         }
625
626         my $continue = 0;
627         while (!$continue) {
628                 print "What is the maximum length of nicknames?\n";
629                 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
630                 chomp($var = <STDIN>);
631                 if ($var eq "") {
632                         $var = $config{NICK_LENGT};
633                 }
634                 if ($var =~ /^\d+$/) {
635                         # We don't care what the number is, set it and be on our way.
636                         $config{NICK_LENGT} = $var;
637                         $continue = 1;
638                         print "\n";
639                 } else {
640                         print "You must enter a number in this field. Please try again.\n\n";
641                 }
642         }
643
644         $continue = 0;
645         while (!$continue) {
646                 print "What is the maximum length of channel names?\n";
647                 print "[\033[1;32m$config{CHAN_LENGT}\033[0m] -> ";
648                 chomp($var = <STDIN>);
649                 if ($var eq "") {
650                         $var = $config{CHAN_LENGT};
651                 }
652                 if ($var =~ /^\d+$/) {
653                         # We don't care what the number is, set it and be on our way.
654                         $config{CHAN_LENGT} = $var;
655                         $continue = 1;
656                         print "\n";
657                 } else {
658                         print "You must enter a number in this field. Please try again.\n\n";
659                 }
660         }
661
662         $continue = 0;
663         while (!$continue) {
664                 print "What is the maximum number of channels a normal user may join at any one time?\n";
665                 print "[\033[1;32m$config{MAX_CHANNE}\033[0m] -> ";
666                 chomp($var = <STDIN>);
667                 if ($var eq "") {
668                         $var = $config{MAX_CHANNE};
669                 }
670                 if ($var =~ /^\d+$/) {
671                         # We don't care what the number is, set it and be on our way.
672                         $config{MAX_CHANNE} = $var;
673                         $continue = 1;
674                         print "\n";
675                 } else {
676                         print "You must enter a number in this field. Please try again.\n\n";
677                 }
678         }
679
680         $continue = 0;
681         while (!$continue) {
682                 print "What is the maximum number of channels an oper may join at any one time?\n";
683                 print "[\033[1;32m$config{MAX_OPERCH}\033[0m] -> ";
684                 chomp($var = <STDIN>);
685                 if ($var eq "") {
686                         $var = $config{MAX_OPERCH};
687                 }
688                 if ($var =~ /^\d+$/) {
689                         # We don't care what the number is, set it and be on our way.
690                         $config{MAX_OPERCH} = $var;
691                         $continue = 1;
692                         print "\n";
693                 }
694         }
695
696         $continue = 0;
697         while (!$continue) {
698                 print "What is the maximum number of mode changes in one line?\n";
699                 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
700                         chomp($var = <STDIN>);
701                 if ($var eq "") {
702                         $var = $config{MAXI_MODES};
703                 }
704                 if ($var =~ /^\d+$/) {
705                         # We don't care what the number is, set it and be on our way.
706                         $config{MAXI_MODES} = $var;
707                         $continue = 1;
708                         print "\n";
709                 } else {
710                         print "You must enter a number in this field. Please try again.\n\n";
711                 }
712         }
713
714         $continue = 0;
715         while (!$continue) {
716                 print "What is the maximum length of an ident (username)?\n";
717                 print "[\033[1;32m$config{MAX_IDENT}\033[0m] -> ";
718                 chomp($var = <STDIN>);
719                 if ($var eq "") {
720                         $var = $config{MAX_IDENT};
721                 }
722                 if ($var =~ /^\d+$/) {
723                         # We don't care what the number is, set it and be on our way.
724                         $config{MAX_IDENT} = $var;
725                         $continue = 1;
726                         print "\n";
727                 } else {
728                         print "You must enter a number in this field. Please try again.\n\n";
729                 }
730         }
731
732         $continue = 0;
733         while (!$continue) {
734                 print "What is the maximum length of a quit message?\n";
735                 print "[\033[1;32m$config{MAX_QUIT}\033[0m] -> ";
736                 chomp($var = <STDIN>);
737                 if ($var eq "") {
738                         $var = $config{MAX_QUIT};
739                 }
740                 if ($var =~ /^\d+$/) {
741                         # We don't care what the number is, set it and be on our way.
742                         $config{MAX_QUIT} = $var;
743                         $continue = 1;
744                         print "\n";
745                 } else {
746                         print "You must enter a number in this field. Please try again.\n\n";
747                 }
748         }
749
750         $continue = 0;
751         while (!$continue) {
752                 print "What is the maximum length of a channel topic?\n";
753                 print "[\033[1;32m$config{MAX_TOPIC}\033[0m] -> ";
754                 chomp($var = <STDIN>);
755                 if ($var eq "") {
756                         $var = $config{MAX_TOPIC};
757                 }
758                 if ($var =~ /^\d+$/) {
759                         # We don't care what the number is, set it and be on our way.
760                         $config{MAX_TOPIC} = $var;
761                         $continue = 1;
762                         print "\n";
763                 } else {
764                         print "You must enter a number in this field. Please try again.\n\n";
765                 }
766         }
767
768         $continue = 0;
769         while (!$continue) {
770                 print "What is the maximum length of a kick message?\n";
771                 print "[\033[1;32m$config{MAX_KICK}\033[0m] -> ";
772                 chomp($var = <STDIN>);
773                 if ($var eq "") {
774                         $var = $config{MAX_KICK};
775                 }
776                 if ($var =~ /^\d+$/) {
777                         # We don't care what the number is, set it and be on our way.
778                         $config{MAX_KICK} = $var;
779                         $continue = 1;
780                         print "\n";
781                 } else {
782                         print "You must enter a number in this field. Please try again.\n\n";
783                 }
784         }
785
786         $continue = 0;
787         while (!$continue) {
788                 print "What is the maximum length of a GECOS (real name) field?\n";
789                 print "[\033[1;32m$config{MAX_GECOS}\033[0m] -> ";
790                 chomp($var = <STDIN>);
791                 if ($var eq "") {
792                         $var = $config{MAX_GECOS};
793                 }
794                 if ($var =~ /^\d+$/) {
795                         # We don't care what the number is, set it and be on our way.
796                         $config{MAX_GECOS} = $var;
797                         $continue = 1;
798                         print "\n";
799                 } else {
800                         print "You must enter a number in this field. Please try again.\n\n";
801                 }
802         }
803
804         $continue = 0;
805         while (!$continue) {
806                 print "What is the maximum length of an away message?\n";
807                 print "[\033[1;32m$config{MAX_AWAY}\033[0m] -> ";
808                 chomp($var = <STDIN>);
809                 if ($var eq "") {
810                         $var = $config{MAX_AWAY};
811                 }
812                 if ($var =~ /^\d+$/) {
813                         # We don't care what the number is, set it and be on our way.
814                         $config{MAX_AWAY} = $var;
815                         $continue = 1;
816                         print "\n";
817                 } else {
818                         print "You must enter a number in this field. Please try again.\n\n";
819                 }
820         }
821 }
822
823 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
824 print "\033[0mBase install path:\033[1;32m\t\t$config{BASE_DIR}\033[0m\n";
825 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\033[0m\n";
826 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\033[0m\n";
827 print "\033[0mLibrary path:\033[1;32m\t\t\t$config{LIBRARY_DIR}\033[0m\n";
828 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\033[0m\n";
829 print "\033[0mMax User Channels:\033[1;32m\t\t$config{MAX_CHANNE}\033[0m\n";
830 print "\033[0mMax Oper Channels:\033[1;32m\t\t$config{MAX_OPERCH}\033[0m\n";
831 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\033[0m\n";
832 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\033[0m\n";
833 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\033[0m\n";
834 print "\033[0mMax ident length:\033[1;32m\t\t$config{MAX_IDENT}\033[0m\n";
835 print "\033[0mMax quit length:\033[1;32m\t\t$config{MAX_QUIT}\033[0m\n";
836 print "\033[0mMax topic length:\033[1;32m\t\t$config{MAX_TOPIC}\033[0m\n";
837 print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\033[0m\n";
838 print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\033[0m\n";
839 print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\033[0m\n";
840 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.x\033[0m\n";
841 # and not echo it out so we don't get some ricer fuck complaining
842 #print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
843 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
844 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n";
845 print "\033[0mIPv6 Support:\033[1;32m\t\t\t$config{IPV6}\033[0m\n";
846 print "\033[0mIPv6 to IPv4 Links:\033[1;32m\t\t$config{SUPPORT_IP6LINKS}\033[0m\n";
847 print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n";
848 print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n";
849
850 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
851 {
852         print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
853         exit(0);
854 }
855 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
856 {
857         print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
858         exit(0);
859 }
860
861 if ($config{USE_GNUTLS} eq "y") {
862         $failed = 0;
863         open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
864         close(TMP);
865         if ($failed) {
866                 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
867                 chdir("src/modules");
868                 system("ln -s extra/m_ssl_gnutls.cpp");
869                 system("ln -s extra/ssl_cert.h");
870                 chdir("../..");
871         }
872         getmodules();
873         if ($interactive)
874         {
875                 $failed = 0;
876                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
877                 close(TMP);
878                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
879                 close(TMP);
880                 if ($failed) {
881                         print "SSL Certificates Not found, Generating.. \n\n
882 *************************************************************
883 * Generating the Private Key may take some time, go grab a  *
884 * Coffee. Even better, to generate some more entropy if it  *
885 * is taking a while, open another console and type du / a   *
886 * few times and get that HD going :) Then answer the        *
887 * Questions which follow. If you are unsure, just hit enter *
888 *************************************************************\n\n";
889                         system("certtool --generate-privkey --outfile key.pem");
890                         system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
891                         print "\nCertificate generation complete, copying to config directory... ";
892                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
893                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
894                         print "Done.\n\n";
895                 } else {
896                         print "SSL Certificates found, skipping.\n\n"
897                 }
898         }
899         else
900         {
901                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
902         }
903 } elsif ($config{USE_OPENSSL} eq "y") {
904         $failed = 0;
905         open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
906         close(TMP);
907         if ($failed) {
908                 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
909                 chdir("src/modules");
910                 system("ln -s extra/m_ssl_openssl.cpp");
911                 system("ln -s extra/ssl_cert.h");
912                 chdir("../..");
913         }
914         getmodules();
915         $failed = 0;
916         if ($interactive)
917         {
918                 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
919                 close(TMP);
920                 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
921                 close(TMP);
922                 if ($failed) {
923                         print "SSL Certificates Not found, Generating.. \n\n
924 *************************************************************
925 * Generating the certificates may take some time, go grab a *
926 * coffee, or something.                                     *
927 *************************************************************\n\n";
928                         system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
929                         system("openssl dhparam -out dhparams.pem 1024");
930                         print "\nCertificate generation complete, copying to config directory... ";
931                         system("mv key.pem $config{CONFIG_DIR}/key.pem");
932                         system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
933                         system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
934                         print "Done.\n\n";
935                 } else {
936                         print "SSL Certificates found, skipping.\n\n"
937                 }
938         }
939         else
940         {
941                 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
942         }
943 }
944 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
945         print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
946 }
947
948 getosflags();
949 makecache();
950 writefiles(1);
951
952 print "\n\n";
953 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
954 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
955         print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
956         print "load the required modules in your config. This configure process\n";
957         print "has just prepared these modules to be compiled for you, and has not\n";
958         print "configured them to be compiled into the core of the ircd.\n";
959 }
960 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
961 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
962         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";
963 }
964
965 if ($config{GCCVER} < "3") {
966         print <<FOO2;
967 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
968 GCC 2.x series compilers only had partial (read as broken) C++ support, and
969 your compile will most likely fail horribly! If you have any problems, do NOT
970 report them to the bugtracker or forums without first upgrading your compiler
971 to a newer 3.x or 4.x (or whatever is available currently) version.
972 FOO2
973 }
974
975 ################################################################################
976 #                              HELPER FUNCTIONS                                #
977 ################################################################################
978 sub getcache {
979         # Retrieves the .config.cache file, and loads values into the main config hash.
980         open(CACHE, ".config.cache") or return undef;
981         while (<CACHE>) {
982                 chomp;
983                 # Ignore Blank lines, and comments..
984                 next if /^\s*$/;
985                 next if /^\s*#/;
986                 my ($key, $value) = split("=", $_);
987                 $value =~ /^\"(.*)\"$/;
988                 # Do something with data here!
989                 $config{$key} = $1;
990         }
991         close(CONFIG);
992         return "true";
993 }
994
995 sub makecache {
996         # Dump the contents of %config
997         print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
998         open(FILEHANDLE, ">.config.cache");
999         foreach $key (keys %config) {
1000                 print FILEHANDLE "$key=\"$config{$key}\"\n";
1001         }
1002         close(FILEHANDLE);
1003 }
1004
1005 sub dir_check {
1006         my ($desc, $hash_key) = @_;
1007         my $complete = 0;
1008         while (!$complete) {
1009                 print "In what directory $desc?\n";
1010                 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
1011                 chomp($var = <STDIN>);
1012                 if ($var eq "") {
1013                         $var = $config{$hash_key};
1014                 }
1015                 if ($var =~ /^\~\/(.+)$/) {
1016                         # Convert it to a full path..
1017                         $var = resolve_directory($ENV{HOME} . "/" . $1);
1018                 }
1019                 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1020                 {
1021                         # Assume relative Path was given.. fill in the rest.
1022                         $var = $this . "/$var";
1023                 }
1024                 
1025                 $var = resolve_directory($var); 
1026                 if (! -e $var) {
1027                         print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
1028                         chomp($tmp = <STDIN>);
1029                         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1030                                 # Attempt to Create the Dir..
1031                                 
1032                                 system("mkdir -p \"$var\" >> /dev/null 2>&1");
1033                                 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
1034                                 if ($chk != 0) {
1035                                         print "Unable to create directory. ($var)\n\n";
1036                                         # Restart Loop..
1037                                         next;
1038                                 }
1039                         } else {
1040                                 # They said they don't want to create, and we can't install there.
1041                                 print "\n\n";
1042                                 next;
1043                         }
1044                 } else {
1045                         if (!is_dir($var)) {
1046                                 # Target exists, but is not a directory.
1047                                 print "File $var exists, but is not a directory.\n\n";
1048                                 next;
1049                         }
1050                 }
1051                 # Either Dir Exists, or was created fine.
1052                 $config{$hash_key} = $var;
1053                 $complete = 1;
1054                 print "\n";
1055         }
1056 }
1057
1058 sub getosflags {
1059
1060         $config{LDLIBS} = "-lstdc++";
1061         $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1062         $config{MAKEPROG} = "make";
1063
1064         if ($config{OSNAME} =~ /OpenBSD/i) {
1065                 $config{MAKEPROG} = "gmake";
1066                 chomp($foo = `eg++ -dumpversion | cut -c 1`);
1067                 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1068                 # if theyre not running this, configure lets the build continue but they probably wont manage to
1069                 # compile as this standard version is 2.95.3!
1070                 if ($foo ne "") {
1071                         $config{CC} = "eg++";
1072                         chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1073                 }
1074                 return "OpenBSD";
1075         }
1076
1077         if ($config{OSNAME} =~ /Linux/i) {
1078                 $config{LDLIBS} = "-ldl -lstdc++";
1079                 $config{FLAGS}  = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1080                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1081                 $config{MAKEPROG} = "make";
1082                 if ($config{OSNAME} =~ /CYGWIN/) {
1083                         $config{FLAGS}  = "-fno-strict-aliasing -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1084                         $config{LDLIBS} = "";
1085                         $config{MAKEPROG} = "/usr/bin/make";
1086                         $config{MAKEORDER} = "ircd mods";
1087                         return "Cygwin";
1088                 } elsif ($config{OSNAME} eq "CYG-STATIC") {
1089                         $config{FLAGS} = "-fno-strict-aliasing -Wall -Woverloaded-virtual $config{OPTIMISATI}";
1090                         $config{LDLIBS} = "";
1091                         $config{MAKEPROG} = "/usr/bin/make";
1092                         $config{MAKEORDER} = "mods ircd";
1093                         $config{STATICLIBS} = "modules/mods.a";
1094                         $config{STATIC_LINK} = "yes";
1095                         return "Cygwin-Static";
1096                 }
1097                 $config{FLAGS}  .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1098         }
1099         
1100         if ($config{OSNAME} =~ /SunOS/i)
1101         {
1102                 # solaris/sunos needs these
1103                 # socket = bsd sockets api
1104                 # nsl = dns stuff
1105                 # rt = POSIX realtime extensions
1106                 # resolv = inet_aton only (why isnt this in nsl?!)
1107                 $config{MAKEPROG} = "gmake";
1108                 $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
1109                 return "Solaris";
1110         }
1111         
1112         if($config{OSNAME} =~ /MINGW32/i)
1113         {
1114                 # All code is position-independent on windows
1115                 $config{FLAGS} =~ s/-fPIC //;
1116                 return "MinGW";
1117         }
1118
1119         return $config{OSNAME};
1120 }
1121
1122 sub is_dir {
1123         my ($path) = @_;
1124         if (chdir($path)) {
1125                 chdir($this);
1126                 return 1;
1127         } else {
1128                 # Just in case..
1129                 chdir($this);
1130                 return 0;
1131         }
1132 }
1133
1134 sub getmodules {
1135         my $i = 0;
1136         print "Detecting modules ";
1137         opendir(DIRHANDLE, "src/modules");
1138         foreach $name (sort readdir(DIRHANDLE)) {
1139                 if ($name =~ /^m_(.+)\.cpp$/)
1140                 {
1141                         $mod = $1;
1142                         if ($mod !~ /_static$/) {
1143                                 $modlist[$i++] = $mod;
1144                                 print ".";
1145                         }
1146                 }
1147         }
1148         closedir(DIRHANDLE);
1149         print "\nOk, $i modules.\n";
1150 }
1151
1152 sub getrevision {
1153         if ($no_svn) {
1154                 return "0";
1155         }
1156         my $data = `svn info`;
1157         
1158         if ($data eq "") {
1159                 $no_svn = 1;
1160                 $rev = "0";
1161                 return $rev;
1162         }
1163         $data =~ /Revision: (\d+)/;
1164         my $rev = $1;
1165         if (!defined($rev)) {
1166                 $rev = "0";
1167         }
1168         return $rev;
1169 }
1170
1171 sub writefiles {
1172         my($writeheader) = @_;
1173         # First File.. inspircd_config.h
1174         chomp(my $incos = `uname -n -s -r`);
1175         chomp(my $version = `sh ./src/version.sh`);
1176         chomp(my $revision = getrevision());
1177         $version = "$version(r$revision)";
1178         chomp(my $revision2 = getrevision());
1179         if ($writeheader == 1)
1180         {
1181                 print "Writing \033[1;32minspircd_config.h\033[0m\n";
1182                 open(FILEHANDLE, ">include/inspircd_config.h");
1183                 my $NL = $config{NICK_LENGT}+1;
1184                 my $CL = $config{CHAN_LENGT}+1;
1185                 print FILEHANDLE <<EOF;
1186 /* Auto generated by configure, do not modify! */
1187 #ifndef __CONFIGURATION_AUTO__
1188 #define __CONFIGURATION_AUTO__
1189
1190 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1191 #define MOD_PATH "$config{MODULE_DIR}"
1192 #define VERSION "$version"
1193 #define REVISION "$revision2"
1194 #define MAXCLIENTS $config{MAX_CLIENT}
1195 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1196 #define NICKMAX $NL
1197 #define CHANMAX $CL
1198 #define MAXCHANS $config{MAX_CHANNE}
1199 #define OPERMAXCHANS $config{MAX_OPERCH}
1200 #define MAXMODES $config{MAXI_MODES}
1201 #define IDENTMAX $config{MAX_IDENT}
1202 #define MAXQUIT $config{MAX_QUIT}
1203 #define MAXTOPIC $config{MAX_TOPIC}
1204 #define MAXKICK $config{MAX_KICK}
1205 #define MAXGECOS $config{MAX_GECOS}
1206 #define MAXAWAY $config{MAX_AWAY}
1207 #define OPTIMISATION $config{OPTIMITEMP}
1208 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1209 #define SYSTEM "$incos"
1210 #define MAXBUF 514
1211 EOF
1212                 if ($config{OSNAME} =~ /SunOS/i) {
1213                         print FILEHANDLE "#define IS_SOLARIS\n";
1214                 }
1215                 if ($config{OSNAME} =~ /CYGWIN/i) {
1216                         print FILEHANDLE "#define IS_CYGWIN\n";
1217                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE        1024\n#endif\n";
1218                 }
1219                 if ($config{OSNAME} =~ /MINGW32/i) {
1220                         print FILEHANDLE "#define IS_MINGW\n";
1221                 }
1222                 if ($config{OSNAME} =~ /CYG-STATIC/i) {
1223                         print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE    1024\n#endif\n";
1224                 }
1225                 if ($config{STATIC_LINK} eq "yes") {
1226                         print FILEHANDLE "#define STATIC_LINK\n";
1227                 }
1228                 if ($config{GCCVER} >= 3) {
1229                         print FILEHANDLE "#define GCC3\n";
1230                 }
1231                 if ($config{HAS_STRLCPY} eq "true") {
1232                         print FILEHANDLE "#define HAS_STRLCPY\n";
1233                 }
1234                 if ($config{HAS_STDINT} eq "true") {
1235                         print FILEHANDLE "#define HAS_STDINT\n";
1236                 }
1237                 if ($config{IPV6} =~ /y/i) {
1238                         print FILEHANDLE "#define IPV6\n";
1239                 }
1240                 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1241                         print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1242                 }
1243                 my $use_hiperf = 0;
1244                 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1245                         print FILEHANDLE "#define USE_KQUEUE\n";
1246                         $se = "socketengine_kqueue";
1247                         $use_hiperf = 1;
1248                 }
1249                 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1250                         print FILEHANDLE "#define USE_EPOLL\n";
1251                         $se = "socketengine_epoll";
1252                         $use_hiperf = 1;
1253                 }
1254                 # user didn't choose either epoll or select for their OS.
1255                 # default them to USE_SELECT (ewwy puke puke)
1256                 if (!$use_hiperf) {
1257                         print FILEHANDLE "#define USE_SELECT\n";
1258                         $se = "socketengine_select";
1259                 }
1260                 print FILEHANDLE "\n#endif\n";
1261                 close(FILEHANDLE);
1262         }
1263
1264         if ($writeheader)
1265         {
1266                 open(FILEHANDLE, ">include/inspircd_se_config.h");
1267                 print FILEHANDLE <<EOF;
1268 /* Auto generated by configure, do not modify or commit to svn! */
1269 #ifndef __CONFIGURATION_SOCKETENGINE__
1270 #define __CONFIGURATION_SOCKETENGINE__
1271
1272 #include "$se.h"
1273
1274 #endif
1275 EOF
1276                 close(FILEHANDLE);
1277         }
1278
1279
1280         # Create a Modules List..
1281         my $modules = "";
1282         foreach $i (@modlist)
1283         {
1284                 if ($config{STATIC_LINK} eq "yes") {
1285                         $modules .= "m_".$i.".o ";
1286                 }
1287                 else {
1288                         $modules .= "m_".$i.".so ";
1289                 }
1290         }
1291         chomp($modules);   # Remove Redundant whitespace..
1292
1293
1294         # Write all .in files.
1295         my $tmp = "";
1296         my $file = "";
1297         my $exe = "inspircd";
1298
1299         if ($config{OSNAME} =~ /CYGWIN/i) {
1300                 $exe = "inspircd.exe";
1301         }
1302
1303         opendir(DIRHANDLE, $this);
1304
1305         # Do this once here, and cache it in the .*.inc files,
1306         # rather than attempting to read src/version.sh from
1307         # compiled code -- we might not have the source to hand.
1308         # Fix for bug#177 by Brain.
1309
1310         chomp(my $version = `sh ./src/version.sh`);
1311         chomp(my $revision = getrevision());
1312         $version = "$version(r$revision)";
1313
1314         # We can actually parse any file starting with . and ending with .inc,
1315         # but right now we only parse .inspircd.inc to form './inspircd'
1316
1317         foreach $name (sort readdir(DIRHANDLE)) {
1318                 if ($name =~ /^\.(.+)\.inc$/) {
1319                         $file = $1;
1320                         # All .name.inc files need parsing!
1321                         $tmp = "";
1322                         open(FILEHANDLE, ".$file.inc");
1323                         while (<FILEHANDLE>) {
1324                                 $tmp .= $_;
1325                         }
1326                         close(FILEHANDLE);
1327
1328                         $tmp =~ s/\@CC\@/$config{CC}/;
1329                         $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1330                         $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1331                         $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1332                         $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1333                         $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1334                         $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1335                         $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1336                         $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1337                         $tmp =~ s/\@MODULES\@/$modules/;
1338                         $tmp =~ s/\@EXECUTABLE\@/$exe/;
1339                         $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1340                         $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
1341                         $tmp =~ s/\@VERSION\@/$version/;
1342
1343                         print "Writing \033[1;32m$file\033[0m\n";
1344                         open(FILEHANDLE, ">$file");
1345                         print FILEHANDLE $tmp;
1346                 }
1347         }
1348         closedir(DIRHANDLE);
1349
1350         # Make inspircd executable!
1351         chmod 0744, 'inspircd';
1352
1353         if ($config{STATIC_LINK} eq "yes") {
1354                 print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
1355                 write_static_makefile();
1356                 write_static_modules_makefile();
1357         } elsif ($config{OSNAME} =~ /CYGWIN/i) {
1358                 print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
1359                 write_static_makefile();
1360                 write_dynamic_modules_makefile();
1361         } else {
1362                 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1363                 write_dynamic_makefile();
1364                 write_dynamic_modules_makefile();
1365         }
1366 }
1367
1368 sub getcompilerflags {
1369         my ($file) = @_;
1370         open(FLAGS, $file);
1371         while (<FLAGS>) {
1372         if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
1373                 close(FLAGS);
1374                         return $1;
1375                 }
1376         }
1377         close(FLAGS);
1378         return undef;
1379 }
1380
1381 sub getlinkerflags {
1382         my ($file) = @_;
1383         open(FLAGS, $file);
1384         while (<FLAGS>) {
1385                 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
1386                         close(FLAGS);
1387                         return $1;
1388                 }
1389         }
1390         close(FLAGS);
1391         return undef;
1392 }
1393
1394 sub getdependencies {
1395         my ($file) = @_;
1396         open(FLAGS, $file);
1397         while (<FLAGS>) {
1398                 if ($_ =~ /^\/\* \$ModDep: (.+) \*\/$/) {
1399                         close(FLAGS);
1400                         return $1;
1401                 }
1402         }
1403         close(FLAGS);
1404         return undef;
1405 }
1406
1407 sub resolve_directory {
1408         use File::Spec;
1409         return File::Spec->rel2abs($_[0]);
1410 }
1411
1412 sub yesno {
1413         my ($flag,$prompt) = @_;
1414         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
1415         chomp($tmp = <STDIN>);
1416         if ($tmp eq "") { $tmp = $config{$flag} }
1417
1418         if (($tmp eq "") || ($tmp =~ /^y/i)) {
1419                 $config{$flag} = "y";
1420         } else {
1421                 $config{$flag} = "n";
1422         }
1423         return;
1424 }
1425
1426 sub write_static_modules_makefile {
1427         # Modules Makefile..
1428         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1429         open(FILEHANDLE, ">src/modules/Makefile");
1430
1431         ###
1432         # Module Makefile Header
1433         ###
1434         print FILEHANDLE <<EOF;
1435 # (C) ChatSpike development team
1436 # Makefile by <Craig\@ChatSpike.net>
1437 # Many Thanks to Andrew Church <achurch\@achurch.org>
1438 #    for assisting with making this work right.
1439 #
1440 # Automatically Generated by ./configure to add a modules
1441 # please run ./configure --update
1442
1443 all: \$(MODULES)
1444
1445 EOF
1446         ###
1447         # End Module Makefile Header
1448         ###
1449
1450         # Create a Modules List..
1451         my $modules = "";
1452         my $cmflags = "";
1453         my $liflags = "";
1454
1455         open(MODLIST,">include/modlist.h");
1456
1457         ###
1458         # Include File Header
1459         ###
1460         print MODLIST <<HEADER;
1461 // Generated automatically by configure. DO NOT EDIT!
1462
1463 #ifndef __SYMBOLS__H_CONFIGURED__
1464 #define __SYMBOLS__H_CONFIGURED__
1465
1466 HEADER
1467         ###
1468         # End Include File Header
1469         ###
1470
1471         # Place Module List into Include
1472         foreach $i (@modlist) {
1473                 if ($i !~ /_static$/) {
1474                         print MODLIST "extern \"C\" void * $i\_init (void);\n";
1475                 }
1476         }
1477         print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
1478
1479         ###
1480         # Build Module Crap
1481         ###
1482         foreach $i (@modlist)
1483         {
1484                 if ($i !~ /_static$/) {
1485                         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1486                         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1487                         $deps = getdependencies("src/modules/m_".$i.".cpp");
1488
1489                         ###
1490                         # Write Entry to the Makefile
1491                         ###
1492                         print FILEHANDLE <<EOCHEESE;
1493 m_$i.o: .m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h $deps
1494         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c .m_$i\_static.cpp
1495         mv .m_$i\_static.o ../m_$i.o
1496
1497 EOCHEESE
1498                         ###
1499                         # End Write Entry to the MakeFile
1500                         ###
1501                         print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
1502                         open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
1503                         open(MUNGED,">src/modules/.m_".$i."_static.cpp") or die("Could not create .m_".$i."_static.cpp");
1504                         while (chomp($a = <MODULE>)) { 
1505                                 $a =~ s/init_module/$i\_init/g;
1506                                 print MUNGED "$a\n";
1507                         }
1508                         close(MODULE);
1509                         close(MUNGED);
1510                         print MODLIST <<EOENT;
1511 {"m_$i.so",\&$i\_init},
1512 EOENT
1513                         print "done\n";
1514                 }
1515         }
1516         print MODLIST "{0}};\n\n#endif\n";
1517         close(MODLIST);
1518 }
1519
1520 sub write_dynamic_modules_makefile {
1521         # Modules Makefile..
1522         print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1523         open(FILEHANDLE, ">src/modules/Makefile");
1524         my $extra = "";
1525
1526         if ($config{OSNAME} =~ /CYGWIN/i) {
1527                 $extra = "../inspircd.dll.a";
1528         }
1529
1530 ###
1531 # Module Makefile Header
1532 ###
1533         print FILEHANDLE <<EOF;
1534 # (C) ChatSpike development team
1535 # Makefile by <Craig\@ChatSpike.net>
1536 # Many Thanks to Andrew Church <achurch\@achurch.org>
1537 #    for assisting with making this work right.
1538 #
1539 # Automatically Generated by ./configure to add a modules
1540 # please run ./configure -update or ./configure -modupdate
1541
1542 all: \$(MODULES)
1543
1544 EOF
1545         ###
1546         # End Module Makefile Header
1547         ###
1548
1549         # Create a Modules List..
1550         my $modules = "";
1551         my $cmflags = "";
1552         my $liflags = "";
1553         my $crud = "";
1554
1555         foreach $i (@modlist) {
1556         ###
1557         # Write Entry to the MakeFile
1558         ###
1559         $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1560         $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1561         $deps = getdependencies("src/modules/m_".$i.".cpp");
1562         print FILEHANDLE <<EOCHEESE;
1563 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
1564         \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
1565         \$(CC) -pipe \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
1566
1567 EOCHEESE
1568         $crud = $crud . "       install -m 0700 m_$i.so \$(MODPATH)\n";
1569 ###
1570         # End Write Entry to the MakeFile
1571         ###
1572         }
1573         print FILEHANDLE "modinst:\n    \@echo \"Installing modules...\"\n" . $crud;
1574 }
1575
1576
1577 sub write_static_makefile {
1578         open(FH,">src/Makefile") or die("Could not write src/Makefile!");
1579         my $i = 0;
1580         my @cmdlist = ();
1581         opendir(DIRHANDLE, "src");
1582         foreach $name (sort readdir(DIRHANDLE)) {
1583                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1584                         $cmdlist[$i++] = $1;
1585                 }
1586         }
1587         closedir(DIRHANDLE);
1588         my $cmdobjs = "";
1589         my $srcobjs = "";
1590         foreach my $cmd (@cmdlist) {
1591                 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1592                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1593         }
1594         print FH <<EOM;
1595 # Insp Makefile :p
1596 #
1597 # (C) ChatSpike development team
1598 # Makefile by <Craig\@ChatSpike.net>
1599 # Makefile version 2 (statically linked core) by <brain\@inspircd.org>
1600 #
1601
1602 CC = im a cheezeball
1603
1604 CXXFLAGS = -I../include \${FLAGS}
1605 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1606 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1607
1608 EOM
1609
1610 $se = "socketengine_select";
1611 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1612         $se = "socketengine_kqueue";
1613 }       
1614 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1615         $se = "socketengine_epoll";
1616 }
1617
1618         ###
1619         # This next section is for cygwin dynamic module builds.
1620         # Basically, what we do, is build the inspircd core as a library
1621         # then the main executable uses that. the library is capable of
1622         # loading / unloading the modules dynamically :)
1623         # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
1624         # make this work :)
1625         ###
1626
1627         if ($config{OSNAME} =~ /CYGWIN/i) {
1628                 print FH <<EOM;
1629 all: timer.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o inspircd.exe
1630
1631 inspircd.exe: inspircd.dll.a
1632         \$(CC) -o \$@ \$^
1633
1634 inspircd.dll inspircd.dll.a: inspircd.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs  commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o timer.o snomasks.o
1635         \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
1636 EOM
1637         } else {
1638                 print FH <<EOM;
1639 all: timer.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o \$(MODULES) inspircd.exe
1640
1641 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/base.h
1642         \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspsocket.o configreader.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o timer.o snomasks.o modes/modeclasses.a \$(MODULES)
1643 EOM
1644         }
1645
1646         print FH <<EOM;
1647
1648 cull_list.o: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1649         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1650
1651 snomasks.o: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1652         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1653
1654 command_parse.o: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1655         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1656
1657 userprocess.o: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1658         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1659
1660 socketengine.o: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1661         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1662
1663 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1664         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1665
1666 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1667         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1668
1669 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1670         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1671
1672 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 \$(RELCPPFILES) modes/modeclasses.a
1673         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS)
1674         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1675
1676 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
1677         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1678
1679 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
1680         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1681
1682 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
1683         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1684
1685 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1686         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1687
1688 configreader.o: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1689         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1690
1691 commands.o: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h $srcobjs
1692         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp $cmdobjs
1693
1694 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
1695         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1696
1697 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
1698         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1699
1700 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
1701         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1702
1703 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
1704         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1705
1706 socket.o: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1707         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1708         
1709 inspsocket.o: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1710         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1711
1712 timer.o: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1713         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1714
1715 EOM
1716         foreach my $cmd (@cmdlist) {
1717                 print FH <<ITEM;
1718 cmd_$cmd.o: 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
1719         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1720 ITEM
1721         }
1722         close(FH);
1723 }
1724
1725 sub write_dynamic_makefile {
1726
1727         my $i = 0;
1728         my @cmdlist = ();
1729         opendir(DIRHANDLE, "src");
1730         foreach $name (sort readdir(DIRHANDLE)) {
1731                 if ($name =~ /^cmd_(.+)\.cpp$/) {
1732                         $cmdlist[$i++] = $1;
1733                 }
1734         }
1735         closedir(DIRHANDLE);
1736
1737         my $cmdobjs = "";
1738         my $srcobjs = "";
1739         foreach my $cmd (@cmdlist) {
1740                 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1741                 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1742         }
1743
1744         $se = "socketengine_select";
1745         if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1746                 $se = "socketengine_kqueue";
1747         }
1748         elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1749                 $se = "socketengine_epoll";
1750         }
1751
1752         open(FH,">src/Makefile") or die("Could not write src/Makefile");
1753         print FH <<EOM;
1754 # Insp Makefile :p
1755 #
1756 # (C) ChatSpike development team
1757 # Makefile by <Craig\@ChatSpike.net>
1758 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
1759 #
1760
1761 CC = im a cheezeball
1762
1763 CXXFLAGS = -I../include \${FLAGS}
1764 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1765 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1766
1767 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 inspircd
1768
1769 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
1770         \$(CC) -pipe -I../include $extra -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) -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
1771
1772 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1773         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1774         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1775
1776 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
1777         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1778         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1779
1780 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
1781         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1782         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1783
1784 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
1785         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1786         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1787
1788 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1789         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1790         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1791
1792 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1793         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1794         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1795
1796 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1797         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1798         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1799
1800 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1801         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1802         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1803
1804 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)
1805         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1806         \${MAKE} -C "modes" DIRNAME="src/modes" CC="\$(CC)" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1807         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1808
1809 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
1810         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1811         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1812
1813 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
1814         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1815         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1816
1817 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
1818         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1819         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1820
1821 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1822         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1823         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1824
1825 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
1826         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1827         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1828
1829 libIRCDcommands.so: commands.cpp ../include/base.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1830         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1831         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o
1832
1833 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
1834         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1835         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1836
1837 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
1838         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1839         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1840
1841 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
1842         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1843         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1844
1845 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
1846         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1847         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1848
1849 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1850         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1851         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1852
1853 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1854         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1855         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1856
1857 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1858         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1859         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1860
1861 EOM
1862         foreach my $cmd (@cmdlist) {
1863                 print FH <<ITEM;
1864 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
1865         \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1866         \$(CC) -pipe -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o cmd_$cmd.so cmd_$cmd.o
1867
1868 ITEM
1869         }
1870         close(FH);
1871 }
1872
1873 sub showhelp
1874 {
1875         chomp($PWD = `pwd`);
1876         print "Usage: configure [options]
1877
1878 *** NOTE: NON-INTERACTIVE CONFIGURE IS *NOT* SUPPORTED BY THE ***
1879 *** INSPIRCD DEVELOPMENT TEAM. DO NOT ASK FOR HELP REGARDING  ***
1880 ***     NON-INTERACTIVE CONFIGURE ON THE FORUMS OR ON IRC!    ***
1881
1882 Options: [defaults in brackets after descriptions]
1883
1884 When no options are specified, interactive
1885 configuration is started and you must specify
1886 any required values manually. If one or more
1887 options are specified, non-interactive configuration
1888 is started, and any omitted values are defaulted.
1889
1890 Arguments with a single \"-\" symbol, as in
1891 InspIRCd 1.0.x, are also allowed.
1892
1893   --disable-interactive        Sets no options intself, but
1894                                will disable any interactive prompting.
1895   --update                     Update makefiles and dependencies
1896   --modupdate                  Detect new modules and write makefiles
1897   --svnupdate {rebuild}        Update working copy via subversion
1898                                {and optionally rebuild it}
1899   --clean                      Remove .config.cache file and go interactive
1900   --enable-gnutls              Enable GnuTLS module [no]
1901   --enable-openssl             Enable OpenSSL module [no]
1902   --with-nick-length=[n]       Specify max. nick length [32]
1903   --with-channel-length=[n]    Specify max. channel length [64]
1904   --with-max-channels=[n]      Specify max. number of channels
1905                                a normal user may join [20]
1906   --with-max-oper-channels=[n] Specify max. number of channels
1907                                an irc operator may join [60]
1908   --with-max-clients=[n]       Specify maximum number of users
1909                                which may connect locally
1910   --enable-optimization=[n]    Optimize using -O[n] gcc flag
1911   --enable-epoll               Enable epoll() where supported [set]
1912   --enable-kqueue              Enable kqueue() where supported [set]
1913   --disable-epoll              Do not enable epoll(), fall back
1914                                to select() [not set]
1915   --disable-kqueue             Do not enable kqueue(), fall back
1916                                to select() [not set]
1917   --enable-ipv6                Build ipv6 native InspIRCd [no]
1918   --enable-remote-ipv6         Build with ipv6 support for remote
1919                                servers on the network [yes]
1920   --disable-remote-ipv6        Do not allow remote ipv6 servers [not set]
1921   --with-cc=[filename]         Use an alternative g++ binary to
1922                                build InspIRCd [g++]
1923   --with-ident-length=[n]      Specify max length of ident [12]
1924   --with-quit-length=[n]       Specify max length of quit [200]
1925   --with-topic-length=[n]      Specify max length of topic [350]
1926   --with-kick-length=[n]       Specify max length of kick [200]
1927   --with-gecos-length=[n]      Specify max length of gecos [150]
1928   --with-away-length=[n]       Specify max length of away [150]
1929   --with-max-modes=[n]         Specify max modes per line which
1930                                have parameters [20]
1931   --prefix=[directory]         Base directory to install into (if defined,
1932                                can automatically define config, module, bin
1933                                and library dirs as subdirectories of prefix)
1934                                [$PWD]
1935   --config-dir=[directory]     Config file directory for config and SSL certs
1936                                [$PWD/conf]
1937   --module-dir=[directory]     Modules directory for loadable modules
1938                                [$PWD/modules]
1939   --binary-dir=[directory]     Binaries directory for core binary
1940                                [$PWD/bin]
1941   --library-dir=[directory]    Library directory for core libraries
1942                                [$PWD/lib]
1943   --help                       Show this help text and exit
1944
1945 ";
1946         exit(0);
1947 }