#!/usr/bin/perl
# $Id: postto.pl 1.0 1995/01/03 19:05:15 michael Exp michael $
#
# written by Michael Kellen, February 1995
#
#      HTTPError, SubRequest, getaddress and parts of PostNNTP
#      taken from access_nntp.script v1.7 (Jeff Gilbreath)
#
# MICHAEL KELLEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL MICHAEL KELLEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
#

$HOME = "$ENV{'HOME'}";
$HOME = "/home/$ENV{'USER'}"		if (!$HOME);
$HOME = "/tmp"				if (!$HOME);
$orgname = "$ENV{'NEWSORG'}";
$orgname = "$ENV{'ORGANIZATION'}"	if (!$orgname);
$orgname = "MSU Physics Department"	if (!$orgname);


$retval = &ParseRequest;
&GetCall if $retval;
&PostCall;
&HTTPHappy;

sub
ParseRequest {
	# Parse incoming URL of the form
	#
	#  GET postto:group or POST postto://server/group
        ($http_cmd, $http_uri, $http_id) = split (/\s+/, <>, 3);

	while (<>) {
		chop;
		($type,$value) = split ( '\s*:\s+' , $_, 2);
		if ($type eq "") {
                        last;
                }
		if ( $type eq "X-hostname" ) {
			$server = $value;
		}

		if ( $type eq "X-filename" ) {
			$group = $value;
		}
	}


	return 1  if ($http_cmd =~ /GET/);

	$_ = <STDIN>;
	chop ;
	($head,$body,$sig,$sign) = split( '&', $_, 4);
	$head =~ s/HEAD=//;
	$body =~ s/BODY=//;
	$sig  =~ s/SIG=//;
	$sign =~ s/SIGN=//;

	return 0;
}

sub
GetCall {
	$sigfile = "$ENV{'SIGNATURE'}";
	$sigfile = "$HOME/.signature"   if (!$sigfile);
	if ( -r $sigfile ) {
		open (SIG, "$sigfile");
		while(<SIG>) {
			$signature .= $_;
		}
	close(SIG);
	} else {
		$signature = $sigfile;
	}
	$REPLYTO = "$ENV{'REPLYTO'}";
	$form  = "<TITLE>Posting to $group</TITLE>\n";
	$form .= "<BODY><FORM METHOD=POST ACTION=postto:$group>\n";
	$form .= "<TEXTAREA NAME=HEAD ROWS=4 COLS=78>";
	$form .= "Newsgroups: $group\nSubject: \n";
	$form .= "Organization: $orgname\n"		if ($orgname);
	$form .= "Reply-To: $REPLYTO\n"			if ($REPLYTO);
	$form .= "Followups-To: \nKeywords: \nCc: \n\n</TEXTAREA>\n";
	$form .= "<TEXTAREA NAME=BODY ROWS=15 COLS=78>";
	$form .= "</TEXTAREA>\n";
	$form .= "<HR>\n";
	$form .= "<TEXTAREA NAME=SIG ROWS=4 COLS=78>";
	$form .= "$signature</TEXTAREA>\n";
	$form .= "<INPUT TYPE=checkbox NAME=SIGN CHECKED>";
	$form .= " Append Signature ";
	$form .= "<input TYPE=submit VALUE=Post>";
	$form .= "<input TYPE=reset VALUE=Reset><HR></form>";

	$form_length = length ($form);

	print "HTTP/1.0 200 OK\n";
	print "Content-type: text/html\n";
	print "Content-length: $form_length\n\n";
	print "$form\n";
	exit 0;
}

sub
PostCall {
	while ( $head =~ /([^%]*)%([0-9A-E][0-9A-E])(.*)/ ) {
		$head = sprintf("%s%c%s", $1,hex($2), $3);
	}
		
	while ( $body =~ /([^%]*)%([0-9A-E][0-9A-E])(.*)/ ) {
		$body = sprintf("%s%c%s", $1,hex($2), $3);
	}
	
	if ( $sign eq "on" ) {	
		while ( $sig =~ /([^%]*)%([0-9A-E][0-9A-E])(.*)/ ) {
			$sig = sprintf("%s%c%s", $1,hex($2), $3);
		}
	}

	$abortflag = 1;
	&PostNNTP;
}

sub
Abort {
	$deadtmpfile = "$HOME/dead.article";

	open(DEAD,">>$deadtmpfile");
	print DEAD "$head\n";
	print DEAD "$body\n";
	print DEAD "--\n$sig\n"		if ($sign eq "on");
	print DEAD "\n\n";
	close(DEAD);
	
	$message  = "<TITLE>Posting Error</TITLE>\n";
	$message .= "<H1>Unable to post to $group</H1>\n";
	$message .= "<BR>A copy of the response has been appended to ";
	$message .= "<a href=file:$deadtmpfile>$deadtmpfile</a>\n";

	$content_length = length($message);

	print STDOUT "HTTP/1.0 200 OK\n";
	print STDOUT "Content-type: text/html\n";
	print STDOUT "Content-length: $content_length\n\n";

	print STDOUT $message;

	exit 0;
}

sub
HTTPHappy {

	print "HTTP/1.0 200 OK\n";
	print "Content-type: application/none\n";
	print "Content-length: 10\n\n";
	print "Post Done\n";

	exit 0;
}

sub
PostNNTP {
	($name, $aliases, $port, $proto) = getservbyname("nntp", "tcp");
	$protocol = "nntp";
	$HEAD = "";
	$BODY = "";

	# connect to the server
	#
	local($sockaddr,$here,$there,$response,$tries) = ("Snc4x8");
	$here  = pack($sockaddr, 2, 0, &getaddress("localhost"));
	$there = pack($sockaddr, 2, $port, &getaddress($server));
	&HTTPError ("socket: $!") if (!socket(N,2,1,6));
	&HTTPError ("connect($hostname:$port): $!") if (!connect(N,$there));
	select(N);       $| = 1;                # make unbuffered
	select(STDOUT);

	# check the response to the initial connection
	#
	$accept = <N>;
	($accept_code, $accept_string) = split (/\s+/, $accept, 2);
	if ($accept_code >=300) {
	
		&HTTPError
		("initial connect problem: $accept_code $accept_string");
	}

	&SubRequest("POST");
	
	print N "$head\n";
	print N "$body\n";
	print N "--\n$sig\n"		if ($sign eq "on");
	&SubRequest(".");
	print N "QUIT\n";
}


sub
SubRequest {

	local ($request) = @_;
	local ($response, $response_code, $response_string);

	print N "$request\n";
	chop ($response = <N>);
	($response_code, $response_string) = split (' ', $response, 2);
	if ($response_code > 340) {

		&HTTPError
		("bad request: \"$request\": $response_code ",
		"$response_string");
	}

	0;
}


sub
getaddress {

	local($host) = @_;
	local(@ary);
	@ary = gethostbyname($host);
	return(unpack("C4",$ary[4]));
}


sub
HTTPError {

	local(@string) = @_;
	local($message); 

	$message .= "\n" .
		"<h1>ERROR</h1>\n" .
		"<b>news:</b> " .
		join ('', @string) . 
		"\n\n";

	&Abort if $abortflag;

	$content_length = length($message);

	print STDOUT "HTTP/1.0 $return_code  $return_string\n";
	print STDOUT "Content-type: text/html\n";
	print STDOUT "Content-length: $content_length\n";

	print STDOUT "$message";

	exit 1;
}
