Commit Diff


commit - 3bd4a6dea08fc977e314877cefed1c6fdd6b1613
commit + f2f8eb35c86c4e1c1d858e782c864deac0511cd3
blob - cc6253a87732028a882fa4e58463565bd9d82732
blob + a866109d8595001d91cc300ee49c947625588558
--- gmid.h
+++ gmid.h
@@ -427,6 +427,7 @@ char		*utf8_nth(char*, size_t);
 /* iri.c */
 int		 parse_iri(char*, struct iri*, const char**);
 int		 serialize_iri(struct iri*, char*, size_t);
+int		 encode_path(char *, size_t, const char *);
 char		*pct_decode_str(char *);
 
 /* proxy.c */
blob - f34b800bae813b3cf0b3f839acabeb9754ba63bb
blob + 4224e6166e867cbd1c214fb6c504c684f40f21b0
--- iri.c
+++ iri.c
@@ -443,7 +443,44 @@ serialize_iri(struct iri *i, char *buf, size_t len)
 
 	return l < len;
 }
+
+int
+encode_path(char *buf, size_t len, const char *path)
+{
+	char *p = buf;
+	int a, b;
+
+	memset(buf, 0, len);
+	while (*path != '\0') {
+		if (len == 1)	/* NUL */
+			return -1;
 
+		if (unreserved(*path) ||
+		    sub_delimiters(*path) ||
+		    *path == '@' ||
+		    *path == ':' ||
+		    *path == '/') {
+			*p++ = *path++;
+			len--;
+		} else if (len < 4)
+			return -1;
+		else {
+			a = (*path & 0xF0) >> 4;
+			b = (*path & 0x0F);
+
+			p[0] = '%';
+			p[1] = a <= 9 ? ('0' + a) : ('7' + a);
+			p[2] = b <= 9 ? ('0' + b) : ('7' + b);
+
+			path++;
+			p += 3;
+			len -= 3;
+		}
+	}
+
+	return 0;
+}
+
 char *
 pct_decode_str(char *s)
 {
blob - c69c13daee56925c9114387cc7dd917ebab1ebaa
blob + 27227dd9a1e373033c048acdde32447e5ef3f5f0
--- server.c
+++ server.c
@@ -1070,6 +1070,7 @@ client_write(struct bufferevent *bev, void *d)
 {
 	struct client	*c = d;
 	struct evbuffer	*out = EVBUFFER_OUTPUT(bev);
+	char		 nam[PATH_MAX];
 	char		 buf[BUFSIZ];
 	ssize_t		 r;
 
@@ -1097,8 +1098,9 @@ client_write(struct bufferevent *bev, void *d)
 	case REQUEST_DIR:
 		/* TODO: handle big big directories better */
 		for (c->diroff = 0; c->diroff < c->dirlen; ++c->diroff) {
-			evbuffer_add_printf(out, "=> %s\n",
+			encode_path(nam, sizeof(nam),
 			    c->dir[c->diroff]->d_name);
+			evbuffer_add_printf(out, "=> ./%s\n", nam);
 			free(c->dir[c->diroff]);
 		}
 		free(c->dir);