Fix recv and gopher+ redirects. Add gopher+ loglevel. - geomyidae - A small C-based gopherd.
git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/
Log
Files
Refs
Tags
README
LICENSE
---
commit 4f4128c66e521eb364bd294f4ba82074b0587ff1
parent 66ca5bb6c50e73fa70c23fd831b021759a22aa06
Author: Christoph Lohmann <20h@r-36.net>
Date:   Fri, 22 Nov 2019 13:54:11 +0100

Fix recv and gopher+ redirects. Add gopher+ loglevel.

Diffstat:
  M geomyidae.8                         |       7 ++++---
  M main.c                              |      30 ++++++++++++++++++++++--------

2 files changed, 26 insertions(+), 11 deletions(-)
---
diff --git a/geomyidae.8 b/geomyidae.8
@@ -111,7 +111,7 @@ Don't perform reverse lookups.
 Specify file where log output is written (no default)
 .
 .It Fl v Ar loglevel
-Set the logging level (default: 15)
+Set the logging level (default: 37)
 .
 .Bd -literal
 Loglevels:
@@ -121,9 +121,10 @@ Loglevels:
         4  - HTTP redirects
         8  - errors (e.g., not found)
         16 - client connections
+        32 - gopher+ redirects
   e.g.:
-        1 + 2 + 4 + 8 = 15
-        (files + directories + HTTP + errors)
+        1 + 2 + 4 + 8 + 32 = 37
+        (files + directories + HTTP + errors + gopher+)
 .Ed
 .
 .It Fl b Ar base
diff --git a/main.c b/main.c
@@ -36,11 +36,12 @@ enum {
         DIRS        = 2,
         HTTP        = 4,
         ERRORS        = 8,
-        CONN        = 16
+        CONN        = 16,
+        GPLUS        = 32
 };
 
 int glfd = -1;
-int loglvl = 15;
+int loglvl = 37;
 int *listfds = NULL;
 int nlistfds = 0;
 int revlookup = 1;
@@ -120,7 +121,7 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
 {
         struct stat dir;
         char recvc[1025], recvb[1025], path[1025], *args, *sear, *c;
-        int len, fd, i;
+        int len, fd, i, retl, maxrecv;
         filetype *type;
 
         memset(&dir, 0, sizeof(dir));
@@ -128,12 +129,23 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
         memset(recvc, 0, sizeof(recvc));
         args = NULL;
 
-        len = recv(sock, recvb, sizeof(recvb)-1, 0);
-        if (len <= 0) {
-                if (len < 0)
-                        perror("recv");
+        len = 0;
+        maxrecv = sizeof(recvb);
+        /*
+         * Force at least one byte per packet. Limit, so the server
+         * cannot be put into DoS via zero-length packets.
+         */
+        do {
+                retl = recv(sock, recvb+len, sizeof(recvb)-1-len, 0);
+                if (retl <= 0) {
+                        if (retl < 0)
+                                perror("recv");
+                        break;
+                }
+                len += retl;
+        } while (recvb[len-1] != '\n' && --maxrecv > 0);
+        if (len <= 0)
                 return;
-        }
 
         c = strchr(recvb, '\r');
         if (c)
@@ -154,6 +166,8 @@ handlerequest(int sock, char *base, char *ohost, char *port, char *clienth,
                  * CRAP.
                  */
                 if (*sear == '+' || *sear == '$' || *sear == '!' || *sear == '\0') {
+                        if (loglvl & GPLUS)
+                                logentry(clienth, clientp, recvb, "gopher+ redirect");
                         dprintf(sock, "+-2\r\n");
                         dprintf(sock, "+INFO: 1gopher+\t\t%s\t%s\r\n",
                                         ohost, port);