#!/usr/bin/perl -w #/* vim: set sw=4 ts=4 si et: */ #*************************************************************************** # lfsendpatch # To be use in conjunction with lfupdate # copyright GPL : (C) 1999 by Eric Santonacci and Guido Socher # email : Eric.Santonacci@talc.fr, guido@bearix.oche.de # # ***************************************************************************/ use strict; use vars qw($opt_u $opt_p $opt_f $opt_n $opt_h); use Getopt::Std; use Socket; require 5.003; # global data my $version="0.6"; my $filename; my $hostname="cgi.linuxfocus.org"; #my $hostname="bearix"; my $cgipath="cgi-bin/lfupdate"; my ($data1,$data2); my $empty=""; my $head; my $filedata; my $filedatalen=0; my $boundary; my @file_stat; my @reqresult; my $line=""; my $patchfileref; my $len; my $anastate; # options management &getopts("u:p:n:h")||die "ERROR: No such option. -h for help.\n"; &help unless ($ARGV[0]); &help if ($opt_h); die "ERROR: I need a username account. -h for help.\n" unless($opt_u); die "ERROR: I need a password. -h for help.\n" unless($opt_p); if($opt_n){ if ($opt_n=~m|http://([\w\.]+)/(.+)|){ $hostname = $1; $cgipath = $2; }else{ die "ERROR: could not parse URL $opt_n\n"; } } #------------------- $filename=shift; $boundary="1999112975150502629" . time; open(PATCH, "$filename") || die ("reading of $filename failed\n"); $filedata=""; while(1){ $len=read(PATCH, $line, 1000); $filedata.=$line; $filedatalen+=$len; last if ($len < 1000); } close(PATCH); # prepare data $data1="-----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name=\"uid\"\r \r $opt_u\r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name=\"passw\"\r \r $opt_p\r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name=\"patch\"; filename=\"t.tar.gz\"\r Content-Type: application/x-tar\r \r\n"; # The data part after file data: $data2="\r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name=\"small_testrun\"\r \r 1\r -----------------------------3787106669039907511219997696--\r "; # calculate the content len: $len=length($data1)+length($data2)+$filedatalen; $head="POST /$cgipath HTTP/1.0\r Referer: http://$hostname/$cgipath?small=1\r User-Agent: lfsendpatch ($version)\r Host: $hostname\r Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r Content-type: multipart/form-data; boundary=---------------------------3787106669039907511219997696\r Content-Length: $len\r \r "; $len=length($head); &sendtcp($head,\$data1,\$filedata,\$data2); print "-----------\n"; $anastate=0; for (@reqresult){ if (/content analysis/){ $anastate=1; } if ($anastate==0 && /^HTTP\//){ print "page ok\n"; $anastate=2 unless(/200/); } if (/ERROR: /){ $anastate=2; } s/<\/?HTML>//; s/<\/?BODY>//; s/<\/?P>/\n /g; s/
/
\n /g;
    print " $_\n" if ($anastate==1 || $anastate==2);
    if (/(<\/PRE>)|(
)/){ if ($anastate==2){ exit 1; } $anastate=3; next; } if (/NAME=.patchfileref. VALUE=.([^"]+)./){ $patchfileref=$1; } if (/VALUE=.really execute./){ $anastate=4; last; } } if ($patchfileref && $anastate==4){ $line=""; while($line!~/y|n/i){ print "-----------\n"; print "Do you want to update this? (Y/N)>"; chomp($line=); } if ($line=~/n/i){ print "...quit\n"; exit 0 } $head="GET /$cgipath?uid=$opt_u&passw=$opt_p&small_real=1&patchfileref=$patchfileref HTTP/1.0\r Referer: http://$hostname/$cgipath\r User-Agent: lfsendpatch ($version)\r Host: $hostname\r Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r \r\n"; &sendtcp($head,\$empty,\$empty,\$empty); $anastate=0; my $blnk=""; for (@reqresult){ chomp; if (/Operation suc\w+ executed/){ $anastate=1; next; } last if (/ ENDBLNKCHECK /); if ($anastate){ # read the broken link check: s/<.?PRE>//; $blnk.="$_\n"; } } if ($anastate==1){ print "\nOk, operation successfully executed\n"; print "$blnk"; print "done."; exit 0; } # print in case of error: for (@reqresult){ print; } }else{ die "ERROR: Fault during analysis of $filename\nOr maybe your password is incorrect?"; } #-------------------- # now build up a tcp connection # to a web-server and return the answer in @reqresult. sub sendtcp($,$,$,$){ my $h=shift; my $d1=shift; my $d2=shift; my $d3=shift; my @in_addrs; my @result; my ($paddr,$proto); my $port=80; @in_addrs = (gethostbyname($hostname ))[4]; if (scalar @in_addrs > 0){ $paddr = sockaddr_in($port,$in_addrs[0]); }else{ die "ERROR: $hostname lookup failure\n"; } $proto = getprotobyname('tcp'); socket(S,PF_INET,SOCK_STREAM,$proto)||die "ERROR socket:$!\n"; connect(S,$paddr)||die "ERROR connect: $!\n"; select(S);$|=1;select(STDOUT);$|=1; print "sending ..."; print "head ..."; print S $h; print "data ..."; print S $$d1; print "data ..."; print S $$d2; print "data ..."; print S $$d3; print "ok ... receiving ..."; while(){ chomp; push(@reqresult,$_); #print "dbg answer: $_\n"; } close S; print "ok\n"; $|=0; } #---------------------------------------- sub help{ print " lfsendpatch sends a LinuxFocus tarball file to LinuxFocus server. It has to be use with lfupdate cgi script from Guido. If you don't know what we are speaking about, you are probably not concerned by this script. USAGE: lfsendpatch -u username -p passwd [-h] [-n hostname] filename.tar.gz OPTIONS: -h : this help. -p passwd : password of your user account on LinuxFocus server. -u username : your username on LinuxFocus server. -n name : URL of the lfupdate program. (default: http://$hostname/$cgipath EXAMPLE: lfsendpatch -p my_password -u eric mypatch.tar.gz This is lfsendpatch version $version \n"; exit 0; } __END__ This is how the first form looks like: POST /cgi-bin/lfupdate HTTP/1.0\r Referer: http://bearix/cgi-bin/lfupdate?small=1\r Connection: Keep-Alive\r User-Agent: Mozilla/3.0Gold (X11; I; Linux 2.2.10 i586)\r Host: bearix\r Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r Content-type: multipart/form-data; boundary=---------------------------3787106669039907511219997696\r Content-Length: 1713\r \r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name="uid"\r \r uname\r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name="passw"\r \r bla\r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name="patch"; filename="t.tar.gz"\r Content-Type: application/x-tar\r \r iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii \r -----------------------------3787106669039907511219997696\r Content-Disposition: form-data; name="small_testrun"\r \r 1\r -----------------------------3787106669039907511219997696--\r This is how the reply after successful answer looks like: GET /cgi-bin/lfupdate?uid=uname&passw=xxxxxxxxx&small_real=1&patchfileref=guido.socher-tmp.tgz HTTP/1.0 Referer: file:/home/guido/bearix/t.html Connection: Keep-Alive User-Agent: Mozilla/3.0Gold (X11; I; Linux 2.2.10 i586) Host: bearix Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*