#!/usr/bin/perl
#
# web configurator script for reamweaver
# original configuration shell script stuff by
# nickie halflinger & the yes men, november 2001
# web config stuff by cue p. doll & the yes men, january 2001
# GNU GPL, 2001, 2002
# Version: $Name:  $
# 
# 
# this now gets called by a php stub, startconfig.php.
# note, original php stub and this
# script will self-destruct for security; copying themselves
# to a random new name, told to the user.
#
# $Id: startconfig.pl,v 1.13 2002/07/08 07:19:09 cue Exp $
#
############################################################


use File::Copy;
use Getopt::Std;
use CGI qw(:standard escapeHTML);
use File::Basename;

use vars qw ($perlpath $host $pwd $webcf $hoststub $webdirsuggestion $swname);
$perlpath = `which perl`;
$host = `hostname`;
$pwd = `pwd`;
$swname = 'Reamweaver';
	
chomp $host;
chomp $pwd;
chomp $perlpath;

		

$hoststub = $host;
$hoststub =~ s/\.[^\.]*$//; # chop off the .com or whatever

$webdirsuggestion = $pwd;
$webdirsuggestion =~ s/.*$hoststub(.*)/$1/i;

$webcf = 1;	# not currently used, likely to be removed in future.

### now, the fun runtime decisions for the web version:
if ($webcf) {
		# we need to determine where we are in the script to have it do the correct
		# functionality, display the right pages, etc. the 2 printed html form pages will send
		# a hidden parameter "run" to their action portions to indicate where they are in the run.
		# we also use the script name - i.e. whether or not it has been changed to
		# its randomized name - to determine where we are. especially handy when we are
		# ready to print a page, because these static pages do not receive parameters from forms.
		
		my $run = param('run');
		my $scriptname = basename($0);
		my $phpscriptname = $scriptname;
		$phpscriptname =~ s/(\.pl|\.cgi)$/\.php/;
		
		
		
		
	

		if ((!$run) &&  ($scriptname !~ /webconfig-\w{8,}/)) {
			# this is a first time run. Get the path for the other files, copy self to new locale, then self-destruct
	
			print_intro();
			exit;
		}
		elsif  ($run eq 'intro') {		#intro has run, and the cgi will move and print new_locale
			my $randomstring = randomgen();
			my $newname = "webconfig-$randomstring.pl";
			my $newphpname = "webconfig-$randomstring.php";
			my $themainpath = ".";
			generate_newfile($themainpath, $newname, $newphpname) || dbgout ("Wasn't able to generate $newname");
			chmod 0755, "$newname" || dbgout ("Couldn't set permissions on $newname");	# move to above subroutine	
			print_newlocale($newphpname) || dbgout ("Wasn't able to tell user newlocale");
			
			# self-destruct:
			unlink $0 || dbgout ("$0 couldn't self-destruct!");	# finally, original script self-destructs
			unlink "$pwd/$phpscriptname" || dbgout ("$pwd/$phpscriptname couldn't self-destruct!");	# php script self-destructs too, for neatness.
			exit;	
		}		
		elsif  ((!$run) &&  ($scriptname =~ /webconfig-\w{8,}/))		{
			# i must be the randomized one, now print the big CGI config page.... 
			set_httpvars();
			print_configpage ($phpscriptname);
			exit;
			# TODO - maybe move up/globalify the configuration of the configs array, so that the defaults can
			# be reused by printconfig page.
		
		}
		elsif (($run eq 'go') &&  ($scriptname =~ /webconfig-\w{8,}/)) {
			# it's time to create the config files now - keep going!
		
			
			# TODO - eventually nickie's original action configure code could go in a subroutine
			# called from here; it would be tidier.
	
		
		}
		
		else {
			# uh oh - we should never get here.
			dbgout ("Danger Will Robinson! My name is $scriptname and my run is $run - How'd I get here???\n");
		}	
						
}	





### these are not used by web-only version and are likely to be removed from code in the future.
my %opts;

getopts('dh', \%opts);
if(defined $opts{h}) {
	print "usage: ./configure [-d] [-h]\n";
	print "\t-d\trun non-interatively, all default values.\n";
	print "\t-h\tdisplay this help message.\n";
	exit;
}
### end removable for web-only version




use vars qw ($config_template $config_target $script_target $ht_template $htaccess $mimetypes $index $indextmpl);



my $installpathname = ".";	# note - this variable will be reset in WEBCONFIG version... leave the word WEBCONFIG here it's a marker...


$config_template = "$installpathname/reamweaver.conf.tmpl";
$config_target = "$installpathname/reamweaver.conf";
$script_target = "$installpathname/reamweaverphp.pl";
$ht_template = "$installpathname/htaccess.tmpl";	# no longer used?
$htaccess = "$installpathname/.htaccess";				# no longer used?	
$mimetypes = "$installpathname/mime.types";
$index = "$installpathname/index.html";
$indextmpl = "$installpathname/index.html.tmpl";



#### here's where the action starts, i.e. writing the config files....
# Try to take a look at $host, remove the .com or whatever,
# and see if it occurs in $pwd (looking from the end).... if it does,
# just remove everything to the left of it--it's a reasonable guess.




# this is an array of hashrefs of tokennames keyed to defaults and question texts.
my @configs = (
	 {'token' 	=>	'perlpath',
	 'question' 	=>	'Where is perl?',
	 'default'	=>	$perlpath, },

	 {'token' 	=>	'givemedomain',
	 'question' 	=>	'What site (domain) would you like to appropriate?',	
	 'default'	=>	'www.weforum.org', },
	 
	 {'token' 	=>	'givemealso',
	 'question' 	=>	"Other domains of hosts found linked from the target domain, to also appropriate as needed?\n(Subdomains--xxx.domain.com--will also be appropriated.)",	
	 'default'	=>	'weforum.org', },
	

	 {'token' 	=>	'putithere',
	 'question' 	=>	'Web URL where your mirrored site will show up:',	
	 'default'	=>	 $host . $webdirsuggestion, }, # $host . $pwd, },

	 
	 {'token' 	=>	'smartsubstitutions',
	 'question' 	=>	'"Smart" substitution: Change plurals, past tense, etc? (0 for no, 1 for yes)',
	 'default'	=>	'1', },
	 
	 {'token' 	=>	'neveroverwritecached',
	 'question' 	=>	"If you want to download files once only, and then never overwrite them, set this to 1.\n
			This can allow you to further modify stored pages as you like.(0 for no, 1 for yes)",
	 'default'	=>	'0', },

	 
	 {'token' 	=>	'killtime',
	 'question' 	=>	"If the software is having problems on a particular page (first time it grabs it),\n this is the number of seconds before it gives up:",	
	 'default'	=>	'240', },
	
	 {'token' 	=>	'cachetime',
	 'question' 	=>	'Cached files will be used for this many minutes without checking for new ones:',	
	 'default'	=>	'90', },
	 
	 
	 
);


my (%varhash,$answer);
# loop through these and ask for values to them.

if (! $webcf) 	{		### another to remove in future


	print "\n\nHello website fan! Welcome to the $swname configure tool. Please 
	answer the following questions.   The defaults are usually okay if you're 
	unsure.  After running this you can make extra changes to by 
	editing the reamweaver.conf file.\n";


	foreach my $i (@configs) {
		print "\n", $i->{question}, " [$i->{default}]: ";
		unless($opts{d}) {
			$answer = <STDIN>; chomp $answer;
			# print "\t\tanswer was '$answer'.\n";		# debugging..
		}
		$varhash{$i->{token}} = $answer !~ /^[\n\r]*$/ ? $answer : $i->{default};
		print "\n";
	}

}

# else: cue condition for web input
else { # it's input through web cgi
	foreach my $i (@configs) {
		$answer = param($i->{token});

		$varhash{$i->{token}} = $answer !~ /^[\n\r]*$/ ? $answer : $i->{default};
		
	}
	
	# print STDOUT "Content-type: text/plain\n\n";	# prepare for stdout to output to browser - only use for CGI
	
}		


### clean up certain variables....

$varhash{putithere} =~ s|(.*)http://(.*)|$1$2|; #correction for users who begin with http://
# make sure cgi url is correct. no http, no slash at end.



# now parse through the config file template and fill in the values.
open(F, $config_template) || 
	dbgout ("Can't read configuration template: $!\nCheck file and directory permissions!");
open(OUT, ">$config_target") || 
	dbgout ("Can't write to configuration file $config_target: $!\nCheck file and directory permissions!");
	
while(<F>) {
	s/\[\[\[(.+)\]\]\]/$varhash{$1}/ig;
	print OUT;
}
close OUT;
close F;
print "<font size='+1' face='Arial, Helvetica, sans-serif'>";
print "Configuration file created.\n\n";

# do other special things based on some of the answers.
# first, change the perl path if neccesary
unless($varhash{perlpath} eq $configs[0]->{default}) {
	open(F, $script_target) || dbgout ("ERROR: couldn't read script: $!");
	my @lines = <F>;
	close F;
	$lines[0] = "\#\!$varhash{perlpath}\n";
	open(F, ">$script_target") || dbgout ("ERROR: couldn't write script: $!");
	print F @lines;
	close F;
	print "perl path set in $script_target.\n";
}




print "<p>Ready to go! If you're brave, make additional changes to reamweaver.conf.\n\n";

	
success_msg();	 # final words, info, for user now that it's succeeded.

### here's where the action ends, and cue's web-specific subroutines begin....

sub set_httpvars {
	# set global variables for necessary http environment variables.
	# note:
	# there is no query string in situations where we use this, so
	# first argument is going to be the first http env. passed.
	
	@myargs = split(' ',"@ARGV");

	$httphost = $myargs[0];
	$httppath = dirname($myargs[1]);

	$httpshowpath = "$httphost$httppath";
		

	
}

sub randomgen {	
	# generate a random string for the secret URL.
	# i'm using just (lc) letters here so user doesn't have to say, "is that a #1 or a small L?" etc.
   my @chars = ("a" .. "z");
   my $string = join ("", @chars[ map {rand @chars} (1 .. 8 ) ]);
   return $string;
}



 
sub print_intro {
	# prints out the introductory html page
	
	my $me = basename($0);
	my $phpme = $me;
	$phpme =~ s/(\.pl|\.cgi)$/\.php/;
	my $pwd = `pwd`;
	my $parent = dirname($pwd);
	# not needed for php...
	# print "Content-type: text/html\n\n";
	print STDOUT <<"Endofheader";
	<HEAD>
	<TITLE>Welcome to $swname's WebConfigurator!</TITLE>
	</HEAD>
	<BODY BGCOLOR=#ffffff TEXT=000000 VLINK=#000000 LINK="000000" ALINK="FF0000">
	<font size="+4" face="Arial, Helvetica, sans-serif">$swname Web-Configurator</font><br>
	<table cellspacing=6 cellpadding=6 border="0">
  	<FORM ACTION="$phpme" METHOD=GET>
  	<tr width="90%">
    <td align="left"  width="2" valign="top" height="144">&nbsp;</td>
    <td align="left"  width="552" valign="top" height="144" colspan="2">
         <font face="Arial, Helvetica, sans-serif" size="3">
         Hello website fan! Welcome to the Pre-Flight Page of the $swname configure tool.<p>
			For security, I (the WebConfigurator), will move myself to a secret new name, which  
			I'll tell only to you, in case you want to run me again later.<br>
			So be sure you're ready to take note of the new name before you begin, Secret $swname Agent!
			<p>
			When you're ready for takeoff, please click 
         the Configurate button once to Begin Web-configuration!
			
			<INPUT TYPE=HIDDEN NAME="run" VALUE="intro">
			<p>
    </td>
	 </tr>
	 <tr width="90%">
	 <td align="left"  width="2">&nbsp;</td>
      <td align="center"  width="358" valign="top"
        <div align="center"> 
  				<font face="Arial, Helvetica, sans-serif" size="3">
            <input type=submit value="Configurate" name="submit">
             </font>
          
        </div>
   </td>
  	</tr>
  	</table>
Endofheader
}
	
	
sub print_newlocale {
	# prints out the html page referring user to the secret new location (randomized) of their cgi.
	my $gohere = shift(@_);
	# print "Content-type: text/html\n\n";
	print STDOUT <<"Endofheader";
	<HEAD>
	<TITLE>Here is Your Script's Secret New Location!</TITLE>
	</HEAD>
	<BODY BGCOLOR=#ffffff TEXT=000000 ALINK="FF0000">
	<font size="+4" face="Arial, Helvetica, sans-serif">Your Script's Secret New Location!</font><br>
	<table cellspacing=6 cellpadding=6 border="0">
	<tr width="80%">
   <td align="left"  width="2" valign="top" height="144">&nbsp;</td>
   <td align="left"  width="552" valign="top" height="144" colspan="2">
	<font face="Arial, Helvetica, sans-serif" size="3">
	Your script's secret new name is <a href="$gohere">$gohere</a><br>
	Please jot it down, and click on the link when you're ready to continue with the configuration.<br>
	For security, the script will self-destruct from its current, pre-flight location as you click the link.<br>
	So if you want to reconfigure, just visit the script under its new name.
	</font>
	</td>
	</tr>
	</table>
	
	 
Endofheader
}


sub print_configpage {  
	# this prints out the main configuration html page, based on info we already have.

	my $secretlocale = shift(@_);

# print "Content-type: text/html\n\n"; # again, only used for cgi...
print STDOUT <<"Endofheader";

<HEAD>

<TITLE>$swname Web-Configurator</TITLE>


</HEAD>
<BODY BGCOLOR=#ffffff TEXT=000000 VLINK=#000000 LINK="000000" ALINK="FF0000">
<font size="+4" face="Arial, Helvetica, sans-serif">$swname Web-Configurator</font><br>
<table cellspacing=6 cellpadding=6 border="0">
  <FORM ACTION="$secretlocale" METHOD=GET>
  <tr width="80%"> 
    <td align="left"  width="2" valign="top" height="144">&nbsp;</td>
    <td align="left"  width="552" valign="top" height="144" colspan="2"> 
	 <font face="Arial, Helvetica, sans-serif" size="3">
	 Hello again website fan! Welcome to the $swname configure tool. Please 
answer the following questions.   The defaults are usually okay if you're 
unsure.  After running this you can make extra changes to the configuration by 
editing the reamweaver.conf file.</font> 
     
      <hr>
    </td>
  </tr>
    <tr width="90%"> 
		<td align="left"  width="2" height="144">&nbsp;</td>
      <td align="left"  width="358" valign="top">
		<INPUT TYPE=HIDDEN NAME="run" VALUE="go">
		  <font size="+1" face="Arial, Helvetica, sans-serif">Where is perl?<br>
          <input type=text name="perlpath" value="$perlpath" size=40 maxlength=80>
			</font>  
		
        <p><font size="+1" face="Arial, Helvetica, sans-serif">What site (domain) would you like to appropriate?<br>
          <input type=text name="givemedomain" value='www.weforum.org' size=40 maxlength=80>
          </font> 
        
        <p><font size="+1" face="Arial, Helvetica, sans-serif">Other domains of hosts found linked from the target domain, to also appropriate as needed? (Separate multiple domains with commas.)<br>
		  		(Subdomains--xxx.domain.com--will also be appropriated.) <br>
          <input type=text name="givemealso" value='weforum.org' size=40 maxlength=80>
          </font> </p>
			 
        <p><font size="+1" face="Arial, Helvetica, sans-serif">Web URL where your mirrored site will show up<br>
          </font><font size="+1" face="Arial, Helvetica, sans-serif"> 
          <input type=text name="putithere" value="http://$httpshowpath" size=60 maxlength=100>
          </font></p>

	
  
      	<p><font size="+1" face="Arial, Helvetica, sans-serif">If you want $swname to download files once only, and then never overwrite them, set this to 'Yes'.
			This can allow you to further modify stored pages as you like.<br>
			If set to 'No', your pages will automatically update whenever the corresponding page changes at your adopted site.<br> 
          </font><font size="+1" face="Arial, Helvetica, sans-serif"> 
        	 <INPUT TYPE="radio" NAME="neveroverwritecached" VALUE="1"> YES &nbsp;
			 <INPUT TYPE="radio" NAME="neveroverwritecached" VALUE="0" CHECKED="YES"> NO<BR>
          </font></p>
			 
		  <p><font size="+1" face="Arial, Helvetica, sans-serif">'Smart' substitution: Change plurals, past tense, etc?<br>
		  	  (Based on English language pluralization rules.) <br> 
			 <INPUT TYPE="radio" NAME="smartsubstitutions" VALUE="1" CHECKED="YES"> YES &nbsp;
			 <INPUT TYPE="radio" NAME="smartsubstitutions" VALUE="0"> NO<BR>
		   </font>
			 </p>
			 
			 
			 
		 <p><font size="+1" face="Arial, Helvetica, sans-serif">Timeout length - if $swname is having problems with a particular page the first time it grabs it, number of seconds it will try before giving up :<br>
          </font><font size="+1" face="Arial, Helvetica, sans-serif"> 
          <input type=text name="killtime" value='240' size=40 maxlength=80>
          </font></p>
			 
		  <p><font size="+1" face="Arial, Helvetica, sans-serif">Cached files will be used for this many minutes without checking for new ones:<br>
          </font><font size="+1" face="Arial, Helvetica, sans-serif"> 
          <input type=text name="cachetime" value='90' size=40 maxlength=80>
          </font></p>
			  
  
  
  
        </td>

      <td align="left"  width="194" valign="top">&nbsp;</td>
    </tr>
    <tr width="90%">
      <td align="left"  width="2">&nbsp;</td>
      <td align="left"  width="358" valign="top">
        <div align="center"> 
          <p><font size="3" face="Arial, Helvetica, sans-serif">Please click 
            the submit button once to Web-configurate!: </font></p><p>
          <p><font size="+1" face="Arial, Helvetica, sans-serif">
            <input type=submit value="Submit" name="submit">
            * 
            <input type=reset value="Reset" name="reset">
            </font></p>
        </div>
      </td>
      <td align="left"  width="194" valign="top">&nbsp;</td>
    </tr>
    <tr> 
      <td width="2" align="center" height="2">&nbsp; 
      <td width="358" align="center" height="2" valign="top"> 
        <p align="center">&nbsp; 
        <p><font size=-1 face="Arial, Helvetica, sans-serif"> </font> 
      </td>
      <td width="194" align="center" height="2" valign="top">&nbsp;</td>
    </tr>
  </form>
</table>
<p>&nbsp;</p>
</BODY>
</HTML>
Endofheader

}
	
sub generate_newfile {	# here comes the part with the self-generating script...
	
	local ($mainpath, $mynewname, $mynewphpname) = @_;
	my $line;
	if (-f "$0.tmp") {unlink "$0.tmp";}
	copy ("$0", "$0.tmp") || dbgout ("Couldn't make tempfile $0.tmp<br>Check your directory write permissions!", 1);
	open (CLONE, "$0.tmp") || dbgout ("Couldn't open my clone, $0.tmp<br>heck your directory write permissions!", 1);
	open (GENOUT, ">>$mynewname") || dbgout ("Couldn't open for writing $mynewname<br>Check your directory write permissions!", 1);
	while ($line = <CLONE>) {
		if ($line !~ /.*WEBCONFIG.*/) {
			# here's finally where we input the install path name they gave us on prev. screen...
			# note - this is currently "."... due to recent changes. regenerating can probably be simplified to simply copying in future.
			$line =~ s/\$installpathname/$mainpath/; #say WEBCONFIG in any line we don't want to substitute, like this one!
		}
		print GENOUT "$line";
	}	
	
	close CLONE;
	close GENOUT;
	chmod 0755, "$mynewname";

	unlink "$0.tmp" || dbgout ("weird - couldn't delete the $0.tmp tempfile... ");
	php_stubgen();	# generate the php stub for the new secret location

}	

sub php_stubgen {
		
	# now generate the php stub. stub includes an if/then depending on whether this is run=go or not.
	open (GENPHPSTUB, ">>$mynewphpname") || dbgout ("Couldn't open for writing $mynewphpname\nCheck your directory write permissions!", 1);
	print GENPHPSTUB "<?\n";
	print GENPHPSTUB <<'EOH';
if ($HTTP_HOST) {
	$theserver = $HTTP_HOST;
}
else	{
	$theserver = $SERVER_NAME;
}
if (!$theserver) {
	$theserver = 'yourhost.com';
}
if ($QUERY_STRING) {
	$string = $QUERY_STRING;
	$string = strtr($string, ';', "");
	$string = strtr($string, '>', "");
	$string = strtr($string, '<', "");
	$string = strtr($string, '|', "");
}	

EOH

	print GENPHPSTUB 'if ($string) {' . "\n";
	print GENPHPSTUB "\t\$command = \"perl $mynewname " . '\"$string\"";' . "\n";
	print GENPHPSTUB "}\n";
	print GENPHPSTUB "else {\n";


	print GENPHPSTUB "\t\$command = \"perl $mynewname " . '\"$theserver $REQUEST_URI $SERVER_PORT\"";' . "\n";
	print GENPHPSTUB "}\n";
	print GENPHPSTUB "passthru(\$command)\;\n";
	print GENPHPSTUB "?>\n";
	
	close GENPHPSTUB;
	chmod 0755, "$mynewphpname";
}	
	

sub dbgout {
	my ($msg, $needheader) = @_;
	
	if ($webcf) {
		my $dumbnum = int(rand(99));
		if ($needheader) {
			# print "Content-type: text/plain\n\n";	removed for php
		}	
		print  "Ooops! $swname WebConfigurator Error \#XYZPDQ-$dumbnum:<br>$msg<br>";

		die "$msg <br>";
	}		
	else {  # shell script option, just give the message.
		die "$msg\n";
	}		
		
}
	
	
sub success_msg {	

	
	# info to print out only if configuration has been done successfully
			
	print STDOUT <<"Endofheader";
<p>
Run your site the first time from
<a href="http://$varhash{putithere}/index.php">http://$varhash{putithere}/index.php</a>


Endofheader



}	
	
	
	
		
