]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/webfs/fs.c
git/branch: somewhere in the syncing, the fix for junk files was lost
[plan9front.git] / sys / src / cmd / webfs / fs.c
index 5e803d07d7797e94b62f214919930b080688c817..e4e08670daba7be2e4feda2f99bcd79cb3428360 100644 (file)
@@ -76,13 +76,15 @@ static char *nametab[] = {
                        nil,
 };
 
+static char *mtpt;
+static char *service;
 static long time0;
 static char *user;
 static char *agent;
 static Client client[64];
 static int nclient;
 
-#define        CLIENTID(c)     (((Client*)(c)) - client)
+#define        CLIENTID(c)     ((int)(((Client*)(c)) - client))
 
 Client*
 newclient(void)
@@ -167,7 +169,7 @@ fsmkqid(Qid *q, int level, void *aux)
        case Qclient:
                q->type = QTDIR;
        default:
-               q->path = (level<<24) | (((ulong)aux ^ time0) & 0x00ffffff);
+               q->path = (level<<24) | (((uintptr)aux ^ time0) & 0x00ffffff);
        }
 }
 
@@ -220,7 +222,7 @@ fsmkdir(Dir *d, int level, void *aux)
                d->length = strlen(((Key*)aux)->val);
                break;
        case Qclient:
-               snprint(buf, sizeof(buf), "%ld", CLIENTID(aux));
+               snprint(buf, sizeof(buf), "%d", CLIENTID(aux));
                d->name = estrdup(buf);
                break;
        case Qctl:
@@ -405,24 +407,6 @@ fsopen(Req *r)
                        if(!lookkey(cl->hdr, "Accept"))
                                cl->hdr = addkey(cl->hdr, "Accept", "*/*");
 
-                       if(!lookkey(cl->hdr, "Referer")){
-                               char *r;
-                               Url *u;
-
-                               /*
-                                * Referer header is often required on broken
-                                * websites even if the spec makes them optional,
-                                * so we make one up.
-                                */
-                               if(u = url("/", cl->url)){
-                                       if(r = smprint("%U", u)){
-                                               cl->hdr = addkey(cl->hdr, "Referer", r);
-                                               free(r);
-                                       }
-                                       freeurl(u);
-                               }
-                       }
-
                        if(!lookkey(cl->hdr, "Connection"))
                                cl->hdr = addkey(cl->hdr, "Connection", "keep-alive");
 
@@ -519,7 +503,7 @@ fsread(Req *r)
                respond(r, nil);
                return;
        case Qctl:
-               snprint(buf, sizeof(buf), "%ld\n", CLIENTID(f->client));
+               snprint(buf, sizeof(buf), "%d\n", CLIENTID(f->client));
                goto String;
        case Qheader:
                snprint(buf, sizeof(buf), "%s", f->key->val);
@@ -543,7 +527,7 @@ fsread(Req *r)
 }
 
 static char*
-rootctl(char *ctl, char *arg)
+rootctl(Srv *fs, char *ctl, char *arg)
 {
        Url *u;
 
@@ -578,6 +562,28 @@ rootctl(char *ctl, char *arg)
                return nil;
        }
 
+       /* ppreemptive authentication only basic
+        * auth supported, ctl message of the form:
+        *    preauth url realm
+        */
+       if(!strcmp(ctl, "preauth")){
+               char *a[3], buf[256];
+               int rc;
+
+               if(tokenize(arg, a, nelem(a)) != 2)
+                       return "preauth - bad field count";
+               if((u = saneurl(url(a[0], 0))) == nil)
+                       return "preauth - malformed url";
+               snprint(buf, sizeof(buf), "BASIC realm=\"%s\"", a[1]);
+               srvrelease(fs);
+               rc = authenticate(u, u, "GET", buf);
+               srvacquire(fs);
+               freeurl(u);
+               if(rc == -1)
+                       return "preauth failed";
+               return nil;
+       }
+
        return "bad ctl message";
 }
 
@@ -613,7 +619,7 @@ clientctl(Client *cl, char *ctl, char *arg)
        else if(!strcmp(ctl, "headers")){
                while(arg && *arg){
                        ctl = arg;
-                       while(*ctl && strchr("\r\n\t ", *ctl))
+                       while(*ctl && strchr(whitespace, *ctl))
                                ctl++;
                        if(arg = strchr(ctl, '\n'))
                                *arg++ = 0;
@@ -663,14 +669,14 @@ fswrite(Req *r)
                        n--;
                s[n] = 0;
                t = s;
-               while(*t && strchr("\r\n\t ", *t)==0)
+               while(*t && strchr(whitespace, *t)==0)
                        t++;
-               while(*t && strchr("\r\n\t ", *t))
+               while(*t && strchr(whitespace, *t))
                        *t++ = 0;
                if(f->level == Qctl)
                        t = clientctl(f->client, s, t);
                else
-                       t = rootctl(s, t);
+                       t = rootctl(r->srv, s, t);
                free(s);
                respond(r, t);
                return;
@@ -715,8 +721,24 @@ fsdestroyfid(Fid *fid)
        }
 }
 
+static void
+fsstart(Srv*)
+{
+       /* drop reference to old webfs mount */
+       if(mtpt != nil)
+               unmount(nil, mtpt);
+}
+
+static void
+fsend(Srv*)
+{
+       postnote(PNGROUP, getpid(), "shutdown");
+       exits(nil);
+}
+
 Srv fs = 
 {
+       .start=fsstart,
        .attach=fsattach,
        .stat=fsstat,
        .walk1=fswalk1,
@@ -726,30 +748,33 @@ Srv fs =
        .write=fswrite,
        .flush=fsflush,
        .destroyfid=fsdestroyfid,
+       .end=fsend,
 };
 
 void
 usage(void)
 {
-       fprint(2, "usage: %s [-D] [-A useragent] [-T timeout] [-m mtpt] [-s srv]\n", argv0);
+       fprint(2, "usage: %s [-Dd] [-A useragent] [-T timeout] [-m mtpt] [-s service]\n", argv0);
        exits("usage");
 }
 
 void
 main(int argc, char *argv[])
 {
-       char *srv, *mtpt, *s;
+       char *s;
 
        quotefmtinstall();
        fmtinstall('U', Ufmt);
+       fmtinstall('N', Nfmt);
+       fmtinstall(']', Mfmt);
        fmtinstall('E', Efmt);
+       fmtinstall('[', encodefmt);
+       fmtinstall('H', encodefmt);
 
-       srv = nil;
        mtpt = "/mnt/web";
        user = getuser();
        time0 = time(0);
        timeout = 10000;
-       agent = nil;
 
        ARGBEGIN {
        case 'D':
@@ -767,7 +792,7 @@ main(int argc, char *argv[])
                mtpt = EARGF(usage());
                break;
        case 's':
-               srv = EARGF(usage());
+               service = EARGF(usage());
                break;
        case 'd':
                debug++;
@@ -779,13 +804,16 @@ main(int argc, char *argv[])
        rfork(RFNOTEG);
 
        if(agent == nil)
-               agent = "hjdicks";
+               agent = "Mozilla/5.0 (compatible; hjdicks)";
        agent = estrdup(agent);
 
        if(s = getenv("httpproxy")){
                proxy = saneurl(url(s, 0));
+               if(proxy == nil || strcmp(proxy->scheme, "http") && strcmp(proxy->scheme, "https"))
+                       sysfatal("invalid httpproxy url: %s", s);
                free(s);
        }
 
-       postmountsrv(&fs, srv, mtpt, MREPL);
+       postmountsrv(&fs, service, mtpt, MREPL);
+       exits(nil);
 }