]> git.lizzy.rs Git - plan9front.git/blob - rc/bin/hpost
torrent(1): update url in examples section
[plan9front.git] / rc / bin / hpost
1 #!/bin/rc
2 rfork e
3 url=()
4 at=()   # text fields
5 af=()   # file fields
6 l=()
7
8 fn usage {
9         echo 'usage: hpost [ -l ] [ -[gpm] action ] [ -u ] url [ field:value | field@file ... ]' >[1=2]
10         exit usage
11 }
12
13 while(~ $1 -*){
14         switch($1){
15         case -l;        l=($l $1)
16         case -u;        shift; url=$1
17         case -g;        shift; action=$1; method=mget
18         case -p;        shift; action=$1; method=mpost
19         case -m;        shift; action=$1; method=multi
20         case *;         usage
21         }
22         shift
23 }
24
25 if(~ $#url 0){
26         url=$1
27         shift
28 }
29
30 if(~ $url '')
31         usage
32
33 while(! ~ $#* 0){
34         switch($1){
35         case *:*@*;     at=($1 $at)
36         case *@*;       af=($1 $af)
37         case *:*;       at=($1 $at)
38         case *;         usage
39         }
40         shift
41 }
42
43 hpost=(hpost $l)
44
45 fn uenc {
46         f=$1
47         for(i in $at){
48                 echo -n $"f`{urlencode /env/i | sed 's!%3A!=!; s!%00$!!'}
49                 f='&'
50         }
51         for(i in $af){
52                 echo -n $"f`{urlencode /env/i | sed 's!@.*$!=!'}
53                 urlencode `{sed 's!^[^@]+@!!' /env/i}
54                 f='&'
55         }
56 }
57 fn menc {
58         f=$1
59         cr=`{echo x | tr x \015}
60         for(i in $at){
61                 k=`{sed 's!:.*$!!; q' /env/i}
62                 echo '--'$"f$"cr
63                 echo 'Content-Disposition: form-data; name="'$"k'"'$"cr
64                 echo $"cr
65                 i=$"i$"cr
66                 sed '1s!^[^:]+:!!' /env/i
67         }
68         for(i in $af){
69                 k=`{sed 's!@.*$!!; q' /env/i}
70         ifs='
71 '       v=`{sed 's!^[^@]+@!!' /env/i}
72                 t=`{file -m $v}
73                 n=`{basename $v}
74                 echo '--'$"f$"cr
75                 echo 'Content-Disposition: form-data; name="'$"k'"; filename="'$"n'"'$"cr
76                 echo 'Content-Type: '$"t$"cr
77                 echo $"cr
78                 cat $v
79                 echo $"cr
80         }
81         echo '--'$"f'--'$"cr
82 }
83
84 fn mget {
85         a=`{uenc '?'}
86         action=$"action$"a
87         $hget -b $url $action
88 }
89 fn mpost {
90         uenc | $hget -b $url -P $action
91 }
92 fn multi {
93         f='HJBOUNDARY'
94         menc $"f | $hget -r 'Content-Type: multipart/form-data; boundary='$"f -b $url -P $action
95 }
96
97 if(! ~ $action ''){
98         hget=(hget $l)
99         $method
100         exit
101 }
102
103 # serialize $at and $af into a0=... a1=... for awk
104 # to preserve newlines and other special characters
105 n=()
106 for(i in $at $af){
107         a$#n=$i
108         n=(1 $n)
109 }
110 a$#n=''
111 hget $url | uhtml | tr '>' '
112 ' | sed '
113 s!^(TAG|ATT)! \1!g;             # escape our inline signaling
114 s!<[    ]*!\nTAG !g;            # find starttags, mark with TAG name ...
115 s!>[^>"'']*$!!g;                # remove garbage after the tag
116 # find attributes, mark with ATT name value
117 s!([a-zA-Z][a-zA-Z0-9:_]*)=("[^"]*"?|''[^'']*''?|[      ]*[^>   ]+)!\nATT \1 \2!g;
118 ' | awk -v 'hpost='$"hpost -v 'url='$"url '
119 BEGIN{
120         for(i=0; ENVIRON["a"i]!=""; i++){
121                 s=ENVIRON["a"i]
122                 x=index(s, ":"); y=index(s, "@")
123                 if(y > 1 && (x < 1 || x > y))
124                         x = y
125                 n=substr(s, 1, x-1)
126                 ainput[n]=substr(s, x+1, length(s))
127                 atypes[n]=substr(s, x, 1);
128         }
129 }
130 function qw(s){
131         if(s !~ /[\n\\#;\|\^$=`''{}\(\)<>       ]/)
132                 return s
133         gsub(/''/, "''''", s)
134         return "''"s"''"
135 }
136 function uq(s){
137         q=substr(s, 1, 1)
138         if(q=="\"" || q=="''"){
139                 s=substr(s, 2, length(s))
140                 x=index(s, q)
141                 if(x > 0) s=substr(s,1,x-1)
142         }
143         return s
144 }
145 function emitform(){
146         if(action!=""){
147                 printf hpost
148                 if(url!="") printf " -u %s", qw(url)
149                 if(method=="post"){
150                         if(enctype=="multipart/form-data")
151                                 printf " -m %s", qw(action)
152                         else
153                                 printf " -p %s", qw(action)
154                 } else
155                                 printf " -g %s", qw(action)
156                 for(n in ainput)
157                         printf " %s%s%s", n, atypes[n], qw(ainput[n])
158                 for(n in input)
159                         if(!(n in ainput))
160                                 printf " %s%s%s", n, types[n], qw(input[n])
161                 printf "\n"
162         }
163         delete input
164         delete types
165         action=""
166         method=""
167         enctype=""
168 }
169 function endtag(){
170         if(tag=="form"){
171                 action=attr["action"]
172                 method=tolower(attr["method"])
173                 enctype=tolower(attr["enctype"])
174         }
175         if(tag=="select")
176                 selectname=attr["name"]
177         if(tag=="option" && selectname!=""){
178                 if(attr["selected"]!=""){
179                         input[selectname]=attr["value"]
180                         selectname=""
181                 }
182         }
183         if(tag=="input" || tag=="textarea" || tag=="submit"){
184                 n=attr["name"]
185                 if(n!=""){
186                         if(tolower(attr["type"])=="file"){
187                                 input[n]="/dev/null"
188                                 types[n]="@"
189                         } else {
190                                 input[n]=attr["value"]
191                                 types[n]=":"
192                         }
193                 }
194         }
195         delete attr
196         tag=""
197 }
198 /^TAG \//{
199         etag=tolower(substr($2, 2, length(etag)-1))
200         endtag()
201         if(etag=="form")
202                 emitform()
203 }
204 /^TAG [^\/]/{
205         endtag()
206         tag=tolower($2)
207         if(tag=="form")
208                 emitform()
209 }
210 /^ATT/{
211         for(i=4; i<=NF; i++) $3=$3" "$i
212         attr[tolower(uq($2))]=uq($3)
213 }
214 END{
215         endtag()
216         emitform()
217 }
218 '