| Adding dynamic CGI support. - geomyidae - A small C-based gopherd. | |
| git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfri… | |
| Log | |
| Files | |
| Refs | |
| Tags | |
| README | |
| LICENSE | |
| --- | |
| commit 6f4cbad45b4f91422cc14d1b843c754b234ffffe | |
| parent 72fa3a9a1750ffa0b5fc2f4fb33f7daafe57a368 | |
| Author: Christoph Lohmann <[email protected]> | |
| Date: Sat, 12 Mar 2011 20:19:25 +0100 | |
| Adding dynamic CGI support. | |
| Diffstat: | |
| M handlr.c | 77 ++++++++++++++++++++++++-----… | |
| M handlr.h | 4 ++-- | |
| M ind.c | 34 ++++++++++++++++++++++++++++-… | |
| M ind.h | 2 ++ | |
| 4 files changed, 95 insertions(+), 22 deletions(-) | |
| --- | |
| diff --git a/handlr.c b/handlr.c | |
| @@ -113,21 +113,8 @@ handlegph(int sock, char *file, char *port, char *base, ch… | |
| } else | |
| snprintf(addr, sizeof(addr), "%s", args); | |
| - | |
| for(i = 0; i < act->num; i++) { | |
| - if(!strncmp(act->n[i]->e[3], "server", 6)) { | |
| - free(act->n[i]->e[3]); | |
| - act->n[i]->e[3] = gstrdup(addr); | |
| - } | |
| - if(!strncmp(act->n[i]->e[4], "port", 4)) { | |
| - free(act->n[i]->e[4]); | |
| - act->n[i]->e[4] = gstrdup(port); | |
| - } | |
| - tprintf(sock, "%.1s%s\t%s\t%s\t%s\r\n", | |
| - act->n[i]->e[0], act->n[i]->e[1], | |
| - act->n[i]->e[2], act->n[i]->e[3], | |
| - act->n[i]->e[4]); | |
| - | |
| + printelem(sock, act->n[i], addr, port); | |
| freeelem(act->n[i]); | |
| act->n[i] = nil; | |
| } | |
| @@ -164,30 +151,86 @@ handlecgi(int sock, char *file, char *port, char *base, c… | |
| { | |
| char *p; | |
| - USED(port); | |
| USED(base); | |
| + USED(port); | |
| p = strrchr(file, '/'); | |
| if(p == nil) | |
| p = file; | |
| - dup2(sock, 1); | |
| + if(sear == nil) | |
| + sear = ""; | |
| + | |
| dup2(sock, 0); | |
| + dup2(sock, 1); | |
| dup2(sock, 2); | |
| + switch(fork()) { | |
| + case 0: | |
| + execl(file, p, sear, args, (char *)nil); | |
| + case -1: | |
| + break; | |
| + default: | |
| + wait(NULL); | |
| + shutdown(sock, SHUT_RDWR); | |
| + close(sock); | |
| + break; | |
| + } | |
| +} | |
| + | |
| +void | |
| +handledcgi(int sock, char *file, char *port, char *base, char *args, | |
| + char *sear) | |
| +{ | |
| + char *p, *ln, addr[512]; | |
| + int outpipe[2]; | |
| + Elems *el; | |
| + | |
| + USED(base); | |
| + | |
| + if(pipe(outpipe) < 0) | |
| + return; | |
| + | |
| + p = strrchr(file, '/'); | |
| + if(p == nil) | |
| + p = file; | |
| + | |
| + if(args == nil) { | |
| + if(gethostname(addr, sizeof(addr)) == -1) { | |
| + perror("gethostname"); | |
| + return; | |
| + } | |
| + } else | |
| + snprintf(addr, sizeof(addr), "%s", args); | |
| if(sear == nil) | |
| sear = ""; | |
| + dup2(sock, 0); | |
| + dup2(sock, 2); | |
| switch(fork()) { | |
| case 0: | |
| + dup2(outpipe[1], 1); | |
| + close(outpipe[0]); | |
| execl(file, p, sear, args, (char *)nil); | |
| case -1: | |
| break; | |
| default: | |
| + dup2(sock, 1); | |
| + close(outpipe[1]); | |
| + | |
| + while((ln = readln(outpipe[0])) != nil) { | |
| + el = getadv(ln); | |
| + if (el == nil) | |
| + continue; | |
| + | |
| + printelem(sock, el, addr, port); | |
| + freeelem(el); | |
| + } | |
| + tprintf(sock, "\r\n.\r\n\r\n"); | |
| + | |
| wait(NULL); | |
| shutdown(sock, SHUT_RDWR); | |
| close(sock); | |
| break; | |
| } | |
| } | |
| - | |
| diff --git a/handlr.h b/handlr.h | |
| @@ -6,8 +6,6 @@ | |
| #ifndef HANDLR_H | |
| #define HANDLR_H | |
| -#define nil NULL | |
| - | |
| void handledir(int sock, char *path, char *port, char *base, char *args, | |
| char *sear); | |
| void handlegph(int sock, char *file, char *port, char *base, char *args, | |
| @@ -16,5 +14,7 @@ void handlebin(int sock, char *file, char *port, char *base, … | |
| char *sear); | |
| void handlecgi(int sock, char *file, char *port, char *base, char *args, | |
| char *sear); | |
| +void handledcgi(int sock, char *file, char *port, char *base, char *args, | |
| + char *sear); | |
| #endif | |
| diff --git a/ind.c b/ind.c | |
| @@ -22,6 +22,7 @@ filetype type[] = { | |
| {"default", "0", handlebin}, | |
| {"gph", "1", handlegph}, | |
| {"cgi", "0", handlecgi}, | |
| + {"dcgi", "1", handledcgi}, | |
| {"bin", "9", handlebin}, | |
| {"tgz", "9", handlebin}, | |
| {"gz", "9", handlebin}, | |
| @@ -195,6 +196,17 @@ getadv(char *str) | |
| return ret; | |
| } | |
| +void | |
| +addindexs(Indexs *idx, Elems *el) | |
| +{ | |
| + | |
| + idx->num++; | |
| + idx->n = realloc(idx->n, sizeof(Elems) * idx->num); | |
| + idx->n[idx->num - 1] = el; | |
| + | |
| + return; | |
| +} | |
| + | |
| Indexs * | |
| scanfile(char *fname) | |
| { | |
| @@ -215,9 +227,7 @@ scanfile(char *fname) | |
| if(el == nil) | |
| continue; | |
| - ret->num++; | |
| - ret->n = realloc(ret->n, sizeof(Elems) * ret->num); | |
| - ret->n[ret->num - 1] = el; | |
| + addindexs(ret, el); | |
| el = nil; | |
| } | |
| close(fd); | |
| @@ -231,6 +241,24 @@ scanfile(char *fname) | |
| } | |
| void | |
| +printelem(int fd, Elems *el, char *addr, char *port) | |
| +{ | |
| + | |
| + if(!strncmp(el->e[3], "server", 6)) { | |
| + free(el->e[3]); | |
| + el->e[3] = gstrdup(addr); | |
| + } | |
| + if(!strncmp(el->e[4], "port", 4)) { | |
| + free(el->e[4]); | |
| + el->e[4] = gstrdup(port); | |
| + } | |
| + tprintf(fd, "%.1s%s\t%s\t%s\t%s\r\n", el->e[0], el->e[1], el->e[2], | |
| + el->e[3], el->e[4]); | |
| + | |
| + return; | |
| +} | |
| + | |
| +void | |
| tprintf(int fd, char *fmt, ...) | |
| { | |
| va_list fmtargs; | |
| diff --git a/ind.h b/ind.h | |
| @@ -35,6 +35,8 @@ void *gmallocz(int l, int d); | |
| char *gstrdup(char *str); | |
| Indexs *scanfile(char *fname); | |
| Elems *getadv(char *str); | |
| +void printelem(int fd, Elems *el, char *addr, char *port); | |
| +void addindexs(Indexs *idx, Elems *el); | |
| void addelem(Elems *e, char *s); | |
| void freeindex(Indexs *i); | |
| void freeelem(Elems *e); |