mothra: refactor url saving, handle unknown content type as file download
This commit is contained in:
parent
205a39474c
commit
24d69465a3
2 changed files with 125 additions and 101 deletions
|
@ -389,6 +389,26 @@ void main(int argc, char *argv[]){
|
|||
}
|
||||
}
|
||||
}
|
||||
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 @@ char *arg(char *s){
|
|||
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;
|
||||
|
@ -552,6 +595,26 @@ void screendump(char *name, int full){
|
|||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
@ -562,7 +625,7 @@ void docmd(Panel *p, char *s){
|
|||
* 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 @@ void docmd(Panel *p, char *s){
|
|||
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 @@ void docmd(Panel *p, char *s){
|
|||
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 docmd(Panel *p, char *s){
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
@ -654,18 +715,6 @@ void doprev(Panel *p, int buttons, int index){
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -679,21 +728,14 @@ void dolink(Panel *p, int buttons, Rtext *word){
|
|||
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 @@ void freetext(Rtext *t){
|
|||
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 @@ void freeurl(Url *u){
|
|||
/*
|
||||
* 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 @@ void geturl(char *urlname, int method, char *body, int cache, int map){
|
|||
break;
|
||||
}
|
||||
message("getting %s", selection->fullname);
|
||||
typ = snooptype(fd);
|
||||
if(typ == GUNZIP){
|
||||
fd=pipeline("/bin/gunzip", fd);
|
||||
typ = snooptype(fd);
|
||||
}
|
||||
if(typ == COMPRESS){
|
||||
fd=pipeline("/bin/uncompress", 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);
|
||||
}
|
||||
}
|
||||
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,14 +1048,14 @@ void geturl(char *urlname, int method, char *body, int cache, int map){
|
|||
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);
|
||||
print("reading gif...\n");
|
||||
filter("gif", fd);
|
||||
}
|
||||
exits(nil);
|
||||
exits(0);
|
||||
}
|
||||
close(fd);
|
||||
break;
|
||||
|
@ -1076,26 +1124,6 @@ mothon(Www *w, int on)
|
|||
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);
|
||||
|
|
|
@ -109,10 +109,6 @@ snooptype(int fd)
|
|||
"application/ghostscript", PAGE,
|
||||
"application/troff", PAGE,
|
||||
|
||||
"application/zip", PAGE,
|
||||
"application/x-tar", PAGE,
|
||||
"application/x-ustar", PAGE,
|
||||
|
||||
"image/", PAGE,
|
||||
"text/", PLAIN,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue