geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

commit 6f4cbad45b4f91422cc14d1b843c754b234ffffe
parent 72fa3a9a1750ffa0b5fc2f4fb33f7daafe57a368
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sat, 12 Mar 2011 20:19:25 +0100

Adding dynamic CGI support.

Diffstat:
handlr.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
handlr.h | 4++--
ind.c | 34+++++++++++++++++++++++++++++++---
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, char *args, } 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, char *args, { 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 *args, 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);