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