Browse Source

Plan 9 from Bell Labs 2005-10-08

David du Colombier 18 years ago
parent
commit
60beb012df

+ 15 - 12
dist/replica/_plan9.db

@@ -329,7 +329,7 @@
 386/bin/mtime - 775 sys sys 1115950094 59139
 386/bin/mv - 775 sys sys 1126321691 65489
 386/bin/ndb - 20000000775 sys sys 985743147 0
-386/bin/ndb/cs - 775 sys sys 1125345996 149228
+386/bin/ndb/cs - 775 sys sys 1128707756 149400
 386/bin/ndb/csquery - 775 sys sys 1125345996 61467
 386/bin/ndb/dns - 775 sys sys 1127445050 245101
 386/bin/ndb/dnsdebug - 775 sys sys 1127445050 219717
@@ -5764,7 +5764,7 @@ sys/games - 20000000775 sys sys 952648872 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
-sys/games/lib/fortunes - 664 sys sys 1128093789 256215
+sys/games/lib/fortunes - 664 sys sys 1128693010 256476
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
@@ -6022,7 +6022,7 @@ sys/include/fcall.h - 664 sys sys 1032058178 3062
 sys/include/flate.h - 664 sys sys 1014929063 1245
 sys/include/frame.h - 664 sys sys 1014929063 2666
 sys/include/geometry.h - 664 sys sys 1014929063 2632
-sys/include/html.h - 664 sys sys 1091904420 15220
+sys/include/html.h - 664 sys sys 1128662123 15232
 sys/include/httpd.h - 664 sys sys 1091904418 5771
 sys/include/ip.h - 664 sys sys 1103554773 2989
 sys/include/keyboard.h - 664 sys sys 1079577798 815
@@ -7642,7 +7642,7 @@ sys/man/6/map - 664 sys sys 944959678 1892
 sys/man/6/mpictures - 664 sys sys 944959678 2899
 sys/man/6/ms - 664 sys sys 958249504 6815
 sys/man/6/namespace - 664 sys sys 1048637182 1576
-sys/man/6/ndb - 664 sys sys 1108476850 6113
+sys/man/6/ndb - 664 sys sys 1128707622 6431
 sys/man/6/plot - 664 sys sys 944959679 6739
 sys/man/6/plumb - 664 sys sys 969499892 10918
 sys/man/6/regexp - 664 sys sys 954089523 2050
@@ -12244,7 +12244,7 @@ sys/src/cmd/mv.c - 664 sys sys 1126278115 4241
 sys/src/cmd/ndb - 20000000775 sys sys 988249988 0
 sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1119276409 6866
 sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1060612175 7248
-sys/src/cmd/ndb/cs.c - 664 sys sys 1104854491 33070
+sys/src/cmd/ndb/cs.c - 664 sys sys 1128706486 33223
 sys/src/cmd/ndb/csgetval.c - 664 sys sys 957402051 1051
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1014926159 1062
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1123602793 18275
@@ -13627,17 +13627,17 @@ sys/src/cmd/wc.c - 664 sys sys 984717764 12652
 sys/src/cmd/webcookies.c - 664 sys sys 1068411571 23687
 sys/src/cmd/webfs - 20000000775 sys sys 1015015823 0
 sys/src/cmd/webfs/buf.c - 664 sys sys 1032665987 1198
-sys/src/cmd/webfs/client.c - 664 sys sys 1045503603 6504
-sys/src/cmd/webfs/cookies.c - 664 sys sys 1068412965 21874
-sys/src/cmd/webfs/dat.h - 664 sys sys 1045503604 1600
+sys/src/cmd/webfs/client.c - 664 sys sys 1128664611 6608
+sys/src/cmd/webfs/cookies.c - 664 sys sys 1128664611 21888
+sys/src/cmd/webfs/dat.h - 664 sys sys 1128664462 1621
 sys/src/cmd/webfs/fns.h - 664 sys sys 1032665987 1453
-sys/src/cmd/webfs/fs.c - 664 sys sys 1036000101 10942
-sys/src/cmd/webfs/http.c - 664 sys sys 1067722969 6726
+sys/src/cmd/webfs/fs.c - 664 sys sys 1128664603 10944
+sys/src/cmd/webfs/http.c - 664 sys sys 1128666924 9396
 sys/src/cmd/webfs/io.c - 664 sys sys 1034736588 1384
-sys/src/cmd/webfs/main.c - 664 sys sys 1067722969 1062
+sys/src/cmd/webfs/main.c - 664 sys sys 1128664462 1083
 sys/src/cmd/webfs/mkfile - 664 sys sys 1032665986 340
 sys/src/cmd/webfs/plumb.c - 664 sys sys 1015090008 2761
-sys/src/cmd/webfs/url.c - 664 sys sys 1019240175 24238
+sys/src/cmd/webfs/url.c - 664 sys sys 1128664462 24144
 sys/src/cmd/webfs/util.c - 664 sys sys 1015015823 1211
 sys/src/cmd/webfs/webget.c - 664 sys sys 1124711795 1589
 sys/src/cmd/webfsget.c - 664 sys sys 1068413017 1595
@@ -14967,3 +14967,6 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+386/bin/webfs - 775 sys sys 1128740945 353759
+386/bin/ndb/cs - 775 sys sys 1128740944 149386
+386/lib/libhtml.a - 664 sys sys 1128740945 220134

+ 14 - 14
dist/replica/plan9.db

@@ -329,7 +329,7 @@
 386/bin/mtime - 775 sys sys 1115950094 59139
 386/bin/mv - 775 sys sys 1126321691 65489
 386/bin/ndb - 20000000775 sys sys 985743147 0
-386/bin/ndb/cs - 775 sys sys 1125345996 149228
+386/bin/ndb/cs - 775 sys sys 1128740944 149386
 386/bin/ndb/csquery - 775 sys sys 1125345996 61467
 386/bin/ndb/dns - 775 sys sys 1127445050 245101
 386/bin/ndb/dnsdebug - 775 sys sys 1127445050 219717
@@ -501,7 +501,7 @@
 386/bin/vtdump - 775 sys sys 1125346038 159458
 386/bin/wc - 775 sys sys 1115950143 41156
 386/bin/webcookies - 775 sys sys 1125346039 161625
-386/bin/webfs - 775 sys sys 1127360616 350516
+386/bin/webfs - 775 sys sys 1128740945 353759
 386/bin/webfsget - 775 sys sys 1115950144 39143
 386/bin/wikifs - 775 sys sys 1128222506 202486
 386/bin/winwatch - 775 sys sys 1115950145 154555
@@ -547,7 +547,7 @@
 386/lib/libflate.a - 664 sys sys 1115950153 76872
 386/lib/libframe.a - 664 sys sys 1115950153 66060
 386/lib/libgeometry.a - 664 sys sys 1115950153 50470
-386/lib/libhtml.a - 664 sys sys 1127360619 220134
+386/lib/libhtml.a - 664 sys sys 1128740945 220134
 386/lib/libhttpd.a - 664 sys sys 1127790504 99596
 386/lib/libip.a - 664 sys sys 1116126324 35602
 386/lib/libl.a - 664 sys sys 1115950154 5384
@@ -5764,7 +5764,7 @@ sys/games - 20000000775 sys sys 952648872 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
-sys/games/lib/fortunes - 664 sys sys 1128093789 256215
+sys/games/lib/fortunes - 664 sys sys 1128693010 256476
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
@@ -6022,7 +6022,7 @@ sys/include/fcall.h - 664 sys sys 1032058178 3062
 sys/include/flate.h - 664 sys sys 1014929063 1245
 sys/include/frame.h - 664 sys sys 1014929063 2666
 sys/include/geometry.h - 664 sys sys 1014929063 2632
-sys/include/html.h - 664 sys sys 1091904420 15220
+sys/include/html.h - 664 sys sys 1128662123 15232
 sys/include/httpd.h - 664 sys sys 1091904418 5771
 sys/include/ip.h - 664 sys sys 1103554773 2989
 sys/include/keyboard.h - 664 sys sys 1079577798 815
@@ -7642,7 +7642,7 @@ sys/man/6/map - 664 sys sys 944959678 1892
 sys/man/6/mpictures - 664 sys sys 944959678 2899
 sys/man/6/ms - 664 sys sys 958249504 6815
 sys/man/6/namespace - 664 sys sys 1048637182 1576
-sys/man/6/ndb - 664 sys sys 1108476850 6113
+sys/man/6/ndb - 664 sys sys 1128707622 6431
 sys/man/6/plot - 664 sys sys 944959679 6739
 sys/man/6/plumb - 664 sys sys 969499892 10918
 sys/man/6/regexp - 664 sys sys 954089523 2050
@@ -12244,7 +12244,7 @@ sys/src/cmd/mv.c - 664 sys sys 1126278115 4241
 sys/src/cmd/ndb - 20000000775 sys sys 988249988 0
 sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1119276409 6866
 sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1060612175 7248
-sys/src/cmd/ndb/cs.c - 664 sys sys 1104854491 33070
+sys/src/cmd/ndb/cs.c - 664 sys sys 1128706486 33223
 sys/src/cmd/ndb/csgetval.c - 664 sys sys 957402051 1051
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1014926159 1062
 sys/src/cmd/ndb/dblookup.c - 664 sys sys 1123602793 18275
@@ -13627,17 +13627,17 @@ sys/src/cmd/wc.c - 664 sys sys 984717764 12652
 sys/src/cmd/webcookies.c - 664 sys sys 1068411571 23687
 sys/src/cmd/webfs - 20000000775 sys sys 1015015823 0
 sys/src/cmd/webfs/buf.c - 664 sys sys 1032665987 1198
-sys/src/cmd/webfs/client.c - 664 sys sys 1045503603 6504
-sys/src/cmd/webfs/cookies.c - 664 sys sys 1068412965 21874
-sys/src/cmd/webfs/dat.h - 664 sys sys 1045503604 1600
+sys/src/cmd/webfs/client.c - 664 sys sys 1128664611 6608
+sys/src/cmd/webfs/cookies.c - 664 sys sys 1128664611 21888
+sys/src/cmd/webfs/dat.h - 664 sys sys 1128664462 1621
 sys/src/cmd/webfs/fns.h - 664 sys sys 1032665987 1453
-sys/src/cmd/webfs/fs.c - 664 sys sys 1036000101 10942
-sys/src/cmd/webfs/http.c - 664 sys sys 1067722969 6726
+sys/src/cmd/webfs/fs.c - 664 sys sys 1128664603 10944
+sys/src/cmd/webfs/http.c - 664 sys sys 1128666924 9396
 sys/src/cmd/webfs/io.c - 664 sys sys 1034736588 1384
-sys/src/cmd/webfs/main.c - 664 sys sys 1067722969 1062
+sys/src/cmd/webfs/main.c - 664 sys sys 1128664462 1083
 sys/src/cmd/webfs/mkfile - 664 sys sys 1032665986 340
 sys/src/cmd/webfs/plumb.c - 664 sys sys 1015090008 2761
-sys/src/cmd/webfs/url.c - 664 sys sys 1019240175 24238
+sys/src/cmd/webfs/url.c - 664 sys sys 1128664462 24144
 sys/src/cmd/webfs/util.c - 664 sys sys 1015015823 1211
 sys/src/cmd/webfs/webget.c - 664 sys sys 1124711795 1589
 sys/src/cmd/webfsget.c - 664 sys sys 1068413017 1595

+ 16 - 0
dist/replica/plan9.log

@@ -21588,3 +21588,19 @@
 1128569448 22 c 386/lib/libauth.a - 664 sys sys 1128568181 58648
 1128573048 0 c mail/lib/validateattachment - 775 upas upas 1128571809 1144
 1128607256 0 m sys/src/cmd/ip/httpfile.c - 664 sys sys 1128556975 10037
+1128663072 0 c sys/include/html.h - 664 sys sys 1128662123 15232
+1128664873 0 c sys/src/cmd/webfs/client.c - 664 sys sys 1128664611 6608
+1128664873 1 c sys/src/cmd/webfs/cookies.c - 664 sys sys 1128664611 21888
+1128664873 2 c sys/src/cmd/webfs/dat.h - 664 sys sys 1128664462 1621
+1128664873 3 c sys/src/cmd/webfs/fs.c - 664 sys sys 1128664603 10944
+1128664873 4 c sys/src/cmd/webfs/http.c - 664 sys sys 1128664462 9422
+1128664873 5 c sys/src/cmd/webfs/main.c - 664 sys sys 1128664462 1083
+1128664873 6 c sys/src/cmd/webfs/url.c - 664 sys sys 1128664462 24144
+1128668474 0 c sys/src/cmd/webfs/http.c - 664 sys sys 1128666924 9396
+1128693678 0 c sys/games/lib/fortunes - 664 sys sys 1128693010 256476
+1128708082 0 c 386/bin/ndb/cs - 775 sys sys 1128707756 149400
+1128708082 1 c sys/man/6/ndb - 664 sys sys 1128707622 6431
+1128708082 2 c sys/src/cmd/ndb/cs.c - 664 sys sys 1128706486 33223
+1128742294 0 c 386/bin/webfs - 775 sys sys 1128740945 353759
+1128742294 1 c 386/bin/ndb/cs - 775 sys sys 1128740944 149386
+1128742294 2 c 386/lib/libhtml.a - 664 sys sys 1128740945 220134

+ 3 - 0
sys/games/lib/fortunes

@@ -4087,3 +4087,6 @@ Linux is for people who hate Windows.  BSD is for people who love UNIX.
 If plan9 was a village then I'd probably be the village idiot, but it would still be better than living in the city.  - Dave Lukes
 Software has gotten too fat and unreliable, so we started with Linux.  - Nicholas Negroponte
 Forgive my ignorance, I am a layman and nowadays get my schooling through search engine results.  - Vester Thacker
+By tradition, the return value of functions report what they did, not what they considered doing.  - rob
+If the restaurant serves poor beer, don't switch to wine. - sape
+There is nothing quite like looking up and seeing YOUR star.  Order now for FREE SHIPPING.

+ 1 - 0
sys/include/html.h

@@ -227,6 +227,7 @@ struct Iformfield
 {
 	Item;				// (with tag ==Iformfieldtag)
 	Formfield*	formfield;
+	void*	aux;
 };
 
 

+ 21 - 1
sys/man/6/ndb

@@ -254,6 +254,26 @@ start of area (for DNS)
 .sp
 .PD
 .PP
+.I Cs
+defers to
+.I dns
+to translate dotted names to IP addresses,
+only consulting the database files if
+.I dns
+cannot translate the name.
+.PP
+.I Cs
+allows network entries with
+.B sys
+and
+.B dom
+attributes but no
+.B ip
+attribute.
+Searches for the system name are resolved
+by looking up the domain name with
+.IR dns .
+.PP
 The file
 .B /lib/ndb/auth
 is used during authentication to decide who has the power to `speak for' other
@@ -264,7 +284,7 @@ users; see
 A tuple for the CPU server, spindle.
 .LP
 .EX
-sys = spindle
+sys=spindle
 	dom=spindle.research.bell-labs.com
 	bootf=/mips/9powerboot
 	ip=135.104.117.32 ether=080069020677

+ 8 - 1
sys/src/cmd/ndb/cs.c

@@ -1330,7 +1330,7 @@ ipattrlookup(Ndb *db, char *ipa, char *attr, char *val, int vlen)
 Ndbtuple*
 iplookup(Network *np, char *host, char *serv, int nolookup)
 {
-	char *attr;
+	char *attr, *dnsname;
 	Ndbtuple *t, *nt;
 	Ndbs s;
 	char ts[Maxservice];
@@ -1397,6 +1397,13 @@ iplookup(Network *np, char *host, char *serv, int nolookup)
 		t = dnsiplookup(host, &s);
 	if(t == 0)
 		free(ndbgetvalue(db, &s, attr, host, "ip", &t));
+	if(t == 0){
+		dnsname = ndbgetvalue(db, &s, attr, host, "dom", nil);
+		if(dnsname){
+			t = dnsiplookup(dnsname, &s);
+			free(dnsname);
+		}
+	}
 	if(t == 0)
 		t = dnsiplookup(host, &s);
 	if(t == 0)

+ 7 - 3
sys/src/cmd/webfs/client.c

@@ -55,6 +55,8 @@ closeclient(Client *c)
 		c->url = nil;
 		free(c->redirect);
 		c->redirect = nil;
+		free(c->authenticate);
+		c->authenticate = nil;
 		c->npostbody = 0;
 		c->havepostbody = 0;
 		c->bodyopened = 0;
@@ -101,6 +103,8 @@ clientbodyopen(Client *c, Req *r)
 				respond(r, e);
 			return;
 		}
+		if (c->authenticate)
+			continue;
 		if(!c->redirect)
 			break;
 		next = c->redirect;
@@ -292,7 +296,7 @@ ctlwrite(Req *r, Ctl *ctl, char *cmd, char *arg)
 
 	if((t = findcmd(cmd, ctltab, nelem(ctltab))) == nil)
 		return 0;
-	a = (void*)((ulong)ctl+(int)t->offset);
+	a = (void*)((uintptr)ctl+(uintptr)t->offset);
 	parseas(r, arg, t->type, a);
 	return 1;
 }
@@ -305,7 +309,7 @@ clientctlwrite(Req *r, Client *c, char *cmd, char *arg)
 
 	if((t = findcmd(cmd, clienttab, nelem(clienttab))) == nil)
 		return 0;
-	a = (void*)((ulong)c+(int)t->offset);
+	a = (void*)((uintptr)c+(uintptr)t->offset);
 	parseas(r, arg, t->type, a);
 	return 1;
 }
@@ -331,7 +335,7 @@ ctlfmt(Ctl *c, char *s)
 	char *t;
 
 	for(i=0; i<nelem(ctltab); i++){
-		a = (void*)((ulong)c+(int)ctltab[i].offset);
+		a = (void*)((uintptr)c+(uintptr)ctltab[i].offset);
 		switch(ctltab[i].type){
 		case Bool:
 			s += sprint(s, "%s %s\n", ctltab[i].name, *(int*)a ? "on" : "off");

+ 7 - 7
sys/src/cmd/webfs/cookies.c

@@ -108,7 +108,7 @@ cookiefmt(Fmt *fp)
 
 	first = 1;
 	for(j=0; j<nelem(stab); j++){
-		t = *(char**)((ulong)c+stab[j].offset);
+		t = *(char**)((uintptr)c+stab[j].offset);
 		if(t == nil)
 			continue;
 		if(first)
@@ -118,7 +118,7 @@ cookiefmt(Fmt *fp)
 		fmtprint(fp, "%s=%q", stab[j].s, t);
 	}
 	for(j=0; j<nelem(itab); j++){
-		k = *(int*)((ulong)c+itab[j].offset);
+		k = *(int*)((uintptr)c+itab[j].offset);
 		if(k == 0)
 			continue;
 		if(first)
@@ -197,7 +197,7 @@ freecookie(Cookie *c)
 	int i;
 
 	for(i=0; i<nelem(stab); i++)
-		free(*(char**)((ulong)c+stab[i].offset));
+		free(*(char**)((uintptr)c+stab[i].offset));
 }
 
 static void
@@ -207,7 +207,7 @@ copycookie(Cookie *c)
 	char **ps;
 
 	for(i=0; i<nelem(stab); i++){
-		ps = (char**)((ulong)c+stab[i].offset);
+		ps = (char**)((uintptr)c+stab[i].offset);
 		if(*ps)
 			*ps = estrdup9p(*ps);
 	}
@@ -295,14 +295,14 @@ addtojar(Jar *jar, char *line, int ondisk)
 		/* string attributes */
 		for(j=0; j<nelem(stab); j++){
 			if(strcmp(stab[j].s, attr) == 0){
-				pstr = (char**)((ulong)&c+stab[j].offset);
+				pstr = (char**)((uintptr)&c+stab[j].offset);
 				*pstr = val;
 			}
 		}
 		/* integer attributes */
 		for(j=0; j<nelem(itab); j++){
 			if(strcmp(itab[j].s, attr) == 0){
-				pint = (int*)((ulong)&c+itab[j].offset);
+				pint = (int*)((uintptr)&c+itab[j].offset);
 				if(val[0]=='\0')
 					*pint = 1;
 				else
@@ -967,7 +967,7 @@ parsecookie(Cookie *c, char *p, char **e, int isns, char *dom, char *path)
 		}
 		for(i=0; i<nelem(stab); i++)
 			if(stab[i].ishttp && cistrcmp(stab[i].s, attr)==0)
-				*(char**)((ulong)c+stab[i].offset) = val;
+				*(char**)((uintptr)c+stab[i].offset) = val;
 		if(cistrcmp(attr, "expires") == 0){
 			if(!isns)
 				return "non-netscape cookie has Expires tag";

+ 1 - 0
sys/src/cmd/webfs/dat.h

@@ -31,6 +31,7 @@ struct Client
 	char *contenttype;
 	char *postbody;
 	char *redirect;
+	char *authenticate;
 	char *ext;
 	int npostbody;
 	int havepostbody;

+ 1 - 1
sys/src/cmd/webfs/fs.c

@@ -273,7 +273,7 @@ fsread(Req *r)
 		c = client[NUM(path)];
 		r->ofcall.count = 0;
 		if(c->url != nil
-		&& (s = *(char**)((ulong)c->url+tab[TYPE(path)].offset)) != nil)
+		&& (s = *(char**)((uintptr)c->url+tab[TYPE(path)].offset)) != nil)
 			readstr(r, s);
 		respond(r, nil);
 		break;

+ 137 - 4
sys/src/cmd/webfs/http.c

@@ -6,6 +6,8 @@
 #include <thread.h>
 #include <fcall.h>
 #include <9p.h>
+#include <libsec.h>
+#include <auth.h>
 #include "dat.h"
 #include "fns.h"
 
@@ -20,6 +22,8 @@ struct HttpState
 	char *location;
 	char *setcookie;
 	char *netaddr;
+	char *credentials;
+	char autherror[ERRMAX];
 	Ibuf	b;
 };
 
@@ -57,6 +61,106 @@ setcookie(HttpState *hs, char *value)
 	}
 }
 
+static char*
+unquote(char *s, char **ps)
+{
+	char *p;
+
+	if(*s != '"'){
+		p = strpbrk(s, " \t\r\n");
+		*p++ = 0;
+		*ps = p;
+		return s;
+	}
+	for(p=s+1; *p; p++){
+		if(*p == '\"'){
+			*p++ = 0;
+			break;
+		}
+		if(*p == '\\' && *(p+1)){
+			p++;
+			continue;
+		}
+	}
+	memmove(s, s+1, p-(s+1));
+	s[p-(s+1)] = 0;
+	*ps = p;
+	return s;
+}
+
+static char*
+servername(char *addr)
+{
+	char *p;
+
+	if(strncmp(addr, "tcp!", 4) == 0
+	|| strncmp(addr, "net!", 4) == 0)
+		addr += 4;
+	addr = estrdup(addr);
+	p = addr+strlen(addr);
+	if(p>addr && *(p-1) == 's')
+		p--;
+	if(p>addr+5 && strcmp(p-5, "!http") == 0)
+		p[-5] = 0;
+	return addr;
+}
+
+void
+wwwauthenticate(HttpState *hs, char *line)
+{
+	char cred[64], *user, *pass, *realm, *s, *spec, *name;
+	Fmt fmt;
+	UserPasswd *up;
+
+	spec = nil;
+	up = nil;
+	cred[0] = 0;
+	hs->autherror[0] = 0;
+	if(cistrncmp(line, "basic ", 6) != 0){
+		werrstr("unknown auth: %s", line);
+		goto error;
+	}
+	line += 6;
+	if(cistrncmp(line, "realm=", 6) != 0){
+		werrstr("missing realm: %s", line);
+		goto error;
+	}
+	line += 6;
+	user = hs->c->url->user;
+	pass = hs->c->url->passwd;
+	if(user==nil || pass==nil){
+		realm = unquote(line, &line);
+		fmtstrinit(&fmt);
+		name = servername(hs->netaddr);
+		fmtprint(&fmt, "proto=pass service=http server=%q realm=%q", name, realm);
+		free(name);
+		if(hs->c->url->user)
+			fmtprint(&fmt, " user=%q", hs->c->url->user);
+		spec = fmtstrflush(&fmt);
+		if(spec == nil)
+			goto error;
+		if((up = auth_getuserpasswd(nil, "%s", spec)) == nil)
+			goto error;
+		user = up->user;
+		pass = up->passwd;
+	}
+	if((s = smprint("%s:%s", user, pass)) == nil)
+		goto error;
+	free(up);
+	enc64(cred, sizeof(cred), (uchar*)s, strlen(s));
+	memset(s, 0, strlen(s));
+	free(s);
+	hs->credentials = smprint("Basic %s", cred);
+	if(hs->credentials == nil)
+		goto error;
+	return;
+
+error:
+	free(up);
+	free(spec);
+	snprint(hs->autherror, sizeof hs->autherror, "%r");
+}
+
 struct {
 	char *name;									/* Case-insensitive */
 	void (*fn)(HttpState *hs, char *value);
@@ -64,6 +168,7 @@ struct {
 	{ "location:", location },
 	{ "content-type:", contenttype },
 	{ "set-cookie:", setcookie },
+	{ "www-authenticate:", wwwauthenticate },
 };
 
 static int
@@ -137,9 +242,9 @@ httpheaders(HttpState *hs)
 		n = getheader(hs, buf, sizeof(buf));
 		if(n < 0)
 			return -1;
-		if (n == 0)
+		if(n == 0)
 			return 0;
-//print("http header: '%.*s'\n", n, buf);
+		//	print("http header: '%.*s'\n", n, buf);
 		for(i = 0; i < nelem(hdrtab); i++){
 			n = strlen(hdrtab[i].name);
 			if(cistrncmp(buf, hdrtab[i].name, n) == 0){
@@ -158,7 +263,7 @@ httpheaders(HttpState *hs)
 int
 httpopen(Client *c, Url *url)
 {
-	int fd, code, redirect;
+	int fd, code, redirect, authenticate;
 	char *cookies;
 	Ioproc *io;
 	HttpState *hs;
@@ -211,6 +316,11 @@ httpopen(Client *c, Url *url)
 			fprint(2, "<- Content-length: %ud\n", c->npostbody);
 		}
 	}
+	if(c->authenticate){
+		ioprint(io, fd, "Authorization: %s\r\n", c->authenticate);
+		if(httpdebug)
+			fprint(2, "<- Authorization: %s\n", c->authenticate);
+	}
 	ioprint(io, fd, "\r\n");
 	if(c->havepostbody)
 		if(iowrite(io, fd, c->postbody, c->npostbody) != c->npostbody)
@@ -218,6 +328,7 @@ httpopen(Client *c, Url *url)
 
 	c->havepostbody = 0;
 	redirect = 0;
+	authenticate = 0;
 	initibuf(&hs->b, io, fd);
 	code = httprcode(hs);
 
@@ -258,8 +369,14 @@ httpopen(Client *c, Url *url)
 		goto Error;
 
 	case 401:	/* Unauthorized */
+		if(c->authenticate){
+			werrstr("Authentication failed (401)");
+			goto Error;
+		}
+		authenticate = 1;
+		break;
 	case 402:	/* ??? */
-		werrstr("Unauthorized (401,402)");
+		werrstr("Unauthorized (402)");
 		goto Error;
 
 	case 403:	/* Forbidden */
@@ -270,6 +387,10 @@ httpopen(Client *c, Url *url)
 		werrstr("Not found on server (404)");
 		goto Error;
 
+	case 407:	/* Proxy auth */
+		werrstr("Proxy authentication required (407)");
+		goto Error;
+
 	case 500:	/* Internal server error */
 		werrstr("Server choked (500)");
 		goto Error;
@@ -296,6 +417,17 @@ httpopen(Client *c, Url *url)
 		goto Error;
 	if(c->ctl.acceptcookies && hs->setcookie)
 		httpsetcookie(hs->setcookie, url->host, url->path);
+	if(authenticate){
+		if(!hs->credentials){
+			if(hs->autherror[0])
+				werrstr("%s", hs->autherror);
+			else
+				werrstr("unauthorized; no www-authenticate: header");
+			return -1;
+		}
+		c->authenticate = hs->credentials;
+		hs->credentials = nil;
+	}
 	if(redirect){
 		if(!hs->location){
 			werrstr("redirection without Location: header");
@@ -349,6 +481,7 @@ httpclose(Client *c)
 	free(hs->location);
 	free(hs->setcookie);
 	free(hs->netaddr);
+	free(hs->credentials);
 	free(hs);
 	c->aux = nil;
 }

+ 2 - 0
sys/src/cmd/webfs/main.c

@@ -49,6 +49,8 @@ threadmain(int argc, char **argv)
 	case 's':
 		service = EARGF(usage());
 		break;
+	default:
+		usage();
 	}ARGEND
 
 	quotefmtinstall();

+ 0 - 4
sys/src/cmd/webfs/url.c

@@ -735,10 +735,6 @@ postparse_http(Url *u)
 		werrstr("missing authority (hostname, port, etc.)");
 		return -1;
 	}
-	if(u->user || u->passwd){
-		werrstr("user information not valid with http");
-		return -1;
-	}
 	if(u->host == nil){
 		werrstr("missing host specification");
 		return -1;