git: 9front

Download patch

ref: 324e88b6ce41b42dd8ba7a49090ab072b4fbbd31
parent: c0ce065f1465089dfcafeb10d456c15366fbb5e2
author: stanley lieber <stanley.lieber@gmail.com>
date: Sat Oct 1 17:30:12 EDT 2011

mothra: add moth mode; display images that are not also links as a link to themselves

--- a/sys/man/1/mothra
+++ b/sys/man/1/mothra
@@ -4,6 +4,9 @@
 .SH SYNOPSIS
 .B mothra
 [
+.B -dv
+]
+[
 .B -m
 .I mtpt
 ] [
@@ -11,7 +14,9 @@
 ]
 .SH DESCRIPTION
 .I Mothra
-retrieves and displays files from the World-Wide Web,
+uses
+.IR webfs (4)
+to retrieve and display files from the World-Wide Web,
 by name or through hypertext links.
 Web names, called URLs, have a peculiar syntax:
 .IP
@@ -55,18 +60,19 @@
 .B  -d
 Debug mode.
 .TP
+.B -m
+Specify the
+.IR webfs (4)
+mountpoint with
+.BR -m
+.I mtpt.
+The default is
+.B /mnt/web.
+.TP
 .B -v
 Verbose mode. Causes HTML errors to appear in
 .B $home/lib/mothra/mothra.err
 .PP
-Mothra uses
-.IR webfs (4)
-to retrive the URL data. The mountpoint, default is
-.B /mnt/web,
-can be changed with the
-.BR -b
-.I mtpt .
-.PP
 The display contains the last message from
 .I mothra,
 a box where typed commands appear,
@@ -85,6 +91,11 @@
 .B alt display
 Collapse or expand the navigation boxes at the top of the browser window.
 .TP
+.B moth mode
+Enter moth mode and switch to the moth cursor. Clicking an image or link
+with mouse button 1 saves a copy of the file in the current directory.
+Clicking any other mouse button exits moth mode.
+.TP
 .B snarf url
 Copy the current URL to the snarf buffer.
 .TP
@@ -91,10 +102,6 @@
 .B paste
 Paste the current snarf buffer at the current cursor position.
 .TP
-.B save url
-Save the currently selected URL as a file. Directory indexes are saved in a file named
-.I index.
-.TP
 .B save hit
 Save the current URL to the hit list.
 .TP
@@ -164,7 +171,12 @@
 Files are saved in the form received,
 not in the form suggested by the name in an
 .B s
-command.
-.br
+command. A directory index saved from moth mode may be written in
+the local directory as a file named
+.B index.
+Sanitizing remote file names for the local file system is imperfect.
+.PP
 .I Mothra
-is distributed in a preliminary state; it has more than its share of bugs.
+is distributed in a preliminary state; it has more than its share of bugs. Note that
+.I mothra,
+like the other Guardian Monsters, has no particular concern for humanity.
--- a/sys/src/cmd/mothra/getpix.c
+++ b/sys/src/cmd/mothra/getpix.c
@@ -43,8 +43,6 @@
 	for(p=w->pix;p!=nil; p=p->next)
 		if(strcmp(ap->image, p->name)==0 && ap->width==p->width && ap->height==p->height){
 			storebitmap(t, p->b);
-			free(ap->image);
-			ap->image=0;
 			w->changed=1;
 			return;
 		}
@@ -54,8 +52,6 @@
 		snprint(err, sizeof(err), "[%s: %r]", url.fullname);
 		free(t->text);
 		t->text=strdup(err);
-		free(ap->image);
-		ap->image=0;
 		w->changed=1;
 		close(fd);
 		return;
@@ -99,8 +95,6 @@
 	p->next=w->pix;
 	w->pix=p;
 	storebitmap(t, b);
-	free(ap->image);
-	ap->image=0;
 	w->changed=1;
 }
 
--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -76,10 +76,22 @@
 	0x0E, 0x60, 0x1C, 0x00, 0x38, 0x00, 0x71, 0xB6,
 	0x61, 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
+Cursor mothcurs={
+	{-7, -7},
+	{0x00, 0x00, 0x60, 0x06, 0xf8, 0x1f, 0xfc, 0x3f, 
+	 0xfe, 0x7f, 0xff, 0xff, 0x7f, 0xfe, 0x7f, 0xfe, 
+	 0x7f, 0xfe, 0x3f, 0xfc, 0x3f, 0xfc, 0x1f, 0xf8, 
+	 0x1f, 0xf8, 0x0e, 0x70, 0x0c, 0x30, 0x00, 0x00, },
+	{0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x58, 0x1a, 
+	 0x5c, 0x3a, 0x64, 0x26, 0x27, 0xe4, 0x37, 0xec, 
+	 0x37, 0xec, 0x17, 0xe8, 0x1b, 0xd8, 0x0e, 0x70, 
+	 0x0c, 0x30, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, }
+};
 char *mtpt="/mnt/web";
 Www *current=0;
 Url *selection=0;
 int logfile;
+int mothmode;
 void docmd(Panel *, char *);
 void doprev(Panel *, int, int);
 void selurl(char *);
@@ -90,9 +102,9 @@
 void hit3(int, int);
 char *buttons[]={
 	"alt display",
+	"moth mode",
 	"snarf url",
 	"paste",
-	"save url",
 	"save hit",
 	"hit list",
 	"exit",
@@ -231,6 +243,7 @@
 	enum { Eplumb = 128 };
 	Plumbmsg *pm;
 	Www *new;
+	Action *a;
 	char *url;
 	int errfile;
 	int i;
@@ -314,7 +327,8 @@
 				current->changed=0;
 				current->alldone=1;
 				message(mothra);
-				esetcursor(0);
+				if(mothmode==0)
+					esetcursor(0);
 			}
 			else if(current->changed){
 				updtext(current);
@@ -355,6 +369,11 @@
 			break;
 		case Emouse:
 			mouse=e.mouse;
+			if(mouse.buttons > 1){
+				mothmode = 0;
+				esetcursor(current && current->alldone?0:&readingcurs);
+				message(mothra);
+			}
 			plmouse(root, e.mouse);
 			break;
 		case Eplumb:
@@ -439,8 +458,12 @@
 }
 
 void donecurs(void){
-	esetcursor(current && current->alldone?0:&readingcurs);
+	if(mothmode)
+		esetcursor(current && current->alldone?0:&mothcurs);
+	else
+		esetcursor(current && current->alldone?0:&readingcurs);
 }
+
 /*
  * selected text should be a url.
  * get the document, scroll to the given tag
@@ -635,23 +658,47 @@
 }
 
 /*
+ * convert a url into a local file name.
+ */
+char *urltofile(char *url){
+	static char file[128];
+	if(strrchr(url, '/')){
+		snprint(file, sizeof(file), "%s", strrchr(url, '/')+1);
+		if(file[0]==0)
+			strcpy(file, "index");
+	}else
+		snprint(file, sizeof(file), "%s", url);
+	return file;
+}
+/*
  * Follow an html link
  */
 void dolink(Panel *p, int buttons, Rtext *word){
-	char mapurl[NNAME];
+	char file[128], mapurl[NNAME];
 	Action *a;
+	Url u;
 	Point coord;
-	int yoffs;
+	int fd, yoffs;
 	USED(p);
 	a=word->user;
-	if(a && a->link){
+	if(mothmode && a){
+		if(a->image){
+			seturl(&u, a->image, current->url->fullname);
+			snprint(file, sizeof(file), "%s", urltofile(a->image));
+		}else{
+			seturl(&u, a->link, current->url->fullname);
+			snprint(file, sizeof(file), "%s", urltofile(a->link));
+		}
+		save(&u, file);
+		message("saved %s", file);
+		esetcursor(&mothcurs);
+	}else if(a && a->link){
 		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, 0);
 	}
 }
@@ -1069,20 +1116,15 @@
 		pldraw(root, screen);
 		break;
 	case 1:
-		snarf(cmd);
+		mothmode = 1;
+		message("moth mode");
+		esetcursor(&mothcurs);
 		break;
 	case 2:
-		paste(cmd);
+		snarf(cmd);
 		break;
 	case 3:
-		if(strrchr(selection->reltext, '/')){
-			snprint(file, sizeof(file), "%s", strrchr(selection->reltext, '/')+1);
-			if(file[0]==0)
-				strcpy(file, "index");
-		} else
-			snprint(file, sizeof(file), "%s", selection->reltext);
-		save(selection, file);
-		message("saved %s", file);
+		paste(cmd);
 		break;
 	case 4:
 		snprint(name, sizeof(name), "%s/hit.html", home);
--- a/sys/src/cmd/mothra/rdhtml.c
+++ b/sys/src/cmd/mothra/rdhtml.c
@@ -639,8 +639,11 @@
 		case Tag_meta:
 			break;
 		case Tag_img:
-			if(str=pl_getattr(g.attr, "src"))
+			if(str=pl_getattr(g.attr, "src")){
 				strncpy(g.state->image, str, sizeof(g.state->image));
+				if(g.state->link[0]==0)
+					strncpy(g.state->link, str, sizeof(g.state->link));
+			}
 			g.state->ismap=pl_hasattr(g.attr, "ismap");
 			if(str=pl_getattr(g.attr, "width"))
 				g.state->width = strtolength(&g, HORIZ, str);
--