Many small edits.
diff --git a/src/cmd/9660/dump9660.c b/src/cmd/9660/dump9660.c
index b66e364..f82ff30 100644
--- a/src/cmd/9660/dump9660.c
+++ b/src/cmd/9660/dump9660.c
@@ -21,9 +21,9 @@
 usage(void)
 {
 	if(mk9660)
-		fprint(2, "usage: disk/mk9660 [-D:] [-9cjr] [-b bootfile] [-p proto] [-s src] cdimage\n");
+		fprint(2, "usage: mk9660 [-D:] [-9cjr] [-b bootfile] [-p proto] [-s src] cdimage\n");
 	else
-		fprint(2, "usage: disk/dump9660 [-D:] [-9cjr] [-m maxsize] [-n now] [-p proto] [-s src] cdimage\n");
+		fprint(2, "usage: dump9660 [-D:] [-9cjr] [-m maxsize] [-n now] [-p proto] [-s src] cdimage\n");
 	exits("usage");
 }
 
@@ -42,7 +42,7 @@
 	fix = 0;
 	status = nil;
 	memset(&info, 0, sizeof info);
-	proto = "/sys/lib/sysconfig/proto/allproto";
+	proto = unsharp("#9/proto/allproto");
 	src = "./";
 
 	info.volumename = atom("9CD");
diff --git a/src/cmd/acid/main.c b/src/cmd/acid/main.c
index 8f3fbb8..415d5e3 100644
--- a/src/cmd/acid/main.c
+++ b/src/cmd/acid/main.c
@@ -357,7 +357,7 @@
 
 	sprint(buf, "#9/acid/%s", mach->name);
 	loadmodule(unsharp(buf));
-	p = getenv("home");
+	p = getenv("HOME");
 	if(p != 0) {
 		sprint(buf, "%s/lib/acid", p);
 		silent = 1;
diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c
index c3b0fba..917aefc 100644
--- a/src/cmd/acme/acme.c
+++ b/src/cmd/acme/acme.c
@@ -123,9 +123,7 @@
 	quotefmtinstall();
 	cputype = getenv("cputype");
 	objtype = getenv("objtype");
-	home = getenv("home");
-	if(home == nil)
-		home = getenv("HOME");
+	home = getenv("HOME");
 	p = getenv("tabstop");
 	if(p != nil){
 		maxtab = strtoul(p, nil, 0);
diff --git a/src/cmd/bc.y b/src/cmd/bc.y
index 1bd638e..fdb09de 100644
--- a/src/cmd/bc.y
+++ b/src/cmd/bc.y
@@ -961,7 +961,7 @@
 	if(lflag) {
 		argv--;
 		argc++;
-		argv[1] = "/sys/lib/bclib";
+		argv[1] = unsharp("#9/lib/bclib");
 	}
 	if(cflag) {
 		yyinit(argc, argv);
diff --git a/src/cmd/calendar.c b/src/cmd/calendar.c
index 6202c5a..ba86ab3 100644
--- a/src/cmd/calendar.c
+++ b/src/cmd/calendar.c
@@ -75,7 +75,7 @@
 	for(i=0; i<argc || (i==0 && argc==0); i++){
 		if(i==0 && argc==0)
 			snprint(buf, sizeof(buf),
-				"/usr/%s/lib/calendar", getuser());
+				"%s/lib/calendar", getenv("HOME"));
 		else
 			strcpy(buf, argv[i]);
 		fd = open(buf, OREAD);
diff --git a/src/cmd/dict/dict.h b/src/cmd/dict/dict.h
index 28a92e8..9b843d8 100644
--- a/src/cmd/dict/dict.h
+++ b/src/cmd/dict/dict.h
@@ -134,6 +134,9 @@
 long	pgwnextoff(long);
 void	pgwprintentry(Entry,int);
 void	pgwprintkey(void);
+void	rogetprintentry(Entry, int);
+long	rogetnextoff(long);
+void	rogetprintkey(void);
 long	slangnextoff(long);
 void	slangprintentry(Entry, int);
 void	slangprintkey(void);
diff --git a/src/cmd/dict/mkfile b/src/cmd/dict/mkfile
index 43d1e15..d2a3a36 100644
--- a/src/cmd/dict/mkfile
+++ b/src/cmd/dict/mkfile
@@ -2,7 +2,7 @@
 
 TARG=dict
 LFILES=oed.$O ahd.$O pcollins.$O pcollinsg.$O movie.$O slang.$O robert.$O\
-	world.$O jis208.$O gb2312.$O thesaurus.$O simple.$O pgw.$O
+	world.$O jis208.$O gb2312.$O thesaurus.$O simple.$O pgw.$O roget.$O\
 
 OFILES=dict.$O\
 	$LFILES\
diff --git a/src/cmd/dict/roget.c b/src/cmd/dict/roget.c
new file mode 100644
index 0000000..16bfeae
--- /dev/null
+++ b/src/cmd/dict/roget.c
@@ -0,0 +1,147 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ctype.h>
+#include "dict.h"
+
+/* Roget's Thesaurus from project Gutenberg */
+
+/* static long Last = 0; */
+
+void
+rogetprintentry(Entry e, int cmd)
+{
+	int spc;
+	char c, *p;
+
+	spc = 0;
+	p = e.start;
+
+	if(cmd == 'h'){
+		while(!isspace(*p) && p < e.end)
+			p++;
+		while(strncmp(p, " -- ", 4) != 0 && p < e.end){
+			while(isspace(*p) && p < e.end)
+				p++;
+			if (*p == '[' || *p == '{'){	
+				c = (*p == '[')? ']': '}';
+				while(*p != c && p < e.end)
+					p++;
+				p++;
+				continue;
+			}
+			if (isdigit(*p) || ispunct(*p)){
+				while(!isspace(*p) && p < e.end)
+					p++;
+				continue;
+			}
+
+
+			if (isspace(*p))
+				spc = 1;
+			else
+			if (spc){
+				outchar(' ');
+				spc = 0;
+			}
+
+			while(!isspace(*p) && p < e.end)
+				outchar(*p++);
+		}
+		return;
+	}	
+
+	while(p < e.end && !isspace(*p))
+		p++;
+	while(p < e.end && isspace(*p))
+		p++;
+
+	while (p < e.end){
+		if (p < e.end -4 && strncmp(p, " -- ", 4) == 0){	/* first line */
+			outnl(2);
+			p += 4;
+			spc = 0;
+		}
+			
+		if (p < e.end -2 && strncmp(p, "[ ", 4) == 0){		/* twiddle layout */
+			outchars(" [");
+			continue;
+		}
+
+		if (p < e.end -4 && strncmp(p, "&c (", 4) == 0){	/* usefull xref */
+			if (spc)
+				outchar(' ');
+			outchar('/');
+			while(p < e.end && *p != '(')
+				p++;
+			p++;
+			while(p < e.end && *p != ')')
+				outchar(*p++);
+			p++;
+			while(p < e.end && isspace(*p))
+				p++;
+			while(p < e.end && isdigit(*p))
+				p++;
+			outchar('/');
+			continue;
+		}
+
+		if (p < e.end -3 && strncmp(p, "&c ", 3) == 0){		/* less usefull xref */
+			while(p < e.end && !isdigit(*p))
+				p++;
+			while(p < e.end && isdigit(*p))
+				p++;
+			continue;
+		}
+
+		if (*p == '\n' && p < (e.end -1)){			/* their newlines */
+			spc = 0;
+			p++;
+			if (isspace(*p)){				/* their continuation line */
+				while (isspace(*p))
+					p++;
+				p--;
+			}
+			else{
+				outnl(2);
+			}
+		}
+		if (spc && *p != ';' && *p != '.' &&
+		    *p != ',' && !isspace(*p)){				/* drop spaces before punct */
+			spc = 0;
+			outchar(' ');
+		}
+		if (isspace(*p))
+			spc = 1;
+		else
+			outchar(*p);
+		p++;
+	}
+	outnl(0);
+}
+
+long
+rogetnextoff(long fromoff)
+{
+	int i;
+	vlong l;
+	char *p;
+
+	Bseek(bdict, fromoff, 0);
+	Brdline(bdict, '\n');
+	while ((p = Brdline(bdict, '\n')) != nil){
+		l = Blinelen(bdict);
+		if (!isdigit(*p))
+			continue;
+		for (i = 0; i < l-4; i++)
+			if (strncmp(p+i, " -- ", 4) == 0)
+				return Boffset(bdict)-l;
+	}
+	return Boffset(bdict);
+}
+
+void
+rogetprintkey(void)
+{
+	Bprint(bout, "No pronunciation key.\n");
+}
diff --git a/src/cmd/dict/utils.c b/src/cmd/dict/utils.c
index 0920dc2..b5baab9 100644
--- a/src/cmd/dict/utils.c
+++ b/src/cmd/dict/utils.c
@@ -16,6 +16,9 @@
 	{"thesaurus",	"Collins Thesaurus",
 	 "#9/dict/thesaurus",	"#9/dict/thesindex",
 	 thesnextoff,	thesprintentry,	thesprintkey},
+	{"roget",		"Project Gutenberg Roget's Thesaurus",
+	 "#9/dict/roget", "#9/dict/rogetindex",
+	 rogetnextoff,	rogetprintentry,	rogetprintkey},
 
 	{"ce",		"Gendai Chinese->English",
 	 "#9/dict/world/sansdata/sandic24.dat",
diff --git a/src/cmd/draw/iconv.c b/src/cmd/draw/iconv.c
new file mode 100644
index 0000000..5a95520
--- /dev/null
+++ b/src/cmd/draw/iconv.c
@@ -0,0 +1,102 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+
+void
+usage(void)
+{
+	fprint(2, "usage: iconv [-u] [-c chanstr] [file]\n");
+	exits("usage");
+}
+
+void
+writeuncompressed(int fd, Memimage *m)
+{
+	char chanstr[32];
+	int bpl, y, j;
+	uchar *buf;
+
+	if(chantostr(chanstr, m->chan) == nil)
+		sysfatal("can't convert channel descriptor: %r");
+	fprint(fd, "%11s %11d %11d %11d %11d ",
+		chanstr, m->r.min.x, m->r.min.y, m->r.max.x, m->r.max.y);
+
+	bpl = bytesperline(m->r, m->depth);
+	buf = malloc(bpl);
+	if(buf == nil)
+		sysfatal("malloc failed: %r");
+	for(y=m->r.min.y; y<m->r.max.y; y++){
+		j = unloadmemimage(m, Rect(m->r.min.x, y, m->r.max.x, y+1), buf, bpl);
+		if(j != bpl)
+			sysfatal("image unload failed: %r");
+		if(write(fd, buf, bpl) != bpl)
+			sysfatal("write failed: %r");
+	}
+	free(buf);
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *tostr, *file;
+	int fd, uncompressed;
+	ulong tochan;
+	Memimage *m, *n;
+
+	tostr = nil;
+	uncompressed = 0;
+	ARGBEGIN{
+	case 'c':
+		tostr = EARGF(usage());
+		break;
+	case 'u':
+		uncompressed = 1;
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	memimageinit();
+
+	file = "<stdin>";
+	m = nil;
+
+	switch(argc){
+	case 0:
+		m = readmemimage(0);
+		break;
+	case 1:
+		file = argv[0];
+		fd = open(file, OREAD);
+		if(fd < 0)
+			sysfatal("can't open %s: %r", file);
+		m = readmemimage(fd);
+		close(fd);
+		break;
+	default:
+		usage();
+	}
+
+	if(m == nil)
+		sysfatal("can't read %s: %r", file);
+
+	if(tostr == nil)
+		tochan = m->chan;
+	else{
+		tochan = strtochan(tostr);
+		if(tochan == 0)
+			sysfatal("bad channel descriptor '%s'", tostr);
+	}
+
+	n = allocmemimage(m->r, tochan);
+	if(n == nil)
+		sysfatal("can't allocate new image: %r");
+
+	memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
+	if(uncompressed)
+		writeuncompressed(1, n);
+	else
+		writememimage(1, n);
+	exits(nil);
+}
diff --git a/src/cmd/ed.c b/src/cmd/ed.c
index d947d89..3af90f6 100644
--- a/src/cmd/ed.c
+++ b/src/cmd/ed.c
@@ -146,7 +146,7 @@
 		vflag = 0;
 	}
 	if(oflag) {
-		p1 = "/fd/1";
+		p1 = "/dev/stdout";
 		p2 = savedfile;
 		while(*p2++ = *p1++)
 			;
diff --git a/src/cmd/grep/main.c b/src/cmd/grep/main.c
index 004d1b7..e32f89a 100644
--- a/src/cmd/grep/main.c
+++ b/src/cmd/grep/main.c
@@ -21,6 +21,9 @@
 		flags[ARGC()]++;
 		break;
 
+	case 'E':	/* ignore, turns gnu grep into egrep */
+		break;
+
 	case 'e':
 		flags['e']++;
 		lineno = 0;
diff --git a/src/cmd/import.c b/src/cmd/import.c
index 88d7c53..f084b8e 100644
--- a/src/cmd/import.c
+++ b/src/cmd/import.c
@@ -32,7 +32,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-s service] [-n remote-ns] [-fd] [-p remote-prog] remote-system\n", argv0);
+	fprint(2, "usage: %s [-df] [-s service] [-n remote-ns] [-p remote-prog] remote-system\n", argv0);
 	exits("usage");
 }
 
diff --git a/src/cmd/map/map.c b/src/cmd/map/map.c
index e8dd3ab..8d4dbfc 100644
--- a/src/cmd/map/map.c
+++ b/src/cmd/map/map.c
@@ -21,7 +21,7 @@
 proj projection;
 
 
-static char *mapdir = "/lib/map";	/* default map directory */
+static char *mapdir = "#9/map";	/* default map directory */
 struct file {
 	char *name;
 	char *color;
@@ -150,6 +150,7 @@
 	double dd;
 	if(sizeof(short)!=2)
 		abort();	/* getshort() won't work */
+	mapdir = unsharp(mapdir);
 	s = getenv("MAP");
 	if(s)
 		file[0].name = s;
diff --git a/src/cmd/map/mapdemo.rc b/src/cmd/map/mapdemo.rc
index 033969a..24be3e1 100755
--- a/src/cmd/map/mapdemo.rc
+++ b/src/cmd/map/mapdemo.rc
@@ -9,7 +9,7 @@
 		echo t $type
 		echo 'm -8192 -8192'
 		echo t $proj - $label
-		MAP=world MAPDIR=/lib/map map $proj $* -s -d 5
+		MAP=world MAPDIR=$PLAN9/map map $proj $* -s -d 5
 	} 
 	sleep 5
 }
diff --git a/src/cmd/mk/mkfile.test b/src/cmd/mk/mkfile.test
index b5bd6db..8a4e4b9 100644
--- a/src/cmd/mk/mkfile.test
+++ b/src/cmd/mk/mkfile.test
@@ -1,9 +1,9 @@
-|$PLAN9/bin/rc
+MKSHELL=$PLAN9/bin/rc
 use-rc:V:
 	for(i in a b c)
 		echo $i
 
-|/bin/sh
+MKSHELL=/bin/sh
 use-sh:V:
 	for i in a b c
 	do
diff --git a/src/cmd/mk/parse.c b/src/cmd/mk/parse.c
index 2d1816b..48bad3d 100644
--- a/src/cmd/mk/parse.c
+++ b/src/cmd/mk/parse.c
@@ -91,18 +91,18 @@
 */
 				setvar(head->s, (void *) tail);
 				symlook(head->s, S_WESET, (void *)"");
+				if(strcmp(head->s, "MKSHELL") == 0){
+					if((err = setshell(tail)) != nil){
+						SYNERR(hline);
+						fprint(2, "%s\n", err);
+						Exit();
+						break;
+					}
+				}
 			}
 			if(attr)
 				symlook(head->s, S_NOEXPORT, (void *)"");
 			break;
-		case 'S':
-			if((err = setshell(tail)) != nil){
-				SYNERR(hline);
-				fprint(2, "%s\n", err);
-				Exit();
-				break;
-			}
-			break;
 		default:
 			SYNERR(hline);
 			fprint(2, "expected one of :<=\n");
@@ -144,19 +144,14 @@
 	int n;
 	Word *w;
 
-	if(*line == '|'){
-		sep = 'S';	/* shell */
-		p = line+1;
-	}else{
-		p = shellt->charin(line,":=<");
-		if(p == 0)
-			return('?');
-		sep = *p;
-		*p++ = 0;
-		if(sep == '<' && *p == '|'){
-			sep = '|';
-			p++;
-		}
+	p = shellt->charin(line,":=<");
+	if(p == 0)
+		return('?');
+	sep = *p;
+	*p++ = 0;
+	if(sep == '<' && *p == '|'){
+		sep = '|';
+		p++;
 	}
 	*attr = 0;
 	*prog = 0;
diff --git a/src/cmd/mk/shell.c b/src/cmd/mk/shell.c
index a4ac3f9..dd41ad1 100644
--- a/src/cmd/mk/shell.c
+++ b/src/cmd/mk/shell.c
@@ -41,6 +41,7 @@
 {
 	shellcmd = stow(shells[0]->name);
 	shellt = shells[0];
+	setvar("MKSHELL", shellcmd);
 }
 
 void
@@ -72,5 +73,6 @@
 	shellstack = s->next;
 	shellt = s->t;
 	shellcmd = s->w;
+	setvar("MKSHELL", shellcmd);
 	free(s);
 }
diff --git a/src/cmd/mkfile b/src/cmd/mkfile
index 42ca0e9..c50d4e1 100644
--- a/src/cmd/mkfile
+++ b/src/cmd/mkfile
@@ -1,6 +1,6 @@
 <$PLAN9/src/mkhdr
 
-TARG=`ls *.[cy] | grep -v "\.tab\.c$" | sed 's/\.[cy]//'`
+TARG=`ls *.[cy] | egrep -v "\.tab\.c$" | sed 's/\.[cy]//'`
 
 <$PLAN9/src/mkmany
 
diff --git a/src/cmd/news.c b/src/cmd/news.c
index c6a99a3..bdffaa3 100644
--- a/src/cmd/news.c
+++ b/src/cmd/news.c
@@ -101,7 +101,7 @@
 	n_count = 0;
 	n_list = malloc(NINC*sizeof(File));
 	na = NINC;
-	home = getenv("home");
+	home = getenv("HOME");
 	if(home) {
 		sprint(newstime, TFILE, home);
 		d = dirstat(newstime);
diff --git a/src/cmd/plumb/plumber.c b/src/cmd/plumb/plumber.c
index 53847cd..2debf49 100644
--- a/src/cmd/plumb/plumber.c
+++ b/src/cmd/plumb/plumber.c
@@ -43,9 +43,7 @@
 	}ARGEND
 
 	user = getuser();
-	home = getenv("home");
-	if(home == nil)
-		home = getenv("HOME");
+	home = getenv("HOME");
 	if(user==nil || home==nil)
 		error("can't initialize $user or $home: %r");
 	if(plumbfile == nil){
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index 9ab7c29..dfd4e37 100644
--- a/src/cmd/rc/exec.c
+++ b/src/cmd/rc/exec.c
@@ -90,6 +90,7 @@
 	v->changed=0;
 	v->fnchanged=0;
 	v->next=next;
+	v->changefn = 0;
 	return v;
 }
 /*
diff --git a/src/cmd/rm.c b/src/cmd/rm.c
index e76fdb0..f71fe98 100644
--- a/src/cmd/rm.c
+++ b/src/cmd/rm.c
@@ -1,4 +1,5 @@
 #include <u.h>
+#include <sys/stat.h>
 #include <libc.h>
 
 #define rmdir p9rmdir
@@ -16,6 +17,13 @@
 	}
 }
 
+int
+issymlink(char *name)
+{
+	struct stat s;
+	return lstat(name, &s) >= 0 && S_ISLNK(s.st_mode);
+}
+
 /*
  * f is a non-empty directory. Remove its contents and then it.
  */
@@ -48,7 +56,7 @@
 	ndir = 0;
 	for(i=0; i<n; i++){
 		snprint(name, nname, "%s/%s", f, dirbuf[i].name);
-		if(remove(name) != -1)
+		if(remove(name) != -1 || issymlink(name))
 			dirbuf[i].qid.type = QTFILE;	/* so we won't recurse */
 		else{
 			if(dirbuf[i].qid.type & QTDIR)
diff --git a/src/cmd/sam/plan9.c b/src/cmd/sam/plan9.c
index 6c3a60e..0a3fe07 100644
--- a/src/cmd/sam/plan9.c
+++ b/src/cmd/sam/plan9.c
@@ -17,7 +17,7 @@
 
 char	RSAM[] = "sam";
 char	SAMTERM[] = "/bin/aux/samterm";
-char	HOME[] = "home";
+char	HOME[] = "HOME";
 char	TMPDIR[] = "/tmp";
 char	SH[] = "rc";
 char	SHPATH[] = "/bin/rc";
diff --git a/src/cmd/sort.c b/src/cmd/sort.c
index 359965e..d34fdc1 100644
--- a/src/cmd/sort.c
+++ b/src/cmd/sort.c
@@ -356,7 +356,7 @@
 	static uint pid;
 	char *dir;
 
-	dir = "/tmp";
+	dir = "/var/tmp";
 	if(args.tname)
 		dir = args.tname;
 	if(strlen(dir) >= nelem(file)-20) {
diff --git a/src/libdraw/mkfile b/src/libdraw/mkfile
index fbbe68e..7b37233 100644
--- a/src/libdraw/mkfile
+++ b/src/libdraw/mkfile
@@ -36,7 +36,6 @@
 	mkfont.$O\
 	openfont.$O\
 	poly.$O\
-	readcolmap.$O\
 	readimage.$O\
 	readsubfont.$O\
 	rectclip.$O\
@@ -52,7 +51,6 @@
 	subfontname.$O\
 	unloadimage.$O\
 	window.$O\
-	writecolmap.$O\
 	writeimage.$O\
 	writesubfont.$O\
 	md-alloc.$O\
diff --git a/src/libdraw/readcolmap.c b/src/libdraw/readcolmap.c
deleted file mode 100644
index 6eb8ee2..0000000
--- a/src/libdraw/readcolmap.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <draw.h>
-#include <bio.h>
-
-static ulong
-getval(char **p)
-{
-	ulong v;
-	char *q;
-
-	v = strtoul(*p, &q, 0);
-	v |= v<<8;
-	v |= v<<16;
-	*p = q;
-	return v;
-}
-
-void
-readcolmap(Display *d, RGB *colmap)
-{
-	int i;
-	char *p, *q;
-	Biobuf *b;
-	char buf[128];
-
-	USED(screen);
-
-	sprint(buf, "/dev/draw/%d/colormap", d->dirno);
-	b = Bopen(buf, OREAD);
-	if(b == 0)
-		drawerror(d, "rdcolmap: can't open colormap device");
-
-	for(;;) {
-		p = Brdline(b, '\n');
-		if(p == 0)
-			break;
-		i = strtoul(p, &q, 0);
-		if(i < 0 || i > 255) {
-			fprint(2, "rdcolmap: bad index\n");
-			exits("bad");
-		}
-		p = q;
-		colmap[255-i].red = getval(&p);
-		colmap[255-i].green = getval(&p);
-		colmap[255-i].blue = getval(&p);
-	}
-	Bterm(b);
-}
diff --git a/src/libdraw/writecolmap.c b/src/libdraw/writecolmap.c
deleted file mode 100644
index 30b026f..0000000
--- a/src/libdraw/writecolmap.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <draw.h>
-
-/*
- * This code (and the devdraw interface) will have to change
- * if we ever get bitmaps with ldepth > 3, because the
- * colormap will have to be written in chunks
- */
-
-void
-writecolmap(Display *d, RGB *m)
-{
-	int i, n, fd;
-	char buf[64], *t;
-	ulong r, g, b;
-
-	sprint(buf, "/dev/draw/%d/colormap", d->dirno);
-	fd = open(buf, OWRITE);
-	if(fd < 0)
-		drawerror(d, "wrcolmap: open colormap failed");
-	t = malloc(8192);
-	n = 0;
-	for(i = 0; i < 256; i++) {
-		r = m[i].red>>24;
-		g = m[i].green>>24;
-		b = m[i].blue>>24;
-		n += sprint(t+n, "%d %lud %lud %lud\n", 255-i, r, g, b);
-	}
-	i = write(fd, t, n);
-	free(t);
-	close(fd);
-	if(i != n)
-		drawerror(d, "wrcolmap: bad write");
-}
diff --git a/src/libdraw/x11-init.c b/src/libdraw/x11-init.c
index fea08e4..b1afcf1 100644
--- a/src/libdraw/x11-init.c
+++ b/src/libdraw/x11-init.c
@@ -346,9 +346,7 @@
 
 		display_resources = XResourceManagerString(_x.display);
 		if(display_resources == nil){
-			home = getenv("home");
-			if(home == nil)
-				home = getenv("HOME");
+			home = getenv("HOME");
 			if(home!=nil && (file=smprint("%s/.Xdefaults", home)) != nil){
 				XrmCombineFileDatabase(file, &database, False);
 				free(file);
diff --git a/src/libthread/channel.c b/src/libthread/channel.c
index 4dc51fc..903889a 100644
--- a/src/libthread/channel.c
+++ b/src/libthread/channel.c
@@ -249,6 +249,7 @@
 	Channel *c;
 	_Thread *t;
 
+	needstack(512);
 	for(i=0; a[i].op != CHANEND && a[i].op != CHANNOBLK; i++)
 		;
 	n = i;
diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c
index c6e00d1..4ed252e 100644
--- a/src/libthread/daemonize.c
+++ b/src/libthread/daemonize.c
@@ -42,10 +42,12 @@
 		fprint(2, "%s: wait pid %d stopped\n", argv0, pid);
 		return;
 	}
+#ifdef WIFCONTINUED
 	if(WIFCONTINUED(status)){
 		fprint(2, "%s: wait pid %d continued\n", argv0, pid);
 		return;
 	}
+#endif
 	fprint(2, "%s: wait pid %d status 0x%ux\n", argv0, pid, status);
 	_exit(99);
 }
@@ -84,8 +86,6 @@
 
 	sigpid = 1;
 
-	threadlinklibrary();
-
 	if(pipe(p) < 0)
 		sysfatal("passer pipe: %r");
 
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 2b6d1e3..b886e30 100644
--- a/src/libthread/thread.c
+++ b/src/libthread/thread.c
@@ -169,6 +169,7 @@
 {
 	Proc *p;
 
+	needstack(0);
 	p = proc();
 //print("threadswtch %p\n", p);
 	contextswitch(&p->thread->context, &p->schedcontext);
@@ -324,6 +325,20 @@
 	va_end(arg);
 }
 
+void
+needstack(int n)
+{
+	_Thread *t;
+
+	t = proc()->thread;
+
+	if((char*)&t <= (char*)t->stk
+	|| (char*)&t - (char*)t->stk < 256+n){
+		fprint(2, "thread stack overflow\n");
+		abort();
+	}
+}
+
 /*
  * locking
  */
@@ -499,11 +514,6 @@
 	threadmain(threadargc, threadargv);
 }
 
-void
-threadlinklibrary(void)
-{
-}
-
 int
 main(int argc, char **argv)
 {