shithub: riscv

Download patch

ref: 24d69465a3024b5a74701af180365c6e27b93903
parent: 205a39474c0a7ec55bdde53612db8f704779fbf2
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Thu Oct 13 02:20:14 EDT 2011

mothra: refactor url saving, handle unknown content type as file download

--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -389,6 +389,26 @@
 		}
 	}
 }
+Cursor confirmcursor={
+	0, 0,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
+	0x00, 0x0E, 0x07, 0x1F, 0x03, 0x17, 0x73, 0x6F,
+	0xFB, 0xCE, 0xDB, 0x8C, 0xDB, 0xC0, 0xFB, 0x6C,
+	0x77, 0xFC, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
+	0x94, 0xA6, 0x63, 0x3C, 0x63, 0x18, 0x94, 0x90,
+};
+int confirm(int b){
+	Mouse down, up;
+	esetcursor(&confirmcursor);
+	do down=emouse(); while(!down.buttons);
+	do up=emouse(); while(up.buttons);
+	donecurs();
+	return down.buttons==(1<<(b-1));
+}
 void message(char *s, ...){
 	static char buf[1024];
 	char *out;
@@ -497,37 +517,60 @@
 	do ++s; while(*s==' ' || *s=='\t');
 	return s;
 }
-void save(Url *url, char *name){
-	int ofd, ifd, n;
+void save(int ifd, char *name){
 	char buf[4096];
-	ofd=create(name, OWRITE, 0666);
-	if(ofd==-1){
+	int ofd;
+	if(ifd < 0){
 		message("save: %s: %r", name);
 		return;
 	}
-	esetcursor(&patientcurs);
-	ifd=urlopen(url, GET, 0);
-	donecurs();
-	if(ifd==-1){
-		message("save: %s: %r", selection->fullname);
-		close(ofd);
+	ofd=create(name, OEXCL|OWRITE, 0666);
+	if(ofd < 0){
+		message("save: %s: %r", name);
+		return;
 	}
-	switch(rfork(RFNOTEG|RFFDG|RFPROC|RFNOWAIT)){
+	switch(rfork(RFNOTEG|RFNAMEG|RFFDG|RFPROC|RFNOWAIT)){
 	case -1:
-		message("Can't fork -- please wait");
-		esetcursor(&patientcurs);
-		while((n=read(ifd, buf, 4096))>0)
-			write(ofd, buf, n);
-		donecurs();
+		message("Can't fork: %r");
 		break;
 	case 0:
-		while((n=read(ifd, buf, 4096))>0)
-			write(ofd, buf, n);
-		if(n==-1) fprint(2, "save: %s: %r\n", url->fullname);
-		_exits(0);
+		snprint(buf, sizeof(buf), "-pid %d", getpid());
+		if(newwindow(buf) != -1){
+			int blk, cfd, n;
+			vlong off;
+
+			close(1); open("/dev/cons", OWRITE);
+			if((cfd = open("/dev/label", OWRITE)) >= 0){
+				fprint(cfd, "save %s", name);
+				close(cfd);
+			}
+			if((cfd = open("/dev/wctl", OWRITE)) >= 0){
+				fprint(cfd, "scroll\n");
+				close(cfd);
+			}
+			off = 0;
+			blk = 0;
+			werrstr("");
+			for(;;){
+				if((blk++ % 4) == 0){
+					if(off > 0)
+						print("\n");
+					print("%s: ", name);
+				}
+				if((n=read(ifd, buf, sizeof(buf))) <= 0)
+					break;
+				if(write(ofd, buf, n) != n)
+					break;
+				off += n;
+				print("%lldK... ", off/1024);
+			}
+			print("%r\n");
+		}
+		exits(0);
 	}
 	close(ifd);
 	close(ofd);
+	donecurs();
 }
 void screendump(char *name, int full){
 	Image *b;
@@ -553,6 +596,26 @@
 }
 
 /*
+ * convert a url into a local file name.
+ */
+char *urltofile(Url *url){
+	char *name, *slash;
+	if(url == nil)
+		return nil;
+	if(url->fullname[0])
+		name = url->fullname;
+	else if(url->reltext[0])
+		name = url->reltext;
+	else
+		name = "/";
+	if(slash = strrchr(name, '/'))
+		name = slash+1;
+	if(name[0] == 0)
+		name = "index";
+	return name;
+}
+
+/*
  * user typed a command.
  */
 void docmd(Panel *p, char *s){
@@ -562,7 +625,7 @@
 	 * Non-command does a get on the url
 	 */
 	if(s[0]!='\0' && s[1]!='\0' && s[1]!=' ')
-		geturl(s, GET, 0, 1, 0);
+		geturl(s, GET, 0, 0, 0);
 	else switch(s[0]){
 	default:
 		message("Unknown command %s, type h for help", s);
@@ -576,11 +639,11 @@
 		s = arg(s);
 		if(*s=='\0'){
 			if(selection)
-				geturl(selection->fullname, GET, 0, 1, 0);
+				geturl(selection->fullname, GET, 0, 0, 0);
 			else
 				message("no url selected");
 		}
-		else geturl(s, GET, 0, 1, 0);
+		else geturl(s, GET, 0, 0, 0);
 		break;
 	case 'j':
 		s = arg(s);
@@ -612,17 +675,15 @@
 		break;
 	case 's':
 		s = arg(s);
-		if(*s=='\0'){
-			if(selection){
-				s=strrchr(selection->fullname, '/');
-				if(s) s++;
-			}
+		if(selection){
+			if(s==0 || *s=='\0')
+				s = urltofile(selection);
 			if(s==0 || *s=='\0'){
 				message("Usage: s file");
 				break;
 			}
+			save(urlopen(selection, GET, 0), s);
 		}
-		save(selection, s);
 		break;
 	case 'q':
 		draw(screen, screen->r, display->white, 0, ZP);
@@ -633,7 +694,7 @@
 }
 void hiturl(int buttons, char *url, int map){
 	switch(buttons){
-	case 1: geturl(url, GET, 0, 1, map); break;
+	case 1: geturl(url, GET, 0, 0, map); break;
 	case 2: selurl(url); break;
 	case 4: message("Button 3 hit on url can't happen!"); break;
 	}
@@ -655,18 +716,6 @@
 }
 
 /*
- * convert a url into a local file name.
- */
-char *urltofile(char *url){
-	char *slash;
-	if(slash = strrchr(url, '/'))
-		url = slash+1;
-	if(url[0] == 0)
-		return "index";
-	return url;
-}
-
-/*
  * Follow an html link
  */
 void dolink(Panel *p, int buttons, Rtext *word){
@@ -679,21 +728,14 @@
 	a=word->user;
 	if(a == nil || a->image == nil && a->link == nil)
 		return;
-	if(mothmode){
-		seturl(&u, a->image ? a->image : a->link, current->url->fullname);
-		if(buttons == 1){
-			save(&u, file=urltofile(u.reltext));
-			message("saved %s", file);
-		} else if(buttons == 2)
-			hiturl(buttons, u.reltext, 0);
-		return;
-	}
-	if(a->ismap){
+	if(mothmode)
+		hiturl(buttons, a->image ? a->image : a->link, 0);
+	else if(a->ismap){
 		yoffs=plgetpostextview(p);
 		coord=subpt(subpt(mouse.xy, word->r.min), p->r.min);
 		snprint(mapurl, sizeof(mapurl), "%s?%d,%d", a->link, coord.x, coord.y+yoffs);
 		hiturl(buttons, mapurl, 1);
-	}else
+	} else
 		hiturl(buttons, a->link ? a->link : a->image, 0);
 }
 
@@ -755,18 +797,6 @@
 	plrtfree(tt);
 }
 
-void popwin(char *cmd){
-	flushimage(display, 1);
-	switch(rfork(RFFDG|RFPROC|RFNOWAIT)){
-	case -1:
-		message("sorry, can't fork to %s", cmd);
-		break;
-	case 0:
-		execl("/bin/window", "window", "100 100 800 800", "rc", "-c", cmd, 0);
-		_exits(0);
-	}
-}
-
 int readstr(char *buf, int nbuf, char *base, char *name)
 {
 	char path[128];
@@ -936,9 +966,9 @@
 /*
  * get the file at the given url
  */
-void geturl(char *urlname, int method, char *body, int cache, int map){
+void geturl(char *urlname, int method, char *body, int plumb, int map){
 	int i, fd, typ;
-	char cmd[NNAME];
+	char *file, cmd[NNAME];
 	int pfd[2];
 	Www *w;
 
@@ -954,18 +984,36 @@
 			break;
 		}
 		message("getting %s", selection->fullname);
-		typ = snooptype(fd);
-		if(typ == GUNZIP){
-			fd=pipeline("/bin/gunzip", fd);
+		if(mothmode && !plumb)
+			typ = -1;
+		else {
 			typ = snooptype(fd);
+			if(typ == GUNZIP){
+				fd=pipeline("/bin/gunzip", fd);
+				typ = snooptype(fd);
+			}
+			if(typ == COMPRESS){
+				fd=pipeline("/bin/uncompress", fd);
+				typ = snooptype(fd);
+			}
 		}
-		if(typ == COMPRESS){
-			fd=pipeline("/bin/uncompress", fd);
-			typ = snooptype(fd);
-		}
 		switch(typ){
 		default:
-			message("Bad type %x in geturl", typ);
+			if(plumb){
+				message("unknown file type");
+				close(fd);
+				break;
+			}
+			file = urltofile(selection);
+			if(!mothmode){
+				message("save to '%s' ?", file);
+				if(!confirm(1)){
+					message(mothra);
+					close(fd);
+					break;
+				}
+			}
+			save(fd, file);
 			break;
 		case HTML:
 			fd = pipeline("/bin/uhtml", fd);
@@ -1000,7 +1048,7 @@
 			setcurrent(i, selection->tag);
 			break;
 		case GIF:
-			if(rfork(RFFDG|RFPROC|RFNAMEG|RFNOWAIT) == 0){
+			if(rfork(RFFDG|RFNOTEG|RFPROC|RFNAMEG|RFNOWAIT) == 0){
 				snprint(cmd, sizeof(cmd), "-pid %d", getpid());
 				if(newwindow(cmd) != -1){
 					close(1); open("/dev/cons", OWRITE);
@@ -1007,7 +1055,7 @@
 					print("reading gif...\n");
 					filter("gif", fd);
 				}
-				exits(nil);
+				exits(0);
 			}
 			close(fd);
 			break;
@@ -1076,26 +1124,6 @@
 	donecurs();
 }
 
-Cursor confirmcursor={
-	0, 0,
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-
-	0x00, 0x0E, 0x07, 0x1F, 0x03, 0x17, 0x73, 0x6F,
-	0xFB, 0xCE, 0xDB, 0x8C, 0xDB, 0xC0, 0xFB, 0x6C,
-	0x77, 0xFC, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
-	0x94, 0xA6, 0x63, 0x3C, 0x63, 0x18, 0x94, 0x90,
-};
-int confirm(int b){
-	Mouse down, up;
-	esetcursor(&confirmcursor);
-	do down=emouse(); while(!down.buttons);
-	do up=emouse(); while(up.buttons);
-	donecurs();
-	return down.buttons==(1<<(b-1));
-}
 void snarf(Panel *p){
 	int fd;
 	fd=create("/dev/snarf", OWRITE, 0666);
--- a/sys/src/cmd/mothra/snoop.c
+++ b/sys/src/cmd/mothra/snoop.c
@@ -109,10 +109,6 @@
 	"application/ghostscript",	PAGE,
 	"application/troff",		PAGE,
 
-	"application/zip",		PAGE,
-	"application/x-tar",		PAGE,
-	"application/x-ustar",		PAGE,
-
 	"image/",			PAGE,
 	"text/",			PLAIN,
 	};