64-bit fixes
diff --git a/src/cmd/sam/cmd.c b/src/cmd/sam/cmd.c
index a5b636a..cdf00b9 100644
--- a/src/cmd/sam/cmd.c
+++ b/src/cmd/sam/cmd.c
@@ -50,10 +50,12 @@
 Rune	*linep = line;
 Rune	*terminp = termline;
 Rune	*termoutp = termline;
-List	cmdlist;
-List	addrlist;
-List	relist;
-List	stringlist;
+
+List	cmdlist = { 'p' };
+List	addrlist = { 'p' };
+List	relist = { 'p' };
+List	stringlist = { 'p' };
+
 int	eof;
 
 void
@@ -108,15 +110,26 @@
 int
 inputline(void)
 {
-	int i, c;
+	int i, c, start;
 
-	linep = line;
-	i = 0;
+	/*
+	 * Could set linep = line and i = 0 here and just
+	 * error(Etoolong) below, but this way we keep
+	 * old input buffer history around for a while.
+	 * This is useful only for debugging.
+	 */
+	i = linep - line;
 	do{
 		if((c = inputc())<=0)
 			return -1;
-		if(i == (sizeof line)/RUNESIZE-1)
-			error(Etoolong);
+		if(i == nelem(line)-1){
+			if(linep == line)
+				error(Etoolong);
+			start = linep - line;
+			runemove(line, linep, i-start);
+			i -= start;
+			linep = line;
+		}
 	}while((line[i++]=c) != '\n');
 	line[i] = 0;
 	return 1;
@@ -275,9 +288,9 @@
 	int i;
 
 	while(cmdlist.nused > 0)
-		free(cmdlist.ucharpptr[--cmdlist.nused]);
+		free(cmdlist.voidpptr[--cmdlist.nused]);
 	while(addrlist.nused > 0)
-		free(addrlist.ucharpptr[--addrlist.nused]);
+		free(addrlist.voidpptr[--addrlist.nused]);
 	while(relist.nused > 0){
 		i = --relist.nused;
 		Strclose(relist.stringpptr[i]);
diff --git a/src/cmd/sam/list.c b/src/cmd/sam/list.c
index a810542..d2e5d2d 100644
--- a/src/cmd/sam/list.c
+++ b/src/cmd/sam/list.c
@@ -3,16 +3,20 @@
 /*
  * Check that list has room for one more element.
  */
-void
-growlist(List *l)
+static void
+growlist(List *l, int esize)
 {
-	if(l->listptr==0 || l->nalloc==0){
+	uchar *p;
+
+	if(l->listptr == nil || l->nalloc == 0){
 		l->nalloc = INCR;
-		l->listptr = emalloc(INCR*sizeof(long));
+		l->listptr = emalloc(INCR*esize);
 		l->nused = 0;
-	}else if(l->nused == l->nalloc){
-		l->listptr = erealloc(l->listptr, (l->nalloc+INCR)*sizeof(long));
-		memset((void*)(l->longptr+l->nalloc), 0, INCR*sizeof(long));
+	}
+	else if(l->nused == l->nalloc){
+		p = erealloc(l->listptr, (l->nalloc+INCR)*esize);
+		l->listptr = p;
+		memset(p+l->nalloc*esize, 0, INCR*esize);
 		l->nalloc += INCR;
 	}
 }
@@ -23,19 +27,51 @@
 void
 dellist(List *l, int i)
 {
-	memmove(&l->longptr[i], &l->longptr[i+1], (l->nused-(i+1))*sizeof(long));
+	Posn *pp;
+	void **vpp;
+
 	l->nused--;
+
+	switch(l->type){
+	case 'P':
+		pp = l->posnptr+i;
+		memmove(pp, pp+1, (l->nused-i)*sizeof(*pp));
+		break;
+	case 'p':
+		vpp = l->voidpptr+i;
+		memmove(vpp, vpp+1, (l->nused-i)*sizeof(*vpp));
+		break;
+	}
 }
 
 /*
  * Add a new element, whose position is i, to the list
  */
 void
-inslist(List *l, int i, long val)
+inslist(List *l, int i, ...)
 {
-	growlist(l);
-	memmove(&l->longptr[i+1], &l->longptr[i], (l->nused-i)*sizeof(long));
-	l->longptr[i] = val;
+	Posn *pp;
+	void **vpp;
+	va_list list;
+
+
+	va_start(list, i);
+	switch(l->type){
+	case 'P':
+		growlist(l, sizeof(*pp));
+		pp = l->posnptr+i;
+		memmove(pp+1, pp, (l->nused-i)*sizeof(*pp));
+		*pp = va_arg(list, Posn);
+		break;
+	case 'p':
+		growlist(l, sizeof(*vpp));
+		vpp = l->voidpptr+i;
+		memmove(vpp+1, vpp, (l->nused-i)*sizeof(*vpp));
+		*vpp = va_arg(list, void*);
+		break;
+	}
+	va_end(list);
+
 	l->nused++;
 }
 
@@ -45,3 +81,16 @@
 	free(l->listptr);
 	free(l);
 }
+
+List*
+listalloc(int type)
+{
+	List *l;
+
+	l = emalloc(sizeof(List));
+	l->type = type;
+	l->nalloc = 0;
+	l->nused = 0;
+
+	return l;
+}
diff --git a/src/cmd/sam/mesg.c b/src/cmd/sam/mesg.c
index 01016ce..8250336 100644
--- a/src/cmd/sam/mesg.c
+++ b/src/cmd/sam/mesg.c
@@ -13,10 +13,18 @@
 int	noflush;
 int	tversion;
 
-long	inlong(void);
-long	invlong(void);
 int	inshort(void);
+long	inlong(void);
+vlong	invlong(void);
 int	inmesg(Tmesg);
+
+void	outshort(int);
+void	outlong(long);
+void	outvlong(vlong);
+void	outcopy(int, void*);
+void	outsend(void);
+void	outstart(Hmesg);
+
 void	setgenstr(File*, Posn, Posn);
 
 #ifdef DEBUG
@@ -90,9 +98,19 @@
 {
 	char buf[32];
 
-	sprint(buf, "%ld", n);
+	snprint(buf, sizeof buf, "%ld", n);
 	journal(out, buf);
 }
+
+void
+journalv(int out, vlong v)
+{
+	char buf[32];
+
+	snprint(buf, sizeof buf, "%lld", v);
+	journal(out, buf);
+}
+
 #else
 #define	journal(a, b)
 #define journaln(a, b)
@@ -176,6 +194,7 @@
 	int i, m;
 	short s;
 	long l, l1;
+	vlong v;
 	File *f;
 	Posn p0, p1, p;
 	Range r;
@@ -204,15 +223,15 @@
 		break;
 
 	case Tstartcmdfile:
-		l = invlong();		/* for 64-bit pointers */
-		journaln(0, l);
+		v = invlong();		/* for 64-bit pointers */
+		journaln(0, v);
 		Strdupl(&genstr, samname);
 		cmd = newfile();
 		cmd->unread = 0;
-		outTsv(Hbindname, cmd->tag, l);
+		outTsv(Hbindname, cmd->tag, v);
 		outTs(Hcurrent, cmd->tag);
 		logsetname(cmd, &genstr);
-		cmd->rasp = emalloc(sizeof(List));
+		cmd->rasp = listalloc('P');
 		cmd->mod = 0;
 		if(cmdstr.n){
 			loginsert(cmd, 0L, cmdstr.s, cmdstr.n);
@@ -263,7 +282,7 @@
 		termlocked++;
 		f = whichfile(inshort());
 		if(!f->rasp)	/* this might be a duplicate message */
-			f->rasp = emalloc(sizeof(List));
+			f->rasp = listalloc('P');
 		current(f);
 		outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
 		outTs(Hcurrent, f->tag);
@@ -353,11 +372,11 @@
 		break;
 
 	case Tstartnewfile:
-		l = invlong();
+		v = invlong();
 		Strdupl(&genstr, empty);
 		f = newfile();
-		f->rasp = emalloc(sizeof(List));
-		outTsv(Hbindname, f->tag, l);
+		f->rasp = listalloc('P');
+		outTsv(Hbindname, f->tag, v);
 		logsetname(f, &genstr);
 		outTs(Hcurrent, f->tag);
 		current(f);
@@ -593,16 +612,16 @@
 	return n;
 }
 
-long
+vlong
 invlong(void)
 {
-	ulong n;
+	vlong v;
 	
-	n = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
-	n = (n<<16) | (inp[3]<<8) | inp[2];
-	n = (n<<16) | (inp[1]<<8) | inp[0];
+	v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
+	v = (v<<16) | (inp[3]<<8) | inp[2];
+	v = (v<<16) | (inp[1]<<8) | inp[0];
 	inp += 8;
-	return n;
+	return v;
 }
 
 void
@@ -732,12 +751,12 @@
 }
 
 void
-outTsv(Hmesg type, int s, Posn l)
+outTsv(Hmesg type, int s, vlong v)
 {
 	outstart(type);
 	outshort(s);
-	outvlong((void*)l);
-	journaln(1, l);
+	outvlong(v);
+	journaln(1, v);
 	outsend();
 }
 
@@ -773,14 +792,14 @@
 }
 
 void
-outvlong(void *v)
+outvlong(vlong v)
 {
 	int i;
-	ulong l;
 
-	l = (ulong) v;
-	for(i = 0; i < 8; i++, l >>= 8)
-		*outp++ = l;
+	for(i = 0; i < 8; i++){
+		*outp++ = v;
+		v >>= 8;
+	}
 }
 
 void
diff --git a/src/cmd/sam/multi.c b/src/cmd/sam/multi.c
index 3df0dbe..3f086aa 100644
--- a/src/cmd/sam/multi.c
+++ b/src/cmd/sam/multi.c
@@ -1,6 +1,6 @@
 #include "sam.h"
 
-List	file;
+List	file = { 'p' };
 ushort	tag;
 
 File *
@@ -9,7 +9,7 @@
 	File *f;
 
 	f = fileopen();
-	inslist(&file, 0, (long)f);
+	inslist(&file, 0, f);
 	f->tag = tag++;
 	if(downloaded)
 		outTs(Hnewname, f->tag);
@@ -88,7 +88,7 @@
 				break;
 		}
 	}
-	inslist(&file, i, (long)f);
+	inslist(&file, i, f);
 	if(downloaded)
 		outTsS(Hmovname, f->tag, &f->name);
 }
diff --git a/src/cmd/sam/rasp.c b/src/cmd/sam/rasp.c
index c5cc570..829a7b4 100644
--- a/src/cmd/sam/rasp.c
+++ b/src/cmd/sam/rasp.c
@@ -177,7 +177,7 @@
 }
 
 #define	M	0x80000000L
-#define	P(i)	r->longptr[i]
+#define	P(i)	r->posnptr[i]
 #define	T(i)	(P(i)&M)	/* in terminal */
 #define	L(i)	(P(i)&~M)	/* length of this piece */
 
diff --git a/src/cmd/sam/sam.c b/src/cmd/sam/sam.c
index d17f235..e34fb13 100644
--- a/src/cmd/sam/sam.c
+++ b/src/cmd/sam/sam.c
@@ -14,7 +14,7 @@
 File	*flist;
 File	*cmd;
 jmp_buf	mainloop;
-List	tempfile;
+List	tempfile = { 'p' };
 int	quitok = TRUE;
 int	downloaded;
 int	dflag;
@@ -37,10 +37,10 @@
 
 extern int notify(void(*)(void*,char*));
 
-int
-main(int volatile argc, char **volatile argv)
+void
+main(int argc, char **argv)
 {
-	int volatile i;
+	int i;
 	String *t;
 	char *termargs[10], **ap;
 	
@@ -82,7 +82,6 @@
 	Strinit0(&genstr);
 	Strinit0(&rhs);
 	Strinit0(&curwd);
-	tempfile.listptr = emalloc(1);	/* so it can be freed later */
 	Strinit0(&plan9cmd);
 	home = getenv(HOME);
 	disk = diskinit();
@@ -112,7 +111,6 @@
 	cmdloop();
 	trytoquit();	/* if we already q'ed, quitok will be TRUE */
 	exits(0);
-	return 0;
 }
 
 void
@@ -721,10 +719,11 @@
 settempfile(void)
 {
 	if(tempfile.nalloc < file.nused){
-		free(tempfile.listptr);
-		tempfile.listptr = emalloc(sizeof(*tempfile.filepptr)*file.nused);
+		if(tempfile.filepptr)
+			free(tempfile.filepptr);
+		tempfile.filepptr = emalloc(sizeof(File*)*file.nused);
 		tempfile.nalloc = file.nused;
 	}
+	memmove(tempfile.filepptr, file.filepptr, sizeof(File*)*file.nused);
 	tempfile.nused = file.nused;
-	memmove(&tempfile.filepptr[0], &file.filepptr[0], file.nused*sizeof(File*));
 }
diff --git a/src/cmd/sam/sam.h b/src/cmd/sam/sam.h
index fa86efd..4033915 100644
--- a/src/cmd/sam/sam.h
+++ b/src/cmd/sam/sam.h
@@ -70,26 +70,23 @@
 
 struct List	/* code depends on a long being able to hold a pointer */
 {
+	int	type;	/* 'p' for pointer, 'P' for Posn */
 	int	nalloc;
 	int	nused;
 	union{
-		void	*listp;
-		Block	*blkp;
-		long	*longp;
-		uchar*	*ucharp;
-		String*	*stringp;
-		File*	*filep;
-		long	listv;
+		void*	listp;
+		void**	voidp;
+		Posn*	posnp;
+		String**stringp;
+		File**	filep;
 	}g;
 };
 
 #define	listptr		g.listp
-#define	blkptr		g.blkp
-#define	longptr		g.longp
-#define	ucharpptr	g.ucharp
+#define	voidpptr	g.voidp
+#define	posnptr		g.posnp
 #define	stringpptr	g.stringp
 #define	filepptr	g.filep
-#define	listval		g.listv
 
 enum
 {
@@ -267,8 +264,9 @@
 int	getname(File*, String*, int);
 long	getnum(int);
 void	hiccough(char*);
-void	inslist(List*, int, long);
+void	inslist(List*, int, ...);
 Address	lineaddr(Posn, Address, int);
+List	*listalloc(int);
 void	listfree(List*);
 void	load(File*);
 File	*lookfile(String*);
@@ -401,12 +399,6 @@
 void	outTsllS(Hmesg, int, long, long, String*);
 void	outTsll(Hmesg, int, long, long);
 void	outTsl(Hmesg, int, long);
-void	outTsv(Hmesg, int, long);
-void	outstart(Hmesg);
-void	outcopy(int, void*);
-void	outshort(int);
-void	outlong(long);
-void	outvlong(void*);
-void	outsend(void);
+void	outTsv(Hmesg, int, vlong);
 void	outflush(void);