tFormat text as HTML on the fly - phroxy - Gopher to HTTP proxy
 (HTM) git clone git://git.z3bra.org/phroxy.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 5f381215e10e7696ffcb418cbc0f2f1a5f4aedb5
 (DIR) parent 6399fbf8c0ea8bb09ad819e86c4393845b5e1472
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Thu, 24 Sep 2020 09:36:43 +0200
       
       Format text as HTML on the fly
       
       Diffstat:
         M config.def.h                        |       8 +++-----
         M phroxy.c                            |     102 +++++++++++++++----------------
       
       2 files changed, 51 insertions(+), 59 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       t@@ -1,14 +1,12 @@
        char *default_hole = "z3bra.org";
        const char *http_host = "z3bra.org";
       -const char *htmlfmt =
       +const char *head =
                "<!DOCTYPE HTML>\n"
                "<html><head>\n"
                "<meta charset=\"utf-8\">"
                "<meta name=\"viewport\" content=\"width=device-width\">"
       -        "<style>body { white-space: pre; }</style>"
                "<title>gopher proxy</title>\n"
                "</head>\n"
       -        "<body>\n"
       -        "%s\n"
       -        "</body></html>\n";
       +        "<body>\n";
       +const char *foot = "</body></html>\n";
        
 (DIR) diff --git a/phroxy.c b/phroxy.c
       t@@ -221,17 +221,13 @@ printheaders(char *ctype)
                printf("Connection: close\r\n");
        }
        
       -char *
       -htmlize(char *data, size_t *bodysize)
       +int
       +printmenu(int fd, char *data)
        {
       -        size_t alen, blen;
       -        char *body = NULL;
                char i, *p, a[LINE_MAX], *f[4];
                char *ifmt = "%s\n";
                char *afmt = "<a href='http://%s/%s:%s/%c%s'>%s (%s)</a>\n";
        
       -        blen = 0;
       -        body = NULL;
                p = data;
        
                while((p = strsep(&data, "\n"))) {
       t@@ -252,57 +248,60 @@ htmlize(char *data, size_t *bodysize)
                                snprintf(a, sizeof(a), afmt, http_host, f[2], f[3], i, f[1], f[0], itemname(i));
                        }
        
       -                alen = strnlen(a, sizeof(a));
       -                body = realloc(body, blen + alen + 1);
       -                memcpy(body + blen, a, alen);
       -                blen += alen;
       -                body[blen] = '\0';
       +                write(fd, a, strlen(a));
                }
        
       -        if (bodysize)
       -                *bodysize = strnlen(body, blen);
       -
       -        return body;
       +        return 0;
        }
        
       -char *
       -htmlwrap(char *data, size_t len, size_t *htmlsize)
       +int
       +printhtml(int fd, const char *data, size_t len)
        {
       -        size_t hlen;
       -        char *html = NULL;
       -
       -        hlen = strlen(htmlfmt) + len;
       -        html = malloc(hlen);
       -        if (!html)
       -                return NULL;
       +        size_t r, n;
       +        const char *s, *e;
        
       -        snprintf(html, hlen, htmlfmt, data);
       +        n = 0;
       +        while(n < len) {
       +                s = data + n;
       +                e = strstr(s, "\n\n");
       +                r = e ? (size_t)(e - s) : strlen(s);
        
       -        if (htmlsize)
       -                *htmlsize = strnlen(html, hlen);
       +                if (!r)
       +                        break;
        
       -        return html;
       +                n += r + 2; /* go past "\n\n" */
       +                write(fd, "<pre>", 5);
       +                write(fd, s, r);
       +                write(fd, "</pre>\n", 7);
       +        }
       +        return 0;
        }
        
        int
        serveitem(char item, char *data, size_t len)
        {
       -        char *send, *html;
       +        char *send;
                int sent;
        
       +
       +        if (!contenttype(item)) {
       +                printhttp(415);
       +                return 1;
       +        }
       +
       +        printf("HTTP/1.1 200 OK\r\n");
       +        printheaders(contenttype(item));
       +
                switch(item) {
       -        case '7': // search
                case '1': // menu
       -                html = htmlize(data, &len);
       -                free(data);
       -                data = html;
       -                /* FALLTHROUGH */
       -
                case '0': // text
       -                html = htmlwrap(data, len, &len);
       -                free(data);
       -                data = html;
       +                printf("\r\n");
       +                write(1, head, strlen(head));
       +                if (item == '1') printmenu(1, data);
       +                if (item == '0') printhtml(1, data, len);
       +                write(1, foot, strlen(foot));
                        break;
       +
                case '4': // BinHexed Macintosh file
                case '5': // DOS binary archive of some sort
                case '6': // uuencoded
       t@@ -310,8 +309,18 @@ serveitem(char item, char *data, size_t len)
                case 'g': // gif
                case 'I': // image
                case 'h': // http redirect
       +                printf("Content-Length: %ld\r\n", len);
       +                printf("\r\n");
       +                send = data;
       +                while (len > 0) {
       +                        if ((sent = write(1, send, len)) < 0)
       +                                return 1;
       +                        len -= sent;
       +                        send += sent;
       +                }
                        break;
        
       +        case '7': // search
                case '2': // CSO phone-book server
                case '3': // Error
                case '8': // telnet session.
       t@@ -319,26 +328,11 @@ serveitem(char item, char *data, size_t len)
                case '+': // mirror link
                default:
                        /* IGNORE */
       -                printhttp(415);
                        break;
                }
        
       -        printf("HTTP/1.1 200 OK\r\n");
       -        printheaders(contenttype(item));
       -
       -        printf("Content-Length: %ld\r\n", len);
       -        printf("\r\n");
       -        fflush(stdout);
       -
       -        send = data;
       -        while (len > 0) {
       -                if ((sent = write(1, send, len)) < 0)
       -                        return 1;
       -                len -= sent;
       -                send += sent;
       -        }
       -
                free(data);
       +        fflush(stdout);
        
                return 0;
        }