From aa9097b4bbf566504c80689fa45b2e82aad56c36 Mon Sep 17 00:00:00 2001
From: cinap_lenrek
Date: Mon, 5 Sep 2011 03:29:26 +0200
Subject: mothra: remove ftp,gopher,file and http code and use /mnt/web instead
---
sys/src/cmd/mothra/auth.c | 68 ------
sys/src/cmd/mothra/cistr.c | 29 ---
sys/src/cmd/mothra/crackurl.c | 188 ---------------
sys/src/cmd/mothra/file.c | 48 ----
sys/src/cmd/mothra/filetype.c | 2 +-
sys/src/cmd/mothra/forms.c | 22 +-
sys/src/cmd/mothra/ftp.c | 428 ---------------------------------
sys/src/cmd/mothra/getpix.c | 49 +++-
sys/src/cmd/mothra/gopher.c | 38 ---
sys/src/cmd/mothra/gopher2html.c | 230 ------------------
sys/src/cmd/mothra/help.html | 78 ------
sys/src/cmd/mothra/http.c | 486 --------------------------------------
sys/src/cmd/mothra/libpanel/mem.c | 1 +
sys/src/cmd/mothra/mkfile | 7 -
sys/src/cmd/mothra/mothra.c | 251 ++++++++------------
sys/src/cmd/mothra/mothra.h | 39 +--
sys/src/cmd/mothra/rdhtml.c | 7 -
sys/src/cmd/mothra/urlcanon.c | 70 ------
sys/src/cmd/mothra/version.c | 2 +-
19 files changed, 162 insertions(+), 1881 deletions(-)
delete mode 100644 sys/src/cmd/mothra/auth.c
delete mode 100644 sys/src/cmd/mothra/cistr.c
delete mode 100644 sys/src/cmd/mothra/crackurl.c
delete mode 100644 sys/src/cmd/mothra/file.c
delete mode 100644 sys/src/cmd/mothra/ftp.c
delete mode 100644 sys/src/cmd/mothra/gopher.c
delete mode 100644 sys/src/cmd/mothra/gopher2html.c
delete mode 100644 sys/src/cmd/mothra/help.html
delete mode 100644 sys/src/cmd/mothra/http.c
delete mode 100644 sys/src/cmd/mothra/urlcanon.c
diff --git a/sys/src/cmd/mothra/auth.c b/sys/src/cmd/mothra/auth.c
deleted file mode 100644
index 3e99e6324..000000000
--- a/sys/src/cmd/mothra/auth.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include "mothra.h"
-
-static int
-basicauth(char *arg, char *str, int n)
-{
- int i;
- char *p;
- char buf[1024];
- Biobuf *b;
-
- if(strncmp(arg, "realm=", 6) == 0)
- arg += 6;
- if(*arg == '"'){
- arg++;
- for(p = arg; *p && *p != '"'; p++);
- *p = 0;
- } else {
- for(p = arg; *p && *p != ' ' && *p != '\t'; p++);
- *p = 0;
- }
-
- p = getenv("home");
- if(p == 0){
- werrstr("$home not set");
- return -1;
- }
- snprint(buf, sizeof(buf), "%s/lib/mothra/insecurity", p);
- b = Bopen(buf, OREAD);
- if(b == 0){
- werrstr("www password file %s: %r", buf);
- return -1;
- }
-
- i = strlen(arg);
- while(p = Brdline(b, '\n'))
- if(strncmp(arg, p, i) == 0 && p[i] == '\t')
- break;
- if(p == 0){
- Bterm(b);
- werrstr("no basic password for domain `%s'", arg);
- return -1;
- }
-
- p[Blinelen(b)-1] = 0;
- for(p += i; *p == '\t'; p++);
- if (enc64(buf, sizeof buf, (uchar*)p, strlen(p)) < 0) {
- Bterm(b);
- werrstr("password too long: %s", p);
- return -1;
- }
- snprint(str, n, "Authorization: Basic %s\r\n", buf);
- return 0;
-}
-
-int
-auth(Url *url, char *str, int n)
-{
- if(cistrcmp(url->authtype, "basic") == 0)
- return basicauth(url->autharg, str, n);
- werrstr("unknown auth method %s", url->authtype);
- return -1;
-}
diff --git a/sys/src/cmd/mothra/cistr.c b/sys/src/cmd/mothra/cistr.c
deleted file mode 100644
index f6aec8681..000000000
--- a/sys/src/cmd/mothra/cistr.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include "mothra.h"
-int cistrcmp(char *s1, char *s2){
- int c1, c2;
-
- for(; *s1; s1++, s2++){
- c1 = isupper(*s1) ? tolower(*s1) : *s1;
- c2 = isupper(*s2) ? tolower(*s2) : *s2;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- }
- return 0;
-}
-int cistrncmp(char *s1, char *s2, int n){
- int c1, c2;
-
- for(; *s1 && n!=0; s1++, s2++, --n){
- c1 = isupper(*s1) ? tolower(*s1) : *s1;
- c2 = isupper(*s2) ? tolower(*s2) : *s2;
- if (c1 < c2) return -1;
- if (c1 > c2) return 1;
- }
- return 0;
-}
diff --git a/sys/src/cmd/mothra/crackurl.c b/sys/src/cmd/mothra/crackurl.c
deleted file mode 100644
index f04f42575..000000000
--- a/sys/src/cmd/mothra/crackurl.c
+++ /dev/null
@@ -1,188 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include "mothra.h"
-enum{
- IP=1, /* url can contain //ipaddress[:port] */
- REL=2, /* fill in ip address & root of name from current, if necessary */
- SSL=4, /* use SSL/TLS encryption */
-};
-Scheme scheme[]={
- "http:", HTTP, IP|REL, 80,
- "https:", HTTP, IP|REL|SSL, 443,
- "ftp:", FTP, IP|REL, 21,
- "file:", FILE, REL, 0,
- "telnet:", TELNET, IP, 0,
- "mailto:", MAILTO, 0, 0,
- "gopher:", GOPHER, IP, 70,
- 0, HTTP, IP|REL, 80,
-};
-int endaddr(int c){
- return c=='/' || c==':' || c=='?' || c=='#' || c=='\0';
-}
-/*
- * Remove ., mu/.. and empty components from path names.
- * Empty last components of urls are significant, and
- * therefore preserved.
- */
-void urlcanon(char *name){
- char *s, *t;
- char **comp, **p, **q;
- int rooted;
- rooted=name[0]=='/';
- /*
- * Break the name into a list of components
- */
- comp=emalloc((strlen(name)+2)*sizeof(char *));
- p=comp;
- *p++=name;
- for(s=name;;s++){
- if(*s=='/'){
- *p++=s+1;
- *s='\0';
- }
- else if(*s=='\0' || *s=='?')
- break;
- }
- *p=0;
- /*
- * go through the component list, deleting components that are empty (except
- * the last component) or ., and any .. and its non-.. predecessor.
- */
- p=q=comp;
- while(*p){
- if(strcmp(*p, "")==0 && p[1]!=0
- || strcmp(*p, ".")==0)
- p++;
- else if(strcmp(*p, "..")==0 && q!=comp && strcmp(q[-1], "..")!=0){
- --q;
- p++;
- }
- else
- *q++=*p++;
- }
- *q=0;
- /*
- * rebuild the path name
- */
- s=name;
- if(rooted) *s++='/';
- for(p=comp;*p;p++){
- t=*p;
- while(*t) *s++=*t++;
- if(p[1]!=0) *s++='/';
- }
- *s='\0';
- free(comp);
-}
-/*
- * True url parsing is a nightmare.
- * This assumes that there are two basic syntaxes
- * for url's -- with and without an ip address.
- * If the type identifier or the ip address and port number
- * or the relative address is missing from urlname or is empty,
- * it is copied from cur.
- */
-void crackurl(Url *url, char *urlname, Url *cur){
- char *relp, *tagp, *httpname;
- int len;
- Scheme *up;
- char buf[30];
- /*
- * The following lines `fix' the most egregious urlname syntax errors
- */
- while(*urlname==' ' || *urlname=='\t' || *urlname=='\n') urlname++;
- relp=strchr(urlname, '\n');
- if(relp) *relp='\0';
- /*
- * In emulation of Netscape, attach a free "http://"
- * to names beginning with "www.".
- */
- if(strncmp(urlname, "www.", 4)==0){
- httpname=emalloc(strlen(urlname)+8);
- strcpy(httpname, "http://");
- strcat(httpname, urlname);
- crackurl(url, httpname, cur);
- free(httpname);
- return;
- }
- url->port=cur->port;
- strncpy(url->ipaddr, cur->ipaddr, sizeof(url->ipaddr));
- strncpy(url->reltext, cur->reltext, sizeof(url->reltext));
- if(strchr(urlname, ':')==0){
- up=cur->scheme;
- if(up==0){
- up=&scheme[0];
- cur->scheme=up;
- }
- }
- else{
- for(up=scheme;up->name;up++){
- len=strlen(up->name);
- if(strncmp(urlname, up->name, len)==0){
- urlname+=len;
- break;
- }
- }
- if(up->name==0) up=&scheme[0]; /* default to http: */
- }
- url->access=up->type;
- url->scheme=up;
- if(up!=cur->scheme)
- url->reltext[0]='\0';
- if(up->flags&IP && strncmp(urlname, "//", 2)==0){
- urlname+=2;
- for(relp=urlname;!endaddr(*relp);relp++);
- len=relp-urlname;
- strncpy(url->ipaddr, urlname, len);
- url->ipaddr[len]='\0';
- urlname=relp;
- if(*urlname==':'){
- urlname++;
- url->port=atoi(urlname);
- while(!endaddr(*urlname)) urlname++;
- }
- else
- url->port=up->port;
- if(*urlname=='\0') urlname="/";
- }
- url->ssl = up->flags&SSL;
-
- tagp=strchr(urlname, '#');
- if(tagp){
- *tagp='\0';
- strncpy(url->tag, tagp+1, sizeof(url->tag));
- }
- else
- url->tag[0]='\0';
- if(!(up->flags&REL) || *urlname=='/')
- strncpy(url->reltext, urlname, sizeof(url->reltext));
- else if(urlname[0]){
- relp=strrchr(url->reltext, '/');
- if(relp==0)
- strncpy(url->reltext, urlname, sizeof(url->reltext));
- else
- strcpy(relp+1, urlname);
- }
- urlcanon(url->reltext);
- if(tagp) *tagp='#';
- /*
- * The following mess of strcpys and strcats
- * can't be changed to a few sprints because
- * urls are not necessarily composed of legal utf
- */
- strcpy(url->fullname, up->name);
- if(up->flags&IP){
- strncat(url->fullname, "//", sizeof(url->fullname));
- strncat(url->fullname, url->ipaddr, sizeof(url->fullname));
- if(url->port!=up->port){
- snprint(buf, sizeof(buf), ":%d", url->port);
- strncat(url->fullname, buf, sizeof(url->fullname));
- }
- }
- strcat(url->fullname, url->reltext);
- url->map=0;
-}
diff --git a/sys/src/cmd/mothra/file.c b/sys/src/cmd/mothra/file.c
deleted file mode 100644
index 50ae60f25..000000000
--- a/sys/src/cmd/mothra/file.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include "mothra.h"
-/*
- * fd is the result of a successful open(name, OREAD),
- * where name is the name of a directory. We convert
- * this into an html page containing links to the files
- * in the directory.
- */
-int dir2html(char *name, int fd){
- int p[2], first;
- Dir *dir;
- int i, n;
- if(pipe(p)==-1){
- close(fd);
- return -1;
- }
- switch(rfork(RFFDG|RFPROC|RFNOWAIT)){
- case -1:
- close(fd);
- return -1;
- case 0:
- close(p[1]);
- fprint(p[0], "\n");
- fprint(p[0], "Directory %s\n", name);
- fprint(p[0], "\n");
- fprint(p[0], "\n");
- fprint(p[0], "%s
\n", name);
- fprint(p[0], "\n");
- first=1;
- while((n = dirread(fd, &dir)) > 0) {
- for (i = 0; i < n; i++)
- fprint(p[0], "- %s%s\n", name, dir[i].name, dir[i].name,
- dir[i].mode&DMDIR?"/":"");
- free(dir);
- }
- fprint(p[0], "
\n");
- fprint(p[0], "\n");
- _exits(0);
- default:
- close(fd);
- close(p[0]);
- return p[1];
- }
-}
diff --git a/sys/src/cmd/mothra/filetype.c b/sys/src/cmd/mothra/filetype.c
index 71ae92bed..c71e87726 100644
--- a/sys/src/cmd/mothra/filetype.c
+++ b/sys/src/cmd/mothra/filetype.c
@@ -86,7 +86,7 @@ Kind content[]={
"application/pdf", PDF,
"application/octet-stream", SUFFIX,
"application/zip", ZIP,
- 0, HTML
+ 0, SUFFIX
};
int content2type(char *s, char *name){
int type;
diff --git a/sys/src/cmd/mothra/forms.c b/sys/src/cmd/mothra/forms.c
index 5e08a3242..6e0775759 100644
--- a/sys/src/cmd/mothra/forms.c
+++ b/sys/src/cmd/mothra/forms.c
@@ -12,7 +12,7 @@ typedef struct Field Field;
typedef struct Option Option;
struct Form{
int method;
- Url *action;
+ char *action;
Field *fields, *efields;
Form *next;
};
@@ -98,12 +98,8 @@ void rdform(Hglob *g){
break;
}
g->form=emallocz(sizeof(Form), 1);
- g->form->action=emalloc(sizeof(Url));
s=pl_getattr(g->attr, "action");
- if(s==0)
- *g->form->action=*g->dst->url;
- else
- crackurl(g->form->action, s, g->dst->base);
+ g->form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
s=pl_getattr(g->attr, "method");
if(s==0)
g->form->method=GET;
@@ -268,12 +264,8 @@ void rdform(Hglob *g){
form=emalloc(sizeof(Form));
form->fields=0;
form->efields=0;
- form->action=emalloc(sizeof(Url));
s=pl_getattr(g->attr, "action");
- if(s==0)
- *form->action=*g->dst->url;
- else
- crackurl(form->action, s, g->dst->base);
+ form->action=strdup((s && s[0]) ? s : g->dst->url->fullname);
form->method=GET;
form->fields=0;
f=newfield(form);
@@ -537,7 +529,7 @@ void h_submitinput(Panel *p, int){
Field *f;
Option *o;
form=((Field *)p->userp)->form;
- if(form->method==GET) size=ulen(form->action->fullname)+1;
+ if(form->method==GET) size=ulen(form->action)+1;
else size=1;
for(f=form->fields;f;f=f->next) switch(f->type){
case TYPEIN:
@@ -564,7 +556,7 @@ void h_submitinput(Panel *p, int){
}
buf=emalloc(size);
if(form->method==GET){
- strcpy(buf, form->action->fullname);
+ strcpy(buf, form->action);
sep='?';
}
else{
@@ -623,8 +615,8 @@ fprint(2, "GET %s\n", buf);
geturl(buf, GET, 0, 0, 0);
}
else{
-fprint(2, "POST %s: %s\n", form->action->fullname, buf);
- geturl(form->action->fullname, POST, buf, 0, 0);
+fprint(2, "POST %s: %s\n", form->action, buf);
+ geturl(form->action, POST, buf, 0, 0);
}
free(buf);
}
diff --git a/sys/src/cmd/mothra/ftp.c b/sys/src/cmd/mothra/ftp.c
deleted file mode 100644
index 78c3ab5da..000000000
--- a/sys/src/cmd/mothra/ftp.c
+++ /dev/null
@@ -1,428 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "mothra.h"
-
-enum
-{
- /* return codes */
- Extra= 1,
- Success= 2,
- Incomplete= 3,
- TempFail= 4,
- PermFail= 5,
-
- NAMELEN= 28,
- Nnetdir= 3*NAMELEN, /* max length of network directory paths */
- Ndialstr= 64, /* max length of dial strings */
-};
-
-typedef struct Ftp Ftp;
-struct Ftp
-{
- char net[Nnetdir];
- Biobuf *ftpctl;
- Url *u;
-};
-
-static int ftpdebug;
-
-
-/*
- * read from biobuf turning cr/nl into nl
- */
-char*
-getcrnl(Biobuf *b)
-{
- char *p, *ep;
-
- p = Brdline(b, '\n');
- if(p == nil)
- return nil;
- ep = p + Blinelen(b) - 1;
- if(*(ep-1) == '\r')
- ep--;
- *ep = 0;
- return p;
-}
-
-char*
-readfile(char *file, char *buf, int len)
-{
- int n, fd;
-
- fd = open(file, OREAD);
- if(fd < 0)
- return nil;
- n = read(fd, buf, len-1);
- close(fd);
- if(n <= 0)
- return nil;
- buf[n] = 0;
- return buf;
-}
-
-char*
-sysname(void)
-{
- static char sys[Ndbvlen];
- char *p;
-
- p = readfile("/dev/sysname", sys, sizeof(sys));
- if(p == nil)
- return "unknown";
- return p;
-}
-
-char*
-domainname(void)
-{
- static char domain[Ndbvlen];
- Ndbtuple *t;
-
- if(*domain)
- return domain;
-
- t = csgetval(0, "sys", sysname(), "dom", domain);
- if(t){
- ndbfree(t);
- return domain;
- } else
- return sysname();
-}
-
-static int
-sendrequest(Biobuf *b, char *fmt, ...)
-{
- char buf[2*1024], *s;
- va_list args;
-
- va_start(args, fmt);
- s = buf + vsnprint(buf, (sizeof(buf)-4) / sizeof(*buf), fmt, args);
- va_end(args);
- *s++ = '\r';
- *s++ = '\n';
- if(write(Bfildes(b), buf, s - buf) != s - buf)
- return -1;
- if(ftpdebug)
- write(2, buf, s - buf);
- return 0;
-}
-
-static int
-getreply(Biobuf *b, char *msg, int len)
-{
- char *line;
- int rv;
- int i, n;
-
- while(line = getcrnl(b)){
- /* add line to message buffer, strip off \r */
- n = Blinelen(b);
- if(ftpdebug)
- write(2, line, n);
- if(n > len - 1)
- i = len - 1;
- else
- i = n;
- if(i > 0){
- memmove(msg, line, i);
- msg += i;
- len -= i;
- *msg = 0;
- }
-
- /* stop if not a continuation */
- rv = atoi(line);
- if(rv >= 100 && rv < 600 && (n == 4 || (n > 4 && line[3] == ' ')))
- return rv/100;
- }
-
- return -1;
-}
-
-int
-terminateftp(Ftp *d)
-{
- if(d->ftpctl){
- close(Bfildes(d->ftpctl));
- Bterm(d->ftpctl);
- free(d->ftpctl);
- d->ftpctl = nil;
- }
- free(d);
- return -1;
-}
-
-Biobuf*
-hello(Ftp *d)
-{
- int fd;
- char *p;
- Biobuf *b;
- char msg[1024];
- char ndir[Nnetdir];
-
- snprint(msg, sizeof msg, "tcp!%s!%d", d->u->ipaddr, d->u->port);
- fd = dial(msg, 0, ndir, 0);
- if(fd < 0){
- d->ftpctl = nil;
- return nil;
- }
- b = emalloc(sizeof(Biobuf));
- Binit(b, fd, OREAD);
- d->ftpctl = b;
-
- /* remember network for the data connections */
- p = strrchr(ndir, '/');
- if(p == 0){
- fprint(2, "dial is out of date\n");
- return nil;
- }
- *p = 0;
- strcpy(d->net, ndir);
-
- /* wait for hello from other side */
- if(getreply(b, msg, sizeof(msg)) != Success){
- fprint(2, "instead of hello: %s\n", msg);
- return nil;
- }
- return b;
-}
-
-int
-logon(Ftp *d)
-{
- char msg[1024];
-
- /* login anonymous */
- sendrequest(d->ftpctl, "USER anonymous");
- switch(getreply(d->ftpctl, msg, sizeof(msg))){
- case Success:
- return 0;
- case Incomplete:
- break; /* need password */
- default:
- fprint(2, "login failed: %s\n", msg);
- werrstr(msg);
- return -1;
- }
-
- /* send user id as password */
- sprint(msg, "%s@", getuser());
- sendrequest(d->ftpctl, "PASS %s", msg);
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Success){
- fprint(2, "login failed: %s\n", msg);
- werrstr(msg);
- return -1;
- }
-
- return 0;
-}
-
-int
-xfertype(Ftp *d, char *t)
-{
- char msg[1024];
-
- sendrequest(d->ftpctl, "TYPE %s", t);
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Success){
- fprint(2, "can't set type %s: %s\n", t, msg);
- werrstr(msg);
- return -1;
- }
- return 0;
-}
-
-int
-passive(Ftp *d)
-{
- char msg[1024];
- char dialstr[Ndialstr];
- char *f[6];
- char *p;
- int fd;
-
- sendrequest(d->ftpctl, "PASV");
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Success)
- return -1;
-
- /* get address and port number from reply, this is AI */
- p = strchr(msg, '(');
- if(p == nil){
- for(p = msg+3; *p; p++)
- if(isdigit(*p))
- break;
- } else
- p++;
- if(getfields(p, f, 6, 0, ",") < 6){
- fprint(2, "passive mode protocol botch: %s\n", msg);
- werrstr("ftp protocol botch");
- return -1;
- }
- snprint(dialstr, sizeof(dialstr), "%s!%s.%s.%s.%s!%d", d->net,
- f[0], f[1], f[2], f[3],
- ((atoi(f[4])&0xff)<<8) + (atoi(f[5])&0xff));
-
-
- /* open data connection */
- fd = dial(dialstr, 0, 0, 0);
- if(fd < 0){
- fprint(2, "passive mode connect to %s failed: %r\n", dialstr);
- return -1;
- }
-
- /* tell remote to send a file */
- sendrequest(d->ftpctl, "RETR %s", d->u->reltext);
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Extra){
- fprint(2, "passive mode retrieve failed: %s\n", msg);
- werrstr(msg);
- return -1;
- }
- return fd;
-}
-
-int
-active(Ftp *d)
-{
- char msg[1024];
- char buf[Ndialstr];
- char netdir[Nnetdir];
- char newdir[Nnetdir];
- uchar ipaddr[4];
- int dfd, cfd, listenfd;
- char *p;
- int port;
-
- /* get a channel to listen on, let kernel pick the port number */
- sprint(buf, "%s!*!0", d->net);
- listenfd = announce(buf, netdir);
- if(listenfd < 0){
- fprint(2, "can't listen for ftp callback: %r\n", buf);
- return -1;
- }
-
- /* get the local address and port number */
- sprint(newdir, "%s/local", netdir);
- readfile(newdir, buf, sizeof buf);
- p = strchr(buf, '!')+1;
- parseip(ipaddr, buf);
- port = atoi(p);
-
- /* tell remote side address and port*/
- sendrequest(d->ftpctl, "PORT %d,%d,%d,%d,%d,%d", ipaddr[0], ipaddr[1], ipaddr[2],
- ipaddr[3], port>>8, port&0xff);
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Success){
- close(listenfd);
- werrstr("ftp protocol botch");
- fprint(2, "active mode connect failed %s\n", msg);
- return -1;
- }
-
- /* tell remote to send a file */
- sendrequest(d->ftpctl, "RETR %s", d->u->reltext);
- if(getreply(d->ftpctl, msg, sizeof(msg)) != Extra){
- close(listenfd);
- fprint(2, "active mode connect failed: %s\n", msg);
- werrstr(msg);
- return -1;
- }
-
- /* wait for a new call */
- cfd = listen(netdir, newdir);
- close(listenfd);
- if(cfd < 0){
- fprint(2, "active mode connect failed: %r\n");
- return -1;
- }
-
- /* open the data connection and close the control connection */
- dfd = accept(cfd, newdir);
- close(cfd);
- if(dfd < 0){
- fprint(2, "active mode connect failed: %r\n");
- werrstr("ftp protocol botch");
- return -1;
- }
-
- return dfd;
-}
-
-/*
- * Given a url, return a file descriptor on which caller can
- * read an ftp document.
- * The caller is responsible for processing redirection loops.
- */
-int
-ftp(Url *url)
-{
- int n;
- int data;
- Ftp *d;
- int pfd[2];
- char buf[2048];
-
- if(url->type == 0)
- url->type = PLAIN;
-
- d = (Ftp*)emalloc(sizeof(Ftp));
- d->u = url;
- d->ftpctl = nil;
-
- if(hello(d) == nil)
- return terminateftp(d);
- if(logon(d) < 0)
- return terminateftp(d);
-
- switch(url->type){
- case PLAIN:
- case HTML:
- if(xfertype(d, "A") < 0)
- return terminateftp(d);
- break;
- default:
- if(xfertype(d, "I") < 0)
- return terminateftp(d);
- break;
- }
-
- /* first try passive mode, then active */
- data = passive(d);
- if(data < 0){
- if(d->ftpctl == nil)
- return -1;
- data = active(d);
- if(data < 0)
- return -1;
- }
-
- if(pipe(pfd) < 0)
- return -1;
-
- switch(rfork(RFFDG|RFPROC|RFNOWAIT)){
- case -1:
- werrstr("Can't fork");
- close(pfd[0]);
- close(pfd[1]);
- return terminateftp(d);
- case 0:
- close(pfd[0]);
- while((n=read(data, buf, sizeof(buf)))>0)
- write(pfd[1], buf, n);
- if(n<0)
- fprint(2, "ftp: %s: %r\n", url->fullname);
- _exits(0);
- default:
- close(pfd[1]);
- close(data);
- terminateftp(d);
- return pfd[0];
- }
- return -1;
-}
diff --git a/sys/src/cmd/mothra/getpix.c b/sys/src/cmd/mothra/getpix.c
index 19e2b8b23..10e7b7467 100644
--- a/sys/src/cmd/mothra/getpix.c
+++ b/sys/src/cmd/mothra/getpix.c
@@ -39,7 +39,7 @@ void getimage(Rtext *t, Www *w){
Pix *p;
ap=t->user;
- crackurl(&url, ap->image, w->base);
+ seturl(&url, ap->image, w->url->fullname);
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);
@@ -105,12 +105,55 @@ void getimage(Rtext *t, Www *w){
}
void getpix(Rtext *t, Www *w){
+ int i, pid, nworker, worker[NXPROC];
Action *ap;
+ nworker = 0;
+ for(i=0; inext){
ap=t->user;
- if(ap && ap->image)
- getimage(t, w);
+ if(ap && ap->image){
+ pid = rfork(RFFDG|RFPROC|RFMEM);
+ switch(pid){
+ case -1:
+ fprint(2, "fork: %r\n");
+ break;
+ case 0:
+ getimage(t, w);
+ exits(0);
+ default:
+ for(i=0; i 0){
+ if((pid = waitpid()) < 0)
+ break;
+ for(i=0; i
-#include
-#include
-#include
-#include
-#include "mothra.h"
-void httpheader(Url *, char *);
-/*
- * Given a url, return a file descriptor on which caller can
- * read a gopher document.
- */
-int gopher(Url *url){
- int pfd[2];
- char port[30];
- if(pipe(pfd)==-1) return -1;
- switch(rfork(RFFDG|RFPROC|RFNOWAIT)){
- case -1:
- close(pfd[0]);
- close(pfd[1]);
- return -1;
- case 0:
- dup(pfd[1], 1);
- close(pfd[0]);
- close(pfd[1]);
- sprint(port, "%d", url->port);
- execl("/bin/aux/gopher2html",
- "gopher2html", url->ipaddr, port, url->reltext+1, 0);
- fprint(2, "Can't exec aux/gopher2html!\n");
- print("Mothra error\n");
- print("Mothra error
\n");
- print("Can't exec aux/gopher2html!\n");
- exits("no exec");
- default:
- close(pfd[1]);
- url->type=HTML;
- return pfd[0];
- }
-}
diff --git a/sys/src/cmd/mothra/gopher2html.c b/sys/src/cmd/mothra/gopher2html.c
deleted file mode 100644
index e0c57d736..000000000
--- a/sys/src/cmd/mothra/gopher2html.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Reads gopher output from a TCP port, outputs
- * html on standard output.
- * Usage: gopher2html gopher-string
- * where gopher-string is the string sent to
- * the gopher server to get the document.
- *
- * Gopher protocol is described in rfc1436
- */
-#include
-#include
-char *cmd;
-int ifd;
-void errexit(char *s, ...){
- static char buf[1024];
- char *out;
- va_list args;
- va_start(args, s);
- out = doprint(buf, buf+sizeof(buf), s, args);
- va_end(args);
- *out='\0';
- print("%s error\n", cmd);
- print("%s error
\n", cmd);
- print("%s\n", buf);
- exits("gopher error");
-}
-void wtext(char *buf, char *ebuf){
- char *bp;
- for(bp=buf;bp!=ebuf;bp++){
- if(*bp=='<' || *bp=='>' || *bp=='&' || *bp=='"'){
- if(bp!=buf) write(1, buf, bp-buf);
- buf=bp+1;
- switch(*bp){
- case '<': print("<"); break;
- case '>': print(">"); break;
- case '&': print("&"); break;
- case '"': print("""); break;
- }
- }
- }
- if(bp!=buf) write(1, buf, bp-buf);
-}
-void savefile(char *name, char *type){
- int fd, n;
- char save[30], buf[1024];
- for(n=1;;n++){
- if(n==100) errexit("can't save binary file %s: %r", name);
- sprint(save, "gopher.save.%d", n);
- fd=create(save, OWRITE, 0444);
- if(fd!=-1) break;
- }
- print("%s%s
\n", name);
- print("Saving %s file %s in %s...\n", type, name, save);
- while((n=read(ifd, buf, sizeof buf))>0) write(fd, buf, n);
- close(fd);
- print("done
%s
\n", title);
- while((n=read(ifd, buf, sizeof buf))>0) wtext(buf, buf+n);
- print("\n");
-}
-/*
- * A directory entry contains
- * type name selector host port
- * all tab separated, except type and name (type is one character)
- */
-char ibuf[1024], *ibp, *eibuf;
-#define EOF (-1)
-int get(void){
- int n;
-Again:
- if(ibp==eibuf){
- n=read(ifd, ibuf, sizeof(ibuf));
- if(n<=0) return EOF;
- eibuf=ibuf+n;
- ibp=ibuf;
- }
- if(*ibp=='\r'){
- ibp++;
- goto Again;
- }
- return *ibp++&255;
-}
-char *escape(char *in){
- static char out[516];
- char *op, *eop;
- eop=out+512;
- op=out;
- for(;*in;in++){
- if(op%s\n", title);
- print("%s
\n", title);
- for(;;){
- type=get();
- if(type==EOF || type=='.') break;
- bp=name;
- while((c=get())!=EOF && c!='\t') if(bp!=&name[512]) *bp++=c;
- ename=bp;
- bp=selector;
- while((c=get())!=EOF && c!='\t') if(bp!=&selector[512]) *bp++=c;
- *bp='\0';
- bp=host;
- while((c=get())!=EOF && c!='\t') if(bp!=&host[512]) *bp++=c;
- *bp='\0';
- bp=port;
- while((c=get())!=EOF && c!='\t' && c!='\n') if(bp!=&port[512]) *bp++=c;
- while(c!=EOF && c!='\n') c=get();
- *bp='\0';
- switch(type){
- case '3':
- print("- ");
- wtext(name, ename);
- break;
- case '7':
- print("
- ",
- host, port, type, escape(selector));
- wtext(name, ename);
- break;
- default:
- print("
- ",
- host, port, type, escape(selector));
- wtext(name, ename);
- print("\n");
- break;
- }
- }
- print("
\n");
-}
-int hexdigit(int c){
- if('0'<=c && c<='9') return c-'0';
- if('a'<=c && c<='f') return c-'a'+10;
- if('A'<=c && c<='F') return c-'A'+10;
- return -1;
-}
-void unescape(char *s){
- char *t;
- int hi, lo;
- t=s;
- while(*s){
- if(*s=='%'
- && (hi=hexdigit(s[1]))>=0
- && (lo=hexdigit(s[2]))>=0){
- *t++=hi*16+lo;
- s+=3;
- }
- else *t++=*s++;
- }
- *t='\0';
-}
-void main(int argc, char *argv[]){
- char dialstr[1024];
- char *name;
- cmd=argv[0];
- if(argc!=4) errexit("Usage: %s host port selector", argv[0]);
- sprint(dialstr, "tcp!%s!%s", argv[1], argv[2]);
- ifd=dial(dialstr, 0, 0, 0);
- if(ifd==-1) errexit("can't call %s:%s", argv[1], argv[2]);
- unescape(argv[3]);
- switch(argv[3][0]){
- case '/':
- fprint(ifd, "\r\n");
- copydir(argv[3]);
- break;
- case '\0':
- fprint(ifd, "\r\n");
- copydir(argv[1]);
- break;
- case '7': /* index query */
- name=strchr(argv[3], '?');
- if(name!=0){
- if(name==argv[3]+1){
- argv[3][1]=argv[3][0];
- argv[3]++;
- }
- else
- *name='\t';
- name++;
- }
- else
- name=argv[3];
- fprint(ifd, "%s\r\n", argv[3]+1);
- copydir(name);
- break;
- default:
- fprint(ifd, "%s\r\n", argv[3]+1);
- name=strrchr(argv[3], '/');
- if(name==0) name=argv[3];
- else name++;
- switch(argv[3][0]){
- default: errexit("sorry, can't handle %s (type %c)",
- argv[3]+1, argv[3][0]);
- case '0': copyfile(name); break;
- case '1': copydir(name); break;
- case '4': savefile(name, "Macintosh BINHEX"); break;
- case '5': savefile(name, "DOS binary"); break;
- case '6': savefile(name, "uuencoded"); break;
- case '9': savefile(name, "binary"); break;
- case 'g': savefile(name, "GIF"); break;
- case 'I': savefile(name, "some sort of image"); break;
- }
- break;
- }
- exits(0);
-}
diff --git a/sys/src/cmd/mothra/help.html b/sys/src/cmd/mothra/help.html
deleted file mode 100644
index 771f4b138..000000000
--- a/sys/src/cmd/mothra/help.html
+++ /dev/null
@@ -1,78 +0,0 @@
-Mothra help
-
-
-Mothra Help
-
-Mothra is a World-wide Web browser. Its display looks like this:
-
-
The display's regions, from top to bottom, are:
-
-- Error messages and other information.
-
- A text input window in which commands can be typed.
-
- A scrollable list of titles of previously visited documents, with the most recent first.
-Pointing at one of these lines with mouse button 1 revisits the document.
-
- The title of the currently-displayed document.
-
- The URL of the currently-displayed document.
-
- The scrollable document display. Underlined text and
-images surrounded by boxes may be pointed at with button 1 to
-visit the files that they refer to. Files that are not
-HTML documents (for example images or mailto: urls) cause
-9v or mail to pop up in a new 8½ window.
-
-Mouse Action
-Pointing with button
-2 instead of button 1 selects a url without following it;
-the url will be displayed in the selection: area and commands
-will refer to the url, but it will not be drawn in the document display.
-Button 3 pops up a command menu that contains
-
-- alt display
switches to (or from) the alternate display, which shows only
-the scrollable document display area. This might be useful when running mothra
-in a small window.
- - snarf url
copies the selected url into the snarf buffer.
- - paste
appends the snarf buffer to the command window.
- - inline pix
turn off/on loading of inline images. Image maps cannot be disabled.
- - fix cmap
reload the default plan 9 colormap
- - save hit
appends the selected url to file:$home/lib/hit.html
- - hit list
displays file:$home/lib/hit.html
- - exit
-
-Commands
-The commands you can type are:
-
-- g [url]
get the page with the given url (default, the selection.)
- - r [url]
refresh the display if the URL changes.
-Otherwise, you will probably see a cached version.
- - s file
save the current page in the given file.
- - w file
write a bitmap image of the document display area in the given file.
- - q
exit.
- - ?
get help.
- - h
get help.
-
-
-
Configuration
-Mothra gets configuration information from the environment.
-
-- $url
The default url displayed when mothra starts.
-A url given on the command line overrides this.
-The default is /sys/lib/mothra/start.html
- - $httpproxy
The network address of an http proxy server,
-in the format expected by dial(2). If $httpproxy is not set
-or is null, no proxy server is used.
-
-Command line
-If the mothra command has an argument, it is the name of a url to visit
-instead of the startup page. Giving mothra the -i flag disables loading
-of inline images. The inline pix menu item will reset this option.
-Files
-Mothra creates several files in $home/lib/mothra.
-
-- mothra.log
a list of all the url's visited
- - mothra.err
a log of error messages, mostly uninteresting
- - hit.html
the hit list used by the save hit
-and hit list commands. Since save hit only
-adds new urls to the end of this file, it is safe to edit it
-to add annotation or sort the saved urls.
-
-
-