Blame


1 9df487d7 2003-11-23 devnull #include <u.h>
2 9df487d7 2003-11-23 devnull #include <libc.h>
3 9df487d7 2003-11-23 devnull #include <httpd.h>
4 9df487d7 2003-11-23 devnull
5 9df487d7 2003-11-23 devnull static char hstates[] = "nrewE";
6 9df487d7 2003-11-23 devnull static char hxfers[] = " x";
7 f599f28c 2007-04-21 devnull static int _hflush(Hio*, int, int);
8 9df487d7 2003-11-23 devnull
9 9df487d7 2003-11-23 devnull int
10 9df487d7 2003-11-23 devnull hinit(Hio *h, int fd, int mode)
11 9df487d7 2003-11-23 devnull {
12 9df487d7 2003-11-23 devnull if(fd == -1 || mode != Hread && mode != Hwrite)
13 9df487d7 2003-11-23 devnull return -1;
14 9df487d7 2003-11-23 devnull h->hh = nil;
15 9df487d7 2003-11-23 devnull h->fd = fd;
16 9df487d7 2003-11-23 devnull h->seek = 0;
17 9df487d7 2003-11-23 devnull h->state = mode;
18 9df487d7 2003-11-23 devnull h->start = h->buf + 16; /* leave space for chunk length */
19 9df487d7 2003-11-23 devnull h->stop = h->pos = h->start;
20 9df487d7 2003-11-23 devnull if(mode == Hread){
21 9df487d7 2003-11-23 devnull h->bodylen = ~0UL;
22 9df487d7 2003-11-23 devnull *h->pos = '\0';
23 9df487d7 2003-11-23 devnull }else
24 9df487d7 2003-11-23 devnull h->stop = h->start + Hsize;
25 9df487d7 2003-11-23 devnull return 0;
26 9df487d7 2003-11-23 devnull }
27 9df487d7 2003-11-23 devnull
28 9df487d7 2003-11-23 devnull int
29 9df487d7 2003-11-23 devnull hiserror(Hio *h)
30 9df487d7 2003-11-23 devnull {
31 9df487d7 2003-11-23 devnull return h->state == Herr;
32 9df487d7 2003-11-23 devnull }
33 9df487d7 2003-11-23 devnull
34 9df487d7 2003-11-23 devnull int
35 9df487d7 2003-11-23 devnull hgetc(Hio *h)
36 9df487d7 2003-11-23 devnull {
37 9df487d7 2003-11-23 devnull uchar *p;
38 9df487d7 2003-11-23 devnull
39 9df487d7 2003-11-23 devnull p = h->pos;
40 9df487d7 2003-11-23 devnull if(p < h->stop){
41 9df487d7 2003-11-23 devnull h->pos = p + 1;
42 9df487d7 2003-11-23 devnull return *p;
43 9df487d7 2003-11-23 devnull }
44 9df487d7 2003-11-23 devnull p -= UTFmax;
45 9df487d7 2003-11-23 devnull if(p < h->start)
46 9df487d7 2003-11-23 devnull p = h->start;
47 9df487d7 2003-11-23 devnull if(!hreadbuf(h, p) || h->pos == h->stop)
48 9df487d7 2003-11-23 devnull return -1;
49 9df487d7 2003-11-23 devnull return *h->pos++;
50 9df487d7 2003-11-23 devnull }
51 9df487d7 2003-11-23 devnull
52 9df487d7 2003-11-23 devnull int
53 9df487d7 2003-11-23 devnull hungetc(Hio *h)
54 9df487d7 2003-11-23 devnull {
55 9df487d7 2003-11-23 devnull if(h->state == Hend)
56 9df487d7 2003-11-23 devnull h->state = Hread;
57 9df487d7 2003-11-23 devnull else if(h->state == Hread)
58 9df487d7 2003-11-23 devnull h->pos--;
59 9df487d7 2003-11-23 devnull if(h->pos < h->start || h->state != Hread){
60 9df487d7 2003-11-23 devnull h->state = Herr;
61 9df487d7 2003-11-23 devnull h->pos = h->stop;
62 9df487d7 2003-11-23 devnull return -1;
63 9df487d7 2003-11-23 devnull }
64 9df487d7 2003-11-23 devnull return 0;
65 9df487d7 2003-11-23 devnull }
66 9df487d7 2003-11-23 devnull
67 9df487d7 2003-11-23 devnull /*
68 9df487d7 2003-11-23 devnull * fill the buffer, saving contents from vsave onwards.
69 9df487d7 2003-11-23 devnull * nothing is saved if vsave is nil.
70 9df487d7 2003-11-23 devnull * returns the beginning of the buffer.
71 9df487d7 2003-11-23 devnull *
72 9df487d7 2003-11-23 devnull * understands message body sizes and chunked transfer encoding
73 9df487d7 2003-11-23 devnull */
74 9df487d7 2003-11-23 devnull void *
75 9df487d7 2003-11-23 devnull hreadbuf(Hio *h, void *vsave)
76 9df487d7 2003-11-23 devnull {
77 9df487d7 2003-11-23 devnull Hio *hh;
78 9df487d7 2003-11-23 devnull uchar *save;
79 9df487d7 2003-11-23 devnull int c, in, cpy, dpos;
80 9df487d7 2003-11-23 devnull
81 9df487d7 2003-11-23 devnull save = vsave;
82 9df487d7 2003-11-23 devnull if(save && (save < h->start || save > h->stop)
83 9df487d7 2003-11-23 devnull || h->state != Hread && h->state != Hend){
84 9df487d7 2003-11-23 devnull h->state = Herr;
85 9df487d7 2003-11-23 devnull h->pos = h->stop;
86 9df487d7 2003-11-23 devnull return nil;
87 9df487d7 2003-11-23 devnull }
88 9df487d7 2003-11-23 devnull
89 9df487d7 2003-11-23 devnull dpos = 0;
90 9df487d7 2003-11-23 devnull if(save && h->pos > save)
91 9df487d7 2003-11-23 devnull dpos = h->pos - save;
92 9df487d7 2003-11-23 devnull cpy = 0;
93 9df487d7 2003-11-23 devnull if(save){
94 9df487d7 2003-11-23 devnull cpy = h->stop - save;
95 9df487d7 2003-11-23 devnull memmove(h->start, save, cpy);
96 9df487d7 2003-11-23 devnull }
97 9df487d7 2003-11-23 devnull h->seek += h->stop - h->start - cpy;
98 9df487d7 2003-11-23 devnull h->pos = h->start + dpos;
99 9df487d7 2003-11-23 devnull
100 9df487d7 2003-11-23 devnull in = Hsize - cpy;
101 9df487d7 2003-11-23 devnull if(h->state == Hend)
102 9df487d7 2003-11-23 devnull in = 0;
103 9df487d7 2003-11-23 devnull else if(in > h->bodylen)
104 9df487d7 2003-11-23 devnull in = h->bodylen;
105 9df487d7 2003-11-23 devnull
106 9df487d7 2003-11-23 devnull /*
107 9df487d7 2003-11-23 devnull * for chunked encoding, fill buffer,
108 9df487d7 2003-11-23 devnull * then read in new chunk length and wipe out that line
109 9df487d7 2003-11-23 devnull */
110 9df487d7 2003-11-23 devnull hh = h->hh;
111 9df487d7 2003-11-23 devnull if(hh != nil){
112 9df487d7 2003-11-23 devnull if(!in && h->xferenc && h->state != Hend){
113 9df487d7 2003-11-23 devnull if(h->xferenc == 2){
114 9df487d7 2003-11-23 devnull c = hgetc(hh);
115 9df487d7 2003-11-23 devnull if(c == '\r')
116 9df487d7 2003-11-23 devnull c = hgetc(hh);
117 9df487d7 2003-11-23 devnull if(c != '\n'){
118 9df487d7 2003-11-23 devnull h->pos = h->stop;
119 9df487d7 2003-11-23 devnull h->state = Herr;
120 9df487d7 2003-11-23 devnull return nil;
121 9df487d7 2003-11-23 devnull }
122 9df487d7 2003-11-23 devnull }
123 9df487d7 2003-11-23 devnull h->xferenc = 2;
124 9df487d7 2003-11-23 devnull in = 0;
125 9df487d7 2003-11-23 devnull while((c = hgetc(hh)) != '\n'){
126 9df487d7 2003-11-23 devnull if(c >= '0' && c <= '9')
127 9df487d7 2003-11-23 devnull c -= '0';
128 9df487d7 2003-11-23 devnull else if(c >= 'a' && c <= 'f')
129 9df487d7 2003-11-23 devnull c -= 'a' - 10;
130 9df487d7 2003-11-23 devnull else if(c >= 'A' && c <= 'F')
131 9df487d7 2003-11-23 devnull c -= 'A' - 10;
132 9df487d7 2003-11-23 devnull else
133 9df487d7 2003-11-23 devnull break;
134 9df487d7 2003-11-23 devnull in = in * 16 + c;
135 9df487d7 2003-11-23 devnull }
136 9df487d7 2003-11-23 devnull while(c != '\n'){
137 9df487d7 2003-11-23 devnull if(c < 0){
138 9df487d7 2003-11-23 devnull h->pos = h->stop;
139 9df487d7 2003-11-23 devnull h->state = Herr;
140 9df487d7 2003-11-23 devnull return nil;
141 9df487d7 2003-11-23 devnull }
142 9df487d7 2003-11-23 devnull c = hgetc(hh);
143 9df487d7 2003-11-23 devnull }
144 9df487d7 2003-11-23 devnull h->bodylen = in;
145 9df487d7 2003-11-23 devnull
146 9df487d7 2003-11-23 devnull in = Hsize - cpy;
147 9df487d7 2003-11-23 devnull if(in > h->bodylen)
148 9df487d7 2003-11-23 devnull in = h->bodylen;
149 9df487d7 2003-11-23 devnull }
150 9df487d7 2003-11-23 devnull if(in){
151 9df487d7 2003-11-23 devnull while(hh->pos + in > hh->stop){
152 9df487d7 2003-11-23 devnull if(hreadbuf(hh, hh->pos) == nil){
153 9df487d7 2003-11-23 devnull h->pos = h->stop;
154 9df487d7 2003-11-23 devnull h->state = Herr;
155 9df487d7 2003-11-23 devnull return nil;
156 9df487d7 2003-11-23 devnull }
157 9df487d7 2003-11-23 devnull }
158 9df487d7 2003-11-23 devnull memmove(h->start + cpy, hh->pos, in);
159 9df487d7 2003-11-23 devnull hh->pos += in;
160 9df487d7 2003-11-23 devnull }
161 2277c5d7 2004-03-21 devnull }else if(in){
162 2277c5d7 2004-03-21 devnull if((in = read(h->fd, h->start + cpy, in)) < 0){
163 2277c5d7 2004-03-21 devnull h->state = Herr;
164 2277c5d7 2004-03-21 devnull h->pos = h->stop;
165 2277c5d7 2004-03-21 devnull return nil;
166 2277c5d7 2004-03-21 devnull }
167 9df487d7 2003-11-23 devnull }
168 9df487d7 2003-11-23 devnull if(in == 0)
169 9df487d7 2003-11-23 devnull h->state = Hend;
170 9df487d7 2003-11-23 devnull
171 9df487d7 2003-11-23 devnull h->bodylen -= in;
172 9df487d7 2003-11-23 devnull
173 9df487d7 2003-11-23 devnull h->stop = h->start + cpy + in;
174 9df487d7 2003-11-23 devnull *h->stop = '\0';
175 9df487d7 2003-11-23 devnull if(h->pos == h->stop)
176 9df487d7 2003-11-23 devnull return nil;
177 9df487d7 2003-11-23 devnull return h->start;
178 9df487d7 2003-11-23 devnull }
179 9df487d7 2003-11-23 devnull
180 9df487d7 2003-11-23 devnull int
181 9df487d7 2003-11-23 devnull hbuflen(Hio *h, void *p)
182 9df487d7 2003-11-23 devnull {
183 9df487d7 2003-11-23 devnull return h->stop - (uchar*)p;
184 9df487d7 2003-11-23 devnull }
185 9df487d7 2003-11-23 devnull
186 9df487d7 2003-11-23 devnull /*
187 9df487d7 2003-11-23 devnull * prepare to receive a message body
188 9df487d7 2003-11-23 devnull * len is the content length (~0 => unspecified)
189 9df487d7 2003-11-23 devnull * te is the transfer encoding
190 9df487d7 2003-11-23 devnull * returns < 0 if setup failed
191 9df487d7 2003-11-23 devnull */
192 9df487d7 2003-11-23 devnull Hio*
193 9df487d7 2003-11-23 devnull hbodypush(Hio *hh, ulong len, HFields *te)
194 9df487d7 2003-11-23 devnull {
195 9df487d7 2003-11-23 devnull Hio *h;
196 9df487d7 2003-11-23 devnull int xe;
197 9df487d7 2003-11-23 devnull
198 9df487d7 2003-11-23 devnull if(hh->state != Hread)
199 9df487d7 2003-11-23 devnull return nil;
200 9df487d7 2003-11-23 devnull xe = 0;
201 9df487d7 2003-11-23 devnull if(te != nil){
202 9df487d7 2003-11-23 devnull if(te->params != nil || te->next != nil)
203 9df487d7 2003-11-23 devnull return nil;
204 9df487d7 2003-11-23 devnull if(cistrcmp(te->s, "chunked") == 0){
205 9df487d7 2003-11-23 devnull xe = 1;
206 9df487d7 2003-11-23 devnull len = 0;
207 9df487d7 2003-11-23 devnull }else if(cistrcmp(te->s, "identity") == 0){
208 9df487d7 2003-11-23 devnull ;
209 9df487d7 2003-11-23 devnull }else
210 9df487d7 2003-11-23 devnull return nil;
211 9df487d7 2003-11-23 devnull }
212 9df487d7 2003-11-23 devnull
213 9df487d7 2003-11-23 devnull h = malloc(sizeof *h);
214 9df487d7 2003-11-23 devnull if(h == nil)
215 9df487d7 2003-11-23 devnull return nil;
216 9df487d7 2003-11-23 devnull
217 9df487d7 2003-11-23 devnull h->hh = hh;
218 9df487d7 2003-11-23 devnull h->fd = -1;
219 9df487d7 2003-11-23 devnull h->seek = 0;
220 9df487d7 2003-11-23 devnull h->state = Hread;
221 9df487d7 2003-11-23 devnull h->xferenc = xe;
222 9df487d7 2003-11-23 devnull h->start = h->buf + 16; /* leave space for chunk length */
223 9df487d7 2003-11-23 devnull h->stop = h->pos = h->start;
224 9df487d7 2003-11-23 devnull *h->pos = '\0';
225 9df487d7 2003-11-23 devnull h->bodylen = len;
226 9df487d7 2003-11-23 devnull return h;
227 9df487d7 2003-11-23 devnull }
228 9df487d7 2003-11-23 devnull
229 9df487d7 2003-11-23 devnull /*
230 9df487d7 2003-11-23 devnull * dump the state of the io buffer into a string
231 9df487d7 2003-11-23 devnull */
232 9df487d7 2003-11-23 devnull char *
233 9df487d7 2003-11-23 devnull hunload(Hio *h)
234 9df487d7 2003-11-23 devnull {
235 9df487d7 2003-11-23 devnull uchar *p, *t, *stop, *buf;
236 9df487d7 2003-11-23 devnull int ne, n, c;
237 9df487d7 2003-11-23 devnull
238 9df487d7 2003-11-23 devnull stop = h->stop;
239 9df487d7 2003-11-23 devnull ne = 0;
240 9df487d7 2003-11-23 devnull for(p = h->pos; p < stop; p++){
241 9df487d7 2003-11-23 devnull c = *p;
242 9df487d7 2003-11-23 devnull if(c == 0x80)
243 9df487d7 2003-11-23 devnull ne++;
244 9df487d7 2003-11-23 devnull }
245 9df487d7 2003-11-23 devnull p = h->pos;
246 9df487d7 2003-11-23 devnull
247 9df487d7 2003-11-23 devnull n = (stop - p) + ne + 3;
248 9df487d7 2003-11-23 devnull buf = mallocz(n, 1);
249 9df487d7 2003-11-23 devnull if(buf == nil)
250 9df487d7 2003-11-23 devnull return nil;
251 9df487d7 2003-11-23 devnull buf[0] = hstates[h->state];
252 9df487d7 2003-11-23 devnull buf[1] = hxfers[h->xferenc];
253 9df487d7 2003-11-23 devnull
254 9df487d7 2003-11-23 devnull t = &buf[2];
255 9df487d7 2003-11-23 devnull for(; p < stop; p++){
256 9df487d7 2003-11-23 devnull c = *p;
257 9df487d7 2003-11-23 devnull if(c == 0 || c == 0x80){
258 9df487d7 2003-11-23 devnull *t++ = 0x80;
259 9df487d7 2003-11-23 devnull if(c == 0x80)
260 9df487d7 2003-11-23 devnull *t++ = 0x80;
261 9df487d7 2003-11-23 devnull }else
262 9df487d7 2003-11-23 devnull *t++ = c;
263 9df487d7 2003-11-23 devnull }
264 9df487d7 2003-11-23 devnull *t++ = '\0';
265 9df487d7 2003-11-23 devnull if(t != buf + n)
266 9df487d7 2003-11-23 devnull return nil;
267 9df487d7 2003-11-23 devnull return (char*)buf;
268 9df487d7 2003-11-23 devnull }
269 9df487d7 2003-11-23 devnull
270 9df487d7 2003-11-23 devnull /*
271 9df487d7 2003-11-23 devnull * read the io buffer state from a string
272 9df487d7 2003-11-23 devnull */
273 9df487d7 2003-11-23 devnull int
274 9df487d7 2003-11-23 devnull hload(Hio *h, char *buf)
275 9df487d7 2003-11-23 devnull {
276 9df487d7 2003-11-23 devnull uchar *p, *t, *stop;
277 9df487d7 2003-11-23 devnull char *s;
278 9df487d7 2003-11-23 devnull int c;
279 9df487d7 2003-11-23 devnull
280 9df487d7 2003-11-23 devnull s = strchr(hstates, buf[0]);
281 9df487d7 2003-11-23 devnull if(s == nil)
282 2e965b33 2004-05-05 devnull return -1;
283 9df487d7 2003-11-23 devnull h->state = s - hstates;
284 9df487d7 2003-11-23 devnull
285 9df487d7 2003-11-23 devnull s = strchr(hxfers, buf[1]);
286 9df487d7 2003-11-23 devnull if(s == nil)
287 4bef0baf 2004-12-27 devnull return -1;
288 9df487d7 2003-11-23 devnull h->xferenc = s - hxfers;
289 9df487d7 2003-11-23 devnull
290 9df487d7 2003-11-23 devnull t = h->start;
291 9df487d7 2003-11-23 devnull stop = t + Hsize;
292 9df487d7 2003-11-23 devnull for(p = (uchar*)&buf[2]; c = *p; p++){
293 9df487d7 2003-11-23 devnull if(c == 0x80){
294 9df487d7 2003-11-23 devnull if(p[1] != 0x80)
295 9df487d7 2003-11-23 devnull c = 0;
296 9df487d7 2003-11-23 devnull else
297 9df487d7 2003-11-23 devnull p++;
298 9df487d7 2003-11-23 devnull }
299 9df487d7 2003-11-23 devnull *t++ = c;
300 9df487d7 2003-11-23 devnull if(t >= stop)
301 2e965b33 2004-05-05 devnull return -1;
302 9df487d7 2003-11-23 devnull }
303 9df487d7 2003-11-23 devnull *t = '\0';
304 9df487d7 2003-11-23 devnull h->pos = h->start;
305 9df487d7 2003-11-23 devnull h->stop = t;
306 9df487d7 2003-11-23 devnull h->seek = 0;
307 2e965b33 2004-05-05 devnull return 0;
308 9df487d7 2003-11-23 devnull }
309 9df487d7 2003-11-23 devnull
310 9df487d7 2003-11-23 devnull void
311 9df487d7 2003-11-23 devnull hclose(Hio *h)
312 9df487d7 2003-11-23 devnull {
313 9df487d7 2003-11-23 devnull if(h->fd >= 0){
314 9df487d7 2003-11-23 devnull if(h->state == Hwrite)
315 9df487d7 2003-11-23 devnull hxferenc(h, 0);
316 9df487d7 2003-11-23 devnull close(h->fd);
317 9df487d7 2003-11-23 devnull }
318 9df487d7 2003-11-23 devnull h->stop = h->pos = nil;
319 9df487d7 2003-11-23 devnull h->fd = -1;
320 9df487d7 2003-11-23 devnull }
321 9df487d7 2003-11-23 devnull
322 9df487d7 2003-11-23 devnull /*
323 9df487d7 2003-11-23 devnull * flush the buffer and possibly change encoding modes
324 9df487d7 2003-11-23 devnull */
325 9df487d7 2003-11-23 devnull int
326 9df487d7 2003-11-23 devnull hxferenc(Hio *h, int on)
327 9df487d7 2003-11-23 devnull {
328 9df487d7 2003-11-23 devnull if(h->xferenc && !on && h->pos != h->start)
329 9df487d7 2003-11-23 devnull hflush(h);
330 f599f28c 2007-04-21 devnull if(_hflush(h, 1, 0) < 0)
331 9df487d7 2003-11-23 devnull return -1;
332 9df487d7 2003-11-23 devnull h->xferenc = !!on;
333 9df487d7 2003-11-23 devnull return 0;
334 9df487d7 2003-11-23 devnull }
335 9df487d7 2003-11-23 devnull
336 9df487d7 2003-11-23 devnull int
337 9df487d7 2003-11-23 devnull hputc(Hio *h, int c)
338 9df487d7 2003-11-23 devnull {
339 9df487d7 2003-11-23 devnull uchar *p;
340 9df487d7 2003-11-23 devnull
341 9df487d7 2003-11-23 devnull p = h->pos;
342 9df487d7 2003-11-23 devnull if(p < h->stop){
343 9df487d7 2003-11-23 devnull h->pos = p + 1;
344 9df487d7 2003-11-23 devnull return *p = c;
345 9df487d7 2003-11-23 devnull }
346 9df487d7 2003-11-23 devnull if(hflush(h) < 0)
347 9df487d7 2003-11-23 devnull return -1;
348 9df487d7 2003-11-23 devnull return *h->pos++ = c;
349 9df487d7 2003-11-23 devnull }
350 9df487d7 2003-11-23 devnull
351 9df487d7 2003-11-23 devnull static int
352 9df487d7 2003-11-23 devnull fmthflush(Fmt *f)
353 9df487d7 2003-11-23 devnull {
354 9df487d7 2003-11-23 devnull Hio *h;
355 9df487d7 2003-11-23 devnull
356 9df487d7 2003-11-23 devnull h = f->farg;
357 9df487d7 2003-11-23 devnull h->pos = f->to;
358 9df487d7 2003-11-23 devnull if(hflush(h) < 0)
359 9df487d7 2003-11-23 devnull return 0;
360 9df487d7 2003-11-23 devnull f->stop = h->stop;
361 9df487d7 2003-11-23 devnull f->to = h->pos;
362 9df487d7 2003-11-23 devnull f->start = h->pos;
363 9df487d7 2003-11-23 devnull return 1;
364 9df487d7 2003-11-23 devnull }
365 9df487d7 2003-11-23 devnull
366 9df487d7 2003-11-23 devnull int
367 9df487d7 2003-11-23 devnull hvprint(Hio *h, char *fmt, va_list args)
368 9df487d7 2003-11-23 devnull {
369 9df487d7 2003-11-23 devnull int n;
370 9df487d7 2003-11-23 devnull Fmt f;
371 9df487d7 2003-11-23 devnull
372 9df487d7 2003-11-23 devnull f.runes = 0;
373 9df487d7 2003-11-23 devnull f.stop = h->stop;
374 9df487d7 2003-11-23 devnull f.to = h->pos;
375 9df487d7 2003-11-23 devnull f.start = h->pos;
376 9df487d7 2003-11-23 devnull f.flush = fmthflush;
377 9df487d7 2003-11-23 devnull f.farg = h;
378 9df487d7 2003-11-23 devnull f.nfmt = 0;
379 30df15f9 2007-04-21 devnull fmtlocaleinit(&f, nil, nil, nil);
380 18443075 2005-02-08 devnull n = fmtvprint(&f, fmt, args);
381 9df487d7 2003-11-23 devnull h->pos = f.to;
382 9df487d7 2003-11-23 devnull return n;
383 9df487d7 2003-11-23 devnull }
384 9df487d7 2003-11-23 devnull
385 9df487d7 2003-11-23 devnull int
386 9df487d7 2003-11-23 devnull hprint(Hio *h, char *fmt, ...)
387 9df487d7 2003-11-23 devnull {
388 9df487d7 2003-11-23 devnull int n;
389 9df487d7 2003-11-23 devnull va_list arg;
390 9df487d7 2003-11-23 devnull
391 9df487d7 2003-11-23 devnull va_start(arg, fmt);
392 9df487d7 2003-11-23 devnull n = hvprint(h, fmt, arg);
393 9df487d7 2003-11-23 devnull va_end(arg);
394 9df487d7 2003-11-23 devnull return n;
395 9df487d7 2003-11-23 devnull }
396 9df487d7 2003-11-23 devnull
397 4bef0baf 2004-12-27 devnull static int
398 f599f28c 2007-04-21 devnull _hflush(Hio *h, int force, int dolength)
399 9df487d7 2003-11-23 devnull {
400 9df487d7 2003-11-23 devnull uchar *s;
401 9df487d7 2003-11-23 devnull int w;
402 9df487d7 2003-11-23 devnull
403 9df487d7 2003-11-23 devnull if(h->state != Hwrite){
404 9df487d7 2003-11-23 devnull h->state = Herr;
405 9df487d7 2003-11-23 devnull h->stop = h->pos;
406 9df487d7 2003-11-23 devnull return -1;
407 9df487d7 2003-11-23 devnull }
408 9df487d7 2003-11-23 devnull s = h->start;
409 9df487d7 2003-11-23 devnull w = h->pos - s;
410 f599f28c 2007-04-21 devnull if(w == 0 && !force)
411 f599f28c 2007-04-21 devnull return 0;
412 9df487d7 2003-11-23 devnull if(h->xferenc){
413 9df487d7 2003-11-23 devnull *--s = '\n';
414 9df487d7 2003-11-23 devnull *--s = '\r';
415 9df487d7 2003-11-23 devnull do{
416 9df487d7 2003-11-23 devnull *--s = "0123456789abcdef"[w & 0xf];
417 9df487d7 2003-11-23 devnull w >>= 4;
418 9df487d7 2003-11-23 devnull }while(w);
419 9df487d7 2003-11-23 devnull h->pos[0] = '\r';
420 9df487d7 2003-11-23 devnull h->pos[1] = '\n';
421 9df487d7 2003-11-23 devnull w = &h->pos[2] - s;
422 9df487d7 2003-11-23 devnull }
423 4bef0baf 2004-12-27 devnull if(dolength)
424 4bef0baf 2004-12-27 devnull fprint(h->fd, "Content-Length: %d\r\n\r\n", w);
425 9df487d7 2003-11-23 devnull if(write(h->fd, s, w) != w){
426 9df487d7 2003-11-23 devnull h->state = Herr;
427 9df487d7 2003-11-23 devnull h->stop = h->pos;
428 9df487d7 2003-11-23 devnull return -1;
429 9df487d7 2003-11-23 devnull }
430 9df487d7 2003-11-23 devnull h->seek += w;
431 9df487d7 2003-11-23 devnull h->pos = h->start;
432 9df487d7 2003-11-23 devnull return 0;
433 4bef0baf 2004-12-27 devnull }
434 4bef0baf 2004-12-27 devnull
435 4bef0baf 2004-12-27 devnull int
436 4bef0baf 2004-12-27 devnull hflush(Hio *h)
437 4bef0baf 2004-12-27 devnull {
438 f599f28c 2007-04-21 devnull return _hflush(h, 0, 0);
439 9df487d7 2003-11-23 devnull }
440 9df487d7 2003-11-23 devnull
441 9df487d7 2003-11-23 devnull int
442 4bef0baf 2004-12-27 devnull hlflush(Hio* h)
443 4bef0baf 2004-12-27 devnull {
444 f599f28c 2007-04-21 devnull return _hflush(h, 0, 1);
445 4bef0baf 2004-12-27 devnull }
446 4bef0baf 2004-12-27 devnull
447 4bef0baf 2004-12-27 devnull int
448 9df487d7 2003-11-23 devnull hwrite(Hio *h, void *vbuf, int len)
449 9df487d7 2003-11-23 devnull {
450 7eded25c 2005-02-16 devnull uchar *buf;
451 9df487d7 2003-11-23 devnull int n, m;
452 9df487d7 2003-11-23 devnull
453 9df487d7 2003-11-23 devnull buf = vbuf;
454 9df487d7 2003-11-23 devnull n = len;
455 9df487d7 2003-11-23 devnull if(n < 0 || h->state != Hwrite){
456 9df487d7 2003-11-23 devnull h->state = Herr;
457 9df487d7 2003-11-23 devnull h->stop = h->pos;
458 9df487d7 2003-11-23 devnull return -1;
459 9df487d7 2003-11-23 devnull }
460 7eded25c 2005-02-16 devnull if(h->pos + n >= h->stop){
461 7eded25c 2005-02-16 devnull if(h->start != h->pos)
462 7eded25c 2005-02-16 devnull if(hflush(h) < 0)
463 9df487d7 2003-11-23 devnull return -1;
464 7eded25c 2005-02-16 devnull while(h->pos + n >= h->stop){
465 7eded25c 2005-02-16 devnull m = h->stop - h->pos;
466 7eded25c 2005-02-16 devnull if(h->xferenc){
467 7eded25c 2005-02-16 devnull memmove(h->pos, buf, m);
468 7eded25c 2005-02-16 devnull h->pos += m;
469 7eded25c 2005-02-16 devnull if(hflush(h) < 0)
470 7eded25c 2005-02-16 devnull return -1;
471 7eded25c 2005-02-16 devnull }else{
472 7eded25c 2005-02-16 devnull if(write(h->fd, buf, m) != m){
473 7eded25c 2005-02-16 devnull h->state = Herr;
474 7eded25c 2005-02-16 devnull h->stop = h->pos;
475 7eded25c 2005-02-16 devnull return -1;
476 7eded25c 2005-02-16 devnull }
477 7eded25c 2005-02-16 devnull h->seek += m;
478 7eded25c 2005-02-16 devnull }
479 7eded25c 2005-02-16 devnull n -= m;
480 7eded25c 2005-02-16 devnull buf += m;
481 9df487d7 2003-11-23 devnull }
482 9df487d7 2003-11-23 devnull }
483 7eded25c 2005-02-16 devnull memmove(h->pos, buf, n);
484 7eded25c 2005-02-16 devnull h->pos += n;
485 9df487d7 2003-11-23 devnull return len;
486 9df487d7 2003-11-23 devnull }