218 lines
3.9 KiB
Bash
Executable file
218 lines
3.9 KiB
Bash
Executable file
#!/bin/rc
|
|
rfork e
|
|
argv0=$0
|
|
url=()
|
|
at=() # text fields
|
|
af=() # file fields
|
|
l=()
|
|
|
|
fn usage {
|
|
echo usage: $argv0 '[ -l ] [ -[gpm] action ] [ -u ] url [ field:value | field@file ... ]' >[1=2]
|
|
exit usage
|
|
}
|
|
|
|
while(~ $1 -*){
|
|
switch($1){
|
|
case -l; l=($l $1)
|
|
case -u; shift; url=$1
|
|
case -g; shift; action=$1; method=mget
|
|
case -p; shift; action=$1; method=mpost
|
|
case -m; shift; action=$1; method=multi
|
|
case *; usage
|
|
}
|
|
shift
|
|
}
|
|
|
|
# tired of typing -u
|
|
if(~ $1 http://* https://*){
|
|
url=$1
|
|
shift
|
|
}
|
|
|
|
if(~ $#url 0)
|
|
usage
|
|
|
|
while(! ~ $#* 0){
|
|
switch($1){
|
|
case *:*@*; at=($1 $at)
|
|
case *@*; af=($1 $af)
|
|
case *:*; at=($1 $at)
|
|
case *; usage
|
|
}
|
|
shift
|
|
}
|
|
|
|
hpost=($argv0 $l)
|
|
|
|
fn uenc {
|
|
f=$1
|
|
for(i in $at){
|
|
echo -n $"f`{urlencode /env/i | sed 's!%3A!=!; s!%00$!!'}
|
|
f='&'
|
|
}
|
|
for(i in $af){
|
|
echo -n $"f`{urlencode /env/i | sed 's!@.*$!=!'}
|
|
urlencode `{sed 's!^[^@]+@!!' /env/i}
|
|
f='&'
|
|
}
|
|
}
|
|
fn menc {
|
|
f=$1
|
|
cr=`{echo x | tr x \015}
|
|
for(i in $at){
|
|
k=`{sed 's!:.*$!!' /env/i}
|
|
echo '--'$"f$"cr
|
|
echo 'Content-Disposition: form-data; name="'$"k'"'$"cr
|
|
echo $"cr
|
|
i=$"i$"cr
|
|
sed 's!^[^:]+:!!' /env/i
|
|
}
|
|
for(i in $af){
|
|
k=`{sed 's!@.*$!!' /env/i}
|
|
v=`{sed 's!^[^@]+@!!' /env/i}
|
|
t=`{file -m $v}
|
|
n=`{basename $v}
|
|
echo '--'$"f$"cr
|
|
echo 'Content-Disposition: form-data; name="'$"k'"; filename="'$"n'"'$"cr
|
|
echo 'Content-Type: '$"t$"cr
|
|
echo $"cr
|
|
cat $v
|
|
echo $"cr
|
|
}
|
|
echo '--'$"f'--'$"cr
|
|
}
|
|
|
|
fn mget {
|
|
a=`{uenc '?'}
|
|
action=$"action$"a
|
|
$hget -b $url $action
|
|
}
|
|
fn mpost {
|
|
uenc | $hget -b $url -P $action
|
|
}
|
|
fn multi {
|
|
f='HJBOUNDARY'
|
|
menc $"f | $hget -r 'Content-Type: multipart/form-data, boundary='$"f -b $url -P $action
|
|
}
|
|
|
|
if(! ~ $action ''){
|
|
hget=(hget $l)
|
|
$method
|
|
exit
|
|
}
|
|
|
|
# serialize $at and $af into a0=... a1=... for awk
|
|
# to preserve newlines and other special characters
|
|
n=()
|
|
for(i in $at $af){
|
|
a$#n=$i
|
|
n=(1 $n)
|
|
}
|
|
a$#n=''
|
|
hget $url | uhtml | sed '
|
|
s!^(TAG|ATT)! \1!g; # escape our inline signaling
|
|
s!<[ ]*!\nTAG !g; # find starttags, mark with TAG name ...
|
|
s!>[^>"'']*$!!g; # remove garbage after the tag
|
|
# find attributes, mark with ATT name value
|
|
s!([a-zA-Z][a-zA-Z0-9:_]*)=("[^"]*"?|''[^'']*''?|[ ]*[^> ]+)!\nATT \1 \2!g;
|
|
' | awk -v 'hpost='$"hpost -v 'url='$"url '
|
|
BEGIN{
|
|
for(i=0; ENVIRON["a"i]!=""; i++){
|
|
s=ENVIRON["a"i]
|
|
x=index(s, ":"); y=index(s, "@")
|
|
if(y > 1 && (x < 1 || x > y))
|
|
x = y
|
|
n=substr(s, 1, x-1)
|
|
ainput[n]=substr(s, x+1, length(s))
|
|
atypes[n]=substr(s, x, 1);
|
|
}
|
|
}
|
|
function qw(s){
|
|
if(s !~ /[\n\\#;\|\^$=`''{}\(\)<> ]/)
|
|
return s
|
|
gsub(/''/, "''''", s)
|
|
return "''"s"''"
|
|
}
|
|
function uq(s){
|
|
q=substr(s, 1, 1)
|
|
if(q=="\"" || q=="''"){
|
|
s=substr(s, 2, length(s))
|
|
x=index(s, q)
|
|
if(x > 0) s=substr(s,1,x-1)
|
|
}
|
|
return s
|
|
}
|
|
function emitform(){
|
|
if(action!=""){
|
|
printf hpost
|
|
if(url!="") printf " -u %s", qw(url)
|
|
if(method=="post"){
|
|
if(enctype=="multipart/form-data")
|
|
printf " -m %s", qw(action)
|
|
else
|
|
printf " -p %s", qw(action)
|
|
} else
|
|
printf " -g %s", qw(action)
|
|
for(n in ainput)
|
|
printf " %s%s%s", n, atypes[n], qw(ainput[n])
|
|
for(n in input)
|
|
if(!(n in ainput))
|
|
printf " %s%s%s", n, types[n], qw(input[n])
|
|
printf "\n"
|
|
}
|
|
delete input
|
|
delete types
|
|
action=""
|
|
method=""
|
|
enctype=""
|
|
}
|
|
function endtag(){
|
|
if(tag=="form"){
|
|
action=attr["action"]
|
|
method=tolower(attr["method"])
|
|
enctype=tolower(attr["enctype"])
|
|
}
|
|
if(tag=="select")
|
|
selectname=attr["name"]
|
|
if(tag=="option" && selectname!=""){
|
|
if(attr["selected"]!=""){
|
|
input[selectname]=attr["value"]
|
|
selectname=""
|
|
}
|
|
}
|
|
if(tag=="input" || tag=="textarea" || tag=="submit"){
|
|
n=attr["name"]
|
|
if(n!=""){
|
|
if(tolower(attr["type"])=="file"){
|
|
input[n]="/dev/null"
|
|
types[n]="@"
|
|
} else {
|
|
input[n]=attr["value"]
|
|
types[n]=":"
|
|
}
|
|
}
|
|
}
|
|
delete attr
|
|
tag=""
|
|
}
|
|
/^TAG \//{
|
|
etag=tolower(substr($2, 2, length(etag)-1))
|
|
endtag()
|
|
if(etag=="form")
|
|
emitform()
|
|
}
|
|
/^TAG [^\/]/{
|
|
endtag()
|
|
tag=tolower($2)
|
|
if(tag=="form")
|
|
emitform()
|
|
}
|
|
/^ATT/{
|
|
for(i=4; i<=NF; i++) $3=$3" "$i
|
|
attr[tolower(uq($2))]=uq($3)
|
|
}
|
|
END{
|
|
endtag()
|
|
emitform()
|
|
}
|
|
'
|