URI: 
       Implement some CGI variables for gopher. - geomyidae - A small C-based gopherd.
  HTML git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
   DIR commit 67eb195e1924b652b193e6332c1ce8f00fd1f2c9
   DIR parent f26ccad8ca8d0f79f7195f6871bb2ceac816ccfa
  HTML Author: Christoph Lohmann <20h@r-36.net>
       Date:   Fri, 26 Jan 2018 13:44:53 +0100
       
       Implement some CGI variables for gopher.
       
       I need this for having a nice IP handler on bitreich.org.
       
       Diffstat:
         M handlr.c                            |      20 +++++++++++++-------
         M handlr.h                            |      23 ++++++++++++++++++-----
         M ind.c                               |      40 +++++++++++++++++++++++++++++++
         M ind.h                               |       5 ++++-
         M main.c                              |       5 +++--
       
       5 files changed, 78 insertions(+), 15 deletions(-)
       ---
   DIR diff --git a/handlr.c b/handlr.c
       @@ -21,7 +21,7 @@
        
        void
        handledir(int sock, char *path, char *port, char *base, char *args,
       -                char *sear, char *ohost)
       +                char *sear, char *ohost, char *chost)
        {
                char *pa, *file, *e, *par, *b;
                struct dirent **dirent;
       @@ -78,7 +78,7 @@ handledir(int sock, char *path, char *port, char *base, char *args,
        
        void
        handlegph(int sock, char *file, char *port, char *base, char *args,
       -                char *sear, char *ohost)
       +                char *sear, char *ohost, char *chost)
        {
                Indexs *act;
                int i, ret = 0;
       @@ -102,7 +102,7 @@ handlegph(int sock, char *file, char *port, char *base, char *args,
        
        void
        handlebin(int sock, char *file, char *port, char *base, char *args,
       -                char *sear, char *ohost)
       +                char *sear, char *ohost, char *chost)
        {
                int fd;
        
       @@ -122,7 +122,7 @@ handlebin(int sock, char *file, char *port, char *base, char *args,
        
        void
        handlecgi(int sock, char *file, char *port, char *base, char *args,
       -                char *sear, char *ohost)
       +                char *sear, char *ohost, char *chost)
        {
                char *p, *path;
        
       @@ -157,7 +157,10 @@ handlecgi(int sock, char *file, char *port, char *base, char *args,
                                        break;
                        }
        
       -                if (execl(file, p, sear, args, ohost, port, (char *)nil) == -1) {
       +                setcgienviron(p, file, port, base, args, sear, ohost, chost);
       +
       +                if (execl(file, p, sear, args, ohost, port,
       +                                (char *)nil) == -1) {
                                perror("execl");
                                _exit(1);
                        }
       @@ -173,7 +176,7 @@ handlecgi(int sock, char *file, char *port, char *base, char *args,
        
        void
        handledcgi(int sock, char *file, char *port, char *base, char *args,
       -                char *sear, char *ohost)
       +                char *sear, char *ohost, char *chost)
        {
                FILE *fp;
                char *p, *path, *ln = nil;
       @@ -216,7 +219,10 @@ handledcgi(int sock, char *file, char *port, char *base, char *args,
                                        break;
                        }
        
       -                if (execl(file, p, sear, args, ohost, port, (char *)nil) == -1) {
       +                setcgienviron(p, file, port, base, args, sear, ohost, chost);
       +
       +                if (execl(file, p, sear, args, ohost, port,
       +                                (char *)nil) == -1) {
                                perror("execl");
                                _exit(1);
                        }
   DIR diff --git a/handlr.h b/handlr.h
       @@ -6,15 +6,28 @@
        #ifndef HANDLR_H
        #define HANDLR_H
        
       +/*
       + * Handler API definition
       + *
       + * path .... path to the script relative from base
       + * port .... port which the script should use when defining menu items
       + *             (See -o and -p in geomyidae(8))
       + * base .... base path of geomyidae ("" in case of chroot)
       + * args .... query string parsed after »script?query«
       + * sear .... search part of request (»selector\tsearch\r\n«)
       + * ohost ... host of geomiydae (See -h in geomyidae(8))
       + * chost ... IP of the client sending a request
       + */
       +
        void handledir(int sock, char *path, char *port, char *base, char *args,
       -                        char *sear, char *ohost);
       +                        char *sear, char *ohost, char *chost);
        void handlegph(int sock, char *file, char *port, char *base, char *args,
       -                        char *sear, char *ohost);
       +                        char *sear, char *ohost, char *chost);
        void handlebin(int sock, char *file, char *port, char *base, char *args,
       -                        char *sear, char *ohost);
       +                        char *sear, char *ohost, char *chost);
        void handlecgi(int sock, char *file, char *port, char *base, char *args,
       -                        char *sear, char *ohost);
       +                        char *sear, char *ohost, char *chost);
        void handledcgi(int sock, char *file, char *port, char *base, char *args,
       -                        char *sear, char *ohost);
       +                        char *sear, char *ohost, char *chost);
        
        #endif
   DIR diff --git a/ind.c b/ind.c
       @@ -419,3 +419,43 @@ reverselookup(char *host)
                return rethost;
        }
        
       +void
       +setcgienviron(char *file, char *path, char *port, char *base, char *args,
       +                char *sear, char *ohost, char *chost)
       +{
       +        char *s;
       +
       +        unsetenv("AUTH_TYPE");
       +        unsetenv("CONTENT_LENGTH");
       +        unsetenv("CONTENT_TYPE");
       +        setenv("GATEWAY_INTERFACE", "CGI/1.1", 1);
       +        /* TODO: Separate, if run like rest.dcgi. */
       +        setenv("PATH_INFO", path, 1);
       +
       +        s = smprintf("%s/%s", base, path);
       +        setenv("PATH_TRANSLATED", s, 1);
       +        free(s);
       +
       +        setenv("QUERY_STRING", args, 1);
       +        setenv("REMOTE_ADDR", chost, 1);
       +        /*
       +         * Don't do a reverse lookup on every call. Only do when needed, in
       +         * the script. The RFC allows us to set the IP to the value.
       +         */
       +        setenv("REMOTE_HOST", chost, 1);
       +        unsetenv("REMOTE_IDENT");
       +        unsetenv("REMOTE_USER");
       +        /*
       +         * Only GET is possible in gopher. POST emulation would be really
       +         * ugly.
       +         */
       +        setenv("REQUEST_METHOD", "GET", 1);
       +        setenv("SCRIPT_NAME", file, 1);
       +        setenv("SERVER_NAME", ohost, 1);
       +        setenv("SERVER_PORT", port, 1);
       +        setenv("SERVER_PROTOCOL", "gopher/1.0", 1);
       +        setenv("SERVER_SOFTWARE", "geomyidae", 1);
       +
       +        setenv("X_GOPHER_SEARCH", sear, 1);
       +}
       +
   DIR diff --git a/ind.h b/ind.h
       @@ -27,7 +27,8 @@ typedef struct filetype filetype;
        struct filetype {
                char *end;
                char *type;
       -        void (* f)(int, char *, char *, char *, char *, char *, char *);
       +        void (* f)(int, char *, char *, char *, char *, char *, char *,
       +                char *);
        };
        
        filetype *gettype(char *filename);
       @@ -47,6 +48,8 @@ int initlogging(char *logf);
        void stoplogging(int fd);
        char *smprintf(char *fmt, ...);
        char *reverselookup(char *host);
       +void setcgienviron(char *file, char *path, char *port, char *base,
       +                char *args, char *sear, char *ohost, char *chost);
        
        #endif
        
   DIR diff --git a/main.c b/main.c
       @@ -192,10 +192,11 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
                        if (c == nil)
                                c = path;
                        type = gettype(c);
       -                type->f(sock, path, port, base, args, sear, ohost);
       +                type->f(sock, path, port, base, args, sear, ohost, clienth);
                } else {
                        if (S_ISDIR(dir.st_mode)) {
       -                        handledir(sock, path, port, base, args, sear, ohost);
       +                        handledir(sock, path, port, base, args, sear, ohost,
       +                                clienth);
                                if (loglvl & DIRS) {
                                        logentry(clienth, clientp, recvc,
                                                                "dir listing");