Browse Source

Plan 9 from Bell Labs Fourth Edition 2005-09-02

David du Colombier 19 years ago
parent
commit
8b6d9ba040
7 changed files with 153 additions and 50 deletions
  1. 12 18
      dist/replica/_plan9.db
  2. 5 5
      dist/replica/plan9.db
  3. 9 0
      dist/replica/plan9.log
  4. 2 0
      sys/games/lib/fortunes
  5. 2 0
      sys/src/9/pc/mmu.c
  6. 83 19
      sys/src/9/port/chan.c
  7. 40 8
      sys/src/cmd/tar.c

+ 12 - 18
dist/replica/_plan9.db

@@ -252,7 +252,7 @@
 386/bin/games/jukebox - 775 sys sys 1105589128 264821
 386/bin/games/jukebox - 775 sys sys 1105589128 264821
 386/bin/games/jukefs - 775 sys sys 1105589129 165320
 386/bin/games/jukefs - 775 sys sys 1105589129 165320
 386/bin/games/mahjongg - 775 sys sys 1125345978 164288
 386/bin/games/mahjongg - 775 sys sys 1125345978 164288
-386/bin/games/memo - 775 sys sys 1115950076 157374
+386/bin/games/memo - 775 sys sys 1125544173 156892
 386/bin/games/playlistfs - 775 sys sys 1105589129 148484
 386/bin/games/playlistfs - 775 sys sys 1105589129 148484
 386/bin/games/sokoban - 775 sys sys 1125345978 163379
 386/bin/games/sokoban - 775 sys sys 1125345978 163379
 386/bin/games/sudoku - 775 sys sys 1117249746 171666
 386/bin/games/sudoku - 775 sys sys 1117249746 171666
@@ -296,8 +296,8 @@
 386/bin/ip/imap4d - 775 sys sys 1125345987 236488
 386/bin/ip/imap4d - 775 sys sys 1125345987 236488
 386/bin/ip/ipconfig - 775 sys sys 1125345988 137742
 386/bin/ip/ipconfig - 775 sys sys 1125345988 137742
 386/bin/ip/ping - 775 sys sys 1116126319 77010
 386/bin/ip/ping - 775 sys sys 1116126319 77010
-386/bin/ip/ppp - 775 sys sys 1125345988 218875
-386/bin/ip/pppoe - 775 sys sys 1116126319 77535
+386/bin/ip/ppp - 775 sys sys 1125544173 218875
+386/bin/ip/pppoe - 775 sys sys 1125544173 77548
 386/bin/ip/pptp - 775 sys sys 1116126320 126658
 386/bin/ip/pptp - 775 sys sys 1116126320 126658
 386/bin/ip/pptpd - 775 sys sys 1125345988 125824
 386/bin/ip/pptpd - 775 sys sys 1125345988 125824
 386/bin/ip/rarpd - 775 sys sys 1125345990 111572
 386/bin/ip/rarpd - 775 sys sys 1125345990 111572
@@ -389,7 +389,7 @@
 386/bin/scp - 775 sys sys 1119496657 151927
 386/bin/scp - 775 sys sys 1119496657 151927
 386/bin/scuzz - 775 sys sys 1125346011 111604
 386/bin/scuzz - 775 sys sys 1125346011 111604
 386/bin/sed - 775 sys sys 1125346011 89514
 386/bin/sed - 775 sys sys 1125346011 89514
-386/bin/seq - 775 sys sys 1115950111 38206
+386/bin/seq - 775 sys sys 1125544174 38396
 386/bin/sha1sum - 775 sys sys 1115950111 61133
 386/bin/sha1sum - 775 sys sys 1115950111 61133
 386/bin/size - 775 sys sys 1119496658 76974
 386/bin/size - 775 sys sys 1119496658 76974
 386/bin/sleep - 775 sys sys 1085077097 3413
 386/bin/sleep - 775 sys sys 1085077097 3413
@@ -398,7 +398,7 @@
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/sniffer - 775 sys sys 1038443185 99028
 386/bin/snoopy - 775 sys sys 1125346014 157537
 386/bin/snoopy - 775 sys sys 1125346014 157537
 386/bin/sort - 775 sys sys 1125346014 82276
 386/bin/sort - 775 sys sys 1125346014 82276
-386/bin/spin - 775 sys sys 1116903736 655162
+386/bin/spin - 775 sys sys 1125544175 758333
 386/bin/split - 775 sys sys 1125346015 75635
 386/bin/split - 775 sys sys 1125346015 75635
 386/bin/srv - 775 sys sys 1115950113 82387
 386/bin/srv - 775 sys sys 1115950113 82387
 386/bin/srvfs - 775 sys sys 1116903736 40065
 386/bin/srvfs - 775 sys sys 1116903736 40065
@@ -412,9 +412,9 @@
 386/bin/swap - 775 sys sys 1115950116 62094
 386/bin/swap - 775 sys sys 1115950116 62094
 386/bin/syscall - 775 sys sys 1115950116 73536
 386/bin/syscall - 775 sys sys 1115950116 73536
 386/bin/tail - 775 sys sys 1125346016 66169
 386/bin/tail - 775 sys sys 1125346016 66169
-386/bin/tar - 775 sys sys 1120014538 96347
+386/bin/tar - 775 sys sys 1125553200 97047
 386/bin/tbl - 775 sys sys 1125346017 113167
 386/bin/tbl - 775 sys sys 1125346017 113167
-386/bin/tcs - 775 sys sys 1125501123 256580
+386/bin/tcs - 775 sys sys 1125544176 256580
 386/bin/tee - 775 sys sys 1115950118 38428
 386/bin/tee - 775 sys sys 1115950118 38428
 386/bin/telco - 775 sys sys 1115950118 103315
 386/bin/telco - 775 sys sys 1115950118 103315
 386/bin/telnet - 775 sys sys 1125346017 80355
 386/bin/telnet - 775 sys sys 1125346017 80355
@@ -5764,7 +5764,7 @@ sys/games - 20000000775 sys sys 952648872 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
-sys/games/lib/fortunes - 664 sys sys 1125330091 255536
+sys/games/lib/fortunes - 664 sys sys 1125564446 255656
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
@@ -7969,7 +7969,7 @@ sys/src/9/pc/main.c - 664 sys sys 1121858827 14693
 sys/src/9/pc/mem.h - 664 sys sys 1018553448 4573
 sys/src/9/pc/mem.h - 664 sys sys 1018553448 4573
 sys/src/9/pc/memory.c - 664 sys sys 1071245460 13028
 sys/src/9/pc/memory.c - 664 sys sys 1071245460 13028
 sys/src/9/pc/mkfile - 664 sys sys 1067810339 3219
 sys/src/9/pc/mkfile - 664 sys sys 1067810339 3219
-sys/src/9/pc/mmu.c - 664 sys sys 1123645071 10456
+sys/src/9/pc/mmu.c - 664 sys sys 1125564128 10489
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
 sys/src/9/pc/mp.c - 664 sys sys 1123637234 17024
 sys/src/9/pc/mp.c - 664 sys sys 1123637234 17024
 sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
 sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
@@ -8039,7 +8039,7 @@ sys/src/9/port/alloc.c - 664 sys sys 1102093389 5645
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/cache.c - 664 sys sys 1055688274 9241
 sys/src/9/port/cache.c - 664 sys sys 1055688274 9241
-sys/src/9/port/chan.c - 664 sys sys 1125517669 30203
+sys/src/9/port/chan.c - 664 sys sys 1125551975 31560
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
 sys/src/9/port/dev.c - 664 sys sys 1077896125 8247
 sys/src/9/port/dev.c - 664 sys sys 1077896125 8247
@@ -12925,7 +12925,7 @@ sys/src/cmd/tapefs/v10fs.c - 664 sys sys 1014926385 3754
 sys/src/cmd/tapefs/v6fs.c - 664 sys sys 1014926385 3971
 sys/src/cmd/tapefs/v6fs.c - 664 sys sys 1014926385 3971
 sys/src/cmd/tapefs/zip.h - 664 sys sys 1097914153 1428
 sys/src/cmd/tapefs/zip.h - 664 sys sys 1097914153 1428
 sys/src/cmd/tapefs/zipfs.c - 664 sys sys 1097900277 6803
 sys/src/cmd/tapefs/zipfs.c - 664 sys sys 1097900277 6803
-sys/src/cmd/tar.c - 664 sys sys 1125515072 21269
+sys/src/cmd/tar.c - 664 sys sys 1125553195 21864
 sys/src/cmd/tbl - 20000000775 sys sys 954038038 0
 sys/src/cmd/tbl - 20000000775 sys sys 954038038 0
 sys/src/cmd/tbl/mkfile - 664 sys sys 944961243 268
 sys/src/cmd/tbl/mkfile - 664 sys sys 944961243 268
 sys/src/cmd/tbl/t.h - 664 sys sys 944961244 3987
 sys/src/cmd/tbl/t.h - 664 sys sys 944961244 3987
@@ -14961,10 +14961,4 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
-386/bin/games/memo - 775 sys sys 1125544173 156892
-386/bin/seq - 775 sys sys 1125544174 38396
-386/bin/spin - 775 sys sys 1125544175 758333
-386/bin/ip/ppp - 775 sys sys 1125544173 218875
-386/bin/ip/pppoe - 775 sys sys 1125544173 77548
-386/bin/tar - 775 sys sys 1125544175 96517
-386/bin/tcs - 775 sys sys 1125544176 256580
+386/bin/tar - 775 sys sys 1125631815 97035

+ 5 - 5
dist/replica/plan9.db

@@ -412,7 +412,7 @@
 386/bin/swap - 775 sys sys 1115950116 62094
 386/bin/swap - 775 sys sys 1115950116 62094
 386/bin/syscall - 775 sys sys 1115950116 73536
 386/bin/syscall - 775 sys sys 1115950116 73536
 386/bin/tail - 775 sys sys 1125346016 66169
 386/bin/tail - 775 sys sys 1125346016 66169
-386/bin/tar - 775 sys sys 1125544175 96517
+386/bin/tar - 775 sys sys 1125631815 97035
 386/bin/tbl - 775 sys sys 1125346017 113167
 386/bin/tbl - 775 sys sys 1125346017 113167
 386/bin/tcs - 775 sys sys 1125544176 256580
 386/bin/tcs - 775 sys sys 1125544176 256580
 386/bin/tee - 775 sys sys 1115950118 38428
 386/bin/tee - 775 sys sys 1115950118 38428
@@ -5764,7 +5764,7 @@ sys/games - 20000000775 sys sys 952648872 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib - 20000000775 sys sys 952648879 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/4scores - 10000000664 sys sys 1118680448 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
 sys/games/lib/5scores - 10000000664 sys sys 1118680453 0
-sys/games/lib/fortunes - 664 sys sys 1125330091 255536
+sys/games/lib/fortunes - 664 sys sys 1125564446 255656
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg - 20000000775 sys sys 1095792278 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds - 20000000775 sys sys 1095792293 0
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
 sys/games/lib/mahjongg/backgrounds/default.bit - 664 sys sys 1095792293 346803
@@ -7969,7 +7969,7 @@ sys/src/9/pc/main.c - 664 sys sys 1121858827 14693
 sys/src/9/pc/mem.h - 664 sys sys 1018553448 4573
 sys/src/9/pc/mem.h - 664 sys sys 1018553448 4573
 sys/src/9/pc/memory.c - 664 sys sys 1071245460 13028
 sys/src/9/pc/memory.c - 664 sys sys 1071245460 13028
 sys/src/9/pc/mkfile - 664 sys sys 1067810339 3219
 sys/src/9/pc/mkfile - 664 sys sys 1067810339 3219
-sys/src/9/pc/mmu.c - 664 sys sys 1123645071 10456
+sys/src/9/pc/mmu.c - 664 sys sys 1125564128 10489
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
 sys/src/9/pc/mouse.c - 664 sys sys 1098479254 7057
 sys/src/9/pc/mp.c - 664 sys sys 1123637234 17024
 sys/src/9/pc/mp.c - 664 sys sys 1123637234 17024
 sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
 sys/src/9/pc/mp.h - 664 sys sys 1015014520 6575
@@ -8039,7 +8039,7 @@ sys/src/9/port/alloc.c - 664 sys sys 1102093389 5645
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/allocb.c - 664 sys sys 1123676437 3340
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/auth.c - 664 sys sys 1123647282 2392
 sys/src/9/port/cache.c - 664 sys sys 1055688274 9241
 sys/src/9/port/cache.c - 664 sys sys 1055688274 9241
-sys/src/9/port/chan.c - 664 sys sys 1125517669 30203
+sys/src/9/port/chan.c - 664 sys sys 1125551975 31560
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/cis.c - 664 sys sys 1099761153 9248
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
 sys/src/9/port/debugalloc.c - 664 sys sys 1014931171 10402
 sys/src/9/port/dev.c - 664 sys sys 1077896125 8247
 sys/src/9/port/dev.c - 664 sys sys 1077896125 8247
@@ -12925,7 +12925,7 @@ sys/src/cmd/tapefs/v10fs.c - 664 sys sys 1014926385 3754
 sys/src/cmd/tapefs/v6fs.c - 664 sys sys 1014926385 3971
 sys/src/cmd/tapefs/v6fs.c - 664 sys sys 1014926385 3971
 sys/src/cmd/tapefs/zip.h - 664 sys sys 1097914153 1428
 sys/src/cmd/tapefs/zip.h - 664 sys sys 1097914153 1428
 sys/src/cmd/tapefs/zipfs.c - 664 sys sys 1097900277 6803
 sys/src/cmd/tapefs/zipfs.c - 664 sys sys 1097900277 6803
-sys/src/cmd/tar.c - 664 sys sys 1125515072 21269
+sys/src/cmd/tar.c - 664 sys sys 1125553195 21864
 sys/src/cmd/tbl - 20000000775 sys sys 954038038 0
 sys/src/cmd/tbl - 20000000775 sys sys 954038038 0
 sys/src/cmd/tbl/mkfile - 664 sys sys 944961243 268
 sys/src/cmd/tbl/mkfile - 664 sys sys 944961243 268
 sys/src/cmd/tbl/t.h - 664 sys sys 944961244 3987
 sys/src/cmd/tbl/t.h - 664 sys sys 944961244 3987

+ 9 - 0
dist/replica/plan9.log

@@ -21215,3 +21215,12 @@
 1125545475 4 c 386/bin/ip/pppoe - 775 sys sys 1125544173 77548
 1125545475 4 c 386/bin/ip/pppoe - 775 sys sys 1125544173 77548
 1125545475 5 c 386/bin/tar - 775 sys sys 1125544175 96517
 1125545475 5 c 386/bin/tar - 775 sys sys 1125544175 96517
 1125545475 6 c 386/bin/tcs - 775 sys sys 1125544176 256580
 1125545475 6 c 386/bin/tcs - 775 sys sys 1125544176 256580
+1125549108 0 c sys/src/9/port/chan.c - 664 sys sys 1125548499 31516
+1125552663 0 c 386/bin/tar - 775 sys sys 1125552254 96980
+1125552663 1 c sys/src/9/port/chan.c - 664 sys sys 1125551975 31560
+1125552663 2 c sys/src/cmd/tar.c - 664 sys sys 1125552250 21645
+1125554465 0 c 386/bin/tar - 775 sys sys 1125553200 97047
+1125554465 1 c sys/src/cmd/tar.c - 664 sys sys 1125553195 21864
+1125565267 0 c sys/games/lib/fortunes - 664 sys sys 1125564446 255656
+1125565267 1 c sys/src/9/pc/mmu.c - 664 sys sys 1125564128 10489
+1125631884 0 c 386/bin/tar - 775 sys sys 1125631815 97035

+ 2 - 0
sys/games/lib/fortunes

@@ -4080,3 +4080,5 @@ C++ is history repeated as tragedy.  Java is history repeated as farce.  - Scott
 Applicants must also have extensive knowledge of UNIX, although they should have sufficiently good programming taste to not consider this an achievement.  - Hal Abelson, MIT AI Lab job ad
 Applicants must also have extensive knowledge of UNIX, although they should have sufficiently good programming taste to not consider this an achievement.  - Hal Abelson, MIT AI Lab job ad
 I recently visited plan9.bell-labs.com/wiki/plan9 and I would like to offer my web design services.  I can help you with your Plan 9 website.  - spam
 I recently visited plan9.bell-labs.com/wiki/plan9 and I would like to offer my web design services.  I can help you with your Plan 9 website.  - spam
 There are no network problems with scone, hale and poptart. IT support is working these issues and we will notify you when the problem is resolved.
 There are no network problems with scone, hale and poptart. IT support is working these issues and we will notify you when the problem is resolved.
+A C, an E-flat, and a G walk into a bar.  The bartender says, "Sorry, but we don't serve minors."
+		exhausted("sleep");

+ 2 - 0
sys/src/9/pc/mmu.c

@@ -260,6 +260,8 @@ checkmmu(ulong va, ulong pa)
 	}
 	}
 	
 	
 	pte = KADDR(PPN(pdb[pdbx]));
 	pte = KADDR(PPN(pdb[pdbx]));
+	if(pte[PTX(va)] == 0)
+		return;
 	if((pte[PTX(va)]&~4095) != pa)
 	if((pte[PTX(va)]&~4095) != pa)
 		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
 		print("%ld %s: va=0x%08lux pa=0x%08lux pte=0x%08lux\n",
 			up->pid, up->text,
 			up->pid, up->text,

+ 83 - 19
sys/src/9/port/chan.c

@@ -84,6 +84,7 @@ struct Elemlist
 	int	*off;
 	int	*off;
 	int	mustbedir;
 	int	mustbedir;
 	int	nerror;
 	int	nerror;
+	int	prefix;
 };
 };
 
 
 #define SEP(c) ((c) == 0 || (c) == '/')
 #define SEP(c) ((c) == 0 || (c) == '/')
@@ -742,6 +743,21 @@ undomount(Chan *c, Cname *name)
 	return c;
 	return c;
 }
 }
 
 
+/*
+ * Walk but catch errors and return nil instead.
+ */
+static Walkqid*
+ewalk(Chan *c, Chan *nc, char **name, int nname)
+{
+	Walkqid *wq;
+
+	if(waserror())
+		return nil;
+	wq = devtab[c->type]->walk(c, nc, name, nname);
+	poperror();
+	return wq;
+}
+
 /*
 /*
  * Either walks all the way or not at all.  No partial results in *cp.
  * Either walks all the way or not at all.  No partial results in *cp.
  * *nerror is the number of names to display in an error message.
  * *nerror is the number of names to display in an error message.
@@ -790,10 +806,10 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
 		dotdot = 0;
 		dotdot = 0;
 		for(i=0; i<ntry; i++){
 		for(i=0; i<ntry; i++){
 			if(isdotdot(names[nhave+i])){
 			if(isdotdot(names[nhave+i])){
-				if(i==0) {
+				if(i==0){
 					dotdot = 1;
 					dotdot = 1;
 					ntry = 1;
 					ntry = 1;
-				} else
+				}else
 					ntry = i;
 					ntry = i;
 				break;
 				break;
 			}
 			}
@@ -805,7 +821,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
 		type = c->type;
 		type = c->type;
 		dev = c->dev;
 		dev = c->dev;
 
 
-		if((wq = devtab[type]->walk(c, nil, names+nhave, ntry)) == nil){
+		if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){
 			/* try a union mount, if any */
 			/* try a union mount, if any */
 			if(mh && !nomount){
 			if(mh && !nomount){
 				/*
 				/*
@@ -813,7 +829,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
 				 */
 				 */
 				rlock(&mh->lock);
 				rlock(&mh->lock);
 				for(f = mh->mount->next; f; f = f->next)
 				for(f = mh->mount->next; f; f = f->next)
-					if((wq = devtab[f->to->type]->walk(f->to, nil, names+nhave, ntry)) != nil)
+					if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil)
 						break;
 						break;
 				runlock(&mh->lock);
 				runlock(&mh->lock);
 				if(f != nil){
 				if(f != nil){
@@ -973,7 +989,7 @@ growparse(Elemlist *e)
 		free(e->elems);
 		free(e->elems);
 		e->elems = new;
 		e->elems = new;
 		inew = smalloc((e->nelems+Delta+1) * sizeof(int));
 		inew = smalloc((e->nelems+Delta+1) * sizeof(int));
-		memmove(inew, e->off, e->nelems*sizeof(int));
+		memmove(inew, e->off, (e->nelems+1)*sizeof(int));
 		free(e->off);
 		free(e->off);
 		e->off = inew;
 		e->off = inew;
 	}
 	}
@@ -989,11 +1005,11 @@ growparse(Elemlist *e)
  * rather than a directory.
  * rather than a directory.
  */
  */
 static void
 static void
-parsename(char *name, Elemlist *e)
+parsename(char *aname, Elemlist *e)
 {
 {
-	char *slash;
+	char *name, *slash;
 
 
-	kstrdup(&e->name, name);
+	kstrdup(&e->name, aname);
 	name = e->name;
 	name = e->name;
 	e->nelems = 0;
 	e->nelems = 0;
 	e->elems = nil;
 	e->elems = nil;
@@ -1001,7 +1017,8 @@ parsename(char *name, Elemlist *e)
 	e->off[0] = skipslash(name) - name;
 	e->off[0] = skipslash(name) - name;
 	for(;;){
 	for(;;){
 		name = skipslash(name);
 		name = skipslash(name);
-		if(*name=='\0'){
+		if(*name == '\0'){
+			e->off[e->nelems] = name+strlen(name) - e->name;
 			e->mustbedir = 1;
 			e->mustbedir = 1;
 			break;
 			break;
 		}
 		}
@@ -1017,7 +1034,15 @@ parsename(char *name, Elemlist *e)
 		*slash++ = '\0';
 		*slash++ = '\0';
 		name = slash;
 		name = slash;
 	}
 	}
-	e->off[e->nelems] = name - e->name;
+	
+	if(chandebug){
+		int i;
+		
+		print("parsename %s:", e->name);
+		for(i=0; i<=e->nelems; i++)
+			print(" %d", e->off[i]);
+		print("\n");
+	}
 }
 }
 
 
 void*
 void*
@@ -1035,12 +1060,44 @@ memrchr(void *va, int c, long n)
 void
 void
 namelenerror(char *aname, int len, char *err)
 namelenerror(char *aname, int len, char *err)
 {
 {
-	char *name;
+	char *ename, *name, *next;
+	int i, errlen;
 
 
-	if(len < ERRMAX/3 || (name=memrchr(aname, '/', len))==nil || name==aname)
-		snprint(up->genbuf, sizeof up->genbuf, "%.*s", len, aname);
-	else
-		snprint(up->genbuf, sizeof up->genbuf, "...%.*s", (int)(len-(name-aname)), name);
+	/*
+	 * If the name is short enough, just use the whole thing.
+	 */
+	errlen = strlen(err);
+	if(len < ERRMAX/3 || len+errlen < 2*ERRMAX/3)
+		snprint(up->genbuf, sizeof up->genbuf, "%.*s", 
+			utfnlen(aname, len), aname);
+	else{
+		/*
+		 * Print a suffix of the name, but try to get a little info.
+		 */
+		ename = aname+len;
+		next = ename;
+		do{
+			name = next;
+			next = memrchr(aname, '/', name-aname);
+			if(next == nil)
+				next = aname;
+			len = ename-next;
+		}while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3);
+
+		/*
+		 * If the name is ridiculously long, chop it.
+		 */
+		if(name == ename){
+			name = ename-ERRMAX/4;
+			if(name <= aname)
+				panic("bad math in namelenerror");
+			/* walk out of current UTF sequence */
+			for(i=0; (*name&0xC0)==0x80 && i<3; i++)
+				name++;
+		}
+		snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
+			utfnlen(name, ename-name), name);
+	}				
 	snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
 	snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
 	nexterror();
 	nexterror();
 }
 }
@@ -1070,7 +1127,7 @@ nameerror(char *name, char *err)
 Chan*
 Chan*
 namec(char *aname, int amode, int omode, ulong perm)
 namec(char *aname, int amode, int omode, ulong perm)
 {
 {
-	int n, t, nomount;
+	int len, n, t, nomount;
 	Chan *c, *cnew;
 	Chan *c, *cnew;
 	Cname *cname;
 	Cname *cname;
 	Elemlist e;
 	Elemlist e;
@@ -1104,7 +1161,7 @@ namec(char *aname, int amode, int omode, ulong perm)
 		nomount = 1;
 		nomount = 1;
 		up->genbuf[0] = '\0';
 		up->genbuf[0] = '\0';
 		n = 0;
 		n = 0;
-		while(*name!='\0' && (*name != '/' || n < 2)){
+		while(*name != '\0' && (*name != '/' || n < 2)){
 			if(n >= sizeof(up->genbuf)-1)
 			if(n >= sizeof(up->genbuf)-1)
 				error(Efilename);
 				error(Efilename);
 			up->genbuf[n++] = *name++;
 			up->genbuf[n++] = *name++;
@@ -1141,6 +1198,7 @@ namec(char *aname, int amode, int omode, ulong perm)
 	}
 	}
 
 
 	e.aname = aname;
 	e.aname = aname;
+	e.prefix = name - aname;
 	e.name = nil;
 	e.name = nil;
 	e.elems = nil;
 	e.elems = nil;
 	e.off = nil;
 	e.off = nil;
@@ -1150,14 +1208,20 @@ namec(char *aname, int amode, int omode, ulong perm)
 		cclose(c);
 		cclose(c);
 		free(e.name);
 		free(e.name);
 		free(e.elems);
 		free(e.elems);
-		free(e.off);
 		/*
 		/*
 		 * Prepare nice error, showing first e.nerror elements of name.
 		 * Prepare nice error, showing first e.nerror elements of name.
 		 */
 		 */
 		if(e.nerror == 0)
 		if(e.nerror == 0)
 			nexterror();
 			nexterror();
 		strcpy(tmperrbuf, up->errstr);
 		strcpy(tmperrbuf, up->errstr);
-		namelenerror(aname, (name-aname)+e.off[e.nerror], tmperrbuf);
+		if(e.off[e.nerror]==0)
+			print("nerror=%d but off=%d\n",
+				e.nerror, e.off[e.nerror]);
+		if(chandebug)
+			print("showing %d+%d/%d (of %d) of %s (%d %d)\n", e.prefix, e.off[e.nerror], e.nerror, e.nelems, aname, e.off[0], e.off[1]);
+		len = e.prefix+e.off[e.nerror];
+		free(e.off);
+		namelenerror(aname, len, tmperrbuf);
 	}
 	}
 
 
 	/*
 	/*

+ 40 - 8
sys/src/cmd/tar.c

@@ -778,6 +778,34 @@ match(char *name, char **argv)
 	return 0;
 	return 0;
 }
 }
 
 
+static void
+cantcreate(char *s, int mode)
+{
+	int len;
+	static char *last;
+	
+	/*
+	 * Always print about files.  Only print about directories
+	 * we haven't printed about.  (Assumes archive is ordered
+	 * nicely.)
+	 */
+	if(mode&DMDIR){
+		if(last){
+			/* already printed this directory */
+			if(strcmp(s, last) == 0)
+				return;
+			/* printed a higher directory, so printed this one */
+			len = strlen(s);
+			if(memcmp(s, last, len) == 0 && last[len] == '/')
+				return;
+		}
+		/* save */
+		free(last);
+		last = strdup(s);
+	}
+	fprint(2, "%s: can't create %s: %r\n", argv0, s);
+}
+	
 static int
 static int
 makedir(char *s)
 makedir(char *s)
 {
 {
@@ -788,20 +816,25 @@ makedir(char *s)
 	f = create(s, OREAD, DMDIR | 0777);
 	f = create(s, OREAD, DMDIR | 0777);
 	if (f >= 0)
 	if (f >= 0)
 		close(f);
 		close(f);
+	else
+		cantcreate(s, DMDIR);
 	return f;
 	return f;
 }
 }
 
 
-static void
+static int
 mkpdirs(char *s)
 mkpdirs(char *s)
 {
 {
-	int done = 0;
-	char *p = s;
-
-	while (!done && (p = strchr(p + 1, '/')) != nil) {
+	int err;
+	char *p;
+	
+	p = s;
+	err = 0;
+	while (!err && (p = strchr(p+1, '/')) != nil) {
 		*p = '\0';
 		*p = '\0';
-		done = (access(s, AEXIST) < 0 && makedir(s) < 0);
+		err = (access(s, AEXIST) < 0 && makedir(s) < 0);
 		*p = '/';
 		*p = '/';
 	}
 	}
+	return -err;
 }
 }
 
 
 /* Call access but preserve the error string. */
 /* Call access but preserve the error string. */
@@ -873,8 +906,7 @@ extract1(int ar, Hdr *hp, char *fname)
 				}
 				}
 				if (fd < 0 &&
 				if (fd < 0 &&
 				    (!dir || xaccess(fname, AEXIST) < 0))
 				    (!dir || xaccess(fname, AEXIST) < 0))
-					fprint(2, "%s: can't create %s: %r\n",
-						argv0, fname);
+				    	cantcreate(fname, mode);
 			}
 			}
 			if (fd >= 0 && verbose)
 			if (fd >= 0 && verbose)
 				fprint(2, "%s\n", fname);
 				fprint(2, "%s\n", fname);