2 ashd - A Sane HTTP Daemon
3 Copyright (C) 2008 Fredrik Tolf <fredrik@dolda2000.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 static char *base64set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
30 static int base64rev[] = {
31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
34 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
35 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
36 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
37 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
38 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
39 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49 void _sizebuf(struct buffer *buf, size_t wanted, size_t el)
61 buf->b = srealloc(buf->b, n * el);
63 buf->b = smalloc(n * el);
67 char *decstr(char **p, size_t *len)
71 for(p2 = *p; (p2 - *p) < *len; p2++) {
84 char *vsprintf2(char *format, va_list al)
91 ret = vsnprintf(NULL, 0, format, al2);
93 buf = smalloc(ret + 1);
95 vsnprintf(buf, ret + 1, format, al2);
100 char *sprintf2(char *format, ...)
105 va_start(args, format);
106 buf = vsprintf2(format, args);
111 char *sprintf3(char *format, ...)
113 static char *buf = NULL;
118 va_start(args, format);
119 buf = vsprintf2(format, args);
126 return((off_t)strtoll(n, NULL, 10));
129 char **tokenize(char *src)
154 else if(isspace(*p) || !*p)
162 n = memcpy(malloc(cl + 1), p2, cl);
164 for(p2 = n; *p2; cl--) {
166 memmove(p2, p2 + 1, cl--);
168 } else if(*p2 == '\"') {
169 memmove(p2, p2 + 1, cl);
174 ret = realloc(ret, sizeof(char *) * (++s));
177 ret = realloc(ret, sizeof(char *) * (++s));
182 void freeca(char **ca)
197 for(i = 0; *a; a++, i++);
201 void bvprintf(struct charbuf *buf, char *format, va_list al)
208 ret = vsnprintf(buf->b + buf->d, buf->s - buf->d, format, al2);
210 if(ret < buf->s - buf->d) {
214 sizebuf(*buf, buf->d + ret + 1);
218 void bprintf(struct charbuf *buf, char *format, ...)
222 va_start(args, format);
223 bvprintf(buf, format, args);
227 void replstr(char **p, char *n)
240 char *base64encode(char *data, size_t datalen)
249 bufadd(buf, base64set[(data[0] & 0xfc) >> 2]);
250 bufadd(buf, base64set[((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4)]);
251 bufadd(buf, base64set[((data[1] & 0x0f) << 2) | ((data[2] & 0xc0) >> 6)]);
252 bufadd(buf, base64set[data[2] & 0x3f]);
258 bufadd(buf, base64set[(data[0] & 0xfc) >> 2]);
259 bufadd(buf, base64set[(data[0] & 0x03) << 4]);
260 bufcat(buf, "==", 2);
264 bufadd(buf, base64set[(data[0] & 0xfc) >> 2]);
265 bufadd(buf, base64set[((data[0] & 0x03) << 4) | ((data[1] & 0xf0) >> 4)]);
266 bufadd(buf, base64set[(data[1] & 0x0f) << 2]);
273 char *base64decode(char *data, size_t *datalen)
282 for(; *data > 0; data++)
284 c = (int)(unsigned char)*data;
289 if(base64rev[c] == -1)
297 cur |= base64rev[c] >> -b;
302 cur |= base64rev[c] << b;
310 static int btheight(struct btree *tree)
317 static void btsetheight(struct btree *tree)
321 tree->h = max(btheight(tree->l), btheight(tree->r)) + 1;
324 static void bbtrl(struct btree **tree);
326 static void bbtrr(struct btree **tree)
328 struct btree *m, *l, *r;
330 if(btheight((*tree)->l->r) > btheight((*tree)->l->l))
342 static void bbtrl(struct btree **tree)
344 struct btree *m, *l, *r;
346 if(btheight((*tree)->r->l) > btheight((*tree)->r->r))
358 static int ptrcmp(void *a, void *b)
367 int bbtreedel(struct btree **tree, void *item, int (*cmp)(void *, void *))
370 struct btree *s, **sp, *o;
376 if((c = cmp(item, (*tree)->d)) < 0) {
377 r = bbtreedel(&(*tree)->l, item, cmp);
379 r = bbtreedel(&(*tree)->r, item, cmp);
383 if(((*tree)->r != NULL) && ((*tree)->l != NULL)) {
386 while(s->l != NULL) {
394 } else if((*tree)->l != NULL) {
396 } else if((*tree)->r != NULL) {
405 if(btheight((*tree)->l) > btheight((*tree)->r) + 1)
407 if(btheight((*tree)->r) > btheight((*tree)->l) + 1)
413 void freebtree(struct btree **tree, void (*ffunc)(void *))
417 freebtree(&(*tree)->l, ffunc);
418 freebtree(&(*tree)->r, ffunc);
425 int bbtreeput(struct btree **tree, void *item, int (*cmp)(void *, void *))
432 *tree = szmalloc(sizeof(**tree));
437 if((c = cmp(item, (*tree)->d)) < 0)
438 r = bbtreeput(&(*tree)->l, item, cmp);
440 r = bbtreeput(&(*tree)->r, item, cmp);
444 if(btheight((*tree)->l) > btheight((*tree)->r) + 1)
446 if(btheight((*tree)->r) > btheight((*tree)->l) + 1)
451 void *btreeget(struct btree *tree, void *key, int (*cmp)(void *, void *))
460 c = cmp(key, tree->d);