shithub: gopher

Download patch

ref: 0ce20bd09df8ea923078920978339a42d2e98092
parent: 3cb37109edadc4df79607f55d06f3be7556d89d5
author: telephil9 <telephil9@gmail.com>
date: Sat Nov 28 01:21:14 EST 2020

Proper gopher:// url handling (thanks nicolagi)

As per RFC4266, the gopher url scheme is supposed to include
the gophertype before the selector.
Add a new urltolink() function to properly parse urls accordingly.
Change url creation functions to include the gophertype.

--- a/gopher.c
+++ b/gopher.c
@@ -242,6 +242,37 @@
 	flushimage(display, 1);
 }
 
+Link*
+urltolink(char *url)
+{
+	char *a, *sel, *hostport, *p;
+	int type;
+	Link *l;
+
+	a = strdup(url);
+	hostport = a;
+	if(strncmp(a, "gopher://", 9) == 0)
+		hostport += 9;
+	p = strchr(hostport, '/');
+	if(p){
+		*p++ = 0;
+		type = *p ? seltype(*p++) : Tmenu;
+		sel = *p ? p : "";
+	}else{
+		type = Tmenu;
+		sel = "";
+	}
+	p = strchr(hostport, ':');
+	if(p){
+		*p++ = 0;
+		l = mklink(netmkaddr(hostport, "tcp", p), sel, type);
+	}else{
+		l = mklink(netmkaddr(hostport, "tcp", "70"), sel, type);
+	}
+	free(a);
+	return l;
+}
+
 char*
 linktourl(Link *l)
 {
@@ -251,11 +282,11 @@
 	a = strdup(l->addr);
 	n = getfields(a, f, 3, 0, "!");
 	if(n != 3)
-		s = smprint("Url: gopher://%s%s", l->addr, l->sel);
+		s = smprint("Url: gopher://%s/%d%s", l->addr, l->type, l->sel);
 	else if(atoi(f[2])!=70)
-		s = smprint("Url: gopher://%s:%s%s", f[1], f[2], l->sel);
+		s = smprint("Url: gopher://%s:%s/%d%s", f[1], f[2], l->type, l->sel);
 	else
-		s = smprint("Url: gopher://%s%s", f[1], l->sel);
+		s = smprint("Url: gopher://%s/%d%s", f[1], l->type, l->sel);
 	free(a);	
 	return s;	
 }
@@ -344,12 +375,6 @@
 }
 
 void
-visitaddr(char *addr)
-{
-	visit(mklink(netmkaddr(addr, "tcp", "70"), "", Tmenu), 1);
-}
-
-void
 plumburl(char *u)
 {
 	int fd;
@@ -610,6 +635,8 @@
 void
 entryhit(Panel *p, char *t)
 {
+	Link *l;
+
 	USED(p);
 	switch(strlen(t)){
 	case 0:
@@ -631,7 +658,11 @@
 		}
 		break;
 	default:
-		visitaddr(t);
+		l = urltolink(t);
+		if(l==nil)
+			message("invalid url %s", t);
+		else
+			visit(l, 1);
 	}
 	plinitentry(entryp, PACKN|FILLX, 0, "", entryhit);
 	pldraw(root, screen);
@@ -727,6 +758,7 @@
 main(int argc, char *argv[])
 {
 	Event e;
+	Link *l;
 	char *url;
 
 	if(argc == 2)
@@ -740,7 +772,11 @@
 	plinit(screen->depth);
 	loadicons();
 	mkpanels();
-	visitaddr(url);
+	l = urltolink(url);
+	if(l==nil)
+		message("invalid url %s", url);
+	else
+		visit(l, 1);
 	eresized(0);
 	for(;;){
 		switch(event(&e)){