Sigrid Solveig Haflínudóttirdump raw to stdout if not /dev/cons456b7095 years agoHistory
202 lines · 4.2 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <plumb.h>#include <ctype.h>#include "gemnine.h" static voidpage(Response *r){	if(rfork(RFPROC|RFFDG|RFNOTEG|RFNOWAIT) == 0){		char tmp[32] = "/tmp/gem9XXXXXXXXXXX", *cmd;		int f;		mktemp(tmp);		cmd = smprint("cat >%s; page %s; rm %s", tmp, tmp, tmp);		dup(r->fd, 0); close(r->fd);		dup((f = open("/dev/null", OWRITE)), 1);		dup(f, 2);		close(f);		execl("/bin/rc", "rc", "-c", cmd, nil);	}} static voidplay(Response *r){	if(rfork(RFPROC|RFFDG|RFNOTEG|RFNOWAIT) == 0){		int wfd, f;		char *wsys, tmp[64];		snprint(tmp, sizeof(tmp), "new -pid %d -dx %d -dy %d", getpid(), 640, 480);		if ((wsys = getenv("wsys")) == nil)			exits("no wsys");		if ((wfd = open(wsys, ORDWR|OCEXEC)) < 0 ||		    mount(wfd, -1, "/mnt/wsys", MREPL, tmp) < 0 ||		    bind("/mnt/wsys", "/dev", MBEFORE) < 0){			exits("wsys: %r");		}		dup(r->fd, 0); close(r->fd);		dup((f = open("/dev/null", OWRITE)), 1);		dup(f, 2);		execl("/bin/play", "play", nil);	}} static voidusage(void){	fprint(2, "usage: %s [-w] [URL]\n", argv0);	exits("usage");} voidmain(int argc, char **argv){	Response *r;	char *s, *t, *u, *tmp;	Url *url, *x;	int len, raw, wait, pl, fd;	Plumbmsg *m;	Biobuf out, body;	char buf[8192]; 	wait = 0;	ARGBEGIN{	case 'w':		wait = 1;		break;	default:		usage();	}ARGEND; 	if(!wait && argc < 1)		usage(); 	raw = fd2path(1, buf, sizeof(buf)) == 0 && strcmp(buf, "/dev/cons") != 0; 	quotefmtinstall();	fmtinstall('U', Ufmt);	fmtinstall('N', Nfmt);	fmtinstall(']', Mfmt);	fmtinstall('E', Efmt);	fmtinstall('[', encodefmt);	fmtinstall('H', encodefmt); 	Binit(&out, 1, OWRITE);	pl = -1; nexturl:	url = nil;	if(wait){		if(pl >= 0 || (pl = plumbopen("gemini", OREAD)) >= 0){			if((m = plumbrecv(pl)) != nil){				url = urlparse(nil, estrdup(m->data));				plumbfree(m);			}else{				exits(nil);			}		}else{			sysfatal("plumbopen: %r");		}	}else{		url = urlparse(nil, estrdup(argv[0]));	} nextreq:	if((r = request(url)) != nil){		if(!raw && r->mime != nil && strncmp(r->mime, "text/", 5) != 0){			if(strncmp(r->mime, "image/", 6) == 0 || strcmp(r->mime, "application/pdf") == 0)				page(r);			else if(strncmp(r->mime, "audio/", 6) == 0)				play(r);			else				fprint(2, "unsupported MIME %q\n", r->mime);		}else if(r->prompt != nil){			if(wait)				close(open("/dev/text", OWRITE|OTRUNC|OCEXEC));			if((fd = open("/dev/consctl", OWRITE|OCEXEC)) >= 0){				write(fd, "holdon", 6);				print("%s\n", r->prompt);				Binit(&body, 0, OREAD);				t = nil;				if((s = Brdstr(&body, 0, 1)) != nil)					t = smprint("%s?%E", r->url->full, (Str2){s, "/:@ \n"});				Bterm(&body);				free(s);				if(t != nil){					freeresponse(r);					freeurl(url);					url = urlparse(nil, t);					free(t);				}else{					fprint(2, "%r\n");				}				close(fd);				goto nextreq;			}else{				fprint(2, "%r\n");			}		}else{			if(wait)				close(open("/dev/text", OWRITE|OTRUNC|OCEXEC));			if(r->code < 20 || r->code >= 30){				if(r->code > 0)					fprint(2, "%U: %d %s\n", url, r->code, (r->meta && r->meta[0]) ? r->meta : r->status);				else					fprint(2, "%U: %r\n", url);				if(!wait)					exits("failed");			}else if(raw){				for(;;){					if((len = read(r->fd, buf, sizeof(buf))) == 0)						break;					if(len < 0)						goto err;					if(write(1, buf, len) <= 0)						break;				}			}else{				Binit(&body, r->fd, OREAD);				while((s = Brdstr(&body, '\n', 1)) != nil){					if((len = Blinelen(&body)) > 0)						s[len] = 0;					for(len--; len >= 0 && (s[len] == '\r' || s[len] == '\n'); len--)						s[len] = 0;					if(s[0] == '=' && s[1] == '>'){						u = s + 2;						while(isspace(*u))							u++;						if((t = strpbrk(u, " \t")) != nil)							*t++ = 0;						else							t = "";						x = urlparse(r->url, u);						if((tmp = smprint("%U", x)) != nil && strcmp(tmp, t) == 0)							Bprint(&out, "→ %s\n", tmp);						else							Bprint(&out, "→ %s %s\n", tmp, t);						free(tmp);						freeurl(x);					}else{						Bprint(&out, "%s\n", s);					}					free(s);				}				Bterm(&body);			}		}		freeresponse(r);		freeurl(url);	}else{err:		fprint(2, "%U: %r\n", url);		if(!wait)			exits("failed");	} 	Bflush(&out);	if(wait)		goto nexturl; 	exits(nil);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t