]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - configure
Added eg++ stuff
[user/henk/code/inspircd.git] / configure
1 #!/usr/bin/perl
2 # InspIRCd Configuration Script
3 #
4 # Copyright 2003 The ChatSpike Development Team
5 # <brain@chatspike.net>
6 # <Craig@chatspike.net>
7 #
8 # [14:21] Brain: <matrix impression> i know perl-fu!
9 #
10 # $Id$
11 #
12 ########################################
13
14 chomp($topdir = `pwd`);
15 $this = resolve_directory($topdir);                                             # PWD, Regardless.
16 @modlist = ();                                                                  # Declare for Module List..
17 %config = ();                                                                   # Initiate Configuration Hash..
18 $config{ME}                 = resolve_directory($topdir);                       # Present Working Directory
19 $config{CONFIG_DIR}         = resolve_directory($config{ME}."/conf");           # Configuration Directory
20 $config{MODULE_DIR}         = resolve_directory($config{ME}."/modules");        # Modules Directory
21 $config{BINARY_DIR}         = resolve_directory($config{ME}."/bin");            # Binary Directory
22 $config{LIBRARY_DIR}        = resolve_directory($config{ME}."/lib");            # Library Directory
23 $config{OPTIMITEMP}         = "0";                                              # Default Optimisation Value
24 $config{OPTIMISATI}         = "-g";                                             # Optimisation Flag
25 $config{NICK_LENGT}         = "32";                                             # Default Nick Length
26 $config{CHAN_LENGT}         = "64";                                             # Default Channel Name Length
27 $config{MAX_CHANNE}         = "20";                                             # Default Max. Channels per user..
28 $config{MAXI_MODES}         = "20";                                             # Default Max. Number of Modes set at once.
29 $config{HAS_STRLCPY}        = "false";                                          # strlcpy Check.
30 $config{USE_KQUEUE}         = "y";                                              # kqueue enabled
31 $config{USE_EPOLL}          = "y";                                              # epoll enabled
32 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`);                           # FD Limit
33 chomp($config{GCCVER}       = `gcc -dumpversion | cut -c 1`);                   # Major GCC Version
34 chomp($config{GCC34}        = `gcc -dumpversion | cut -c 3`);                   # Minor GCC Version
35 chomp($config{OSNAME}       = `/bin/uname`);                                    # Operating System Name
36 $config{CC}                 = "g++";                                            # C++ compiler
37
38 if ((!$config{OSNAME}) || ($config{OSNAME} eq "")) {
39   chomp($config{OSNAME} = `/usr/bin/uname`);
40   if ((!$config{OSNAME}) || ($config{OSNAME} eq "")){
41         $config{OSNAME} = "Unknown";
42   }
43 }
44
45 if (!$config{MAX_CLIENT_T}) { 
46   $config{MAX_CLIENT_T} = 1024;                                 # Set a reasonable 'Default'
47   $fd_scan_fail = "true";                                       # Used Later
48 }
49
50 # Get and Set some important vars..
51 getmodules();
52
53 my $arg = $ARGV[0];                                             # Do Some Argument Checks..
54 if ($arg eq "-clean") { `rm -rf .config.cache`; }               # Remove the config.cache file.
55
56 if ($arg eq "-update") {
57   # Does the cache file exist?
58   if (!getcache()) {
59     # No, No it doesn't.. *BASH*
60     print "You have not run ./configure before. Please do this before trying to run the update script.\n";
61     exit 0;
62   } else {
63     # We've Loaded the cache file and all our variables..
64     print "Updating Files..\n";
65     getosflags();
66     writefiles();
67     print "Complete.\n";
68     exit;
69   }
70 }
71
72 print "Checking for cache from previous configure...\n";
73 getcache();
74 print "Checking operating system version...\n";
75 getosflags();
76
77 if (!$config{MAX_CLIENT}) { 
78   # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
79   # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
80   # higher than the found value" :))
81   $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
82 }
83
84 printf "Checking if strlcpy exists... ";
85 # Perform the strlcpy() test..
86 $config{HAS_STRLCPY} = "false";
87 my $fail = 0;
88 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
89 if (!$fail)
90 {
91         while (chomp($line = <STRLCPY>))
92         {
93                 # try and find the delcaration of:
94                 # size_t strlcpy(...)
95                 if (($line =~ /size_t(\0x9|\s)+strlcpy(\0x9|\s)+\(/) || ($line =~ /size_t(\0x9|\s)+strlcpy\(/))
96                 {
97                         $config{HAS_STRLCPY} = "true";
98                 }
99         }
100         close(STRLCPY);
101 }
102 print "yes\n" if $config{HAS_STRLCPY} eq "true";
103 print "no\n" if $config{HAS_STRLCPY} eq "false";
104
105 printf "Checking if kqueue exists... ";
106 $has_kqueue = 0;
107 $fail = 0;
108 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
109 if (!$fail)
110 {
111         while (chomp($line = <KQUEUE>))
112         {
113                 # try and find the delcaration of:
114                 # int kqueue(void);
115                 if (($line =~ /int(\0x9|\s)+kqueue(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+kqueue\(/))
116                 {
117                         $has_kqueue = 1;
118                 }
119         }
120         close(KQUEUE);
121 }
122 print "yes\n" if $has_kqueue == 1;
123 print "no\n" if $has_kqueue == 0;
124
125 printf "Checking if epoll exists... ";
126 $has_epoll = 0;
127 $fail = 0;
128 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
129 if (!$fail)
130 {
131         while (chomp($line = <EPOLL>))
132         {
133                 # try and find the declaration of:
134                 # extern int epoll_create (int __size) __THROW;
135                 if (($line =~ /int(\0x9|\s)+epoll_create(\0x9|\s)+\(/) || ($line =~ /int(\0x9|\s)+epoll_create\(/))
136                 {
137                         $has_epoll = 1;
138                 }
139         }
140         close(EPOLL);
141 }
142 print "yes\n" if $has_epoll == 1;
143 print "no\n" if $has_epoll == 0;
144
145 ################################################################################
146 #                          BEGIN INTERACTIVE PART                              #
147 ################################################################################
148
149 # Clear the Screen..
150 system("clear");
151 # Display Splash Logo..
152 show_splash();
153 chomp($wholeos = `uname -mnr`);
154
155 # Display Introduction Message..
156 print "
157 Welcome to the InspIRCd Configuration program!
158
159 *** If you are unsure of any of these values, leave it blank for    ***
160 *** standard settings that will work, and your server will run      ***
161 *** using them. If you are running this server as part of a         ***
162 *** larger network, you must consult with your network admins       ***
163 *** for the proper values to use, or server links will be unstable! ***
164
165 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
166 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
167 dir, otherwise you won't have a config file!
168
169 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}\n\n";
170
171 # Directory Settings..
172 dir_check("are the configuration files", "CONFIG_DIR");
173 dir_check("are the modules to be compiled to", "MODULE_DIR");
174 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
175 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
176
177 if ($has_kqueue) {
178         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?");
179 }
180 if ($has_epoll) {
181         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?");
182 }
183 $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
184 if (!$chose_hiperf)
185 {
186         print "No high-performance socket engines are available, or you chose\n";
187         print "not to enable one. Defaulting to select() engine.\n\n";
188 }
189
190 # File Descriptor Settings..
191 my $continue = 0;
192 while (!$continue) {
193   print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
194   print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
195   chomp($var = <STDIN>);
196   if ($var eq "") { $var = $config{MAX_CLIENT}; }
197   if ($var =~ /^\d+$/) {
198     if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
199       # Client has entered a larger number than the 'discovered' value
200       # Confirm.
201       print "WARNING: Our scans have indicated that you are attempting
202 to use more sockets than there are avaliable. Are you sure
203 you wish to do this? It may cause the IRCd to malfunction [y/n]
204 [\033[1;32mn\033[0m] -> $c";
205       chomp($tmp = <STDIN>);
206       if ($tmp ne "y") {
207         print "Please enter the correct value.\n\n";
208         next;
209       }
210     }
211   } else {
212     print "You must enter a number in this field. Please try again.\n\n";
213     next;
214   }
215   # If we get here, we should be good to go.
216   $config{MAX_CLIENT} = $var;
217   $continue = 1;
218   print "\n";
219 }
220
221 my $continue = 0;
222 while (!$continue) {
223   print "What is the Maximum length of nicknames?\n";
224   print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
225   chomp($var = <STDIN>);
226   if ($var eq "") { $var = $config{NICK_LENGT}; }
227   if ($var =~ /^\d+$/) {
228     # We don't care what the number is, set it and be on our way.
229     $config{NICK_LENGT} = $var;
230     $continue = 1;
231     print "\n";
232   } else {
233     print "You must enter a number in this field. Please try again.\n\n";
234   }
235 }
236
237 my $continue = 0;
238 while (!$continue) {
239   print "What is the Maximum number of mode changes in one line?\n";
240   print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
241   chomp($var = <STDIN>);
242   if ($var eq "") { $var = $config{MAXI_MODES}; }
243   if ($var =~ /^\d+$/) {
244     # We don't care what the number is, set it and be on our way.
245     $config{MAXI_MODES} = $var;
246     $continue = 1;
247     print "\n";
248   } else {
249     print "You must enter a number in this field. Please try again.\n\n";
250   }
251 }
252
253 # Code Optimisation
254 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3 (inclusive)
255 The InspIRCd Team will _NOT_ support any bug reports above 0.
256 Also note, the IRCd behaviour will be different depending on this value.
257 Please read the documentation for more information.
258
259 The Higher the number, the more optimised your binary will be. This value will default to 0
260 If you either a) Dont enter a number, or b) Enter a value outside the range.\n";
261 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
262 chomp($var = <STDIN>);
263 if ($var eq "") {
264   $var = $config{OPTIMITEMP};
265 }
266
267 if ($var eq "1") {
268   $config{OPTIMITEMP} = 1;
269   $config{OPTIMISATI} = "-O";
270 } elsif ($var eq "2") {
271   $config{OPTIMITEMP} = 2;
272   $config{OPTIMISATI} = "-O2";
273 } elsif ($var eq "3") {
274   $config{OPTIMITEMP} = 3;
275   $config{OPTIMISATI} = "-O3";
276 } else {
277   $config{OPTIMITEMP} = 0;
278   $config{OPTIMISATI} = "-g";
279 }
280
281 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
282 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\n";
283 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\n";
284 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\n";
285 print "\033[0mMax User Channels\033[1;32m\t\t$config{MAX_CHANNE}\n";
286 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\n";
287 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\n";
288 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\n";
289 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
290 print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
291 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n\n";
292
293 makecache();
294 writefiles();
295
296 print "\n\n";
297 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
298 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
299
300 ################################################################################
301 #                              HELPER FUNCTIONS                                #
302 ################################################################################
303 sub getcache {
304   # Retrieves the .config.cache file, and loads values into the main config hash.
305   open(CACHE, ".config.cache") or return undef;
306   while (<CACHE>) {
307     chomp;
308
309     # Ignore Blank lines, and comments..
310     next if /^\s*$/;
311     next if /^\s*#/;
312
313     my ($key, $value) = split("=", $_);
314     $value =~ /^\"(.*)\"$/;
315     # Do something with data here!
316     $config{$key} = $1;
317   }
318   close(CONFIG);
319   return "true";
320 }
321
322 sub makecache {
323   # Dump the contents of %config
324   print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
325   open(FILEHANDLE, ">.config.cache");
326   foreach $key (keys %config)
327   {
328     print FILEHANDLE "$key=\"$config{$key}\"\n";
329   }
330   close(FILEHANDLE);
331 }
332
333 sub dir_check {
334   my ($desc, $hash_key) = @_;
335   my $complete = 0;
336   while (!$complete) {
337     print "In what directory $desc?\n";
338     print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
339     chomp($var = <STDIN>);
340     if ($var eq "") { $var = $config{$hash_key}; }
341     if ($var =~ /^\~\/(.+)$/) {
342         # Convert it to a full path..
343         $var = resolve_directory($ENV{HOME} . "/" . $1);
344     }
345     if (substr($var,0,1) ne "/")
346     {
347         # Assume relative Path was given.. fill in the rest.
348         $var = $this . "/$var";
349     }
350     $var = resolve_directory($var); 
351     if (! -e $var) {
352       print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
353       chomp($tmp = <STDIN>);
354       if (($tmp eq "") || ($tmp =~ /^y/i)) {
355         # Attempt to Create the Dir..
356         $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
357         if ($chk != 0) {
358           print "Unable to create directory. ($var)\n\n";
359           # Restart Loop..
360           next;
361         }
362       } else {
363         # They said they don't want to create, and we can't install there.
364         print "\n\n";
365         next;
366       }
367     } else {
368       if (!is_dir($var)) {
369         # Target exists, but is not a directory.
370         print "File $var exists, but is not a directory.\n\n";
371         next;
372       }
373     }
374     # Either Dir Exists, or was created fine.
375     $config{$hash_key} = $var;
376     $complete = 1;
377     print "\n";
378   }
379 }
380
381 sub getosflags {
382   if ($config{OSNAME} =~ /BSD$/) {
383     $config{LDLIBS} = "-Ldl";
384     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
385     $config{MAKEPROG} = "gmake";
386     if ($config{OSNAME} eq "OpenBSD") {
387         $config{CC} = "eg++";
388         chomp($config{GCCVER}       = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change
389         chomp($config{GCC34}        = `eg++ -dumpversion | cut -c 3`); # the compiler path
390     }
391   } else {
392     $config{LDLIBS} = "-ldl";
393     $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Woverloaded-virtual $config{OPTIMISATI}";
394     $config{MAKEPROG} = "make";
395   }
396   if ($config{OSNAME} =~ /SunOS/) {
397     # solaris/sunos needs these
398     # socket = bsd sockets api
399     # nsl = dns stuff
400     # rt = POSIX realtime extensions
401     # resolv = inet_aton only (why isnt this in nsl?!)
402     $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
403   }
404 }
405
406 sub is_dir {
407   my ($path) = @_;
408   if (chdir($path)) {
409     chdir($this);
410     return 1;
411   } else {
412     # Just in case..
413     chdir($this);
414     return 0;
415   }
416 }
417
418 sub getmodules {
419   my $i = 0;
420   opendir(DIRHANDLE, "src/modules");
421   foreach $name (sort readdir(DIRHANDLE)) {
422     if ($name =~ /^m_(.+)\.cpp$/)
423     {
424       $modlist[$i++] = $1;
425     }
426   }
427   closedir(DIRHANDLE);
428 }
429
430 sub writefiles {
431
432   print "Writing \033[1;32minspircd_config.h\033[0m\n";
433   # First File.. inspircd_config.h
434   chomp(my $incos = `uname -n -s -r`);
435   chomp(my $version = `sh ./src/version.sh`);
436   open(FILEHANDLE, ">include/inspircd_config.h");
437   print FILEHANDLE <<EOF;
438 /* Auto generated by configure, do not modify! */
439 #define SYSLOG_FACILITY LOG_DAEMON
440 #define SYSLOG_LEVEL LOG_NOTICE
441 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
442 #define MOD_PATH "$config{MODULE_DIR}"
443 #define VERSION "$version"
444 #define MAXCLIENTS $config{MAX_CLIENT}
445 #define NICKMAX $config{NICK_LENGT}
446 #define CHANMAX $config{CHAN_LENGT}
447 #define MAXCHANS $config{MAX_CHANNE}
448 #define MAXMODES $config{MAXI_MODES}
449 #define OPTIMISATION $config{OPTIMITEMP}
450 #define SYSTEM "$incos"
451 #define MAXBUF 514
452 EOF
453
454   if ($config{OSNAME} =~ /SunOS/) {
455     print FILEHANDLE "#define IS_SOLARIS\n";
456   }
457   if ($config{GCCVER} > 3) {
458     print FILEHANDLE "#define GCC3\n";
459     print FILEHANDLE "#define GCC34\n";
460   }
461   else
462   {
463     if ($config{GCCVER} == 3) {
464       print FILEHANDLE "#define GCC3\n";
465       if ($config{GCC34} > 3) {
466         print FILEHANDLE "#define GCC34\n";
467       }
468     }
469   }
470   if ($config{HAS_STRLCPY} eq "true") {
471     print FILEHANDLE "#define HAS_STRLCPY\n";
472   }
473   my $use_hiperf = 0;
474   if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
475     print FILEHANDLE "#define USE_KQUEUE\n";
476     $use_hiperf = 1;
477   }
478   if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
479     print FILEHANDLE "#define USE_EPOLL\n";
480     $use_hiperf = 1;
481   }
482   # user didn't choose either epoll or select for their OS.
483   # default them to USE_SELECT (ewwy puke puke)
484   if (!$use_hiperf) {
485     print FILEHANDLE "#define USE_SELECT\n";
486   }
487   close(FILEHANDLE);
488
489   # Create a Modules List..
490   my $modules = "";
491   foreach $i (@modlist)
492   {
493     $modules .= "m_".$i.".so ";
494   }
495   chomp($modules);   # Remove Redundant whitespace..
496
497
498   # Write all .in files.
499   my $tmp = "";
500   my $file = "";
501   opendir(DIRHANDLE, $this);
502   foreach $name (sort readdir(DIRHANDLE)) {
503     if ($name =~ /^\.(.+)\.inc$/)
504     {
505       $file = $1;
506       # All .name.inc files need parsing!
507       $tmp = "";
508       open(FILEHANDLE, ".$file.inc");
509       while (<FILEHANDLE>) {
510         $tmp .= $_;
511       }
512       close(FILEHANDLE);
513
514       $tmp =~ s/\@CC\@/$config{CC}/;
515       $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
516       $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
517       $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
518       $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
519       $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
520       $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
521       $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
522       $tmp =~ s/\@MODULES\@/$modules/;
523
524       print "Writing \033[1;32m$file\033[0m\n";
525       open(FILEHANDLE, ">$file");
526       print FILEHANDLE $tmp;
527     }
528   }
529   closedir(DIRHANDLE);
530
531   # Make inspircd executable!
532   chmod 0744, 'inspircd';
533
534   # Modules Makefile..
535   print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
536   open(FILEHANDLE, ">src/modules/Makefile");
537   print FILEHANDLE <<EOF;
538 # (C) ChatSpike development team
539 # Makefile by <Craig\@ChatSpike.net>
540 # Many Thanks to Andrew Church <achurch\@achurch.org>
541 #    for assisting with making this work right.
542 #
543 # Automatically Generated by ./configure to add a modules
544 # please run ./configure --update
545
546 all: \$(MODULES)
547
548 EOF
549
550   # Create a Modules List..
551   my $modules = "";
552   my $flags = "";
553   foreach $i (@modlist)
554   {
555     $flags = getcompilerflags("src/modules/m_".$i.".cpp");
556     print FILEHANDLE <<EOCHEESE;
557 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/servers.h ../../include/base.h
558         \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i.cpp
559         \$(CC) \$(FLAGS) -shared $flags -o m_$i.so m_$i.o
560         cp m_$i.so \$(MODPATH)/
561         chmod 0700 \$(MODPATH)/m_$i.so
562
563 EOCHEESE
564   }
565 }
566
567 sub getcompilerflags {
568   my ($file) = @_;
569   open(FLAGS, $file);
570   while (<FLAGS>) {
571     if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
572       close(FLAGS);
573       return $1;
574     }
575   }
576   close(FLAGS);
577   return undef;
578 }
579
580 sub show_splash {
581   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";
582   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";
583   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";
584   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";
585   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";
586   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";
587   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";
588   print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
589 }
590
591 sub resolve_directory {
592         use File::Spec;
593         return File::Spec->rel2abs($_[0]);
594 }
595
596 sub yesno {
597         my ($flag,$prompt) = @_;
598         print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
599         chomp($tmp = <STDIN>);
600         if ($tmp eq "") { $tmp = $config{$flag} }
601
602         if (($tmp eq "") || ($tmp =~ /^y/i)) {
603                 $config{$flag} = "y";
604         } else {
605                 $config{$flag} = "n";
606         }
607         return;
608 }