shithub: castor9

Download patch

ref: 059574a9bdc29c5381e12ed18158f05320ad7cd7
parent: 0fcf30342402aff054a8106bb08a30f670ad62c0
author: Julien Blanchard <julien@typed-hole.org>
date: Thu Oct 28 10:42:30 EDT 2021

Handle local files, thanks binarycat!

--- a/castor.c
+++ b/castor.c
@@ -47,6 +47,7 @@
 void addbookmark(void);
 void showbookmarks(void);
 void message(char *s, ...);
+void visit(Url *url);
 
 Panel *root;
 Panel *backp;
@@ -58,6 +59,8 @@
 Mouse *mouse;
 Hist *hist = nil;
 int preformatted = 0;
+char *bookmarkspath;
+Url *filebase;
 
 enum
 {
@@ -354,10 +357,38 @@
 }
 
 void
+geminishow(Ctx *c, Biobuf *body)
+{
+	char *line;
+	Hist *h;
+	
+	h = malloc(sizeof *h);
+	if(h == nil)
+		sysfatal("malloc: %r");
+
+	while((line = Brdstr(body, '\n', 0)) != nil){
+		if(strbeg(line, "=>") == 0){
+			renderlink(c, line);					
+		}else{
+			rendertext(c, line);
+		}
+		free(line);
+	}
+
+	Bflush(body);
+
+	h->p = hist;
+	h->n = nil;
+	h->c = c;
+	hist = h;
+
+	show(c);
+}
+
+void
 geminiget(Url *url)
 {
 	int fd;
-	char *line;
 	Biobuf body;
 
 	Ctx *c;
@@ -372,11 +403,6 @@
 		sysfatal("malloc: %r");
 	r->url = url;
 
-	Hist *h;
-	h = malloc(sizeof *h);
-	if(h == nil)
-		sysfatal("malloc: %r");
-
 	plrtstr(&c->text, 1000000, 0, 0, font, strdup(" "), 0, 0);
 
 	message("loading %s...", urlstr(url));
@@ -405,23 +431,7 @@
 			page(url);
 			resettitle();
 		}else{
-			while((line = Brdstr(&body, '\n', 0)) != nil){
-				if(strbeg(line, "=>") == 0){
-					renderlink(c, line);					
-				}else{
-					rendertext(c, line);
-				}
-				free(line);
-			}
-
-			Bflush(&body);
-
-			h->p = hist;
-			h->n = nil;
-			h->c = c;
-			hist = h;
-
-			show(c);
+			geminishow(c, &body);
 		}
 		break;
 	case 30:
@@ -607,8 +617,12 @@
 createbookmarks(void)
 {
 	int fd;
-	if((fd = create(getbookmarkspath(), OWRITE, 0600 | DMAPPEND)) < 0)
-		sysfatal("create(bookmarks): %r");
+
+	if((fd = open(bookmarkspath, OWRITE)) < 0)
+		sysfatal("open(bookmarks): %r");
+	if(seek(fd, 0, 2)<0)
+		sysfatal("seek(bookmarks): %r");	
+		
 	return fd;
 }
 
@@ -615,44 +629,7 @@
 void
 showbookmarks(void)
 {
-	char *line;
-	Biobuf *bfile;
-
-	bfile = Bopen(getbookmarkspath(), OREAD);
-	if(bfile==nil){
-		message("You must bookmark a page first!");
-		return;
-	}
-
-	Ctx *c;
-	c = malloc(sizeof *c);
-	if(c==nil)
-		sysfatal("malloc: %r");
-	c->text = nil;
-	c->url = urlparse(nil, "file://bookmarks");
-
-	Hist *h;
-	h = malloc(sizeof *h);
-	if(h == nil)
-		sysfatal("malloc: %r");
-
-	plrtstr(&c->text, 1000000, 0, 0, font, strdup(" "), 0, 0);
-
-	message("loading bookmarks...");
-	
-	while((line = Brdstr(bfile, '\n', 0)) != nil){
-		renderlink(c, line);
-		free(line);
-	}
-
-	Bflush(bfile);
-
-	h->p = hist;
-	h->n = nil;
-	h->c = c;
-	hist = h;
-
-	show(c);
+	visit(urlparse(filebase, bookmarkspath));
 }
 
 void
@@ -672,10 +649,10 @@
 	if(strlen(t) == 0)
 		return;
 
-	if(strbeg(t, "gemini://") != 0)
+	if(strchr(t, ':') == 0)
 		t = smprint("gemini://%s", t);
 			
-	geminiget(urlparse(nil, t));
+	visit(urlparse(currentbaseurl(), t));
 }
 
 void
@@ -713,12 +690,8 @@
 		}
 		next_url = urlparse(nil, n);
 	}
-
-	if(strcmp(next_url->scheme, "gemini") == 0){
-		geminiget(next_url);
-	}else{
-		plumburl(next_url);
-	}
+	
+	visit(next_url);
 }
 
 void 
@@ -797,6 +770,30 @@
 }
 
 void
+visit(Url *url)
+{
+	if(strcmp(url->scheme, "gemini") == 0){
+		geminiget(url);
+	}else if(strcmp(url->scheme, "file") == 0){
+		Ctx *c;
+		Biobuf* b;
+		
+		c = malloc(sizeof *c);
+		if(c == nil)
+			sysfatal("malloc: %r");
+		c->text = nil;
+		c->url = url;
+		plrtstr(&c->text, 1000000, 0, 0, font, strdup(" "), 0, 0);
+		b = Bopen(url->path, OREAD);
+		if(b == nil)
+			sysfatal("open: %r");
+		geminishow(c, b);
+	}else{
+		plumburl(url);
+	}
+}
+
+void
 main(int argc, char *argv[])
 {
 	Event e;
@@ -803,15 +800,19 @@
 	Url *url;
 	enum { Eplumb = 128 };
 	Plumbmsg *pm;
-	if(argc == 2)
-		if(strbeg(argv[1], "gemini://") != 0){
+	char buf[256];
+	
+	filebase = urlparse(nil, smprint("file://%s/%s/", getenv("sysname"),getwd(buf, sizeof buf)));
+	argv0 = argv[0];
+	if(argc == 2){
+		if(strchr(argv[1], ':') || access(argv[1], AEXIST) == 0)
+			url = urlparse(filebase, argv[1]);
+		else
 			url = urlparse(nil, smprint("gemini://%s", argv[1]));
-		}else{
-			url = urlparse(nil, argv[1]);
-		}
-	else
+	}else
 		url = urlparse(nil, "gemini://gemini.circumlunar.space/capcom/");
-
+	if(url == nil)
+		sysfatal("bad url");
 	quotefmtinstall();
 	fmtinstall('U', Ufmt);
 	fmtinstall('N', Nfmt);
@@ -819,6 +820,7 @@
 	fmtinstall('E', Efmt);
 	fmtinstall('[', encodefmt);
 	fmtinstall('H', encodefmt);
+	bookmarkspath = getbookmarkspath();
 
 	if(initdraw(nil, nil, "gemini")<0)
 		sysfatal("initdraw: %r");
@@ -825,7 +827,7 @@
 	einit(Emouse|Ekeyboard);
 	plinit(screen->depth);
 	mkpanels();
-	geminiget(url);
+	visit(url);
 	eresized(0);
 	eplumb(Eplumb, "gemini");
 	for(;;){
@@ -833,7 +835,7 @@
 		case Eplumb:
 			pm = e.v;
 			if(pm->ndata > 0){
-				geminiget(urlparse(nil, pm->data));
+				visit(urlparse(nil, pm->data));
 			}
 			plumbfree(pm);
 			break;