shithub: riscv

Download patch

ref: 0fc761bc845bd9795f05206e24621c0f5e76423e
parent: 7a95bef00e41cbab2d97f6392b221e6192335343
author: ftrvxmtrx <[email protected]>
date: Mon Jun 8 20:15:59 EDT 2015

unix is BUGGERED. remove it

--- a/lib/namespace.ftp
+++ b/lib/namespace.ftp
@@ -3,7 +3,6 @@
 
 # visible things go here
 bind /sys/doc /usr/web/plan9/doc
-bind /sys/src/cmd/unix /usr/web/plan9/unixsrc
 
 # anonymous ftp only allows writes to files below /incoming
 # bind a personal incoming directory below incoming
--- a/sys/man/4/u9fs
+++ /dev/null
@@ -1,289 +1,0 @@
-.TH U9FS 4
-.SH NAME
-u9fs \- serve 9P from Unix
-.SH SYNOPSIS
-.B u9fs
-[
-.B -Dnz
-]
-[
-.B -a
-.I authtype
-]
-[
-.B -A
-.I autharg
-]
-[
-.B -l
-.I logfile
-]
-[
-.B -m
-.I msize
-]
-[
-.B -u
-.I onlyuser
-]
-.I fsroot
-.SH DESCRIPTION
-.I U9fs
-is
-.I not
-a Plan 9 program.  Instead it is a program that
-serves Unix files to Plan 9 machines using the 9P protocol
-(see
-.IR intro (5)).
-It is typically invoked on a
-Unix machine by
-.B inetd
-with its standard input and output connected to a
-network connection, typically TCP on an Ethernet.
-It typically runs as user
-.B root
-and multiplexes access to multiple Plan 9 clients over the single wire.
-It assumes Plan 9 uids match Unix login names,
-and changes to the corresponding Unix effective uid when processing requests.
-Characters in file and directory names unacceptable to Plan 9 are translated
-into a three-character sequence:
-.L \e
-followed by two hexadecimal digits.
-.I U9fs
-serves both 9P1 (the 9P protocol as used by
-the second and third editions of Plan 9) and 9P2000.
-.PP
-The options are:
-.TF "\fL-A \fIautharg"
-.PD
-.TP
-.B -D
-Write very chatty debugging output to the log file (see
-.B -l
-option below).
-.TP
-.B -n
-Signals that
-.I u9fs
-is
-.I not
-being invoked with a network connection
-on standard input and output, and thus should
-not try to determine the remote address of the connection.
-This is useful when
-.I u9fs
-is not invoked from
-.I inetd
-(see examples below).
-.TP
-.B -z
-Truncate the log file on startup.  This is useful mainly when debugging
-with
-.BR -D .
-.TP
-.BI -a " authtype
-Sets the authentication method to be used.
-.I Authtype
-should be
-.BR rhosts ,
-.BR none ,
-or
-.BR p9any .
-The default is
-.BR rhosts ,
-which uses the
-.I ruserok
-library call to authenticate users by entries in
-.B /etc/hosts.equiv
-or
-.BR $HOME/.rhosts .
-This default is discouraged for all but the most controlled networks.
-Specifying
-.B none
-turns off authentication altogether.
-This is useful when
-.I u9fs
-is not invoked from
-.I inetd
-(see examples below, or
-.I srvssh
-in
-.IR srv (4)).
-Specifying
-.B p9any
-uses the fourth edition Plan 9 authentication mechanisms.
-The file
-.BR /etc/u9fs.key ,
-or
-.I autharg
-if specified
-(see the
-.B -A
-option),
-is consulted for the authentication data
-and should be suitably protected.
-This file must contain exactly three lines:
-.I secret
-(plaintext password),
-.I u9fs-user
-(user id),
-and
-.I plan9-auth.dom
-(authentication domain).
-.RS
-.LP
-Finally,
-.I factotum
-must be taught a key of the form:
-.LP
-.EX
-.B
-key proto=p9sk1 dom=\fIplan9-auth.dom\fP user=\fIu9fs-user\fP !password=\fIsecret\fP
-.EE
-.RE
-.TP
-.BI -A " autharg
-Used to specify an argument to the authentication method.
-See the authentication descriptions above.
-.TP
-.BI -l " logfile
-Specifies the file which should contain debugging output
-and other messages.
-The out-of-the-box compile-time default is
-.BR /tmp/u9fs.log .
-.TP
-.BI -m " msize
-Set
-.I msize
-for 9P2000
-(see
-.IR open (5)).
-.TP
-.BI -u " user
-Treat all attaches as coming from
-.IR user .
-This is useful in some cases when running without
-.IR inetd ;
-see the examples.
-.PP
-If
-.I fsroot
-is specified,
-.I u9fs
-will serve only that tree; othwise, it will serve the entire Unix
-file system.
-.SH EXAMPLES
-.PP
-Plan 9 calls 9P file service
-.B 9fs
-with TCP port number 564.
-Set up this way on a machine called, say,
-.BR kremvax ,
-.I u9fs
-may be connected to the name space of a Plan 9 process by
-.IP
-.EX
-9fs kremvax
-.EE
-.PP
-For more information on this procedure, see
-.IR srv (4)
-and
-.IR bind (1).
-.PP
-By default,
-.I u9fs
-serves the entire file system of the Unix machine.
-It forbids access to devices
-because the program is single-threaded and may block unpredictably.
-Using the
-.B attach
-specifier
-.B device
-connects to a file system identical to the usual system except
-it only permits device access (and may block unpredictably):
-.IP
-.EX
-srv tcp!kremvax!9fs
-mount -c /srv/tcp!kremvax!9fs /n/kremvax device
-.EE
-.PP
-(The
-.B 9fs
-command
-does not accept an attach specifier.)
-Even so,
-device access may produce unpredictable
-results if the block size of the device is greater than 8192,
-the maximum data size of a 9P message.
-.PP
-The source to
-.I u9fs
-is in the Plan 9 directory
-.BR /sys/src/cmd/unix/u9fs .
-To install
-.I u9fs
-on a Unix system with an ANSI C compiler, copy the source to a directory on that system
-and run
-.BR make .
-Then install the binary in
-.BR /usr/etc/u9fs .
-Add this line to
-.BR inetd.conf :
-.IP
-.EX
-9fs     stream  tcp     nowait  root   /usr/etc/u9fs   u9fs
-.EE
-.PP
-and this to
-.BR services :
-.IP
-.EX
-9fs     564/tcp       9fs  # Plan 9 fs
-.EE
-.LP
-Due to a bug in their
-IP software, some systems will not accept the service name
-.BR 9fs ,
-thinking it
-a service number because of the initial digit.
-If so, run the service as
-.B u9fs
-or
-.BR 564 .
-.PP
-On systems where listeners cannot be started,
-.IR execnet (4)
-is useful for running
-.I u9fs
-via other network mechanisms; the script
-.I srvssh
-in
-.IR srv (4)
-provides this for the
-.I ssh
-protocol.
-.SH SOURCE
-.B /sys/src/cmd/unix/u9fs
-.SH DIAGNOSTICS
-Problems are reported to the
-log file specified with the
-.B -l
-option (default
-.BR /tmp/u9fs.log ).
-The
-.B -D
-flag enables chatty debugging.
-.SH SEE ALSO
-.IR bind (1),
-.IR execnet (4),
-.IR srv (4),
-.IR ip (3),
-.IR nfsserver (8)
-.SH BUGS
-The implementation of devices is unsatisfactory.
-.LP
-Semantics like remove-on-close or the
-atomicity of
-.B wstat
-are hard to provide exactly.
--- a/sys/src/cmd/mkfile
+++ b/sys/src/cmd/mkfile
@@ -8,10 +8,8 @@
 YFLAGS=-d
 
 NOTSYS=sml|dup|.+\..+
-BUGGERED=unix
-OUTOFDATE=old
 
-NOMK=$NOTSYS|$BUGGERED|$OUTOFDATE
+NOMK=$NOTSYS
 
 cpuobjtype=`{sed -n 's/^O=//p' /$cputype/mkfile}
 DIRS=`{echo */mkfile | sed 's,/mkfile *,\n,g' | grep -v '^('$NOMK')$'}
--- a/sys/src/cmd/unix/9pfreebsd/README
+++ /dev/null
@@ -1,134 +1,0 @@
-
-This package implements Plan 9's IL and 9fs client for FreeBSD 3.2.
-
-> Getting the software
-
-  9pfreebsd.tgz
-
-> Installation
-
-  0. unpack:
-	mkdir ~/9pfreebsd
-	cd ~/9pfreebsd
-	zcat 9pfreebsd.tgz | tar -xf -
-
-     this creates the file freebsd-3.2.il-kernel.patch and the
-     directory mount_9fs.
-
-  1. get a fresh copy of the kernel. for example:
-	cp -r /usr/src/sys ~/9pfreebsd/freebsd-3.2
-
-  2. apply the patch:
-	cd ~/9pfreebsd/freebsd-3.2
-	patch -p0 < ../freebsd-3.2.il-kernel.patch
-
-  3. build a new kernel:
-	cd ~/9pfreebsd/freebsd-3.2/i386/conf
-	config IL
-	cd ../../compile/IL; make depend; make
-
-  4. boot the new kernel:
-	cp -p /kernel /kernel.good
-	cp ~/9pfreebsd/freebsd-3.2/compile/IL/kernel /kernel
-	reboot
-
-  5. build mount_9fs:
-	cd ~/9pfreebsd; make
-
-> Using IL
-
-  1. connect via IL:
-
-	  if( (s = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_IL)) < 0 ) {
-	    perror("socket");    
-	    exit(1);
-	  }
-	
-	  bzero(&sin, sizeof(sin));
-	  sin.sin_family = AF_INET;
-	  sin.sin_addr.s_addr = dest_addr;
-	  sin.sin_port = htons(dest_port);
-	  if( connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0 ) {
-	    perror("connect");
-	    exit(1);
-	  }
-
-  2. listen via IL:
-
-	  if( (s = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_IL)) < 0 ) {
-	    perror("socket");    
-	    exit(1);
-	  }
-	
-	  bzero(&sin, sizeof(sin));
-	  sin.sin_family = AF_INET;
-	  sin.sin_addr.s_addr = INADDR_ANY;
-	  sin.sin_port = htons(port_number);
-	
-	  if( bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0 ) {
-	    perror("bind");
-	    exit(1);
-	  }
-	
-	  if( listen(s, 5) < 0 ) {
-	    perror("listen");
-	    exit(1);
-	  }
-	
-	  len = sizeof(sin);
-	  if ( (c = accept(s, (struct sockaddr *)& sin, &len)) < 0 ) {
-	    perror("accept");
-	    exit(1);
-	  }
-  
-
-> Using 9fs 
-
-  1. limitations:
-
-     The current implementation is mostly tested with a single user on
-     the client. No one else can access the mounted file system except
-     the authenticator. But two users can mount the same file system
-     on the client with different nodes. This is not yet tested much.
-
-  2. mapping plan9 usernames to UNIX uids
-
-     Mount_9fs requires a translation between plan9 usernames and UNIX
-     uids. /etc/9uid.conf contains the map. The format is:
-
-		plan9_username	unix_uid
-
-     Not all plan9 users have to have an UNIX account on the
-     client. Just give them a unique uid which can be non-existent in
-     /etc/passwd.
-
-  3. mounting 9fs:
-
-     To mount by a regular user, the root has to set vfs.usermount to 1
-     first (sysctl -w vfs.usermount=1). Then follow the steps below.
-
-     To mount by root:
-	
-	mount_9fs -u 9user@9auth_server 9fileserver:path node
-
-     This mounts "path" on 9fileserver on local "node" on behalf of
-     "9user". Plan9 authentication server "9auth_server" is
-     contacted to obtain a ticket.
-
-     mount_9fs will prompt for "9username"'s plan9 password.
-
-     umount works as usual.
-
-     Only the caller of mount_9fs has access to the mounted file system.
-
-  4. WARNING:
-
-     The password is stored in kernel memory and can be read via kmem.
-
-> Bugs and Fixes:
-
-  You are welcome to contact [email protected] for bug
-  reports and fixes.
-
-
-
--- a/sys/src/cmd/unix/9pfreebsd/freebsd-3.2.il-kernel.patch
+++ /dev/null
@@ -1,7901 +1,0 @@
-diff -N -c -r /usr/src/sys/9fs/9auth.c ./9fs/9auth.c
-*** /usr/src/sys/9fs/9auth.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9auth.c	Mon May 22 17:11:29 2000
-***************
-*** 0 ****
---- 1,238 ----
-+ #include <sys/param.h>
-+ #include <sys/systm.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/protosw.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/uio.h>
-+ 
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ 
-+ #define	N2HCHAR(x)		x = *p++
-+ #define	N2HSHORT(x)	x = (p[0] | (p[1]<<8)); p += 2
-+ #define	N2HLONG(x)		x = (p[0] | (p[1]<<8) |\
-+ 				(p[2]<<16) | (p[3]<<24)); p += 4
-+ #define	N2HQUAD(x)	x = (u_int64_t)(p[0] | (p[1]<<8) |\
-+ 					(p[2]<<16) | (p[3]<<24)) |\
-+ 				((u_int64_t)(p[4] | (p[5]<<8) |\
-+ 					(p[6]<<16) | (p[7]<<24)) << 32); p += 8
-+ #define	N2HSTRING(x,n)	bcopy(p, x, n); p += n
-+ 
-+ #define	H2NCHAR(x)	*p++ = x
-+ #define	H2NSHORT(x)	p[0]=x; p[1]=x>>8; p += 2
-+ #define	H2NLONG(x)		p[0]=x; p[1]=x>>8; p[2]=x>>16; p[3]=x>>24; p += 4
-+ #define	H2NQUAD(x)	p[0]=x;	p[1]=x>>8;\
-+ 			p[2]=x>>16;	p[3]=x>>24;\
-+ 			p[4]=x>>32;	p[5]=x>>40;\
-+ 			p[6]=x>>48;	p[7]=x>>56;\
-+ 			p += 8
-+ #define	H2NSTRING(x,n)	bcopy(x, p, n); p += n
-+ 
-+ static int u9auth_send __P((struct socket *so, struct mbuf *top, struct proc *p));
-+ static int u9auth_recv __P((struct socket *so, struct mbuf **mp, struct proc *p));
-+ 
-+ static int u9auth_count = 0;
-+ 
-+ static int u9auth_tr2m(struct u9auth_ticketreq *f, char *ap)
-+ {
-+ 	int n;
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+         H2NCHAR(f->type);
-+ 	H2NSTRING(f->authid, U9FS_NAMELEN);
-+ 	H2NSTRING(f->authdom, U9FS_DOMLEN);
-+ 	H2NSTRING(f->chal, U9FS_CHALLEN);
-+ 	H2NSTRING(f->hostid, U9FS_NAMELEN);
-+ 	H2NSTRING(f->uid, U9FS_NAMELEN);
-+ 	n = p - (u_char*)ap;
-+ 	return n;
-+ }
-+ 
-+ static struct mbuf * u9auth_m_tr2m(struct u9auth_ticketreq * tktq)
-+ {
-+   register struct mbuf *m;
-+   char * ap;
-+   int sz = 141;
-+ 
-+   MGETHDR(m, M_WAIT, MT_DATA);
-+   if( sz > MHLEN )
-+     MCLGET(m, M_WAIT);
-+   m->m_len = 0;
-+ 
-+   if ( M_TRAILINGSPACE(m) < sz )
-+     panic("u9auth_m_tr2m");
-+   
-+   ap = mtod(m, char *);
-+   m->m_len = u9auth_tr2m(tktq, ap);
-+   m->m_pkthdr.len = m->m_len;
-+ 
-+   return (m);
-+ }
-+ 
-+ static int
-+ u9auth_send(so, top, p)
-+ 	register struct socket *so;
-+ 	register struct mbuf *top;
-+ 	register struct proc *p;
-+ 	
-+ {
-+   int error, soflags, flags;
-+   
-+   soflags = so->so_proto->pr_flags;
-+   if (so->so_type == SOCK_SEQPACKET)
-+     flags = MSG_EOR;
-+   else
-+     flags = 0;
-+   
-+   error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 0, top, 0, flags, p);
-+ 
-+   return (error);
-+ }
-+ 
-+ static int
-+ u9auth_recv(so, mp, p)	
-+      register struct socket * so;
-+      register struct mbuf **mp;
-+      struct proc *p;
-+ {
-+   struct uio auio;
-+   u_int32_t len;
-+   int error = 0, sotype, rcvflg;
-+ 
-+   *mp = 0;
-+   sotype = so->so_type;
-+   
-+   /*
-+    * For reliable protocols, lock against other senders/receivers
-+    * in case a reconnect is necessary.
-+    * For SOCK_STREAM, first get the Record Mark to find out how much
-+    * more there is to get.
-+    * We must lock the socket against other receivers
-+    * until we have an entire rpc request/reply.
-+    */
-+   if (sotype == SOCK_SEQPACKET ) {
-+     if( (so->so_state & SS_ISCONNECTED) == 0 )
-+       return (EACCES);
-+ 		auio.uio_resid = len = 1000000;
-+ 		auio.uio_procp = p;
-+ 		do {
-+ 			rcvflg = 0;
-+ 			error =  so->so_proto->pr_usrreqs->pru_soreceive
-+ 				(so, 0, &auio, mp,
-+ 				(struct mbuf **)0, &rcvflg);
-+ 		} while (error == EWOULDBLOCK);
-+ 		len -= auio.uio_resid;    
-+   }
-+   if (error) {
-+     m_freem(*mp);
-+     *mp = 0;
-+   }
-+   return (error);  
-+ }
-+ 
-+ static void
-+ u9auth_m2t(char *ap, struct u9auth_ticket *f, char *key)
-+ {
-+ 	u_char *p;
-+ 
-+ 	if(key)
-+ 		decrypt9(key, ap, U9AUTH_TICKETLEN);
-+ 	p = (u_char*)ap;
-+ 	N2HCHAR(f->num);
-+ 	N2HSTRING(f->chal, U9FS_CHALLEN);
-+ 	N2HSTRING(f->cuid, U9FS_NAMELEN);
-+ 	f->cuid[U9FS_NAMELEN-1] = 0;
-+ 	N2HSTRING(f->suid, U9FS_NAMELEN);
-+ 	f->suid[U9FS_NAMELEN-1] = 0;
-+ 	N2HSTRING(f->key, U9AUTH_DESKEYLEN);
-+ };
-+ 
-+ static int 
-+ u9auth_a2m(struct u9auth_authenticator *f, char *ap, char *key)
-+ {
-+ 	int n;
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+ 	H2NCHAR(f->num);
-+ 	H2NSTRING(f->chal, U9FS_CHALLEN);
-+ 	H2NLONG(f->id);
-+ 	n = p - (u_char*)ap;
-+ 	if(key)
-+ 		encrypt9(key, ap, n);
-+ 	return n;
-+ }
-+ 
-+ void u9auth_genchal (char * chal)
-+ {
-+   u_long * lp = (u_long *)chal;
-+ 
-+   *lp++ = random();
-+   *lp = random();
-+ }
-+ 
-+ int u9auth_gettickets (struct socket * so, struct u9fsreq * rep,
-+ 			   char * user, char * ckey, char * ts, char * authc,
-+ 		       struct proc *p)
-+ {
-+   char * cp;
-+   struct u9auth_ticketreq tktq;
-+   struct u9auth_ticket tc;
-+   struct u9auth_authenticator auth;
-+   struct mbuf * m;
-+   int error, len;
-+   
-+   bzero(&tktq, sizeof(tktq));
-+   tktq.type = AuthTreq;
-+   bcopy(rep->r_authid, tktq.authid, U9FS_NAMELEN);
-+   bcopy(rep->r_authdom, tktq.authdom, U9FS_DOMLEN);
-+   bcopy(rep->r_chal, tktq.chal, U9FS_CHALLEN);
-+   strncpy(tktq.hostid, user, U9FS_NAMELEN);
-+   strncpy(tktq.uid, user, U9FS_NAMELEN);
-+ 
-+   m = u9auth_m_tr2m(&tktq);
-+   error = u9auth_send(so, m, p);
-+   if( error ) 
-+     goto bad;
-+   error = u9auth_recv(so, &m, p);
-+   if( error )
-+     goto bad;
-+ 
-+   len = U9AUTH_TICKETLEN+1;
-+   if( m->m_len < len && (m = m_pullup(m, len)) == 0 )
-+     goto bad;
-+ 
-+   cp = mtod(m, char *);
-+   switch( cp[0] ) {
-+   case AuthOK:
-+     u9auth_m2t(&cp[1], & tc, ckey);
-+     bzero(&auth, sizeof(auth));
-+     auth.num = AuthAc;
-+     bcopy(tc.chal, auth.chal, sizeof(auth.chal));
-+     auth.id = u9auth_count++;
-+ 
-+     m->m_len -= len;
-+     m->m_data += len;
-+ 
-+     len = U9AUTH_TICKETLEN;
-+     if( m->m_len < len && (m = m_pullup(m, len)) == 0 )
-+       goto bad;
-+     cp = mtod(m, char *);
-+     bcopy(cp, ts, len);
-+     break;
-+   case AuthErr:
-+   case AuthOKvar:
-+     m_freem(m);
-+     goto bad;
-+     break;
-+   }
-+ 
-+   u9auth_a2m(&auth, authc, tc.key);
-+   return 0;
-+  bad:
-+   return error;
-+ }
-+ 
-diff -N -c -r /usr/src/sys/9fs/9auth.h ./9fs/9auth.h
-*** /usr/src/sys/9fs/9auth.h	Wed Dec 31 19:00:00 1969
---- ./9fs/9auth.h	Thu Nov 11 15:00:29 1999
-***************
-*** 0 ****
---- 1,129 ----
-+ #ifndef P9AUTH_H
-+ #define P9AUTH_H
-+ 
-+ #define U9AUTH_DOMLEN		48		/* length of an authentication domain name */
-+ #define U9AUTH_DESKEYLEN	7		/* length of a des key for encrypt/decrypt */
-+ #define U9AUTH_CHALLEN	8		/* length of a challenge */
-+ #define U9AUTH_NETCHLEN	16		/* max network challenge length	*/
-+ #define U9AUTH_CONFIGLEN	14
-+ #define U9AUTH_SECRETLEN	32		/* max length of a secret */
-+ #define U9AUTH_APOPCHLEN	256
-+ #define U9AUTH_MD5LEN		16
-+ #define U9AUTH_KEYDBOFF	8		/* length of random data at the start of key file */
-+ #define U9AUTH_OKEYDBLEN	U9FSNAMELEN+U9AUTH_DESKEYLEN+4+2,	/* length of an entry in old key file */
-+ #define U9AUTH_KEYDBLEN	OKEYDBLENSECRETLEN,	/* length of an entry in key file */
-+ 
-+ /* encryption numberings (anti-replay) */
-+ enum
-+ {
-+ 	AuthTreq=1,	/* ticket request */
-+ 	AuthChal=2,	/* challenge box request */
-+ 	AuthPass=3,	/* change password */
-+ 	AuthOK=4,	/* fixed length reply follows */
-+ 	AuthErr=5,	/* error follows */
-+ 	AuthMod=6,	/* modify user */
-+ 	AuthApop=7,	/* apop authentication for pop3 */
-+ 	AuthOKvar=9,	/* variable length reply follows */
-+ 	AuthChap=10,	/* chap authentication for ppp */
-+ 	AuthMSchap=11,	/* MS chap authentication for ppp */
-+ 
-+ 
-+ 	AuthTs=64,	/* ticket encrypted with server's key */
-+ 	AuthTc,		/* ticket encrypted with client's key */
-+ 	AuthAs,		/* server generated authenticator */
-+ 	AuthAc,		/* client generated authenticator */
-+ 	AuthTp,		/* ticket encrypted with clien's key for password change */
-+ };
-+ 
-+ struct u9auth_ticketreq
-+ {
-+ 	char	type;
-+ 	char	authid[U9FS_NAMELEN];	/* server's encryption id */
-+ 	char	authdom[U9AUTH_DOMLEN];	/* server's authentication domain */
-+ 	char	chal[U9AUTH_CHALLEN];		/* challenge from server */
-+ 	char	hostid[U9FS_NAMELEN];	/* host's encryption id */
-+ 	char	uid[U9FS_NAMELEN];		/* uid of requesting user on host */
-+ };
-+ #define	U9AUTH_TICKREQLEN	(3*U9FS_NAMELEN+U9AUTH_CHALLEN+U9AUTH_DOMLEN+1)
-+ 
-+ struct u9auth_ticket
-+ {
-+ 	char	num;			/* replay protection */
-+ 	char	chal[U9AUTH_CHALLEN];		/* server challenge */
-+ 	char	cuid[U9FS_NAMELEN];		/* uid on client */
-+ 	char	suid[U9FS_NAMELEN];		/* uid on server */
-+ 	char	key[U9AUTH_DESKEYLEN];		/* nonce DES key */
-+ };
-+ #define	U9AUTH_TICKETLEN	(U9AUTH_CHALLEN+2*U9FS_NAMELEN+U9AUTH_DESKEYLEN+1)
-+ 
-+ struct u9auth_authenticator
-+ {
-+ 	char	num;			/* replay protection */
-+ 	char	chal[U9AUTH_CHALLEN];
-+ 	u_long	id;			/* authenticator id, ++'d with each auth */
-+ };
-+ #define	U9AUTH_AUTHENTLEN	(U9AUTH_CHALLEN+4+1)
-+ 
-+ struct u9auth_passwordreq
-+ {
-+ 	char	num;
-+ 	char	old[U9FS_NAMELEN];
-+ 	char	new[U9FS_NAMELEN];
-+ 	char	changesecret;
-+ 	char	secret[U9AUTH_SECRETLEN];	/* new secret */
-+ };
-+ #define	U9AUTH_PASSREQLEN	(2*U9FS_NAMELEN+1+1+U9AUTH_SECRETLEN)
-+ 
-+ struct u9auth_nvrsafe
-+ {
-+ 	char	machkey[U9AUTH_DESKEYLEN];
-+ 	u_char	machsum;
-+ 	char	authkey[U9AUTH_DESKEYLEN];
-+ 	u_char	authsum;
-+ 	char	config[U9AUTH_CONFIGLEN];
-+ 	u_char	configsum;
-+ 	char	authid[U9FS_NAMELEN];
-+ 	u_char	authidsum;
-+ 	char	authdom[U9AUTH_DOMLEN];
-+ 	u_char	authdomsum;
-+ };
-+ 
-+ struct u9auth_chalstate
-+ {
-+ 	int	afd;			/* /dev/authenticate */
-+ 	int	asfd;			/* authdial() */
-+ 	char	chal[U9AUTH_NETCHLEN];		/* challenge/response */
-+ };
-+ 
-+ struct u9auth_apopchalstate
-+ {
-+ 	int	afd;			/* /dev/authenticate */
-+ 	int	asfd;			/* authdial() */
-+ 	char	chal[U9AUTH_APOPCHLEN];	/* challenge/response */
-+ };
-+ 
-+ struct	u9auth_chapreply
-+ {
-+ 	u_char	id;
-+ 	char	uid[U9FS_NAMELEN];
-+ 	char	resp[U9AUTH_MD5LEN];
-+ };
-+ 
-+ struct	u9auth_mSchapreply
-+ {
-+ 	char	uid[U9FS_NAMELEN];
-+ 	char	LMresp[24];		/* Lan Manager response */
-+ 	char	NTresp[24];		/* NT response */
-+ };
-+ 
-+ #ifdef KERNEL
-+ void u9auth_genchal __P((char *));
-+ int  u9auth_gettickets __P((struct socket * so, struct u9fsreq * rep,
-+ 			   char * user, char * ckey, char * ts, char * authc,
-+ 			    struct proc * p));
-+ int encrypt9 __P((void *key, void * vbuf, int n));
-+ int decrypt9 __P((void *key, void * vbuf, int n));
-+ 
-+ #endif
-+ 
-+ #endif
-diff -N -c -r /usr/src/sys/9fs/9crypt.c ./9fs/9crypt.c
-*** /usr/src/sys/9fs/9crypt.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9crypt.c	Thu Nov 11 12:23:02 1999
-***************
-*** 0 ****
---- 1,416 ----
-+ /*
-+  *	Data Encryption Standard
-+  *	D.P.Mitchell  83/06/08.
-+  *
-+  *	block_cipher(key, block, decrypting)
-+  */
-+ #include <sys/param.h>
-+ #include <sys/systm.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ 
-+ typedef unsigned char uchar;
-+ typedef unsigned long ulong;
-+ #define NAMELEN 28      /* length of path element, including '\0' */
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ 
-+ static	long	ip_low(char [8]);
-+ static	long	ip_high(char [8]);
-+ static	void	fp(long, long, char[8]);
-+ static	void	key_setup(char[U9AUTH_DESKEYLEN], char[128]);
-+ static	void	block_cipher(char[128], char[8], int);
-+ 
-+ /*
-+  * destructively encrypt the buffer, which
-+  * must be at least 8 characters long.
-+  */
-+ int
-+ encrypt9(void *key, void *vbuf, int n)
-+ {
-+ 	char ekey[128], *buf;
-+ 	int i, r;
-+ 
-+ 	if(n < 8)
-+ 		return 0;
-+ 	key_setup(key, ekey);
-+ 	buf = vbuf;
-+ 	n--;
-+ 	r = n % 7;
-+ 	n /= 7;
-+ 	for(i = 0; i < n; i++){
-+ 		block_cipher(ekey, buf, 0);
-+ 		buf += 7;
-+ 	}
-+ 	if(r)
-+ 		block_cipher(ekey, buf - 7 + r, 0);
-+ 	return 1;
-+ }
-+ 
-+ /*
-+  * destructively decrypt the buffer, which
-+  * must be at least 8 characters long.
-+  */
-+ int
-+ decrypt9(void *key, void *vbuf, int n)
-+ {
-+ 	char ekey[128], *buf;
-+ 	int i, r;
-+ 
-+ 	if(n < 8)
-+ 		return 0;
-+ 	key_setup(key, ekey);
-+ 	buf = vbuf;
-+ 	n--;
-+ 	r = n % 7;
-+ 	n /= 7;
-+ 	buf += n * 7;
-+ 	if(r)
-+ 		block_cipher(ekey, buf - 7 + r, 1);
-+ 	for(i = 0; i < n; i++){
-+ 		buf -= 7;
-+ 		block_cipher(ekey, buf, 1);
-+ 	}
-+ 	return 1;
-+ }
-+ 
-+ /*
-+  *	Tables for Combined S and P Boxes
-+  */
-+ 
-+ static long  s0p[] = {
-+ 0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
-+ 0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
-+ 0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
-+ 0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
-+ 0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
-+ 0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
-+ 0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
-+ 0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
-+ };
-+ 
-+ static long  s1p[] = {
-+ 0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
-+ 0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
-+ 0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
-+ 0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
-+ 0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
-+ 0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
-+ 0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
-+ 0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
-+ };
-+ 
-+ static long  s2p[] = {
-+ 0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
-+ 0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
-+ 0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
-+ 0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
-+ 0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
-+ 0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
-+ 0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
-+ 0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
-+ };
-+ 
-+ static long  s3p[] = {
-+ 0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
-+ 0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
-+ 0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
-+ 0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
-+ 0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
-+ 0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
-+ 0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
-+ 0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
-+ };
-+ 
-+ static long  s4p[] = {
-+ 0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
-+ 0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
-+ 0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
-+ 0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
-+ 0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
-+ 0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
-+ 0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
-+ 0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
-+ };
-+ 
-+ static long  s5p[] = {
-+ 0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
-+ 0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
-+ 0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
-+ 0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
-+ 0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
-+ 0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
-+ 0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
-+ 0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
-+ };
-+ 
-+ static long  s6p[] = {
-+ 0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
-+ 0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
-+ 0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
-+ 0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
-+ 0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
-+ 0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
-+ 0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
-+ 0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
-+ };
-+ 
-+ static long  s7p[] = {
-+ 0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
-+ 0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
-+ 0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
-+ 0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
-+ 0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
-+ 0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
-+ 0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
-+ 0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
-+ };
-+ 
-+ /*
-+  *	DES electronic codebook encryption of one block
-+  */
-+ static void
-+ block_cipher(char expanded_key[128], char text[8], int decrypting)
-+ {
-+ 	char *key;
-+ 	long crypto, temp, right, left;
-+ 	int i, key_offset;
-+ 
-+ 	key = expanded_key;
-+ 	left = ip_low(text);
-+ 	right = ip_high(text);
-+ 	if (decrypting) {
-+ 		key_offset = 16;
-+ 		key = key + 128 - 8;
-+ 	} else
-+ 		key_offset = 0;
-+ 	for (i = 0; i < 16; i++) {
-+ 		temp = (right << 1) | ((right >> 31) & 1);
-+ 		crypto  = s0p[(temp         & 0x3f) ^ *key++];
-+ 		crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
-+ 		crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
-+ 		crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
-+ 		crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
-+ 		crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
-+ 		crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
-+ 		temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
-+ 		crypto |= s7p[temp ^ *key++];
-+ 		temp = left;
-+ 		left = right;
-+ 		right = temp ^ crypto;
-+ 		key -= key_offset;
-+ 	}
-+ 	/*
-+ 	 *	standard final permutation (IPI)
-+ 	 *	left and right are reversed here
-+ 	 */
-+ 	fp(right, left, text);
-+ }
-+ 
-+ /*
-+  *	Initial Permutation
-+  */
-+ static long iptab[] = {
-+ 	0x00000000, 0x00008000, 0x00000000, 0x00008000,
-+ 	0x00000080, 0x00008080, 0x00000080, 0x00008080
-+ };
-+ 
-+ static long
-+ ip_low(char block[8])
-+ {
-+ 	int i;
-+ 	long l;
-+ 
-+ 	l = 0;
-+ 	for(i = 0; i < 8; i++){
-+ 		l |= iptab[(block[i] >> 4) & 7] >> i;
-+ 		l |= iptab[block[i] & 7] << (16 - i);
-+ 	}
-+ 	return l;
-+ }
-+ 
-+ static long
-+ ip_high(char block[8])
-+ {
-+ 	int i;
-+ 	long l;
-+ 
-+ 	l = 0;
-+ 	for(i = 0; i < 8; i++){
-+ 		l |= iptab[(block[i] >> 5) & 7] >> i;
-+ 		l |= iptab[(block[i] >> 1) & 7] << (16 - i);
-+ 	}
-+ 	return l;
-+ }
-+ 
-+ /*
-+  *	Final Permutation
-+  */
-+ static unsigned long	fptab[] = {
-+ 0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
-+ 0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
-+ };
-+ 
-+ static void
-+ fp(long left, long right, char text[8])
-+ {
-+ 	unsigned long ta[2], t, v[2];
-+ 	int i, j, sh;
-+ 
-+ 	ta[0] = right;
-+ 	ta[1] = left;
-+ 	v[0] = v[1] = 0;
-+ 	for(i = 0; i < 2; i++){
-+ 		t = ta[i];
-+ 		sh = i;
-+ 		for(j = 0; j < 4; j++){
-+ 			v[1] |= fptab[t & 0xf] >> sh;
-+ 			t >>= 4;
-+ 			v[0] |= fptab[t & 0xf] >> sh;
-+ 			t >>= 4;
-+ 			sh += 2;
-+ 		}
-+ 	}
-+ 	for(i = 0; i < 2; i++)
-+ 		for(j = 0; j < 4; j++){
-+ 			*text++ = v[i];
-+ 			v[i] >>= 8;
-+ 		}
-+ }
-+ 
-+ /*
-+  *	Key set-up
-+  */
-+ static uchar keyexpand[][15][2] = {
-+ 	{   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 16, 
-+ 	   74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
-+ 	{   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 32, 
-+ 	   64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
-+ 	{   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 32, 
-+ 	   89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
-+ 	{   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  1, 
-+ 	   78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
-+ 	{   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  8, 
-+ 	   85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
-+ 	{  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 32, 
-+ 	   86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
-+ 	{  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 16, 
-+ 	   85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
-+ 	{   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  8, 
-+ 	   83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
-+ 	{   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  2, 
-+ 	   74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
-+ 	{   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  8, 
-+ 	   82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
-+ 	{  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  8, 
-+ 	   94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
-+ 	{   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  8, 
-+ 	   78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
-+ 	{   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  8, 
-+ 	   84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
-+ 	{   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  2, 
-+ 	   69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
-+ 	{   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  2, 
-+ 	   72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
-+ 	{   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  2, 
-+ 	   67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
-+ 	{   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  2, 
-+ 	   72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
-+ 	{   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  2, 
-+ 	   70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
-+ 	{   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 16, 
-+ 	   84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
-+ 	{   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 32, 
-+ 	   78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
-+ 	{   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 16, 
-+ 	   77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
-+ 	{   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  1, 
-+ 	   80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
-+ 	{   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 16, 
-+ 	   72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
-+ 	{   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  8, 
-+ 	   74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
-+ 	{   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  8, 
-+ 	   86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
-+ 	{   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 32, 
-+ 	   85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
-+ 	{   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  2, 
-+ 	   87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
-+ 	{   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 16, 
-+ 	   71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
-+ 	{   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  4, 
-+ 	   83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
-+ 	{   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 16, 
-+ 	   74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
-+ 	{   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 32, 
-+ 	   73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
-+ 	{   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  4, 
-+ 	   91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
-+ 	{   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 16, 
-+ 	   76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
-+ 	{   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  4, 
-+ 	   86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
-+ 	{   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  8, 
-+ 	   84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
-+ 	{   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  1, 
-+ 	   72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
-+ 	{   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  8, 
-+ 	   99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
-+ 	{   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 32, 
-+ 	   81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
-+ 	{   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  4, 
-+ 	   73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
-+ 	{   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  1, 
-+ 	   86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
-+ 	{  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  4, 
-+ 	   85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
-+ 	{   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  8, 
-+ 	   70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
-+ 	{   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 16, 
-+ 	   80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
-+ 	{  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  1, 
-+ 	   73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
-+ 	{   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  8, 
-+ 	   65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
-+ 	{   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 32, 
-+ 	   97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
-+ 	{   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  4, 
-+ 	   79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
-+ 	{   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  4, 
-+ 	   78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
-+ 	{   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  1, 
-+ 	   86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
-+ 	{   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  1, 
-+ 	   74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
-+ 	{   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  8, 
-+ 	   91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
-+ 	{   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 32, 
-+ 	   73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
-+ 	{   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  4, 
-+ 	   65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
-+ 	{   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  8, 
-+ 	   92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
-+ 	{   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  4, 
-+ 	   77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
-+ 	{   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  2, 
-+ 	   77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
-+ };
-+ 
-+ static void
-+ key_setup(char key[U9AUTH_DESKEYLEN], char *ek)
-+ {
-+ 	int i, j, k, mask;
-+ 	uchar (*x)[2];
-+ 
-+ 	bzero(ek, 128);
-+ 	x = keyexpand[0];
-+ 	for(i = 0; i < 7; i++){
-+ 		k = key[i];
-+ 		for(mask = 0x80; mask; mask >>= 1){
-+ 			if(k & mask)
-+ 				for(j = 0; j < 15; j++)
-+ 					ek[x[j][0]] |= x[j][1];
-+ 			x += 15;
-+ 		}
-+ 	}
-+ }
-diff -N -c -r /usr/src/sys/9fs/9fs.h ./9fs/9fs.h
-*** /usr/src/sys/9fs/9fs.h	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs.h	Mon May 22 11:31:29 2000
-***************
-*** 0 ****
---- 1,294 ----
-+ /*
-+  * Copyright (c) 1989, 1993, 1995
-+  *	The Regents of the University of California.  All rights reserved.
-+  *
-+  * This code is derived from software contributed to Berkeley by
-+  * Rick Macklem at The University of Guelph.
-+  *
-+  * Redistribution and use in source and binary forms, with or without
-+  * modification, are permitted provided that the following conditions
-+  * are met:
-+  * 1. Redistributions of source code must retain the above copyright
-+  *    notice, this list of conditions and the following disclaimer.
-+  * 2. Redistributions in binary form must reproduce the above copyright
-+  *    notice, this list of conditions and the following disclaimer in the
-+  *    documentation and/or other materials provided with the distribution.
-+  * 3. All advertising materials mentioning features or use of this software
-+  *    must display the following acknowledgement:
-+  *	This product includes software developed by the University of
-+  *	California, Berkeley and its contributors.
-+  * 4. Neither the name of the University nor the names of its contributors
-+  *    may be used to endorse or promote products derived from this software
-+  *    without specific prior written permission.
-+  *
-+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+  * SUCH DAMAGE.
-+  *
-+  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
-+  * $Id: nfs.h,v 1.44 1998/09/07 05:42:15 bde Exp $
-+  */
-+ 
-+ #ifndef _9FS_H_
-+ #define _9FS_H_
-+ 
-+ #ifdef KERNEL
-+ #include "opt_u9fs.h"
-+ #endif
-+ 
-+ #define U9FS_FABLKSIZE   512
-+ #define U9FS_PORT        17008
-+ 
-+ /*
-+  * The set of signals the interrupt an I/O in progress for U9FSMNT_INT mounts.
-+  * What should be in this set is open to debate, but I believe that since
-+  * I/O system calls on ufs are never interrupted by signals the set should
-+  * be minimal. My reasoning is that many current programs that use signals
-+  * such as SIGALRM will not expect file I/O system calls to be interrupted
-+  * by them and break.
-+  */
-+ #define	U9FSINT_SIGMASK	(sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
-+ 			 sigmask(SIGHUP)|sigmask(SIGQUIT))
-+ 
-+ /*
-+  * U9FS mount option flags
-+  */
-+ #define	U9FSMNT_SOFT		0x00000001  /* soft mount (hard is default) */
-+ #define	U9FSMNT_MAXGRPS		0x00000020  /* set maximum grouplist size */
-+ #define	U9FSMNT_INT		0x00000040  /* allow interrupts on hard mount */
-+ #define	U9FSMNT_KERB		0x00000400  /* Use Kerberos authentication */
-+ #define	U9FSMNT_READAHEAD	0x00002000  /* set read ahead */
-+ 
-+ #define U9FSSTA_HASWRITEVERF	0x00040000  /* Has write verifier for V3 */
-+ #define U9FSSTA_GOTPATHCONF	0x00080000  /* Got the V3 pathconf info */
-+ #define U9FSSTA_GOTFSINFO	0x00100000  /* Got the V3 fsinfo */
-+ #define	U9FSSTA_MNTD		0x00200000  /* Mnt server for mnt point */
-+ #define	U9FSSTA_DISMINPROG	0x00400000  /* Dismount in progress */
-+ #define	U9FSSTA_DISMNT		0x00800000  /* Dismounted */
-+ #define	U9FSSTA_SNDLOCK		0x01000000  /* Send socket lock */
-+ #define	U9FSSTA_WANTSND		0x02000000  /* Want above */
-+ #define	U9FSSTA_RCVLOCK		0x04000000  /* Rcv socket lock */
-+ #define	U9FSSTA_WANTRCV		0x08000000  /* Want above */
-+ #define	U9FSSTA_WAITAUTH		0x10000000  /* Wait for authentication */
-+ #define	U9FSSTA_HASAUTH		0x20000000  /* Has authenticator */
-+ #define	U9FSSTA_WANTAUTH		0x40000000  /* Wants an authenticator */
-+ #define	U9FSSTA_AUTHERR		0x80000000  /* Authentication error */
-+ 
-+ #define	U9FSNOHASH(fhsum) (&u9fsnodehashtbl[(fhsum) % u9fsnodehash])
-+ 
-+ /*
-+  * Arguments to mount 9FS
-+  */
-+ #define U9FS_ARGSVERSION	1	/* change when nfs_args changes */
-+ struct u9fs_args {
-+ 	int		version;	/* args structure version number */
-+ 	struct sockaddr	*addr;		/* file server address */
-+ 	int		addrlen;	/* length of address */
-+ 	int		sotype;		/* Socket type */
-+ 	int		proto;		/* and Protocol */
-+ 	int		fhsize;		/* Size, in bytes, of fh */
-+ 	int		flags;		/* flags */
-+ 	int		wsize;		/* write size in bytes */
-+ 	int		rsize;		/* read size in bytes */
-+ 	int		readdirsize;	/* readdir size in bytes */
-+ 	char		*hostname;	/* server's name */
-+ 
-+         struct sockaddr * authaddr;
-+         int             authaddrlen;
-+         int             authsotype;
-+         int             authsoproto;
-+ 
-+         int             nusers;
-+         char            user[U9FS_NAMELEN];
-+         char            key[U9AUTH_DESKEYLEN];
-+         struct p9user {
-+ 	  uid_t p9_uid;
-+ 	  char p9_name[U9FS_NAMELEN];
-+ 	} * users;
-+ };
-+ 
-+ #define U9FS_USER_HASHSIZE 512
-+ 
-+ struct u9fsuser {
-+   LIST_ENTRY(u9fsuser) u_hash;
-+   uid_t                u_uid;
-+   char                 u_name[U9FS_NAMELEN];
-+   char                 u_ckey[U9AUTH_DESKEYLEN];  /* user key */
-+   char                 u_skey[U9AUTH_DESKEYLEN];  /* session key */
-+ };
-+ 
-+ /*
-+  * The u9fsnode is the u9fs equivalent to ufs's inode. Any similarity
-+  * is purely coincidental.
-+  * There is a unique u9fsnode allocated for each active file,
-+  * each current directory, each mounted-on file, text file, and the root.
-+  * An u9fsnode is 'named' by its file handle. (nget/u9fs_node.c)
-+  * If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite
-+  * type definitions), file handles of > 32 bytes should probably be split out
-+  * into a separate MALLOC()'d data structure. (Reduce the size of u9fsfh_t by
-+  * changing the definition in u9fsproto.h of U9FS_SMALLFH.)
-+  * NB: Hopefully the current order of the fields is such that everything will
-+  *     be well aligned and, therefore, tightly packed.
-+  */
-+ struct u9fsnode {
-+ 	LIST_ENTRY(u9fsnode)	n_hash;		/* Hash chain */
-+ 	u_quad_t		n_size;		/* Current size of file */
-+ 	struct vattr		n_vattr;	/* Vnode attribute cache */
-+ 	time_t			n_attrstamp;	/* Attr. cache timestamp */
-+ 	u_int32_t		n_mode;		/* ACCESS mode cache */
-+ 	uid_t			n_modeuid;	/* credentials having mode */
-+ 	time_t			n_modestamp;	/* mode cache timestamp */
-+ 	time_t			n_mtime;	/* Prev modify time. */
-+ 	time_t			n_ctime;	/* Prev create time. */
-+         struct u9fs_qid         n_qid;
-+ 	u_short			n_fid;		/* U9FS FID */
-+         u_short                 n_rdfid;      
-+         u_short                 n_wrfid;      
-+ 	struct vnode		*n_vnode;	/* associated vnode */
-+ 	struct lockf		*n_lockf;	/* Locking record of file */
-+ 	int			n_error;	/* Save write error value */
-+         struct u9fsdir          n_dir;
-+ 	short			n_flag;		/* Flag for locking.. */
-+         int                     n_opens;        /* number of opens */
-+ };
-+ 
-+ #define n_atim		n_un1.nf_atim
-+ #define n_mtim		n_un2.nf_mtim
-+ #define n_sillyrename	n_un3.nf_silly
-+ #define n_cookieverf	n_un1.nd_cookieverf
-+ #define n_direofoffset	n_un2.nd_direof
-+ #define n_cookies	n_un3.nd_cook
-+ 
-+ /*
-+  * Flags for n_flag
-+  */
-+ #define	NFLUSHWANT	0x0001	/* Want wakeup from a flush in prog. */
-+ #define	NFLUSHINPROG	0x0002	/* Avoid multiple calls to vinvalbuf() */
-+ #define	NMODIFIED	0x0004	/* Might have a modified buffer in bio */
-+ #define	NWRITEERR	0x0008	/* Flag write errors so close will know */
-+ #define	NQU9FSNONCACHE	0x0020	/* Non-cachable lease */
-+ #define	NQU9FSWRITE	0x0040	/* Write lease */
-+ #define	NQU9FSEVICTED	0x0080	/* Has been evicted */
-+ #define	NACC		0x0100	/* Special file accessed */
-+ #define	NUPD		0x0200	/* Special file updated */
-+ #define	NCHG		0x0400	/* Special file times changed */
-+ #define NLOCKED		0x0800  /* node is locked */
-+ #define NWANTED		0x0100  /* someone wants to lock */
-+ 
-+ /*
-+  * Convert between u9fsnode pointers and vnode pointers
-+  */
-+ #define VTOU9FS(vp)	((struct u9fsnode *)(vp)->v_data)
-+ #define U9FSTOV(np)	((struct vnode *)(np)->n_vnode)
-+ 
-+ /*
-+  * Mount structure.
-+  * One allocated on every U9FS mount.
-+  * Holds U9FS specific information for mount.
-+  */
-+ struct	u9fsmount {
-+ 	int	nm_flag;		/* Flags for soft/hard... */
-+ 	int	nm_state;		/* Internal state flags */
-+ 	struct	mount *nm_mountp;	/* Vfs structure for this filesystem */
-+ 	int	nm_numgrps;		/* Max. size of groupslist */
-+         u9fsfh_t nm_fh;                /* qid.path */
-+ 	u_short	nm_fid;	                /* fid of root dir */
-+ 	struct	socket *nm_so;		/* Rpc socket */
-+ 	int	nm_sotype;		/* Type of socket */
-+ 	int	nm_soproto;		/* and protocol */
-+ 	int	nm_soflags;		/* pr_flags for socket protocol */
-+ 	struct	sockaddr *nm_nam;	/* Addr of server */
-+ 	int	nm_sent;		/* Request send count */
-+ 	int	nm_cwnd;		/* Request send window */
-+ 	int	nm_rsize;		/* Max size of read rpc */
-+ 	int	nm_wsize;		/* Max size of write rpc */
-+ 	int	nm_readdirsize;		/* Size of a readdir rpc */
-+   
-+   struct lock   nm_lock;                /* lock for tag/fid freelist */
-+   bitstr_t * nm_tags;
-+   bitstr_t * nm_fids;
-+   TAILQ_HEAD(u9fs_reqq, u9fsreq) nm_reqq;
-+ 
-+         uid_t   nm_authuid;             /* Uid for authenticator */
-+ #if 0
-+ 	struct vnode *nm_inprog;	/* Vnode in prog by nqu9fs_clientd() */
-+ 	uid_t	nm_authuid;		/* Uid for authenticator */
-+ 	int	nm_authtype;		/* Authenticator type */
-+ 	int	nm_authlen;		/* and length */
-+ 	char	*nm_authstr;		/* Authenticator string */
-+ 	char	*nm_verfstr;		/* and the verifier */
-+ 	int	nm_verflen;
-+ 	u_char	nm_verf[U9FSX_V3WRITEVERF]; /* V3 write verifier */
-+ 	U9FSKERBKEY_T nm_key;		/* and the session key */
-+ 	int	nm_numuids;		/* Number of u9fsuid mappings */
-+ 	TAILQ_HEAD(, u9fsuid) nm_uidlruhead; /* Lists of u9fsuid mappings */
-+ 	LIST_HEAD(, u9fsuid) nm_uidhashtbl[U9FS_MUIDHASHSIZ];
-+ 	TAILQ_HEAD(, buf) nm_bufq;	/* async io buffer queue */
-+ 	short	nm_bufqlen;		/* number of buffers in queue */
-+ 	short	nm_bufqwant;		/* process wants to add to the queue */
-+ 	int	nm_bufqiods;		/* number of iods processing queue */
-+ #endif
-+ 	u_int64_t nm_maxfilesize;	/* maximum file size */
-+ };
-+ 
-+ #ifdef KERNEL
-+ 
-+ #ifdef MALLOC_DECLARE
-+ MALLOC_DECLARE(M_U9FSHASH);
-+ MALLOC_DECLARE(M_U9FSBITS);
-+ 
-+ extern        vop_t   **u9fs_vnodeop_p;
-+ 
-+ /* u9fs_node.c */
-+ void     u9fs_nhinit __P((void));
-+ int u9fs_nget __P((struct mount *mntp, u9fsfh_t fh, struct u9fsnode **npp, struct proc * p));
-+ 
-+ /* u9fs_subr.c */
-+ void u9fs_id_init __P((bitstr_t ** bits));
-+ u_short u9fs_id_new __P((bitstr_t * bits));
-+ void u9fs_id_free __P((bitstr_t * bits, u_short v));
-+ void u9fs_uhinit __P((void));
-+ uid_t u9fs_name2uid __P((char * name));
-+ struct u9fsuser *  u9fs_finduser __P((uid_t uid));
-+ void  u9fs_hashuser __P((uid_t uid, char *name));
-+ int u9fs_mbuftouio __P((struct mbuf *m, struct uio *uiop, int siz));
-+ int u9fs_uiotombuf __P((struct uio *uiop, struct mbuf **mq, int siz));
-+ 
-+ /* u9fs_vnopes.c */
-+ int u9fs_readdirrpc __P((struct vnode *, struct uio *, struct ucred *));
-+ int u9fs_readrpc __P((struct vnode *vp, struct uio *uiop, struct ucred *cred));
-+ int u9fs_writerpc __P((struct vnode *vp, struct uio *uiop, struct ucred *cred));
-+ 
-+ /* u9fs_bio.c */
-+ int u9fs_bioread __P((struct vnode *, struct uio *, int, struct ucred *,int));
-+ int u9fs_biowrite __P((struct vnode *, struct uio *, int ioflag, struct ucred *));
-+ int u9fs_doio __P((struct buf *, struct ucred *, struct proc *));
-+ int	u9fs_vinvalbuf __P((struct vnode *, int, struct ucred *, struct proc *, int));
-+ 
-+ 
-+ /* u9fs_socket.c */
-+ int u9fs_sigintr __P((struct u9fsmount *nmp, struct proc *p));
-+ void     u9fs_disconnect __P((struct socket *));
-+ int      u9fs_connect __P((struct socket ** sop, struct sockaddr * saddr, int sotype, int soproto, struct proc * p));
-+ int      u9fs_connect_9fs __P((struct u9fsmount *));
-+ int      u9fs_connect_9auth __P((struct u9fsmount *, struct u9fs_args *, struct socket **));
-+ int u9fs_request __P((struct u9fsreq * req, struct u9fsreq * rep, int relm));
-+ 
-+ #endif
-+ 
-+ /*
-+  * Convert mount ptr to u9fsmount ptr.
-+  */
-+ #define VFSTOU9FS(mp)	((struct u9fsmount *)((mp)->mnt_data))
-+ 
-+ #endif	/* KERNEL */
-+ 
-+ #endif
-diff -N -c -r /usr/src/sys/9fs/9fs_bio.c ./9fs/9fs_bio.c
-*** /usr/src/sys/9fs/9fs_bio.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_bio.c	Fri Nov 26 12:28:50 1999
-***************
-*** 0 ****
---- 1,550 ----
-+ #include <sys/param.h>
-+ #include <sys/sockio.h>
-+ #include <sys/proc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/kernel.h>
-+ #include <sys/sysctl.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mount.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/systm.h>
-+ #include <sys/protosw.h>
-+ #include <sys/syslog.h>
-+ 
-+ #include <netinet/in.h>
-+ #include <netinet/tcp.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ #include <vm/vm_prot.h>
-+ #include <vm/vm_page.h>
-+ #include <vm/vm_object.h>
-+ #include <vm/vm_pager.h>
-+ #include <vm/vnode_pager.h>
-+ 
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ static struct buf *u9fs_getcacheblk __P((struct vnode *vp, daddr_t bn, int size, struct proc *p));
-+ static void u9fs_prot_buf __P((struct buf *bp, int off, int n));
-+ 
-+ /*
-+  * Vnode op for read using bio
-+  */
-+ int
-+ u9fs_bioread(vp, uio, ioflag, cred, getpages)
-+ 	register struct vnode *vp;
-+ 	register struct uio *uio;
-+ 	int ioflag;
-+ 	struct ucred *cred;
-+ 	int getpages;
-+ {
-+ 	register struct u9fsnode *np = VTOU9FS(vp);
-+ 	register int biosize;
-+ 	off_t diff;
-+ 	struct buf *bp = 0;
-+ 	struct proc *p;
-+ 	struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+ 	daddr_t lbn;
-+ 	int error = 0, n = 0, on = 0, bufsize, not_readin;
-+ 
-+ 	if (uio->uio_resid == 0)
-+ 		return (0);
-+ 	if (uio->uio_offset < 0)
-+ 		return (EINVAL);
-+ 	p = uio->uio_procp;
-+ 	if (vp->v_type != VDIR &&
-+ 	    (uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
-+ 		return (EFBIG);
-+ 	biosize = vp->v_mount->mnt_stat.f_iosize;
-+ #if 0
-+ 	if( np->n_qid.vers ) { /* in cache, check revision */
-+ 	  error = VOP_GETATTR(vp, &vattr, cred, p);
-+ 	  if( error )
-+ 	    return error;
-+ 	  if( np->n_qid.vers != np->n_dir.dir_qid.vers ) {
-+ 	    /* content changed */
-+ 	    u9fs_vinvalbuf(vp, V_SAVE, cred, p, 1);
-+ 	  }
-+ 	}
-+ #endif
-+ 	do {
-+ 	    switch (vp->v_type) {
-+ 	    case VREG:
-+ 		lbn = uio->uio_offset / biosize;
-+ 		on = uio->uio_offset & (biosize - 1);
-+ 		not_readin = 1;
-+ 
-+ #if 0
-+ 		/*
-+ 		 * Start the read ahead(s), as required.
-+ 		 */
-+ 		if (u9fs_numasync > 0 && nmp->nm_readahead > 0) {
-+ 		    for (nra = 0; nra < nmp->nm_readahead &&
-+ 			(off_t)(lbn + 1 + nra) * biosize < np->n_size; nra++) {
-+ 			rabn = lbn + 1 + nra;
-+ 			if (!incore(vp, rabn)) {
-+ 			    rabp = u9fs_getcacheblk(vp, rabn, biosize, p);
-+ 			    if (!rabp)
-+ 				return (EINTR);
-+ 			    if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
-+ 				rabp->b_flags |= (B_READ | B_ASYNC);
-+ 				vfs_busy_pages(rabp, 0);
-+ 				if (u9fs_asyncio(rabp, cred)) {
-+ 				    rabp->b_flags |= B_INVAL|B_ERROR;
-+ 				    vfs_unbusy_pages(rabp);
-+ 				    brelse(rabp);
-+ 				}
-+ 			    } else
-+ 				brelse(rabp);
-+ 			}
-+ 		    }
-+ 		}
-+ #endif
-+ 
-+ 		/*
-+ 		 * If the block is in the cache and has the required data
-+ 		 * in a valid region, just copy it out.
-+ 		 * Otherwise, get the block and write back/read in,
-+ 		 * as required.
-+ 		 */
-+ again:
-+ 		bufsize = biosize;
-+ 		if ((off_t)(lbn + 1) * biosize > np->n_size && 
-+ 		    (off_t)(lbn + 1) * biosize - np->n_size < biosize) {
-+ 			bufsize = np->n_size - (off_t)lbn * biosize;
-+ 			bufsize = (bufsize + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
-+ 		}
-+ 		bp = u9fs_getcacheblk(vp, lbn, bufsize, p);
-+ 		if (!bp)
-+ 			return (EINTR);
-+ 		/*
-+ 		 * If we are being called from u9fs_getpages, we must
-+ 		 * make sure the buffer is a vmio buffer.  The vp will
-+ 		 * already be setup for vmio but there may be some old
-+ 		 * non-vmio buffers attached to it.
-+ 		 */
-+ 		if (getpages && !(bp->b_flags & B_VMIO)) {
-+ #ifdef DIAGNOSTIC
-+ 			printf("u9fs_bioread: non vmio buf found, discarding\n");
-+ #endif
-+ 			bp->b_flags |= B_NOCACHE;
-+ 			if (bp->b_dirtyend > 0) {
-+ 				if ((bp->b_flags & B_DELWRI) == 0)
-+ 					panic("u9fsbioread");
-+ 				if (VOP_BWRITE(bp) == EINTR)
-+ 					return (EINTR);
-+ 			} else
-+ 				brelse(bp);
-+ 			goto again;
-+ 		}
-+ 		if ((bp->b_flags & B_CACHE) == 0) {
-+ 		    bp->b_flags |= B_READ;
-+ 		    bp->b_flags &= ~(B_DONE | B_ERROR | B_INVAL);
-+ 		    not_readin = 0;
-+ 		    vfs_busy_pages(bp, 0);
-+ 		    error = u9fs_doio(bp, cred, p);
-+ 		    if (error) {
-+ 			brelse(bp);
-+ 			return (error);
-+ 		    }
-+ 		    np->n_qid.vers = np->n_dir.dir_qid.vers;
-+ 		}
-+ 		if (bufsize > on) {
-+ 			n = min((unsigned)(bufsize - on), uio->uio_resid);
-+ 		} else {
-+ 			n = 0;
-+ 		}
-+ 		diff = np->n_size - uio->uio_offset;
-+ 		if (diff < n)
-+ 			n = diff;
-+ 		if (not_readin && n > 0) {
-+ 			if (on < bp->b_validoff || (on + n) > bp->b_validend) {
-+ 				bp->b_flags |= B_NOCACHE;
-+ 				if (bp->b_dirtyend > 0) {
-+ 				    if ((bp->b_flags & B_DELWRI) == 0)
-+ 					panic("u9fsbioread");
-+ 				    if (VOP_BWRITE(bp) == EINTR)
-+ 					return (EINTR);
-+ 				} else
-+ 				    brelse(bp);
-+ 				goto again;
-+ 			}
-+ 		}
-+ 		vp->v_lastr = lbn;
-+ 		diff = (on >= bp->b_validend) ? 0 : (bp->b_validend - on);
-+ 		if (diff < n)
-+ 			n = diff;
-+ 		break;
-+ 	    case VDIR:
-+ 	        biosize = nmp->nm_readdirsize;
-+ 		lbn = (uoff_t)uio->uio_offset / biosize;
-+ 		on = uio->uio_offset % biosize;
-+ 		bp = u9fs_getcacheblk(vp, lbn, biosize, p);
-+ 		if (!bp)
-+ 		    return (EINTR);
-+ 		if ((bp->b_flags & B_CACHE) == 0) {
-+ 		    bp->b_flags |= B_READ;
-+ 		    vfs_busy_pages(bp, 0);
-+ 		    error = u9fs_doio(bp, cred, p);
-+ 		    if (error) {
-+ 			    brelse(bp);
-+ 		    }
-+ 		    if (error)
-+ 			    return (error);
-+ 		    np->n_qid.vers = np->n_dir.dir_qid.vers;
-+ 		}
-+ 
-+ 		/*
-+ 		 * Make sure we use a signed variant of min() since
-+ 		 * the second term may be negative.
-+ 		 */
-+ 		n = lmin(uio->uio_resid, biosize - bp->b_resid - on);
-+ 		break;
-+ 	    default:
-+ 		printf(" u9fs_bioread: type %x unexpected\n",vp->v_type);
-+ 		break;
-+ 	    };
-+ 
-+ 	    if (n > 0) {
-+ 		    error = uiomove(bp->b_data + on, (int)n, uio);
-+ 	    }
-+ 	    brelse(bp);
-+ 	} while (error == 0 && uio->uio_resid > 0 && n > 0);
-+ 	return (error);
-+ }
-+ 
-+ /*
-+  * Vnode op for write using bio
-+  */
-+ int
-+ u9fs_biowrite(vp, uio, ioflag, cred)
-+      register struct vnode *vp;
-+      register struct uio *uio;
-+      register int  ioflag;
-+      register struct ucred *cred;
-+ {
-+   register int biosize;
-+   struct proc *p = uio->uio_procp;
-+   struct u9fsnode *np = VTOU9FS(vp);
-+   struct buf *bp;
-+   struct vattr vattr;
-+   struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+   daddr_t lbn;
-+   int bufsize;
-+   int n, on, error = 0;
-+ 
-+   if (ioflag & (IO_APPEND | IO_SYNC)) {
-+     if (ioflag & IO_APPEND) {
-+       error = VOP_GETATTR(vp, &vattr, cred, p);
-+       if (error)
-+ 	return (error);
-+       uio->uio_offset = np->n_size;
-+     }
-+   }
-+   if (uio->uio_offset < 0)
-+     return (EINVAL);
-+   if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
-+     return (EFBIG);
-+   if (uio->uio_resid == 0)
-+     return (0);
-+ 
-+ 	/*
-+ 	 * I use nm_rsize, not nm_wsize so that all buffer cache blocks
-+ 	 * will be the same size within a filesystem. nfs_writerpc will
-+ 	 * still use nm_wsize when sizing the rpc's.
-+ 	 */
-+ 	biosize = vp->v_mount->mnt_stat.f_iosize;
-+ 	do {
-+ 		lbn = uio->uio_offset / biosize;
-+ 		on = uio->uio_offset & (biosize-1);
-+ 		n = min((unsigned)(biosize - on), uio->uio_resid);
-+ 		if (uio->uio_offset + n > np->n_size) {
-+ 			np->n_size = uio->uio_offset + n;
-+ 			vnode_pager_setsize(vp, np->n_size);
-+ 		}
-+ 		bufsize = biosize;
-+ 		if ((off_t)(lbn + 1) * biosize > np->n_size) {
-+ 			bufsize = np->n_size - (off_t)lbn * biosize;
-+ 			bufsize = (bufsize + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
-+ 		}
-+ 		bp = u9fs_getcacheblk(vp, lbn, bufsize, p);
-+ 		if (!bp)
-+ 			return (EINTR);
-+ 		if (bp->b_wcred == NOCRED) {
-+ 			crhold(cred);
-+ 			bp->b_wcred = cred;
-+ 		}
-+ 
-+ 		error = uiomove((char *)bp->b_data + on, n, uio);
-+ 		if (error) {
-+ 			bp->b_flags |= B_ERROR;
-+ 			brelse(bp);
-+ 			return (error);
-+ 		}
-+ 
-+ 		/*
-+ 		 * This will keep the buffer and mmaped regions more coherent.
-+ 		 */
-+ 		u9fs_prot_buf(bp, on, n);
-+ 		bp->b_dirtyoff = on;
-+ 		bp->b_dirtyend = on + n;
-+ 
-+ 		if (bp->b_validend == 0 || bp->b_validend < bp->b_dirtyoff ||
-+ 		    bp->b_validoff > bp->b_dirtyend) {
-+ 		  /* XXX: destroys our read cache if not overlapping */
-+ 		  /* two choice: none implemented
-+ 		     1> keep the bigger(smaller) piece
-+ 		     2> read the missing segment		     
-+ 		  */
-+ 			bp->b_validoff = bp->b_dirtyoff;
-+ 			bp->b_validend = bp->b_dirtyend;
-+ 		} else {
-+ 			bp->b_validoff = min(bp->b_validoff, bp->b_dirtyoff);
-+ 			bp->b_validend = max(bp->b_validend, bp->b_dirtyend);
-+ 		}
-+ 
-+ 		error = bwrite(bp);
-+ 		if( error ) {
-+ 		  bp->b_flags |= B_ERROR;
-+ 		  /* brelse(bp); */
-+ 		  return error;		  
-+ 		}
-+ 	} while (uio->uio_resid > 0 && n > 0);
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * Do an I/O operation to/from a cache block. This may be called
-+  * synchronously or from an u9fsiod.
-+  */
-+ int
-+ u9fs_doio(bp, cr, p)
-+ 	register struct buf *bp;
-+ 	struct ucred *cr;
-+ 	struct proc *p;
-+ {
-+ 	register struct uio *uiop;
-+ 	register struct vnode *vp;
-+ 	struct u9fsnode *np;
-+ 	struct u9fsmount *nmp;
-+ 	int error = 0, diff, len;
-+ 	struct uio uio;
-+ 	struct iovec io;
-+ 
-+ 	vp = bp->b_vp;
-+ 	np = VTOU9FS(vp);
-+ 	nmp = VFSTOU9FS(vp->v_mount);
-+ 	uiop = &uio;
-+ 	uiop->uio_iov = &io;
-+ 	uiop->uio_iovcnt = 1;
-+ 	uiop->uio_segflg = UIO_SYSSPACE;
-+ 	uiop->uio_procp = p;
-+ 
-+ 	if (bp->b_flags & B_READ ) {
-+ 	    io.iov_len = uiop->uio_resid = bp->b_bcount;
-+ 	    io.iov_base = bp->b_data;
-+ 	    uiop->uio_rw = UIO_READ;
-+ 	    switch (vp->v_type) {
-+ 	    case VREG:
-+ 		uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
-+ 		error = u9fs_readrpc(vp, uiop, cr);
-+ 		if (!error) {
-+ 		    bp->b_validoff = 0;
-+ 		    if (uiop->uio_resid) {
-+ 			/*
-+ 			 * If len > 0, there is a hole in the file and
-+ 			 * no writes after the hole have been pushed to
-+ 			 * the server yet.
-+ 			 * Just zero fill the rest of the valid area.
-+ 			 */
-+ 			diff = bp->b_bcount - uiop->uio_resid;
-+ 			len = np->n_size - (((u_quad_t)bp->b_blkno) * DEV_BSIZE
-+ 				+ diff);
-+ 			if (len > 0) {
-+ 			    len = min(len, uiop->uio_resid);
-+ 			    bzero((char *)bp->b_data + diff, len);
-+ 			    bp->b_validend = diff + len;
-+ 			} else
-+ 			    bp->b_validend = diff;
-+ 		    } else
-+ 			bp->b_validend = bp->b_bcount;
-+ 		}
-+ 		break;
-+ 	    case VDIR:
-+ 		uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * nmp->nm_readdirsize;
-+ 		error = u9fs_readdirrpc(vp, uiop, cr);
-+ 		if (error == 0 && uiop->uio_resid == bp->b_bcount)
-+ 		  bp->b_flags |= B_INVAL;
-+ 		break;
-+ 	    default:
-+ 		printf("u9fs_doio:  type %x unexpected\n",vp->v_type);
-+ 		break;
-+ 	    };
-+ 	    if (error) {
-+ 		bp->b_flags |= B_ERROR;
-+ 		bp->b_error = error;
-+ 	    }
-+ 	} else {
-+ 	    if ((off_t)bp->b_blkno * DEV_BSIZE + bp->b_dirtyend > np->n_size)
-+ 		bp->b_dirtyend = np->n_size - (off_t)bp->b_blkno * DEV_BSIZE;
-+ 
-+ 	    if (bp->b_dirtyend > bp->b_dirtyoff) {
-+ 		io.iov_len = uiop->uio_resid = bp->b_dirtyend
-+ 		    - bp->b_dirtyoff;
-+ 		uiop->uio_offset = (off_t)bp->b_blkno * DEV_BSIZE
-+ 		    + bp->b_dirtyoff;
-+ 		io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
-+ 		uiop->uio_rw = UIO_WRITE;
-+ 		bp->b_flags |= B_WRITEINPROG;
-+ 		error = u9fs_writerpc(vp, uiop, cr);
-+ 		bp->b_flags &= ~B_WRITEINPROG;
-+ 
-+ 		if (error) {
-+ 		  bp->b_flags |= B_ERROR;
-+ 		  bp->b_error = np->n_error = error;
-+ 		  np->n_flag |= NWRITEERR;
-+ 		}
-+ 		bp->b_dirtyoff = bp->b_dirtyend = 0;
-+ 	    } else {
-+ 		bp->b_resid = 0;
-+ 		biodone(bp);
-+ 		return (0);
-+ 	    }
-+ 	}
-+ 	bp->b_resid = uiop->uio_resid;
-+ 	biodone(bp);
-+ 	return error;
-+ }
-+ 
-+ /*
-+  * Get an u9fs cache block.
-+  * Allocate a new one if the block isn't currently in the cache
-+  * and return the block marked busy. If the calling process is
-+  * interrupted by a signal for an interruptible mount point, return
-+  * NULL.
-+  */
-+ static struct buf *
-+ u9fs_getcacheblk(vp, bn, size, p)
-+ 	struct vnode *vp;
-+ 	daddr_t bn;
-+ 	int size;
-+ 	struct proc *p;
-+ {
-+ 	register struct buf *bp;
-+ 	struct mount *mp;
-+ 	struct u9fsmount *nmp;
-+ 
-+ 	mp = vp->v_mount;
-+ 	nmp = VFSTOU9FS(mp);
-+ 
-+ 	if (nmp->nm_flag & U9FSMNT_INT) {
-+ 		bp = getblk(vp, bn, size, PCATCH, 0);
-+ 		while (bp == (struct buf *)0) {
-+ 			if (u9fs_sigintr(nmp, p))
-+ 				return ((struct buf *)0);
-+ 			bp = getblk(vp, bn, size, 0, 2 * hz);
-+ 		}
-+ 	} else
-+ 		bp = getblk(vp, bn, size, 0, 0);
-+ 
-+ 	if (vp->v_type == VREG) {
-+ 		int biosize;
-+ 		biosize = mp->mnt_stat.f_iosize;
-+ 		bp->b_blkno = bn * (biosize / DEV_BSIZE);
-+ 	}
-+ 
-+ 	return (bp);
-+ }
-+ 
-+ static void
-+ u9fs_prot_buf(bp, off, n)
-+ 	struct buf *bp;
-+ 	int off;
-+ 	int n;
-+ {
-+ 	int pindex, boff, end;
-+ 
-+ 	if ((bp->b_flags & B_VMIO) == 0)
-+ 		return;
-+ 
-+ 	end = round_page(off + n);
-+ 	for (boff = trunc_page(off); boff < end; boff += PAGE_SIZE) {
-+ 		pindex = boff >> PAGE_SHIFT;
-+ 		vm_page_protect(bp->b_pages[pindex], VM_PROT_NONE);
-+ 	}
-+ }
-+ 
-+ /*
-+  * Flush and invalidate all dirty buffers. If another process is already
-+  * doing the flush, just wait for completion.
-+  */
-+ int
-+ u9fs_vinvalbuf(vp, flags, cred, p, intrflg)
-+ 	struct vnode *vp;
-+ 	int flags;
-+ 	struct ucred *cred;
-+ 	struct proc *p;
-+ 	int intrflg;
-+ {
-+ 	register struct u9fsnode *np = VTOU9FS(vp);
-+ 	struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+ 	int error = 0, slpflag, slptimeo;
-+ 
-+ 	if (vp->v_flag & VXLOCK) {
-+ 		return (0);
-+ 	}
-+ 
-+ 	if ((nmp->nm_flag & U9FSMNT_INT) == 0)
-+ 		intrflg = 0;
-+ 	if (intrflg) {
-+ 		slpflag = PCATCH;
-+ 		slptimeo = 2 * hz;
-+ 	} else {
-+ 		slpflag = 0;
-+ 		slptimeo = 0;
-+ 	}
-+ 	/*
-+ 	 * First wait for any other process doing a flush to complete.
-+ 	 */
-+ 	while (np->n_flag & NFLUSHINPROG) {
-+ 		np->n_flag |= NFLUSHWANT;
-+ 		error = tsleep((caddr_t)&np->n_flag, PRIBIO + 2, "u9fsvinval",
-+ 			slptimeo);
-+ 		if (error && intrflg && u9fs_sigintr(nmp, p))
-+ 			return (EINTR);
-+ 	}
-+ 
-+ 	/*
-+ 	 * Now, flush as required.
-+ 	 */
-+ 	np->n_flag |= NFLUSHINPROG;
-+ 	error = vinvalbuf(vp, flags, cred, p, slpflag, 0);
-+ 	while (error) {
-+ 		if (intrflg && u9fs_sigintr(nmp, p)) {
-+ 			np->n_flag &= ~NFLUSHINPROG;
-+ 			if (np->n_flag & NFLUSHWANT) {
-+ 				np->n_flag &= ~NFLUSHWANT;
-+ 				wakeup((caddr_t)&np->n_flag);
-+ 			}
-+ 			return (EINTR);
-+ 		}
-+ 		error = vinvalbuf(vp, flags, cred, p, 0, slptimeo);
-+ 	}
-+ 	np->n_flag &= ~(NMODIFIED | NFLUSHINPROG);
-+ 	if (np->n_flag & NFLUSHWANT) {
-+ 		np->n_flag &= ~NFLUSHWANT;
-+ 		wakeup((caddr_t)&np->n_flag);
-+ 	}
-+ 	return (0);
-+ }
-+ 
-diff -N -c -r /usr/src/sys/9fs/9fs_node.c ./9fs/9fs_node.c
-*** /usr/src/sys/9fs/9fs_node.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_node.c	Thu Nov 25 15:36:49 1999
-***************
-*** 0 ****
---- 1,132 ----
-+ #include <sys/param.h>
-+ #include <sys/sockio.h>
-+ #include <sys/proc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/kernel.h>
-+ #include <sys/sysctl.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mount.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/systm.h>
-+ #include <sys/protosw.h>
-+ #include <sys/syslog.h>
-+ 
-+ #include <netinet/in.h>
-+ #include <netinet/tcp.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ 
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ vm_zone_t u9fsnode_zone;
-+ static LIST_HEAD(u9fsnodehashhead, u9fsnode) *u9fsnodehashtbl;
-+ static u_long u9fsnodehash;
-+ MALLOC_DEFINE(M_U9FSHASH, "U9FS hash", "U9FS hash tables");
-+ 
-+ /*
-+  * Initialize hash links for u9fsnodes
-+  * and build u9fsnode free list.
-+  */
-+ void
-+ u9fs_nhinit()
-+ {
-+   u9fsnode_zone = zinit("U9FSNODE", sizeof(struct u9fsnode), 0, 0, 1);
-+   u9fsnodehashtbl = phashinit(desiredvnodes, M_U9FSHASH, &u9fsnodehash);
-+ }
-+ 
-+ /*
-+  * Look up a vnode/u9fsnode by file handle.
-+  * Callers must check for mount points!!
-+  * In all cases, a pointer to a
-+  * u9fsnode structure is returned.
-+  */
-+ static int u9fs_node_hash_lock;
-+ 
-+ int
-+ u9fs_nget(mntp, fh, npp, p)
-+      struct mount *mntp;
-+      register u9fsfh_t fh;
-+      struct u9fsnode **npp;
-+      struct proc * p;
-+ {
-+   struct u9fsnode *np;
-+   struct u9fsnodehashhead *nhpp;
-+   register struct vnode *vp;
-+   struct vnode *nvp;
-+   int error;
-+ 
-+   nhpp = U9FSNOHASH(fh);
-+ loop:
-+   for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
-+     if (mntp != U9FSTOV(np)->v_mount || fh != np->n_qid.path )
-+       continue;
-+     vp = U9FSTOV(np);
-+     if (vget(vp, LK_EXCLUSIVE, p))
-+       goto loop;
-+     *npp = np;
-+     return(0);
-+   }
-+   /*
-+    * Obtain a lock to prevent a race condition if the getnewvnode()
-+    * or MALLOC() below happens to block.
-+    */
-+   if (u9fs_node_hash_lock) {
-+     while (u9fs_node_hash_lock) {
-+       u9fs_node_hash_lock = -1;
-+       tsleep(&u9fs_node_hash_lock, PVM, "u9fsngt", 0);
-+     }
-+     goto loop;
-+   }
-+   u9fs_node_hash_lock = 1;
-+ 
-+   /*
-+    * allocate before getnewvnode since doing so afterward
-+    * might cause a bogus v_data pointer to get dereferenced
-+    * elsewhere if zalloc should block.
-+    */
-+   np = zalloc(u9fsnode_zone);
-+   
-+   error = getnewvnode(VT_U9FS, mntp, u9fs_vnodeop_p, &nvp);
-+   if (error) {
-+     if (u9fs_node_hash_lock < 0)
-+       wakeup(&u9fs_node_hash_lock);
-+     u9fs_node_hash_lock = 0;
-+     *npp = 0;
-+     zfree(u9fsnode_zone, np);
-+     return (error);
-+   }
-+   vp = nvp;
-+   bzero((caddr_t)np, sizeof *np);
-+   vp->v_data = np;
-+   np->n_vnode = vp;
-+   /*
-+    * Insert the u9fsnode in the hash queue for its new file handle
-+    */
-+   LIST_INSERT_HEAD(nhpp, np, n_hash);
-+   np->n_qid.path = fh;
-+   np->n_qid.vers = 0; /* not in cache yet */
-+   np->n_fid = 0; /* should be set by the caller */
-+   *npp = np;
-+ 
-+   if (u9fs_node_hash_lock < 0)
-+     wakeup(&u9fs_node_hash_lock);
-+   u9fs_node_hash_lock = 0;
-+ 
-+   /*
-+    * Lock the new u9fsnode.
-+    */
-+   vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
-+   
-+   return (0);
-+ }
-diff -N -c -r /usr/src/sys/9fs/9fs_socket.c ./9fs/9fs_socket.c
-*** /usr/src/sys/9fs/9fs_socket.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_socket.c	Thu Nov 25 15:48:46 1999
-***************
-*** 0 ****
---- 1,503 ----
-+ #include <sys/param.h>
-+ #include <sys/sockio.h>
-+ #include <sys/proc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/kernel.h>
-+ #include <sys/sysctl.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mount.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/systm.h>
-+ #include <sys/protosw.h>
-+ #include <sys/syslog.h>
-+ 
-+ #include <netinet/in.h>
-+ #include <netinet/tcp.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ 
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ static int u9fs_reply __P((struct u9fsreq * req));
-+ static int u9fs_send __P((struct socket * so, struct mbuf * mreq, struct u9fsreq * req));
-+ static int u9fs_receive __P((struct socket * so, struct mbuf **mrep, struct u9fsreq * req));
-+ 
-+ static int u9fs_sndlock __P((int *flagp, int *statep, struct u9fsreq *rep));
-+ static void u9fs_sndunlock __P((int *flagp, int *statep));
-+ static int u9fs_rcvlock __P((struct u9fsreq *req));
-+ static void u9fs_rcvunlock __P((int *flagp, int *statep));
-+ 
-+ int
-+ u9fs_connect(struct socket ** sop, struct sockaddr * saddr, int sotype, int soproto, struct proc * p)
-+ {
-+   register struct socket * so;
-+   int error, s;
-+   
-+   *sop = 0;
-+   error = socreate(saddr->sa_family, sop, sotype, soproto, p);
-+   if( error )
-+     return error;
-+   so = *sop;
-+   error = soconnect(so, saddr, p);
-+   if( error )
-+     return error;
-+ 
-+   /*
-+    * Wait for the connection to complete. Cribbed from the
-+    * connect system call but with the wait timing out so
-+    * that interruptible mounts don't hang here for a long time.
-+    */
-+   s = splnet();
-+   while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
-+     (void) tsleep((caddr_t)&so->so_timeo, PSOCK,
-+ 		  "u9fscon", 2 * hz);
-+ 
-+   if (so->so_error) {
-+     error = so->so_error;
-+     so->so_error = 0;
-+     splx(s);
-+     return error;
-+   }
-+   splx(s);
-+ 
-+   return (0);
-+ }
-+ 
-+ int u9fs_connect_9auth(struct u9fsmount * nmp, struct u9fs_args * argp, struct socket ** sop)
-+ {
-+   int error;
-+   struct proc * p = & proc0;
-+   struct sockaddr *nam;
-+ 
-+   error = getsockaddr(&nam, (caddr_t)argp->authaddr, argp->authaddrlen);
-+   if( error )
-+     return error;
-+   error = u9fs_connect(sop, nam, argp->authsotype, 
-+ 		       argp->authsoproto, p);
-+   if( error == 0 )
-+     return 0;
-+ 
-+   u9fs_disconnect(*sop);
-+   *sop = 0;
-+   return error;
-+ }
-+ 
-+ /*
-+  * Initialize sockets and congestion for a new U9FS connection.
-+  * We do not free the sockaddr if error.
-+  */
-+ int
-+ u9fs_connect_9fs(nmp)
-+      register struct u9fsmount *nmp;
-+ {
-+   register struct socket *so;
-+   int error, rcvreserve, sndreserve;
-+   struct proc *p = &proc0; /* only used for socreate and sobind */
-+ 
-+   error = u9fs_connect(&nmp->nm_so, nmp->nm_nam, nmp->nm_sotype, 
-+ 		       nmp->nm_soproto, p);
-+   if (error)
-+     goto bad;
-+   so = nmp->nm_so;
-+   nmp->nm_soflags = so->so_proto->pr_flags;
-+ 
-+   if (nmp->nm_flag & (U9FSMNT_SOFT | U9FSMNT_INT)) {
-+     so->so_rcv.sb_timeo = (5 * hz);
-+     so->so_snd.sb_timeo = (5 * hz);
-+   } else {
-+     so->so_rcv.sb_timeo = 0;
-+     so->so_snd.sb_timeo = 0;
-+   }
-+ 
-+   /* XXX: i dont understand this, only one outstanding request? */
-+   if (nmp->nm_sotype == SOCK_SEQPACKET) {
-+     sndreserve = (nmp->nm_wsize) * 2;
-+     rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize)) * 2;
-+   } else {
-+     if (nmp->nm_sotype != SOCK_STREAM)
-+       panic("u9fscon sotype");
-+     if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
-+       struct sockopt sopt;
-+       int val;
-+       
-+       bzero(&sopt, sizeof sopt);
-+       sopt.sopt_level = SOL_SOCKET;
-+       sopt.sopt_name = SO_KEEPALIVE;
-+       sopt.sopt_val = &val;
-+       sopt.sopt_valsize = sizeof val;
-+       val = 1;
-+       sosetopt(so, &sopt);
-+     }
-+     if (so->so_proto->pr_protocol == IPPROTO_TCP) {
-+       struct sockopt sopt;
-+       int val;
-+       
-+       bzero(&sopt, sizeof sopt);
-+       sopt.sopt_level = IPPROTO_TCP;
-+       sopt.sopt_name = TCP_NODELAY;
-+       sopt.sopt_val = &val;
-+       sopt.sopt_valsize = sizeof val;
-+       val = 1;
-+       sosetopt(so, &sopt);
-+     }
-+     sndreserve = (nmp->nm_wsize) * 2;
-+     rcvreserve = (nmp->nm_rsize) * 2;
-+   }
-+   error = soreserve(so, sndreserve, rcvreserve);
-+   if (error)
-+     goto bad;
-+   so->so_rcv.sb_flags |= SB_NOINTR;
-+   so->so_snd.sb_flags |= SB_NOINTR;
-+ 
-+   /* Initialize other non-zero congestion variables */
-+   nmp->nm_sent = 0;
-+   return (0);
-+ 
-+ bad:
-+   u9fs_disconnect(nmp->nm_so);
-+   nmp->nm_so = 0;
-+   return (error);
-+ }
-+ 
-+ /*
-+  * U9FS disconnect. Clean up and unlink.
-+  */
-+ void
-+ u9fs_disconnect(struct socket * so)
-+ {
-+     soshutdown(so, 2);
-+     soclose(so);
-+ }
-+ 
-+ /*
-+  * Lock a socket against others.
-+  * Necessary for STREAM sockets to ensure you get an entire rpc request/reply
-+  * and also to avoid race conditions between the processes with u9fs requests
-+  * in progress when a reconnect is necessary.
-+  */
-+ static int
-+ u9fs_sndlock(flagp, statep, rep)
-+ 	register int *flagp;
-+ 	register int *statep;
-+ 	struct u9fsreq *rep;
-+ {
-+ 	struct proc *p;
-+ 	int slpflag = 0, slptimeo = 0;
-+ 
-+ 	if (rep) {
-+ 		p = rep->r_procp;
-+ 		if (rep->r_nmp->nm_flag & U9FSMNT_INT)
-+ 			slpflag = PCATCH;
-+ 	} else
-+ 		p = (struct proc *)0;
-+ 	while (*statep & U9FSSTA_SNDLOCK) {
-+ 		if (u9fs_sigintr(rep->r_nmp, p))
-+ 			return (EINTR);
-+ 		*statep |= U9FSSTA_WANTSND;
-+ 		(void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1),
-+ 			"u9fsndlck", slptimeo);
-+ 		if (slpflag == PCATCH) {
-+ 			slpflag = 0;
-+ 			slptimeo = 2 * hz;
-+ 		}
-+ 	}
-+ 	*statep |= U9FSSTA_SNDLOCK;
-+ 	return (0);
-+ }
-+ 
-+ 
-+ /*
-+  * Unlock the stream socket for others.
-+  */
-+ static void
-+ u9fs_sndunlock(flagp, statep)
-+ 	register int *flagp;
-+ 	register int *statep;
-+ {
-+ 
-+ 	if ((*statep & U9FSSTA_SNDLOCK) == 0)
-+ 		panic("u9fs sndunlock");
-+ 	*statep &= ~U9FSSTA_SNDLOCK;
-+ 	if (*statep & U9FSSTA_WANTSND) {
-+ 		*statep &= ~U9FSSTA_WANTSND;
-+ 		wakeup((caddr_t)flagp);
-+ 	}
-+ }
-+ 
-+ /*
-+  * Test for a termination condition pending on the process.
-+  * This is used for U9FSMNT_INT mounts.
-+  */
-+ int
-+ u9fs_sigintr(nmp, p)
-+ 	struct u9fsmount *nmp;
-+ 	struct proc * p;
-+ {
-+ 	if (!(nmp->nm_flag & U9FSMNT_INT))
-+ 		return (0);
-+ 	if (p && p->p_siglist &&
-+ 	    (((p->p_siglist & ~p->p_sigmask) & ~p->p_sigignore) &
-+ 	    U9FSINT_SIGMASK))
-+ 		return (EINTR);
-+ 	return (0);
-+ }
-+ 
-+ /*
-+  * This is the u9fs send routine. For connection based socket types, it
-+  * must be called with an u9fs_sndlock() on the socket.
-+  * "rep == NULL" indicates that it has been called from a server.
-+  * For the client side:
-+  * - return EINTR if the RPC is terminated, 0 otherwise
-+  * - set R_MUSTRESEND if the send fails for any reason
-+  * - do any cleanup required by recoverable socket errors (?)
-+  * For the server side:
-+  * - return EINTR or ERESTART if interrupted by a signal
-+  * - return EPIPE if a connection is lost for connection based sockets (TCP...)
-+  * - do any cleanup required by recoverable socket errors (?)
-+  */
-+ static int
-+ u9fs_send(so, top, req)
-+ 	register struct socket *so;
-+ 	register struct mbuf *top;
-+ 	struct u9fsreq *req;
-+ {
-+   int error, soflags, flags;
-+   
-+   soflags = so->so_proto->pr_flags;
-+   if (so->so_type == SOCK_SEQPACKET)
-+     flags = MSG_EOR;
-+   else
-+     flags = 0;
-+   
-+   error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 0, top, 0,
-+ 					       flags, req->r_procp);
-+   if (error)
-+     log(LOG_INFO, "u9fs send error %d for server %s\n",error,
-+ 	  req->r_nmp->nm_mountp->mnt_stat.f_mntfromname);
-+ 
-+   return (error);
-+ }
-+ 
-+ static int
-+ u9fs_receive(so, mrep, req)	
-+      register struct socket * so;
-+      struct mbuf **mrep;
-+      struct u9fsreq * req;
-+ {
-+   struct uio auio;
-+   u_int32_t len;
-+   int error = 0, sotype, rcvflg;
-+   
-+   /*
-+    * Set up arguments for soreceive()
-+    */
-+   *mrep = (struct mbuf *)0;
-+   sotype = req->r_nmp->nm_sotype;
-+   
-+   /*
-+    * For reliable protocols, lock against other senders/receivers
-+    * in case a reconnect is necessary.
-+    * For SOCK_STREAM, first get the Record Mark to find out how much
-+    * more there is to get.
-+    * We must lock the socket against other receivers
-+    * until we have an entire rpc request/reply.
-+    */
-+   if (sotype == SOCK_SEQPACKET ) {
-+     if( (so->so_state & SS_ISCONNECTED) == 0 )
-+       return (EACCES);
-+ 		auio.uio_resid = len = 1000000;
-+ 		auio.uio_procp = req->r_procp;
-+ 		do {
-+ 			rcvflg = 0;
-+ 			error =  so->so_proto->pr_usrreqs->pru_soreceive
-+ 				(so, 0, &auio, mrep,
-+ 				(struct mbuf **)0, &rcvflg);
-+ 		} while (error == EWOULDBLOCK);
-+ 		len -= auio.uio_resid;    
-+   }
-+   if (error) {
-+     m_freem(*mrep);
-+     *mrep = (struct mbuf *)0;
-+   }
-+   return (error);  
-+ }
-+ 
-+ static int
-+ u9fs_rcvlock(req)
-+ 	register struct u9fsreq *req;
-+ {
-+ 	register int *flagp = &req->r_nmp->nm_flag;
-+ 	register int *statep = &req->r_nmp->nm_state;
-+ 	int slpflag, slptimeo = 0;
-+ 
-+ 	if (*flagp & U9FSMNT_INT)
-+ 		slpflag = PCATCH;
-+ 	else
-+ 		slpflag = 0;
-+ 	while (*statep & U9FSSTA_RCVLOCK) {
-+ 		if (u9fs_sigintr(req->r_nmp, req->r_procp))
-+ 			return (EINTR);
-+ 		*statep |= U9FSSTA_WANTRCV;
-+ 		(void) tsleep((caddr_t)flagp, slpflag | (PZERO - 1), "u9fsrcvlk",
-+ 			slptimeo);
-+ 		/*
-+ 		 * If our reply was recieved while we were sleeping,
-+ 		 * then just return without taking the lock to avoid a
-+ 		 * situation where a single iod could 'capture' the
-+ 		 * recieve lock.
-+ 		 */
-+ 		if (req->r_mrep != NULL)
-+ 			return (EALREADY);
-+ 		if (slpflag == PCATCH) {
-+ 			slpflag = 0;
-+ 			slptimeo = 2 * hz;
-+ 		}
-+ 	}
-+ 	*statep |= U9FSSTA_RCVLOCK;
-+ 	return (0);
-+ }
-+ 
-+ /*
-+  * Unlock the stream socket for others.
-+  */
-+ static void
-+ u9fs_rcvunlock(flagp, statep)
-+ 	register int *flagp;
-+ 	register int *statep;
-+ {
-+ 
-+ 	if ((*statep & U9FSSTA_RCVLOCK) == 0)
-+ 		panic("u9fs rcvunlock");
-+ 	*statep &= ~U9FSSTA_RCVLOCK;
-+ 	if (*statep & U9FSSTA_WANTRCV) {
-+ 		*statep &= ~U9FSSTA_WANTRCV;
-+ 		wakeup((caddr_t)flagp);
-+ 	}
-+ }
-+ 
-+ /*
-+  * Implement receipt of reply on a socket.
-+  * We must search through the list of received datagrams matching them
-+  * with outstanding requests using the xid, until ours is found.
-+  */
-+ /* ARGSUSED */
-+ static 
-+ int u9fs_reply(struct u9fsreq * req)
-+ {
-+   int error;
-+   struct mbuf * mrep;
-+   register struct u9fsmount *nmp = req->r_nmp;
-+   u_short tag;
-+   struct u9fsreq * qp;
-+ 
-+   /*
-+    * Loop around until we get our own reply
-+    */
-+   for (;;) {
-+     /*
-+      * Lock against other receivers so that I don't get stuck in
-+      * sbwait() after someone else has received my reply for me.
-+      * Also necessary for connection based protocols to avoid
-+      * race conditions during a reconnect.
-+      * If u9fs_rcvlock() returns EALREADY, that means that
-+      * the reply has already been recieved by another
-+      * process and we can return immediately.  In this
-+      * case, the lock is not taken to avoid races with
-+      * other processes.
-+      */
-+     error = u9fs_rcvlock(req);
-+     if (error == EALREADY)
-+       return (0);
-+     if (error)
-+       return (error);
-+     /*
-+      * Get the next Rpc reply off the socket
-+      */
-+     error = u9fs_receive(nmp->nm_so, &mrep, req);
-+     u9fs_rcvunlock(&nmp->nm_flag, &nmp->nm_state);
-+     if (error)
-+       return (error);
-+ 
-+     /* extract the tag */
-+     tag = u9p_m_tag(&mrep);
-+ 
-+     /*
-+      * Loop through the request list to match up the reply
-+      * Iff no match, just drop the datagram
-+      */
-+     for (qp = nmp->nm_reqq.tqh_first; qp != 0; qp = qp->r_chain.tqe_next) {
-+       if ( qp->r_mrep == 0 && qp->r_tag == tag )
-+ 	break;
-+     }
-+     if( qp == 0 ) {
-+       m_freem(mrep);
-+       continue;
-+     }
-+ 
-+     if( u9p_m_m2s(&mrep, qp->r_rep) ) { /* freed by m2s */
-+       continue;
-+     }
-+ 
-+     qp->r_mrep = mrep;  /* should not be freed until the reply is read */
-+ 
-+     if( qp == req )
-+       return 0;
-+   }
-+ }
-+ 
-+ int u9fs_request(struct u9fsreq * req, struct u9fsreq * rep, int relm)
-+ {
-+   struct mbuf * mreq;
-+   int error,s;
-+   struct u9fsmount * nmp;  
-+ 
-+   req->r_rep = rep;
-+   req->r_mrep = 0;
-+   nmp = req->r_nmp;
-+   req->r_tag = u9fs_id_new(nmp->nm_tags);
-+ 
-+   mreq = u9p_m_s2m(req);
-+ 
-+   /*
-+    * Chain request into list of outstanding requests. Be sure
-+    * to put it LAST so timer finds oldest requests first.
-+    */
-+   s = splsoftclock();
-+   TAILQ_INSERT_TAIL(&nmp->nm_reqq, req, r_chain);
-+   splx(s);
-+ 
-+   error = u9fs_send(nmp->nm_so, mreq, req);
-+ 
-+   if( !error )
-+     error = u9fs_reply(req);
-+ 
-+   /*
-+    * RPC done, unlink the request.
-+    */
-+   s = splsoftclock();
-+   TAILQ_REMOVE(&nmp->nm_reqq, req, r_chain);
-+   splx(s);
-+ 
-+   u9fs_id_free(nmp->nm_tags, req->r_tag);
-+ 
-+   if( !error && relm ) {
-+ 	m_freem(req->r_mrep);
-+ 	req->r_mrep = 0;
-+   }      
-+   if( rep->r_type == Rerror )
-+       error = EACCES;
-+ 
-+   return error;
-+ }
-+ 
-diff -N -c -r /usr/src/sys/9fs/9fs_subr.c ./9fs/9fs_subr.c
-*** /usr/src/sys/9fs/9fs_subr.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_subr.c	Fri Nov 26 12:28:17 1999
-***************
-*** 0 ****
---- 1,240 ----
-+ #include <sys/param.h>
-+ #include <sys/sockio.h>
-+ #include <sys/proc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/kernel.h>
-+ #include <sys/sysctl.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mount.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/systm.h>
-+ #include <sys/protosw.h>
-+ #include <sys/syslog.h>
-+ 
-+ #include <netinet/in.h>
-+ #include <netinet/tcp.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ 
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ vm_zone_t u9fsuser_zone;
-+ LIST_HEAD(u9fsuserhashhead, u9fsuser) * u9fsuidhashtbl, * u9fsunamehashtbl;
-+ u_long u9fsuidhash;
-+ u_long u9fsunamehash;
-+ MALLOC_DEFINE(M_U9FSBITS, "U9FS bits", "U9FS tag/fid maps");
-+ 
-+ static int   u9fs_hashname __P((char * name));
-+ 
-+ void u9fs_uhinit()
-+ {
-+   u9fsuser_zone = zinit("U9FSUSER", sizeof(struct u9fsuser), 0, 0, 1);
-+   u9fsuidhashtbl   = phashinit(U9FS_USER_HASHSIZE, M_U9FSHASH, &u9fsuidhash);
-+   u9fsunamehashtbl = phashinit(U9FS_USER_HASHSIZE, M_U9FSHASH, &u9fsunamehash);
-+ }
-+ 
-+ void
-+ u9fs_id_init(bits)
-+      bitstr_t ** bits;
-+ {
-+   bit_alloc(*bits, 0x10000, M_U9FSBITS, M_WAITOK);
-+   bit_nset(*bits, 1, 0xffff);  /* we dont use zero */
-+ }
-+ 
-+ u_short
-+ u9fs_id_new(bits)
-+      bitstr_t * bits;
-+ {
-+   int v;
-+ 
-+   bit_ffs(bits, 0x10000, &v);
-+   if( v < 0 )
-+     panic("no more u9fs bits!");
-+ 
-+   bit_clear(bits, v);
-+   return ((u_short)v);
-+ }
-+ 
-+ void
-+ u9fs_id_free(bits, v)
-+      bitstr_t * bits;
-+      u_short v;
-+ {
-+   bit_set(bits, v);
-+ }
-+ 
-+ 
-+ static int u9fs_hashname(char * cp)
-+ {
-+   int h = 0;
-+ 
-+   cp[U9FS_NAMELEN-1] = 0;
-+   do
-+     h += *cp;
-+   while ( *cp++ );
-+ 
-+   return h;
-+ }
-+ 
-+ void u9fs_hashuser(uid_t uid, char * name)
-+ {
-+   int h;
-+   struct u9fsuser * u9p, *u9p2;
-+   struct u9fsuserhashhead * u9hp;
-+ 
-+   if( u9fs_name2uid(name) != 65534 ) /* already hashed by previous mount */
-+     return;
-+ 
-+   u9p = zalloc(u9fsuser_zone);
-+   bzero(u9p, sizeof(*u9p));
-+   u9p->u_uid = uid;
-+   strncpy(u9p->u_name, name, U9FS_NAMELEN);
-+   u9hp = & u9fsuidhashtbl[uid % u9fsuidhash];
-+   LIST_INSERT_HEAD(u9hp, u9p, u_hash);
-+   
-+   u9p2 = zalloc(u9fsuser_zone);
-+   bcopy(u9p, u9p2, sizeof(*u9p));
-+   h = u9fs_hashname(name);
-+   u9hp = & u9fsunamehashtbl[h%u9fsunamehash];
-+   LIST_INSERT_HEAD(u9hp, u9p2, u_hash);  
-+ }
-+ 
-+ /* name must be at least U9FS_NAMELEN long! */
-+ struct u9fsuser * u9fs_finduser(uid_t uid)
-+ {
-+   struct u9fsuser * u9p;
-+   struct u9fsuserhashhead * u9hp;
-+ 
-+   u9hp = & u9fsuidhashtbl[uid % u9fsuidhash];
-+   LIST_FOREACH(u9p, u9hp, u_hash)
-+     if( u9p->u_uid == uid )
-+       break;
-+ 
-+   return u9p;
-+ }
-+ 
-+ uid_t u9fs_name2uid(char *name)
-+ {
-+   struct u9fsuser * u9p;
-+   struct u9fsuserhashhead * u9hp;
-+   int h;
-+ 
-+   h = u9fs_hashname(name);
-+   u9hp = & u9fsunamehashtbl[h%u9fsunamehash];
-+   LIST_FOREACH(u9p, u9hp, u_hash)
-+     if( strcmp(u9p->u_name, name) == 0 )
-+       break;
-+ 
-+   if( u9p )
-+     return u9p->u_uid;
-+   else
-+     return 65534; /* nobody */
-+ }
-+ 
-+ /*
-+  * copies a uio scatter/gather list to an mbuf chain.
-+  */
-+ int
-+ u9fs_uiotombuf(uiop, mq, siz)
-+ 	register struct uio *uiop;
-+ 	struct mbuf **mq;
-+ 	int siz;
-+ {
-+   register struct mbuf *m;
-+   struct mbuf * top, **mp;
-+   int mlen, len, error = 0;
-+ 
-+   mp = & top;
-+   while(siz) {
-+     MGET(m, M_WAIT, MT_DATA);
-+     mlen = MLEN;
-+     if (siz >= MINCLSIZE) {
-+       MCLGET(m, M_WAIT);
-+       if ((m->m_flags & M_EXT))
-+ 	mlen = MCLBYTES;
-+     }
-+     len = min(mlen, siz);
-+     error = uiomove(mtod(m, caddr_t), (int)len, uiop);
-+     siz -= len;
-+     m->m_len = len;
-+     *mp = m;
-+     if (error)
-+       goto release;
-+     mp = &m->m_next;
-+   }
-+   *mq = top;
-+   return 0;
-+ 
-+  release:
-+   if( top )
-+     m_freem(top);
-+ 
-+   return error;
-+ }
-+ 
-+ /*
-+  * copies mbuf chain to the uio scatter/gather list
-+  */
-+ int
-+ u9fs_mbuftouio(m, uiop, siz)
-+      struct mbuf *m;
-+      register struct uio *uiop;
-+      int siz;
-+ {
-+   register char *mbufcp, *uiocp;
-+   register int xfer, left, len;
-+   long uiosiz;
-+ 
-+   mbufcp = mtod(m, char *);
-+   len = m->m_len;
-+   while (siz > 0) {
-+     if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
-+       return (EFBIG);
-+     left = uiop->uio_iov->iov_len;
-+     uiocp = uiop->uio_iov->iov_base;
-+     if (left > siz)
-+       left = siz;
-+     uiosiz = left;
-+     while (left > 0) {
-+       while (len == 0) {
-+ 	m = m->m_next;
-+ 	if (m == NULL)
-+ 	  return (EBADRPC);
-+ 	mbufcp = mtod(m, caddr_t);
-+ 	len = m->m_len;
-+       }
-+       xfer = (left > len) ? len : left;
-+       if (uiop->uio_segflg == UIO_SYSSPACE)
-+ 	bcopy(mbufcp, uiocp, xfer);
-+       else
-+ 	copyout(mbufcp, uiocp, xfer);
-+       left -= xfer;
-+       len -= xfer;
-+       mbufcp += xfer;
-+       uiocp += xfer;
-+       uiop->uio_offset += xfer;
-+       uiop->uio_resid -= xfer;
-+     }
-+     if (uiop->uio_iov->iov_len <= siz) {
-+       uiop->uio_iovcnt--;
-+       uiop->uio_iov++;
-+     } else {
-+       uiop->uio_iov->iov_base += uiosiz;
-+       uiop->uio_iov->iov_len -= uiosiz;
-+     }
-+     siz -= uiosiz;
-+   }
-+   return (0);
-+ }
-+ 
-diff -N -c -r /usr/src/sys/9fs/9fs_vfsops.c ./9fs/9fs_vfsops.c
-*** /usr/src/sys/9fs/9fs_vfsops.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_vfsops.c	Mon May 22 16:33:47 2000
-***************
-*** 0 ****
---- 1,639 ----
-+ /*
-+  * Copyright (c) 1989, 1993, 1995
-+  *	The Regents of the University of California.  All rights reserved.
-+  *
-+  * This code is derived from software contributed to Berkeley by
-+  * Rick Macklem at The University of Guelph.
-+  *
-+  * Redistribution and use in source and binary forms, with or without
-+  * modification, are permitted provided that the following conditions
-+  * are met:
-+  * 1. Redistributions of source code must retain the above copyright
-+  *    notice, this list of conditions and the following disclaimer.
-+  * 2. Redistributions in binary form must reproduce the above copyright
-+  *    notice, this list of conditions and the following disclaimer in the
-+  *    documentation and/or other materials provided with the distribution.
-+  * 3. All advertising materials mentioning features or use of this software
-+  *    must display the following acknowledgement:
-+  *	This product includes software developed by the University of
-+  *	California, Berkeley and its contributors.
-+  * 4. Neither the name of the University nor the names of its contributors
-+  *    may be used to endorse or promote products derived from this software
-+  *    without specific prior written permission.
-+  *
-+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+  * SUCH DAMAGE.
-+  *
-+  *	@(#)u9fs_vfsops.c	8.12 (Berkeley) 5/20/95
-+  * $Id: u9fs_vfsops.c,v 1.79 1998/12/04 22:54:54 archie Exp $
-+  */
-+ 
-+ #include <sys/param.h>
-+ #include <sys/sockio.h>
-+ #include <sys/proc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/kernel.h>
-+ #include <sys/sysctl.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mount.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/systm.h>
-+ #include <sys/protosw.h>
-+ #include <sys/syslog.h>
-+ 
-+ #include <netinet/in.h>
-+ #include <netinet/tcp.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ 
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ vm_zone_t u9fsmount_zone;
-+ 
-+ static int	u9fs_mount __P(( struct mount *mp, char *path, caddr_t data,
-+ 			struct nameidata *ndp, struct proc *p));
-+ static int	u9fs_start __P(( struct mount *mp, int flags,
-+ 			struct proc *p));
-+ static int	u9fs_unmount __P(( struct mount *mp, int mntflags,
-+ 			struct proc *p));
-+ static int	u9fs_root __P(( struct mount *mp, struct vnode **vpp));
-+ static int	u9fs_quotactl __P(( struct mount *mp, int cmds, uid_t uid,
-+ 			caddr_t arg, struct proc *p));
-+ static int	u9fs_statfs __P(( struct mount *mp, struct statfs *sbp,
-+ 			struct proc *p));
-+ static int	u9fs_sync __P(( struct mount *mp, int waitfor,
-+ 			struct ucred *cred, struct proc *p));
-+ static int	u9fs_vptofh __P(( struct vnode *vp, struct fid *fhp));
-+ static int	u9fs_fhtovp __P((struct mount *mp, struct fid *fhp,
-+ 			struct sockaddr *nam, struct vnode **vpp,
-+ 			int *exflagsp, struct ucred **credanonp));
-+ static int	u9fs_vget __P((struct mount *, ino_t, struct vnode **));
-+ static int      u9fs_init __P((struct vfsconf *vfsp));
-+ int             u9fs_uninit __P((struct vfsconf *vfsp));
-+ 
-+ /* */
-+ static int	mountu9fs __P((struct u9fs_args *,struct mount *,
-+ 			struct sockaddr *,char *,char *,struct vnode **, struct proc *p));
-+ static int	u9fs_iosize __P((struct u9fsmount *nmp));
-+ static void	u9fs_decode_args __P((struct u9fsmount *nmp, struct u9fs_args *argp, struct proc *p));
-+ 
-+ /*
-+  * u9fs vfs operations.
-+  */
-+ static struct vfsops u9fs_vfsops = {
-+ 	u9fs_mount,
-+ 	u9fs_start,
-+ 	u9fs_unmount,
-+ 	u9fs_root,
-+ 	u9fs_quotactl,
-+ 	u9fs_statfs,
-+ 	u9fs_sync,
-+ 	u9fs_vget,
-+ 	u9fs_fhtovp,
-+ 	u9fs_vptofh,
-+ 	u9fs_init,
-+ 	u9fs_uninit,
-+ 	0
-+ };
-+ VFS_SET(u9fs_vfsops, u9fs, VFCF_NETWORK);
-+ 
-+ /*
-+  * u9fs statfs call
-+  */
-+ static int
-+ u9fs_statfs(mp, sbp, p)
-+ 	struct mount *mp;
-+ 	register struct statfs *sbp;
-+ 	struct proc *p;
-+ {
-+   /* we have a worm with infinite storage,
-+      stat not supported by 9fs */
-+   return 0;
-+ }
-+ 
-+ /*
-+  * Common code for mount and mountroot
-+  */
-+ static int
-+ mountu9fs(argp, mp, nam, pth, hst, vpp, p)
-+ 	register struct u9fs_args *argp;
-+ 	register struct mount *mp;
-+ 	struct sockaddr *nam;
-+ 	char *pth, *hst;
-+ 	struct vnode **vpp;
-+ 	struct proc *p;
-+ {
-+   register struct u9fsmount *nmp;
-+   struct u9fsnode *np;
-+   int error;
-+   struct vattr attrs;
-+   struct u9fsreq req, rep;
-+   char * mntpoint;
-+   struct u9fsuser * u9p;
-+   struct socket * so;
-+ 
-+   if (mp->mnt_flag & MNT_UPDATE) {
-+ #if 0
-+     nmp = VFSTONFS(mp);
-+ <    /* update paths, file handles, etc, here	XXX */
-+     FREE(nam, M_SONAME);
-+ #endif
-+     return (0);
-+   } else {
-+     nmp = zalloc(u9fsmount_zone);
-+     bzero((caddr_t)nmp, sizeof (struct u9fsmount));
-+ #if 0
-+     TAILQ_INIT(&nmp->nm_uidlruhead);
-+     TAILQ_INIT(&nmp->nm_bufq);
-+ #endif
-+     mp->mnt_data = (qaddr_t)nmp;
-+   }
-+   vfs_getnewfsid(mp);
-+   nmp->nm_mountp = mp;
-+ 
-+   nmp->nm_maxfilesize = (u_int64_t)0xffffffffffffffffLL;
-+ 
-+   nmp->nm_wsize = U9FS_MAXFDATA;
-+   nmp->nm_rsize = U9FS_MAXFDATA;
-+   nmp->nm_readdirsize = U9FS_MAXDDATA;
-+   bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
-+   bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);
-+   nmp->nm_nam = nam;
-+ 
-+   mntpoint = index(hst, '/');
-+   if( mntpoint )
-+     mntpoint++;
-+ 
-+   /* Set up the sockets and per-host congestion */
-+   nmp->nm_sotype = argp->sotype;
-+   nmp->nm_soproto = argp->proto;
-+ 
-+   u9fs_decode_args(nmp, argp, p);
-+ 
-+   lockinit(& nmp->nm_lock, PVFS, "u9fsmount", 0, 0);
-+   u9fs_id_init(&nmp->nm_tags);
-+   u9fs_id_init(&nmp->nm_fids);
-+   TAILQ_INIT(&nmp->nm_reqq);
-+ 
-+   if ((error = u9fs_connect_9fs(nmp)))
-+     goto bad;
-+   
-+   /* "Tnop 1", "Tsession 1 0", "Tattach 1 1 none main 0 0", */
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = p;
-+ 
-+   req.r_type = Tnop;
-+   error = u9fs_request(& req, & rep, 1);
-+   if( error )
-+     return error;
-+ 
-+   req.r_type = Tsession;
-+   /* bzero(req.r_chal, sizeof(req.r_chal)); */
-+   u9auth_genchal(req.r_chal);
-+   error = u9fs_request(& req, & rep, 1);
-+   if( error )
-+     return error;
-+ 
-+   if( argp->authaddr ) {
-+     /* get tickets from the auth server */
-+     error = u9fs_connect_9auth(nmp, argp, & so);
-+     if( error )
-+       goto bad;
-+     u9p = u9fs_finduser(u9fs_name2uid(argp->user));
-+     error = u9auth_gettickets(so, & rep, argp->user, u9p->u_ckey, 
-+ 			      req.r_ticket, req.r_auth, p);
-+     u9fs_disconnect(so);
-+     if( error )
-+       goto bad;
-+   }
-+ 
-+   req.r_type = Tattach;
-+   req.r_fid = u9fs_id_new(nmp->nm_fids);
-+   strcpy(req.r_uname, argp->user);
-+   strcpy(req.r_aname, mntpoint);
-+   error = u9fs_request(& req, & rep, 1);
-+   if( error )
-+     return error;
-+   nmp->nm_fh = rep.r_qid.path;
-+   nmp->nm_fid = req.r_fid;
-+   /* XXX: we should have checked our challenge to the server! */
-+ 
-+   /*
-+    * This is silly, but it has to be set so that vinifod() works.
-+    * We do not want to do an u9fs_statfs() here since we can get
-+    * stuck on a dead server and we are holding a lock on the mount
-+    * point.
-+    */
-+   mp->mnt_stat.f_iosize = u9fs_iosize(nmp);
-+ 
-+   /*
-+    * A reference count is needed on the u9fsnode representing the
-+    * remote root.  If this object is not persistent, then backward
-+    * traversals of the mount point (i.e. "..") will not work if
-+    * the u9fsnode gets flushed out of the cache. Ufs does not have
-+    * this problem, because one can identify root inodes by their
-+    * number == ROOTINO (2).
-+    */
-+   error = u9fs_nget(mp, nmp->nm_fh, &np, p);
-+   np->n_fid = nmp->nm_fid;
-+ 
-+   nmp->nm_authuid = p->p_ucred->cr_uid;
-+ 
-+   if (error)
-+     goto bad;
-+   *vpp = U9FSTOV(np);
-+   
-+   /*
-+    * Get file attributes for the mountpoint.  This has the side
-+    * effect of filling in (*vpp)->v_type with the correct value.
-+    */
-+   VOP_GETATTR(*vpp, &attrs, p->p_ucred, p);
-+   
-+   /*
-+    * Lose the lock but keep the ref.
-+    */
-+   VOP_UNLOCK(*vpp, 0, p);
-+ 
-+   return (0);
-+ bad:
-+   u9fs_disconnect(nmp->nm_so);
-+   zfree(u9fsmount_zone, nmp);
-+   FREE(nam, M_SONAME);
-+   return (error);
-+ }
-+ 
-+ /*
-+  * VFS Operations.
-+  *
-+  * mount system call
-+  * It seems a bit dumb to copyinstr() the host and path here and then
-+  * bcopy() them in mountu9fs(), but I wanted to detect errors before
-+  * doing the sockargs() call because sockargs() allocates an mbuf and
-+  * an error after that means that I have to release the mbuf.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_mount(mp, path, data, ndp, p)
-+ 	struct mount *mp;
-+ 	char *path;
-+ 	caddr_t data;
-+ 	struct nameidata *ndp;
-+ 	struct proc *p;
-+ {
-+   int error;
-+   struct u9fs_args args;
-+   struct sockaddr *nam;
-+   struct vnode *vp;
-+   char pth[MNAMELEN], hst[MNAMELEN];
-+   size_t len;
-+ 
-+   if( path == NULL )
-+     return (EOPNOTSUPP);
-+ 
-+   error = copyin(data, (caddr_t)&args, sizeof (struct u9fs_args));
-+   if (error)
-+     return (error);
-+ 
-+   if (args.version != U9FS_ARGSVERSION)
-+     return (EPROGMISMATCH);
-+ 
-+   if (mp->mnt_flag & MNT_UPDATE) {
-+ #if 0
-+     register struct u9fsmount *nmp = VFSTONFS(mp);
-+     
-+     if (nmp == NULL)
-+       return (EIO);
-+     /*
-+      * When doing an update, we can't change from or to
-+      * v3 and/or nqu9fs, or change cookie translation
-+      */
-+     args.flags = (args.flags &
-+ 		  ~(NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/)) |
-+       (nmp->nm_flag &
-+        (NFSMNT_NFSV3|NFSMNT_NQNFS /*|NFSMNT_XLATECOOKIE*/));
-+     u9fs_decode_args(nmp, &args, p);
-+ #endif
-+     return (0);
-+   }
-+ 
-+   error = copyinstr(path, pth, MNAMELEN-1, &len);
-+   if (error)
-+     return (error);
-+   bzero(&pth[len], MNAMELEN - len);
-+   error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
-+   if (error)
-+     return (error);
-+   bzero(&hst[len], MNAMELEN - len);
-+   /* sockargs() call must be after above copyin() calls */
-+   error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen);
-+   if (error)
-+     return (error);
-+   error = mountu9fs(&args, mp, nam, pth, hst, &vp, p);
-+   return (error);  
-+ }
-+ 
-+ /*
-+  * unmount system call
-+  */
-+ static int
-+ u9fs_unmount(mp, mntflags, p)
-+      struct mount *mp;
-+      int mntflags;
-+      struct proc *p;
-+ {
-+   register struct u9fsmount *nmp;
-+   struct u9fsnode *np;
-+   struct vnode *vp;
-+   int error, flags = 0;
-+   
-+   if (mntflags & MNT_FORCE)
-+     flags |= FORCECLOSE;
-+   nmp = VFSTOU9FS(mp);
-+ 
-+   if( p->p_ucred->cr_uid != nmp->nm_authuid )
-+     return (EPERM);
-+ 
-+   /*
-+    * Goes something like this..
-+    * - Check for activity on the root vnode (other than ourselves).
-+    * - Call vflush() to clear out vnodes for this file system,
-+    *   except for the root vnode.
-+    * - Decrement reference on the vnode representing remote root.
-+    * - Close the socket
-+    * - Free up the data structures
-+    */
-+   /*
-+    * We need to decrement the ref. count on the u9fsnode representing
-+    * the remote root.  See comment in mountu9fs().  The VFS unmount()
-+    * has done vput on this vnode, otherwise we would get deadlock!
-+    */
-+   error = u9fs_nget(mp, nmp->nm_fh, &np, p);
-+   if (error)
-+     return(error);
-+   vp = U9FSTOV(np);
-+   if (vp->v_usecount > 2) {
-+     vput(vp);
-+     return (EBUSY);
-+   }
-+ 
-+   error = vflush(mp, vp, flags);
-+   if (error) {
-+     vput(vp);
-+     return (error);
-+   }
-+ 
-+   /*
-+    * We are now committed to the unmount.
-+    */
-+   /*
-+    * There are two reference counts and one lock to get rid of here.
-+    */
-+   vput(vp);
-+   vrele(vp);
-+   vgone(vp);
-+   u9fs_disconnect(nmp->nm_so);
-+   FREE(nmp->nm_nam, M_SONAME);
-+ 
-+   zfree(u9fsmount_zone, nmp);
-+   return (0);
-+ }
-+ 
-+ /*
-+  * Return root of a filesystem
-+  */
-+ static int
-+ u9fs_root(mp, vpp)
-+ 	struct mount *mp;
-+ 	struct vnode **vpp;
-+ {
-+         register struct vnode *vp;
-+         struct u9fsmount *nmp;
-+         struct u9fsnode *np;
-+         int error;
-+ 
-+         nmp = VFSTOU9FS(mp);
-+         error = u9fs_nget(mp, nmp->nm_fh, &np, curproc); /* XXX */
-+         if (error)
-+                 return (error);
-+         vp = U9FSTOV(np);
-+         if (vp->v_type == VNON)
-+             vp->v_type = VDIR;
-+         vp->v_flag = VROOT;
-+         *vpp = vp;
-+         return (0);
-+ }
-+ 
-+ extern int syncprt;
-+ 
-+ /*
-+  * Flush out the buffer cache
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_sync(mp, waitfor, cred, p)
-+ 	struct mount *mp;
-+ 	int waitfor;
-+ 	struct ucred *cred;
-+ 	struct proc *p;
-+ {
-+   /* no cache yet */
-+   return 0;
-+ }
-+ 
-+ /*
-+  * U9FS flat namespace lookup.
-+  * Currently unsupported.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_vget(mp, ino, vpp)
-+ 	struct mount *mp;
-+ 	ino_t ino;
-+ 	struct vnode **vpp;
-+ {
-+ 
-+ 	return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * At this point, this should never happen
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
-+ 	register struct mount *mp;
-+ 	struct fid *fhp;
-+ 	struct sockaddr *nam;
-+ 	struct vnode **vpp;
-+ 	int *exflagsp;
-+ 	struct ucred **credanonp;
-+ {
-+ 
-+ 	return (EINVAL);
-+ }
-+ 
-+ /*
-+  * Vnode pointer to File handle, should never happen either
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_vptofh(vp, fhp)
-+ 	struct vnode *vp;
-+ 	struct fid *fhp;
-+ {
-+ 
-+ 	return (EINVAL);
-+ }
-+ 
-+ /*
-+  * Vfs start routine, a no-op.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_start(mp, flags, p)
-+ 	struct mount *mp;
-+ 	int flags;
-+ 	struct proc *p;
-+ {
-+ 
-+ 	return (0);
-+ }
-+ 
-+ /*
-+  * Do operations associated with quotas, not supported
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_quotactl(mp, cmd, uid, arg, p)
-+ 	struct mount *mp;
-+ 	int cmd;
-+ 	uid_t uid;
-+ 	caddr_t arg;
-+ 	struct proc *p;
-+ {
-+ 
-+ 	return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * Called once to initialize data structures...
-+  */
-+ int
-+ u9fs_init(vfsp)
-+ 	struct vfsconf *vfsp;
-+ {
-+   u9fsmount_zone = zinit("U9FSMOUNT", sizeof(struct u9fsmount), 0, 0, 1);
-+   u9fs_nhinit();			/* Init the u9fsnode table */
-+   u9fs_uhinit();
-+   return 0;
-+ }
-+ 
-+ int
-+ u9fs_uninit(vfsp)
-+ 	struct vfsconf *vfsp;
-+ {
-+   return 0;
-+ }
-+ 
-+ static int
-+ u9fs_iosize(nmp)
-+      struct u9fsmount* nmp;
-+ {
-+   int iosize;
-+   
-+   /*
-+    * Calculate the size used for io buffers.  Use the larger
-+    * of the two sizes to minimise u9fs requests but make sure
-+    * that it is at least one VM page to avoid wasting buffer
-+    * space.
-+    */
-+   iosize = max(nmp->nm_rsize, nmp->nm_wsize);
-+   if (iosize < PAGE_SIZE) iosize = PAGE_SIZE;
-+   return iosize;
-+ }
-+ 
-+ static void
-+ u9fs_decode_args(nmp, argp, p)
-+      struct u9fsmount *nmp;
-+      struct u9fs_args *argp;
-+      struct proc * p;
-+ {
-+   int s, i;
-+   int maxio;
-+   struct p9user * p9p, p9u;
-+   struct u9fsuser * u9p;
-+   
-+   s = splnet();
-+   /* Update flags atomically.  Don't change the lock bits. */
-+   nmp->nm_flag = argp->flags | nmp->nm_flag;
-+   splx(s);
-+ 
-+   maxio = U9FS_MAXFDATA;
-+ 
-+   if (argp->wsize > 0) {
-+     nmp->nm_wsize = argp->wsize;
-+     /* Round down to multiple of blocksize */
-+     nmp->nm_wsize &= ~(U9FS_FABLKSIZE - 1);
-+     if (nmp->nm_wsize <= 0)
-+       nmp->nm_wsize = U9FS_FABLKSIZE;
-+   }
-+   if (nmp->nm_wsize > maxio)
-+     nmp->nm_wsize = maxio;
-+   if (nmp->nm_wsize > MAXBSIZE)
-+     nmp->nm_wsize = MAXBSIZE;
-+ 
-+   if (argp->rsize > 0) {
-+     nmp->nm_rsize = argp->rsize;
-+     /* Round down to multiple of blocksize */
-+     nmp->nm_rsize &= ~(U9FS_FABLKSIZE - 1);
-+     if (nmp->nm_rsize <= 0)
-+       nmp->nm_rsize = U9FS_FABLKSIZE;
-+   }
-+   if (nmp->nm_rsize > maxio)
-+     nmp->nm_rsize = maxio;
-+   if (nmp->nm_rsize > MAXBSIZE)
-+     nmp->nm_rsize = MAXBSIZE;
-+ 
-+   if (argp->readdirsize > 0) {
-+     nmp->nm_readdirsize = argp->readdirsize;
-+   }
-+   if (nmp->nm_readdirsize > maxio)
-+     nmp->nm_readdirsize = maxio;
-+   if (nmp->nm_readdirsize > nmp->nm_rsize)
-+     nmp->nm_readdirsize = nmp->nm_rsize;
-+ 
-+   if( argp->nusers ) {
-+     p9p = argp->users;
-+     for(i = 0; i < argp->nusers; i++) {
-+       copyin(p9p, &p9u, sizeof(p9u));
-+       u9fs_hashuser(p9u.p9_uid, p9u.p9_name);
-+       p9p ++;
-+     }
-+     printf("%d p9users loaded\n", argp->nusers);
-+   }
-+ 
-+   if( (u9p = u9fs_finduser(u9fs_name2uid(argp->user))) ) {
-+     bcopy(argp->key, u9p->u_ckey, U9AUTH_DESKEYLEN);
-+   }
-+ }
-diff -N -c -r /usr/src/sys/9fs/9fs_vnops.c ./9fs/9fs_vnops.c
-*** /usr/src/sys/9fs/9fs_vnops.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9fs_vnops.c	Mon May 22 11:40:00 2000
-***************
-*** 0 ****
---- 1,1794 ----
-+ /*
-+  * Copyright (c) 1989, 1993
-+  *	The Regents of the University of California.  All rights reserved.
-+  *
-+  * This code is derived from software contributed to Berkeley by
-+  * Rick Macklem at The University of Guelph.
-+  *
-+  * Redistribution and use in source and binary forms, with or without
-+  * modification, are permitted provided that the following conditions
-+  * are met:
-+  * 1. Redistributions of source code must retain the above copyright
-+  *    notice, this list of conditions and the following disclaimer.
-+  * 2. Redistributions in binary form must reproduce the above copyright
-+  *    notice, this list of conditions and the following disclaimer in the
-+  *    documentation and/or other materials provided with the distribution.
-+  * 3. All advertising materials mentioning features or use of this software
-+  *    must display the following acknowledgement:
-+  *	This product includes software developed by the University of
-+  *	California, Berkeley and its contributors.
-+  * 4. Neither the name of the University nor the names of its contributors
-+  *    may be used to endorse or promote products derived from this software
-+  *    without specific prior written permission.
-+  *
-+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+  * SUCH DAMAGE.
-+  *
-+  *	@(#)u9fs_vnops.c	8.16 (Berkeley) 5/27/95
-+  * $Id: u9fs_vnops.c,v 1.116.2.3 1999/02/13 08:03:47 dillon Exp $
-+  */
-+ 
-+ 
-+ /*
-+  * vnode op calls for 9FS
-+  */
-+ 
-+ #include "opt_inet.h"
-+ 
-+ #include <sys/param.h>
-+ #include <sys/kernel.h>
-+ #include <sys/systm.h>
-+ #include <sys/resourcevar.h>
-+ #include <sys/proc.h>
-+ #include <sys/mount.h>
-+ #include <sys/buf.h>
-+ #include <sys/malloc.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/namei.h>
-+ #include <sys/socket.h>
-+ #include <sys/vnode.h>
-+ #include <sys/dirent.h>
-+ #include <sys/fcntl.h>
-+ #include <sys/lockf.h>
-+ #include <sys/stat.h>
-+ #include <sys/sysctl.h>
-+ 
-+ #include <vm/vm.h>
-+ #include <vm/vm_extern.h>
-+ #include <vm/vm_zone.h>
-+ #include <vm/vm_prot.h>
-+ #include <vm/vm_page.h>
-+ #include <vm/vm_object.h>
-+ #include <vm/vm_pager.h>
-+ #include <vm/vnode_pager.h>
-+ 
-+ #include <net/if.h>
-+ #include <netinet/in.h>
-+ #include <netinet/in_var.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ #define u9fs_poll vop_nopoll
-+ static	int	u9fs_lookup __P((struct vop_lookup_args *));
-+ static	int	u9fs_create __P((struct vop_create_args *));
-+ static	int	u9fs_mknod __P((struct vop_mknod_args *));
-+ static	int	u9fs_open __P((struct vop_open_args *));
-+ static	int	u9fs_close __P((struct vop_close_args *));
-+ static	int	u9fs_access __P((struct vop_access_args *));
-+ static	int	u9fs_getattr __P((struct vop_getattr_args *));
-+ static	int	u9fs_setattr __P((struct vop_setattr_args *));
-+ static	int	u9fs_read __P((struct vop_read_args *));
-+ static	int	u9fs_mmap __P((struct vop_mmap_args *));
-+ static	int	u9fs_fsync __P((struct vop_fsync_args *));
-+ static	int	u9fs_remove __P((struct vop_remove_args *));
-+ static	int	u9fs_link __P((struct vop_link_args *));
-+ static	int	u9fs_rename __P((struct vop_rename_args *));
-+ static	int	u9fs_mkdir __P((struct vop_mkdir_args *));
-+ static	int	u9fs_rmdir __P((struct vop_rmdir_args *));
-+ static	int	u9fs_symlink __P((struct vop_symlink_args *));
-+ static	int	u9fs_readdir __P((struct vop_readdir_args *));
-+ static	int	u9fs_bmap __P((struct vop_bmap_args *));
-+ static	int	u9fs_strategy __P((struct vop_strategy_args *));
-+ static int	u9fs_readlink __P((struct vop_readlink_args *));
-+ static int	u9fs_print __P((struct vop_print_args *));
-+ static int	u9fs_advlock __P((struct vop_advlock_args *));
-+ static int	u9fs_bwrite __P((struct vop_bwrite_args *));
-+ static int   u9fs_abortop __P((struct vop_abortop_args *));
-+ static int   u9fs_getpages __P((struct vop_getpages_args *));
-+ static int   u9fs_putpages __P((struct vop_putpages_args *));
-+ static int   u9fs_inactive __P((struct vop_inactive_args *));
-+ static int   u9fs_reclaim __P((struct vop_reclaim_args *));
-+ static int   u9fs_write __P((struct vop_write_args *));
-+ 
-+ /*
-+  * Global vfs data structures for u9fs
-+  */
-+ vop_t **u9fs_vnodeop_p;
-+ static struct vnodeopv_entry_desc u9fs_vnodeop_entries[] = {
-+ 	{ &vop_default_desc,		(vop_t *) vop_defaultop },
-+ 	{ &vop_abortop_desc,		(vop_t *) u9fs_abortop },
-+ 	{ &vop_access_desc,		(vop_t *) u9fs_access },
-+ 	{ &vop_advlock_desc,		(vop_t *) u9fs_advlock },
-+ 	{ &vop_bmap_desc,		(vop_t *) u9fs_bmap },
-+ 	{ &vop_bwrite_desc,		(vop_t *) u9fs_bwrite },
-+ 	{ &vop_close_desc,		(vop_t *) u9fs_close },
-+ 	{ &vop_create_desc,		(vop_t *) u9fs_create },
-+ 	{ &vop_fsync_desc,		(vop_t *) u9fs_fsync },
-+ 	{ &vop_getattr_desc,		(vop_t *) u9fs_getattr },
-+ 	{ &vop_getpages_desc,		(vop_t *) u9fs_getpages },
-+ 	{ &vop_putpages_desc,		(vop_t *) u9fs_putpages },
-+ 	{ &vop_inactive_desc,		(vop_t *) u9fs_inactive },
-+ 	{ &vop_lease_desc,		(vop_t *) vop_null },
-+ 	{ &vop_link_desc,		(vop_t *) u9fs_link },
-+ 	{ &vop_lock_desc,		(vop_t *) vop_sharedlock },
-+ 	{ &vop_lookup_desc,		(vop_t *) u9fs_lookup },
-+ 	{ &vop_mkdir_desc,		(vop_t *) u9fs_mkdir },
-+ 	{ &vop_mknod_desc,		(vop_t *) u9fs_mknod },
-+ 	{ &vop_mmap_desc,		(vop_t *) u9fs_mmap },
-+ 	{ &vop_open_desc,		(vop_t *) u9fs_open },
-+ 	{ &vop_poll_desc,		(vop_t *) vop_nopoll },
-+ 	{ &vop_print_desc,		(vop_t *) u9fs_print },
-+ 	{ &vop_read_desc,		(vop_t *) u9fs_read },
-+ 	{ &vop_readdir_desc,		(vop_t *) u9fs_readdir },
-+ 	{ &vop_readlink_desc,		(vop_t *) u9fs_readlink },
-+ 	{ &vop_reclaim_desc,		(vop_t *) u9fs_reclaim },
-+ 	{ &vop_remove_desc,		(vop_t *) u9fs_remove },
-+ 	{ &vop_rename_desc,		(vop_t *) u9fs_rename },
-+ 	{ &vop_rmdir_desc,		(vop_t *) u9fs_rmdir },
-+ 	{ &vop_setattr_desc,		(vop_t *) u9fs_setattr },
-+ 	{ &vop_strategy_desc,		(vop_t *) u9fs_strategy },
-+ 	{ &vop_symlink_desc,		(vop_t *) u9fs_symlink },
-+ 	{ &vop_write_desc,		(vop_t *) u9fs_write },
-+ 	{ NULL, NULL }
-+ };
-+ static struct vnodeopv_desc u9fs_vnodeop_opv_desc =
-+ 	{ &u9fs_vnodeop_p, u9fs_vnodeop_entries };
-+ VNODEOP_SET(u9fs_vnodeop_opv_desc);
-+ 
-+ extern vm_zone_t u9fsnode_zone;
-+ 
-+ static int u9fs_trunc(struct vnode * vp, struct ucred * cred, struct proc * p);
-+ static void u9fs_free_fid __P((u_short fid, struct u9fsmount * nmp, struct proc * p));
-+ static void u9fs_updtcache __P((struct u9fsnode *, struct u9fsreq *));
-+ 
-+ #define     DIRHDSIZ        (sizeof (struct dirent) - (MAXNAMLEN + 1))
-+ 
-+ /* open returns a qid for cache consistent check */
-+ static void
-+ u9fs_updtcache(struct u9fsnode * np, struct u9fsreq * rep)
-+ {
-+   if( rep->r_type != Rerror )
-+     np->n_dir.dir_qid = rep->r_qid;
-+ }
-+ 
-+ static int
-+ u9fs_trunc(vp, cred, p)
-+      register struct vnode * vp;
-+      struct ucred * cred;
-+      struct proc * p;
-+ {
-+   struct u9fsnode *np = VTOU9FS(vp);
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   int error;
-+   u_short newfid;
-+   struct u9fsreq req, rep;
-+   u_char mode;
-+ 
-+   /*
-+    * Disallow write attempts on filesystems mounted read-only;
-+    * unless the file is a socket, fifo, or a block or character
-+    * device resident on the filesystem.
-+    */
-+   if ( (vp->v_mount->mnt_flag & MNT_RDONLY)) {
-+     switch (vp->v_type) {
-+     case VREG:
-+     case VDIR:
-+     case VLNK:
-+       return (EROFS);
-+     default:
-+       break;
-+     }
-+   }
-+   mode = U9P_MODE_WR | U9P_MODE_TRUNC;
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = p;
-+   newfid = u9fs_id_new(nmp->nm_fids);
-+   req.r_type = Tclone;
-+   req.r_fid  = np->n_fid;
-+   req.r_newfid = newfid;
-+   error = u9fs_request(&req, &rep, 1);
-+   if( error )
-+     return error;
-+   req.r_type = Topen;
-+   req.r_fid = newfid;
-+   req.r_mode = mode;
-+   error = u9fs_request(&req, &rep, 1);
-+   if( !error )
-+     u9fs_vinvalbuf(vp, 0, cred, p, 0);
-+   if( error || np->n_wrfid ) {
-+     u9fs_free_fid(newfid, nmp, p);
-+     return error;
-+   }
-+ 
-+   if( !U9P_PERM_EXCL(np->n_dir.dir_mode))
-+     np->n_wrfid = newfid;
-+   else
-+     u9fs_free_fid(newfid, nmp, p);
-+ 
-+   return (0);  
-+ }
-+ 
-+ /*
-+  * u9fs access vnode op.
-+  */
-+ static int
-+ u9fs_access(ap)
-+ 	struct vop_access_args /* {
-+ 		struct vnode *a_vp;
-+ 		int  a_mode;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   struct u9fsnode *np = VTOU9FS(vp);
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   struct proc * p = ap->a_p;
-+   int error, a_mode = ap->a_mode;
-+   u_short * fidp = 0, *fidp2 = 0, newfid;
-+   struct u9fsreq req, rep;
-+   u_char mode;
-+   struct ucred * cred = ap->a_cred;
-+ 
-+   /* XXX: for the moment, only the authenticator has access */
-+   if( cred->cr_uid != nmp->nm_authuid )
-+     return (EPERM);
-+ 
-+   /*
-+    * Disallow write attempts on filesystems mounted read-only;
-+    * unless the file is a socket, fifo, or a block or character
-+    * device resident on the filesystem.
-+    */
-+   if ((a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
-+     switch (vp->v_type) {
-+     case VREG:
-+     case VDIR:
-+     case VLNK:
-+       return (EROFS);
-+     default:
-+       break;
-+     }
-+   }
-+ 
-+   /* we cant open an exclusive open file here */
-+   if( U9P_PERM_EXCL(np->n_dir.dir_mode) )
-+     return 0;
-+ 
-+   /* check permission by actually opening it */
-+   /* translate mode */
-+   mode = 0;
-+   if( a_mode & VREAD ) {
-+     fidp = &np->n_rdfid;
-+     mode = U9P_MODE_RD;
-+   }
-+   if( a_mode & VWRITE ) {
-+     fidp = &np->n_wrfid;
-+     mode = U9P_MODE_WR;
-+   }
-+   if( (a_mode & (VREAD|VWRITE)) == (VREAD|VWRITE) ) {
-+     fidp2 = &np->n_rdfid;
-+     mode = U9P_MODE_RDWR;
-+   }
-+ 
-+   if( a_mode & VEXEC ) {
-+     fidp = &np->n_rdfid;
-+     if( vp->v_type == VREG )
-+       mode = U9P_MODE_EX;
-+   }
-+ 
-+   if( fidp2 == 0 )
-+     fidp2 = fidp;
-+ 
-+   /* open fid mode */
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = p;
-+   newfid = u9fs_id_new(nmp->nm_fids);
-+   req.r_type = Tclone;
-+   req.r_fid  = np->n_fid;
-+   req.r_newfid = newfid;
-+   error = u9fs_request(&req, &rep, 1);
-+   if( error )
-+     return error;
-+   req.r_type = Topen;
-+   req.r_fid = newfid;
-+   req.r_mode = mode;
-+   error = u9fs_request(&req, &rep, 1);
-+   u9fs_updtcache(np, &rep);
-+   if( error || (*fidp && *fidp2 ) ) {
-+     u9fs_free_fid(newfid, nmp, p);
-+     return error;
-+   }
-+ 
-+   *fidp = *fidp2 = newfid;
-+ 
-+   return (0);
-+ }
-+ 
-+ /*
-+  * u9fs open vnode op
-+  * Check to see if the type is ok
-+  * and that deletion is not in progress.
-+  * For paged in text files, you will need to flush the page cache
-+  * if consistency is lost.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_open(ap)
-+ 	struct vop_open_args /* {
-+ 		struct vnode *a_vp;
-+ 		int  a_mode;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   struct u9fsnode *np = VTOU9FS(vp);
-+   int error=0, a_mode = ap->a_mode;
-+   u_short * fidp = 0, *fidp2 = 0, newfid;
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   struct proc * p = ap->a_p;
-+   struct u9fsreq req, rep;
-+   u_char mode;
-+   struct ucred * cred = ap->a_cred;
-+ 
-+   /* assume access permissions have been checked via VOP_ACCESS */
-+   /* the file is actually opened except the rdwr case */
-+ 
-+   if( a_mode & (O_EXCL|O_SHLOCK|O_EXLOCK) ) {
-+ #if 0  /* XXX: what can we do here? */
-+     return (EOPNOTSUPP);
-+ #endif
-+   }
-+ 
-+   /* translate mode */
-+   mode = 0;
-+   if( a_mode & FREAD ) {
-+     fidp = &np->n_rdfid;
-+     mode = U9P_MODE_RD;
-+   }
-+   if( a_mode & FWRITE ) {
-+     fidp = &np->n_wrfid;
-+     mode = U9P_MODE_WR;
-+   }
-+   if( (a_mode & (FREAD|FWRITE)) == (FREAD|FWRITE) ) {
-+     fidp2 = & np->n_rdfid;
-+     mode = U9P_MODE_RDWR;
-+   }
-+   if( fidp2 == 0)
-+     fidp2 = fidp;
-+ 
-+   if( U9P_PERM_EXCL(np->n_dir.dir_mode) ) {
-+     if( *fidp || *fidp2 )
-+       return ENOLCK;
-+ 
-+     /* open fid mode */
-+     bzero(&req, sizeof(req));
-+     req.r_nmp = nmp;
-+     req.r_procp = p;
-+     newfid = u9fs_id_new(nmp->nm_fids);
-+     req.r_type = Tclone;
-+     req.r_fid  = np->n_fid;
-+     req.r_newfid = newfid;
-+     error = u9fs_request(&req, &rep, 1);
-+     if( error )
-+       return error;
-+     req.r_type = Topen;
-+     req.r_fid = newfid;
-+     req.r_mode = mode;
-+     error = u9fs_request(&req, &rep, 1);
-+     if( error ) {
-+       u9fs_free_fid(newfid, nmp, p);
-+       return error;
-+     }
-+     u9fs_updtcache(np, &rep);
-+ 
-+     *fidp = *fidp2 = newfid;
-+   }
-+ 
-+   if( *fidp == 0 )
-+     panic("open");
-+ 
-+   if( *fidp2 == 0 ) {
-+     /* open fid mode */
-+     bzero(&req, sizeof(req));
-+     req.r_nmp = nmp;
-+     req.r_procp = p;
-+     newfid = u9fs_id_new(nmp->nm_fids);
-+     req.r_type = Tclone;
-+     req.r_fid  = np->n_fid;
-+     req.r_newfid = newfid;
-+     error = u9fs_request(&req, &rep, 1);
-+     if( error )
-+       return error;
-+     req.r_type = Topen;
-+     req.r_fid = newfid;
-+     req.r_mode = mode;
-+     error = u9fs_request(&req, &rep, 1);
-+     if( error ) {
-+       u9fs_free_fid(newfid, nmp, p);
-+       return error;
-+     }
-+     u9fs_updtcache(np, &rep);
-+     *fidp2 = newfid;
-+   }
-+ 
-+   if( np->n_qid.vers != np->n_dir.dir_qid.vers ) /* content changed */
-+     u9fs_vinvalbuf(vp, 0, cred, p, 0);
-+ 
-+   return 0;
-+ }
-+ 
-+ /*
-+  * u9fs close vnode op
-+  * What an U9FS client should do upon close after writing is a debatable issue.
-+  * Most U9FS clients push delayed writes to the server upon close, basically for
-+  * two reasons:
-+  * 1 - So that any write errors may be reported back to the client process
-+  *     doing the close system call. By far the two most likely errors are
-+  *     U9FSERR_NOSPC and U9FSERR_DQUOT to indicate space allocation failure.
-+  * 2 - To put a worst case upper bound on cache inconsistency between
-+  *     multiple clients for the file.
-+  * There is also a consistency problem for Version 2 of the protocol w.r.t.
-+  * not being able to tell if other clients are writing a file concurrently,
-+  * since there is no way of knowing if the changed modify time in the reply
-+  * is only due to the write for this client.
-+  * (U9FS Version 3 provides weak cache consistency data in the reply that
-+  *  should be sufficient to detect and handle this case.)
-+  *
-+  * The current code does the following:
-+  * for U9FS Version 2 - play it safe and flush/invalidate all dirty buffers
-+  * for U9FS Version 3 - flush dirty buffers to the server but don't invalidate
-+  *                     or commit them (this satisfies 1 and 2 except for the
-+  *                     case where the server crashes after this close but
-+  *                     before the commit RPC, which is felt to be "good
-+  *                     enough". Changing the last argument to u9fs_flush() to
-+  *                     a 1 would force a commit operation, if it is felt a
-+  *                     commit is necessary now.
-+  * for NQU9FS         - do nothing now, since 2 is dealt with via leases and
-+  *                     1 should be dealt with via an fsync() system call for
-+  *                     cases where write errors are important.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_close(ap)
-+ 	struct vop_close_args /* {
-+ 		struct vnodeop_desc *a_desc;
-+ 		struct vnode *a_vp;
-+ 		int  a_fflag;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ { 
-+   int fflag = ap->a_fflag;
-+   struct vnode * vp = ap->a_vp;
-+   struct u9fsnode * np = VTOU9FS(vp);
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   struct proc * p = ap->a_p;
-+ 
-+   if( U9P_PERM_EXCL(np->n_dir.dir_mode) ) {
-+     if( (fflag & FREAD) ) {
-+       u9fs_free_fid(np->n_rdfid, nmp, p);
-+       np->n_rdfid = 0;
-+     }
-+ 
-+     if( (fflag & FWRITE) == FWRITE ) {
-+       u9fs_free_fid(np->n_wrfid, nmp, p);
-+       np->n_wrfid = 0;
-+     }
-+     
-+     if( (fflag & (FREAD|FWRITE)) == (FREAD|FWRITE) )
-+       np->n_wrfid = 0;
-+   }
-+ 
-+   return 0;
-+ }
-+ 
-+ /*
-+  * u9fs getattr call from vfs.
-+  */
-+ static int
-+ u9fs_getattr(ap)
-+ 	struct vop_getattr_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct vattr *a_vap;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   register struct u9fsnode *np = VTOU9FS(vp);
-+   int error = 0;
-+   struct u9fsreq req, rep;
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   struct u9fsdir * dir;
-+   struct vattr * vap = ap->a_vap;
-+   
-+   /*
-+    * Update local times for special files.
-+    */
-+   if (np->n_flag & (NACC | NUPD))
-+     np->n_flag |= NCHG;
-+ #if 0
-+   /*
-+    * First look in the cache.
-+    */
-+   if (u9fs_getattrcache(vp, ap->a_vap) == 0)
-+     return (0);
-+ #endif
-+   if( np->n_fid == 0 )
-+     panic("u9fs_getattr");
-+ 
-+   /* stat fid */
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = ap->a_p;
-+   req.r_type = Tstat;
-+   req.r_fid = np->n_fid;
-+   error = u9fs_request(& req, & rep, 1);
-+   if( error )
-+     return error;
-+ 
-+   /* fill in vattr */
-+   dir = & np->n_dir;
-+   u9p_m2d(rep.r_stat, dir);
-+ 
-+   bzero(vap, sizeof(*vap));
-+   /* the plan9 file system has no other types. */
-+   /* XXX: we have not delt with devices yet */
-+   if( U9P_PERM_CHDIR(dir->dir_mode) )
-+     vap->va_type = VDIR;
-+   else
-+     vap->va_type = VREG;
-+ 
-+   vap->va_mode  = U9P_PERM_ALL(dir->dir_mode);
-+   vap->va_nlink = 1;
-+   vap->va_uid = u9fs_name2uid(dir->dir_uid);
-+   vap->va_gid = u9fs_name2uid(dir->dir_gid);
-+   vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
-+   vap->va_fileid = dir->dir_qid.path;
-+   vap->va_size = np->n_size = dir->dir_length;
-+   vap->va_blocksize = PAGE_SIZE;
-+   vap->va_atime.tv_sec = dir->dir_atime;
-+   vap->va_atime.tv_nsec = 0;
-+   vap->va_mtime.tv_sec = dir->dir_mtime;
-+   vap->va_mtime.tv_nsec = 0;
-+   vap->va_ctime.tv_sec = dir->dir_mtime;
-+   vap->va_ctime.tv_nsec = dir->dir_mtime;
-+   vap->va_gen = VNOVAL;
-+   vap->va_flags = 0;
-+   vap->va_bytes = vap->va_size;
-+   vap->va_filerev = dir->dir_qid.vers;
-+ 
-+   vp->v_type = vap->va_type;
-+   vp->v_tag = VT_U9FS;
-+ 
-+   return (error);
-+ }
-+ 
-+ /*
-+  * u9fs setattr call.
-+  */
-+ static int
-+ u9fs_setattr(ap)
-+ 	struct vop_setattr_args /* {
-+ 		struct vnodeop_desc *a_desc;
-+ 		struct vnode *a_vp;
-+ 		struct vattr *a_vap;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   register struct u9fsnode *np = VTOU9FS(vp);
-+   register struct vattr *vap = ap->a_vap;
-+   int error = 0;
-+   struct u9fsmount * nmp = VFSTOU9FS(vp->v_mount);
-+   struct u9fsdir dir;
-+   struct u9fsuser * u9p;
-+   struct vattr attr;
-+   struct u9fsreq req, rep;
-+ 
-+   if( vp->v_mount->mnt_flag & MNT_RDONLY )
-+     return (EROFS);
-+ 
-+   if( vap->va_nlink != VNOVAL || vap->va_uid != VNOVAL ||
-+       vap->va_fsid != VNOVAL || vap->va_fileid != VNOVAL ||
-+ #if 0
-+       vap->va_size != VNOVAL || vap->va_blocksize != VNOVAL ||
-+ #endif
-+       vap->va_atime.tv_sec != VNOVAL || vap->va_ctime.tv_sec != VNOVAL ||
-+       vap->va_gen != VNOVAL ||
-+       vap->va_flags != VNOVAL || vap->va_bytes != VNOVAL ) {
-+ #if 0
-+     printf("%d %d %d %d %d %d %d %d %d %d %d\n", vap->va_nlink, vap->va_uid, vap->va_fsid, 
-+ 	       vap->va_fileid, vap->va_size, vap->va_blocksize, 
-+ 	       vap->va_atime.tv_sec, vap->va_ctime.tv_sec, vap->va_gen, 
-+ 	       vap->va_flags, vap->va_bytes);
-+     printf("unsupported setattr\n");
-+     /* touch tries to change ctime first. 
-+      * if fails, it touches the first byte
-+     */
-+ #endif
-+     return (EOPNOTSUPP);
-+   }
-+ 
-+   if( vap->va_size == 0 )
-+     u9fs_trunc(vp, ap->a_cred, ap->a_p);
-+ 
-+   bcopy(&np->n_dir, &dir, sizeof(dir));
-+   if( vap->va_mode  != (mode_t)VNOVAL ) {
-+     dir.dir_mode = U9P_PERM_NONPERM(dir.dir_mode)|U9P_PERM_ALL(vap->va_mode);
-+   }
-+   if( vap->va_gid != VNOVAL ) {
-+     if( (u9p = u9fs_finduser(vap->va_gid)) == 0 )
-+       return (EINVAL);
-+     strncpy(u9p->u_name, dir.dir_gid, U9FS_NAMELEN);
-+   }
-+   if( vap->va_mtime.tv_sec != VNOVAL ) {
-+     dir.dir_mtime = vap->va_mtime.tv_sec;
-+   }
-+ 
-+   /* stat fid */
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = ap->a_p;
-+   req.r_type = Twstat;
-+   req.r_fid = np->n_fid;
-+   u9p_d2m(&dir, req.r_stat);
-+   error = u9fs_request(& req, & rep, 1);
-+   if( error )
-+     return error;
-+   VOP_GETATTR(vp, &attr, ap->a_cred, ap->a_p);
-+ 
-+   return 0;
-+ }
-+ 
-+ /*
-+  * u9fs lookup call, one step at a time...
-+  * First look in cache
-+  * If not found, unlock the directory u9fsnode and do the rpc
-+  */
-+ static int
-+ u9fs_lookup(ap)
-+ 	struct vop_lookup_args /* {
-+ 		struct vnodeop_desc *a_desc;
-+ 		struct vnode *a_dvp;
-+ 		struct vnode **a_vpp;
-+ 		struct componentname *a_cnp;
-+ 	} */ *ap;
-+ {
-+ 	struct componentname *cnp = ap->a_cnp;
-+ 	struct vnode *dvp = ap->a_dvp;
-+ 	struct vnode **vpp = ap->a_vpp;
-+ 	int flags = cnp->cn_flags;
-+ 	struct vnode *newvp;
-+ 	struct u9fsmount *nmp;
-+ 	long len;
-+ 	u9fsfh_t fh;
-+ 	struct u9fsnode *np;
-+ 	int lockparent, wantparent, error = 0;
-+ 	struct proc *p = cnp->cn_proc;
-+ 	struct u9fsreq req, rep;
-+ 	u_short newfid;
-+ 	struct vattr attrs;
-+ 
-+ 	*vpp = NULLVP;
-+ 	if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
-+ 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
-+ 		return (EROFS);
-+ 	if (dvp->v_type != VDIR)
-+ 		return (ENOTDIR);
-+ 	lockparent = flags & LOCKPARENT;
-+ 	wantparent = flags & (LOCKPARENT|WANTPARENT);
-+ 	nmp = VFSTOU9FS(dvp->v_mount);
-+ 	np = VTOU9FS(dvp);
-+ #if 0
-+ 	if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {
-+ 		struct vattr vattr;
-+ 		int vpid;
-+ 
-+ 		if (error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, p)) {
-+ 			*vpp = NULLVP;
-+ 			return (error);
-+ 		}
-+ 
-+ 		newvp = *vpp;
-+ 		vpid = newvp->v_id;
-+ 		/*
-+ 		 * See the comment starting `Step through' in ufs/ufs_lookup.c
-+ 		 * for an explanation of the locking protocol
-+ 		 */
-+ 		if (dvp == newvp) {
-+ 			VREF(newvp);
-+ 			error = 0;
-+ 		} else if (flags & ISDOTDOT) {
-+ 			VOP_UNLOCK(dvp, 0, p);
-+ 			error = vget(newvp, LK_EXCLUSIVE, p);
-+ 			if (!error && lockparent && (flags & ISLASTCN))
-+ 				error = vn_lock(dvp, LK_EXCLUSIVE, p);
-+ 		} else {
-+ 			error = vget(newvp, LK_EXCLUSIVE, p);
-+ 			if (!lockparent || error || !(flags & ISLASTCN))
-+ 				VOP_UNLOCK(dvp, 0, p);
-+ 		}
-+ 		if (!error) {
-+ 			if (vpid == newvp->v_id) {
-+ 			   if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, p)
-+ 			    && vattr.va_ctime.tv_sec == VTOU9FS(newvp)->n_ctime) {
-+ 				u9fsstats.lookupcache_hits++;
-+ 				if (cnp->cn_nameiop != LOOKUP &&
-+ 				    (flags & ISLASTCN))
-+ 					cnp->cn_flags |= SAVENAME;
-+ 				return (0);
-+ 			   }
-+ 			   cache_purge(newvp);
-+ 			}
-+ 			vput(newvp);
-+ 			if (lockparent && dvp != newvp && (flags & ISLASTCN))
-+ 				VOP_UNLOCK(dvp, 0, p);
-+ 		}
-+ 		error = vn_lock(dvp, LK_EXCLUSIVE, p);
-+ 		*vpp = NULLVP;
-+ 		if (error)
-+ 			return (error);
-+ 	}
-+ #endif
-+ 	error = 0;
-+ 	newvp = NULLVP;
-+ 	len = cnp->cn_namelen;
-+ 
-+ 	/* Tclwalk tag fid newfid name */
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_procp = p;
-+ 	req.r_nmp = nmp;
-+ 	req.r_type = Tclwalk;
-+ 	req.r_fid = np->n_fid;
-+ 	newfid = req.r_newfid = u9fs_id_new(nmp->nm_fids);
-+ 	bcopy(cnp->cn_nameptr, req.r_name, len);
-+ 	if( (error = u9fs_request(&req, &rep, 1)) ) {
-+ 	  u9fs_id_free(nmp->nm_fids, newfid);
-+ 	  return error;
-+ 	}
-+ 
-+ 	fh = rep.r_qid.path;
-+ 	if( fh == 0 ) {
-+ 	  u9fs_id_free(nmp->nm_fids, newfid);
-+ 	  error = ENOENT;
-+ 	  goto lastcheck;
-+ 	}
-+ 
-+ 	/*
-+ 	 * Handle RENAME case...
-+ 	 */
-+ 	if (cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) {
-+ #if 0
-+ 	  /* XXX: I dont understand this. rename foo foo? */
-+ 		if (U9FS_CMPFH(np, fhp, fhsize)) {
-+ 			m_freem(mrep);
-+ 			return (EISDIR);
-+ 		}
-+ #endif
-+ 		error = u9fs_nget(dvp->v_mount, fh, &np, p);
-+ 		if (error)
-+ 		  goto fail;
-+ 
-+ 		if ( np->n_fid )
-+ 		  u9fs_free_fid(newfid, nmp, p);
-+ 		else
-+ 		  np->n_fid = newfid;
-+ 
-+ 		newvp = U9FSTOV(np);
-+ 		*vpp = newvp;
-+ 		cnp->cn_flags |= SAVENAME;
-+ 		if (!lockparent)
-+ 			VOP_UNLOCK(dvp, 0, p);
-+ 		return (0);
-+ 	}
-+ 
-+ 	if (flags & ISDOTDOT) {
-+ 		VOP_UNLOCK(dvp, 0, p);
-+ 		error = u9fs_nget(dvp->v_mount, fh, &np, p);
-+ 		if (error) {
-+ 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
-+ 			goto fail;
-+ 		}
-+ 		if( np->n_fid )
-+ 		  u9fs_free_fid(newfid, nmp, p);
-+ 		else
-+ 		  np->n_fid = req.r_newfid;
-+ 
-+ 		newvp = U9FSTOV(np);
-+ 		if (lockparent && (flags & ISLASTCN) &&
-+ 		    (error = vn_lock(dvp, LK_EXCLUSIVE, p))) {
-+ 		    	vput(newvp);
-+ 			return (error);
-+ 		}
-+ 	} else if (np->n_qid.path == fh) {
-+ 	        u9fs_free_fid(newfid, nmp, p);
-+ 		VREF(dvp);
-+ 		newvp = dvp;
-+ 	} else {
-+ 		error = u9fs_nget(dvp->v_mount, fh, &np, p);
-+ 		if (error)
-+ 		  goto fail;
-+ 
-+ 		if( np->n_fid )
-+ 		  u9fs_free_fid(newfid, nmp, p);
-+ 		else
-+ 		  np->n_fid = req.r_newfid;
-+ 
-+ 		if (!lockparent || !(flags & ISLASTCN))
-+ 			VOP_UNLOCK(dvp, 0, p);
-+ 		newvp = U9FSTOV(np);
-+ 
-+ 		VOP_GETATTR(newvp, & attrs, p->p_ucred, p);
-+ 	}
-+ 
-+ 	if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
-+ 		cnp->cn_flags |= SAVENAME;
-+ #if 0
-+ 	if ((cnp->cn_flags & MAKEENTRY) &&
-+ 	    (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {
-+ 		np->n_ctime = np->n_vattr.va_ctime.tv_sec;
-+ 		cache_enter(dvp, newvp, cnp);
-+ 	}
-+ #endif
-+ 	*vpp = newvp;
-+  lastcheck:
-+ 	if (error) {
-+ 		if (newvp != NULLVP) {
-+ 			vrele(newvp);
-+ 			*vpp = NULLVP;
-+ 		}
-+ 		if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
-+ 		    (flags & ISLASTCN) && error == ENOENT) {
-+ 			if (!lockparent)
-+ 				VOP_UNLOCK(dvp, 0, p);
-+ 			if (dvp->v_mount->mnt_flag & MNT_RDONLY)
-+ 				error = EROFS;
-+ 			else
-+ 				error = EJUSTRETURN;
-+ 		}
-+ 		if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
-+ 			cnp->cn_flags |= SAVENAME;
-+ 	}
-+ 	return (error);
-+ 
-+  fail:
-+ 	u9fs_free_fid(newfid, nmp, p);
-+ 	return (error);
-+ }
-+ 
-+ /*
-+  * u9fs read call.
-+  * Just call u9fs_bioread() to do the work.
-+  */
-+ static int
-+ u9fs_read(ap)
-+ 	struct vop_read_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct uio *a_uio;
-+ 		int  a_ioflag;
-+ 		struct ucred *a_cred;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   
-+   if (vp->v_type != VREG)
-+     return (EPERM);
-+   return (u9fs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0));
-+ }
-+ 
-+ /*
-+  * u9fs readlink call
-+  */
-+ static int
-+ u9fs_readlink(ap)
-+ 	struct vop_readlink_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct uio *a_uio;
-+ 		struct ucred *a_cred;
-+ 	} */ *ap;
-+ {
-+   return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * u9fs mknod vop
-+  * just call u9fs_mknodrpc() to do the work.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_mknod(ap)
-+ 	struct vop_mknod_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct vnode **a_vpp;
-+ 		struct componentname *a_cnp;
-+ 		struct vattr *a_vap;
-+ 	} */ *ap;
-+ {
-+   return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * u9fs file create call
-+  */
-+ static int
-+ u9fs_create(ap)
-+ 	struct vop_create_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct vnode **a_vpp;
-+ 		struct componentname *a_cnp;
-+ 		struct vattr *a_vap;
-+ 	} */ *ap;
-+ {
-+ 	register struct vnode *dvp = ap->a_dvp;
-+ 	register struct vattr *vap = ap->a_vap;
-+ 	register struct componentname *cnp = ap->a_cnp;
-+ 	struct u9fsnode *np = (struct u9fsnode *)0;
-+ 	struct vnode *newvp = (struct vnode *)0;
-+ 	int error = 0, len;
-+ 	struct vattr vattr;
-+ 	struct u9fsreq req, rep;
-+ 	struct u9fsmount *nmp;
-+ 	u9fsfh_t fh;
-+ 	struct proc * p;
-+ 	int pfid;
-+ 
-+ #if 0
-+ 	/*
-+ 	 * Oops, not for me..
-+ 	 */
-+ 	if (vap->va_type == VSOCK)
-+ 		return (u9fs_mknodrpc(dvp, ap->a_vpp, cnp, vap));
-+ #endif
-+ 
-+ 	if (error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred, cnp->cn_proc)) {
-+ 		VOP_ABORTOP(dvp, cnp);
-+ 		return (error);
-+ 	}
-+ 
-+ 	nmp = VFSTOU9FS(dvp->v_mount);
-+ 	np = VTOU9FS(dvp);
-+ 	p = cnp->cn_proc;
-+ 
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_nmp = nmp;
-+ 	req.r_procp = p;
-+ 
-+ 	req.r_type = Tclone;
-+ 	pfid = req.r_fid  = np->n_fid;
-+ 	req.r_newfid = u9fs_id_new(nmp->nm_fids);
-+ 	error = u9fs_request(&req, &rep, 1);
-+ 	if( error )
-+ 	  return error;
-+ 
-+ 	req.r_type = Tcreate;
-+ 	req.r_fid = req.r_newfid;
-+ 	len = cnp->cn_namelen;
-+ 	if( len > U9FS_NAMELEN )
-+ 	  len = U9FS_NAMELEN;
-+ 	strncpy(req.r_name, cnp->cn_nameptr, len);
-+ 	req.r_name[U9FS_NAMELEN] = 0;
-+ 	req.r_perm = U9P_PERM_ALL(vap->va_mode);
-+ 	if( vap->va_type == VDIR ) {
-+ 	  req.r_perm |= 0x80000000;
-+ 	  req.r_mode = U9P_MODE_RD;
-+ 	} else
-+ 	  req.r_mode = U9P_MODE_WR | U9P_MODE_TRUNC;
-+ 	if(vap->va_vaflags & VA_EXCLUSIVE) 
-+ 	  req.r_mode = U9P_MODE_EX;
-+ 
-+ 	error = u9fs_request(&req, &rep, 1);
-+ 	if( error )
-+ 	  return error;
-+ 
-+ 	fh = rep.r_qid.path;
-+ 	u9fs_nget(dvp->v_mount, fh, &np, p);
-+ 	newvp = U9FSTOV(np);
-+ 	if( vap->va_type == VDIR )
-+ 	  np->n_rdfid = req.r_fid;
-+ 	else
-+ 	  np->n_wrfid = req.r_fid;
-+ 	
-+ 	req.r_type = Tclwalk;
-+ 	req.r_fid  = pfid;
-+ 	req.r_newfid = u9fs_id_new(nmp->nm_fids);
-+ 	/* r_name is already filled */
-+ 	error = u9fs_request(&req, &rep, 1);
-+ 	if( error )
-+ 	  return error;
-+ 	np->n_fid = req.r_newfid;
-+ 	VOP_GETATTR(newvp, & vattr, p->p_ucred, p);
-+ 
-+ 	*ap->a_vpp = newvp;
-+ 	zfree(namei_zone, cnp->cn_pnbuf);
-+ 
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * u9fs file remove call
-+  * To try and make u9fs semantics closer to ufs semantics, a file that has
-+  * other processes using the vnode is renamed instead of removed and then
-+  * removed later on the last close.
-+  * - If v_usecount > 1
-+  *	  If a rename is not already in the works
-+  *	     call u9fs_sillyrename() to set it up
-+  *     else
-+  *	  do the remove rpc
-+  */
-+ static int
-+ u9fs_remove(ap)
-+ 	struct vop_remove_args /* {
-+ 		struct vnodeop_desc *a_desc;
-+ 		struct vnode * a_dvp;
-+ 		struct vnode * a_vp;
-+ 		struct componentname * a_cnp;
-+ 	} */ *ap;
-+ {
-+ 	register struct vnode *vp = ap->a_vp;
-+ 	register struct componentname *cnp = ap->a_cnp;
-+ 	struct u9fsnode *np;
-+ 	struct u9fsreq req, rep;
-+ 	struct u9fsmount *nmp;
-+ 	struct proc * p;
-+ 	int error;
-+ 
-+ 	nmp = VFSTOU9FS(vp->v_mount);
-+ 	np = VTOU9FS(vp);
-+ 	p = cnp->cn_proc;
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_nmp = nmp;
-+ 	req.r_procp = p;
-+ 	req.r_type = Tremove;
-+ 	req.r_fid = np->n_fid;
-+ 	error = u9fs_request(&req, &rep, 1);
-+ 	if( error )
-+ 	  return error;
-+ 	zfree(namei_zone, cnp->cn_pnbuf);
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * u9fs file rename call
-+  */
-+ static int
-+ u9fs_rename(ap)
-+ 	struct vop_rename_args  /* {
-+ 		struct vnode *a_fdvp;
-+ 		struct vnode *a_fvp;
-+ 		struct componentname *a_fcnp;
-+ 		struct vnode *a_tdvp;
-+ 		struct vnode *a_tvp;
-+ 		struct componentname *a_tcnp;
-+ 	} */ *ap;
-+ {
-+ 	register struct vnode *fvp = ap->a_fvp;
-+ 	register struct vnode *tvp = ap->a_tvp;
-+ 	register struct vnode *fdvp = ap->a_fdvp;
-+ 	register struct vnode *tdvp = ap->a_tdvp;
-+ 	register struct componentname *tcnp = ap->a_tcnp;
-+ 	register struct componentname *fcnp = ap->a_fcnp;
-+ 	int error, len;
-+ 	struct u9fsmount * nmp;
-+ 	struct u9fsreq req, rep;
-+ 	struct u9fsdir dir;
-+ 	struct u9fsnode * np;
-+ 
-+ 	/* we cant do cross-directory renaming or move to an existing file */
-+ 	if( fdvp != tdvp || tvp != 0 || fvp->v_mount->mnt_flag & MNT_RDONLY ){
-+ 	  printf("rename to existing file not supported\n");
-+ 	  error = EOPNOTSUPP;
-+ 	  goto out;
-+ 	}
-+ 
-+ 	nmp = VFSTOU9FS(fvp->v_mount);
-+ 	np = VTOU9FS(fvp);
-+ 
-+ 	bcopy(&np->n_dir, &dir, sizeof(dir));
-+ 	len = tcnp->cn_namelen;
-+ 	if( len > U9FS_NAMELEN )
-+ 	  len = U9FS_NAMELEN;
-+ 	strncpy(dir.dir_name, tcnp->cn_nameptr, len);
-+ 	dir.dir_name[U9FS_NAMELEN-1] = 0;
-+ 	
-+ 	/* stat fid */
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_nmp = nmp;
-+ 	req.r_procp = fcnp->cn_proc;
-+ 	req.r_type = Twstat;
-+ 	req.r_fid = np->n_fid;
-+ 	u9p_d2m(&dir, req.r_stat);
-+ 	error = u9fs_request(& req, & rep, 1);
-+ 
-+  out:
-+ 	if (tdvp == tvp)
-+ 		vrele(tdvp);
-+ 	else
-+ 		vput(tdvp);
-+ 	if (tvp)
-+ 		vput(tvp);
-+ 	vrele(fdvp);
-+ 	vrele(fvp);
-+ 
-+ 	return error;
-+ }
-+ 
-+ /*
-+  * u9fs hard link create call
-+  */
-+ static int
-+ u9fs_link(ap)
-+ 	struct vop_link_args /* {
-+ 		struct vnode *a_tdvp;
-+ 		struct vnode *a_vp;
-+ 		struct componentname *a_cnp;
-+ 	} */ *ap;
-+ {
-+   return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * u9fs symbolic link create call
-+  */
-+ static int
-+ u9fs_symlink(ap)
-+ 	struct vop_symlink_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct vnode **a_vpp;
-+ 		struct componentname *a_cnp;
-+ 		struct vattr *a_vap;
-+ 		char *a_target;
-+ 	} */ *ap;
-+ {
-+   return (EOPNOTSUPP);
-+ }
-+ 
-+ /*
-+  * u9fs make dir call
-+  */
-+ static int
-+ u9fs_mkdir(ap)
-+ 	struct vop_mkdir_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct vnode **a_vpp;
-+ 		struct componentname *a_cnp;
-+ 		struct vattr *a_vap;
-+ 	} */ *ap;
-+ {
-+   struct vop_create_args cap;
-+ 
-+   cap.a_dvp = ap->a_dvp;
-+   cap.a_vpp = ap->a_vpp;
-+   cap.a_cnp = ap->a_cnp;
-+   cap.a_vap = ap->a_vap;
-+   return u9fs_create(&cap);
-+ }
-+ 
-+ /*
-+  * u9fs remove directory call
-+  */
-+ static int
-+ u9fs_rmdir(ap)
-+ 	struct vop_rmdir_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct vnode *a_vp;
-+ 		struct componentname *a_cnp;
-+ 	} */ *ap;
-+ {
-+ 	register struct vnode *vp = ap->a_vp;
-+ 	register struct componentname *cnp = ap->a_cnp;
-+ 	struct u9fsnode *np;
-+ 	struct u9fsreq req, rep;
-+ 	struct u9fsmount *nmp;
-+ 	struct proc * p;
-+ 	int error;
-+ 
-+ 	nmp = VFSTOU9FS(vp->v_mount);
-+ 	np = VTOU9FS(vp);
-+ 	p = cnp->cn_proc;
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_nmp = nmp;
-+ 	req.r_procp = p;
-+ 	req.r_type = Tremove;
-+ 	req.r_fid = np->n_fid;
-+ 	error = u9fs_request(&req, &rep, 1);
-+ 	if( error )
-+ 	  return error;
-+ 	u9fs_id_free(nmp->nm_fids, np->n_fid);
-+ 	np->n_fid = 0;
-+ 	zfree(namei_zone, cnp->cn_pnbuf);
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * u9fs readdir call
-+  */
-+ static int
-+ u9fs_readdir(ap)
-+ 	struct vop_readdir_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct uio *a_uio;
-+ 		struct ucred *a_cred;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   register struct uio *uio = ap->a_uio;
-+   int error;
-+   
-+   if (vp->v_type != VDIR)
-+     return (EPERM);
-+ 
-+   /*
-+    * Call u9fs_bioread() to do the real work.
-+    */
-+   error = u9fs_bioread(vp, uio, 0, ap->a_cred, 0);
-+   
-+   return (error);
-+ }
-+ 
-+ /*
-+  * Kludge City..
-+  * - make u9fs_bmap() essentially a no-op that does no translation
-+  * - do u9fs_strategy() by doing I/O with u9fs_readrpc/u9fs_writerpc
-+  *   (Maybe I could use the process's page mapping, but I was concerned that
-+  *    Kernel Write might not be enabled and also figured copyout() would do
-+  *    a lot more work than bcopy() and also it currently happens in the
-+  *    context of the swapper process (2).
-+  */
-+ static int
-+ u9fs_bmap(ap)
-+ 	struct vop_bmap_args /* {
-+ 		struct vnode *a_vp;
-+ 		daddr_t  a_bn;
-+ 		struct vnode **a_vpp;
-+ 		daddr_t *a_bnp;
-+ 		int *a_runp;
-+ 		int *a_runb;
-+ 	} */ *ap;
-+ {
-+   register struct vnode *vp = ap->a_vp;
-+   
-+   if (ap->a_vpp != NULL)
-+     *ap->a_vpp = vp;
-+   if (ap->a_bnp != NULL)
-+     *ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize);
-+   if (ap->a_runp != NULL)
-+     *ap->a_runp = 0;
-+   if (ap->a_runb != NULL)
-+     *ap->a_runb = 0;
-+   return (0);
-+ 
-+   return 0;
-+ }
-+ 
-+ /*
-+  * Strategy routine.
-+  * For async requests when u9fsiod(s) are running, queue the request by
-+  * calling u9fs_asyncio(), otherwise just all u9fs_doio() to do the
-+  * request.
-+  */
-+ static int
-+ u9fs_strategy(ap)
-+ 	struct vop_strategy_args *ap;
-+ {
-+ 	register struct buf *bp = ap->a_bp;
-+ 	struct ucred *cr;
-+ 	struct proc *p;
-+ 	int error = 0;
-+ 
-+ 	if (bp->b_flags & B_PHYS)
-+ 		panic("nfs physio");
-+ 	if (bp->b_flags & B_ASYNC)
-+ 	        panic("u9fs async");
-+ 
-+ 	p = curproc;	/* XXX */
-+ 	if (bp->b_flags & B_READ)
-+ 		cr = bp->b_rcred;
-+ 	else
-+ 		cr = bp->b_wcred;
-+ 	error = u9fs_doio(bp, cr, p);
-+ 	return (error);  
-+ }
-+ 
-+ /*
-+  * Mmap a file
-+  *
-+  * NB Currently unsupported.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_mmap(ap)
-+ 	struct vop_mmap_args /* {
-+ 		struct vnode *a_vp;
-+ 		int  a_fflags;
-+ 		struct ucred *a_cred;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+ 	return (EINVAL);
-+ }
-+ 
-+ /*
-+  * fsync vnode op. Just call u9fs_flush() with commit == 1.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_fsync(ap)
-+ 	struct vop_fsync_args /* {
-+ 		struct vnodeop_desc *a_desc;
-+ 		struct vnode * a_vp;
-+ 		struct ucred * a_cred;
-+ 		int  a_waitfor;
-+ 		struct proc * a_p;
-+ 	} */ *ap;
-+ {
-+   /* we have a blocking writeback cache */
-+   return 0;
-+ }
-+ 
-+ /*
-+  * U9FS advisory byte-level locks.
-+  * Currently unsupported.
-+  */
-+ static int
-+ u9fs_advlock(ap)
-+ 	struct vop_advlock_args /* {
-+ 		struct vnode *a_vp;
-+ 		caddr_t  a_id;
-+ 		int  a_op;
-+ 		struct flock *a_fl;
-+ 		int  a_flags;
-+ 	} */ *ap;
-+ {
-+ 	register struct u9fsnode *np = VTOU9FS(ap->a_vp);
-+ 
-+ 	/*
-+ 	 * The following kludge is to allow diskless support to work
-+ 	 * until a real NFS lockd is implemented. Basically, just pretend
-+ 	 * that this is a local lock.
-+ 	 */
-+ 	return (lf_advlock(ap, &(np->n_lockf), np->n_size));
-+ }
-+ 
-+ /*
-+  * Print out the contents of an u9fsnode.
-+  */
-+ static int
-+ u9fs_print(ap)
-+ 	struct vop_print_args /* {
-+ 		struct vnode *a_vp;
-+ 	} */ *ap;
-+ {
-+   panic("u9fs_print");
-+   return 0;
-+ }
-+ 
-+ /*
-+  * Just call u9fs_writebp() with the force argument set to 1.
-+  */
-+ static int
-+ u9fs_bwrite(ap)
-+ 	struct vop_bwrite_args /* {
-+ 		struct vnode *a_bp;
-+ 	} */ *ap;
-+ {
-+   panic("u9fs_bwrite");
-+   return 0;
-+ }
-+ 
-+ /*
-+  * Vnode op for VM getpages.
-+  */
-+ static int
-+ u9fs_getpages(ap)
-+ 	struct vop_getpages_args /* {
-+ 		struct vnode *a_vp;
-+ 		vm_page_t *a_m;
-+ 		int a_count;
-+ 		int a_reqpage;
-+ 		vm_ooffset_t a_offset;
-+ 	} */ *ap;
-+ {
-+ 	int i, error, nextoff, size, toff, npages, count;
-+ 	struct uio uio;
-+ 	struct iovec iov;
-+ 	vm_offset_t kva;
-+ 	struct buf *bp;
-+ 	struct vnode *vp;
-+ 	struct proc *p;
-+ 	struct ucred *cred;
-+ 	struct u9fsmount *nmp;
-+ 	vm_page_t *pages;
-+ 
-+ 	vp = ap->a_vp;
-+ 	p = curproc;				/* XXX */
-+ 	cred = curproc->p_ucred;		/* XXX */
-+ 	nmp = VFSTOU9FS(vp->v_mount);
-+ 	pages = ap->a_m;
-+ 	count = ap->a_count;
-+ 
-+ 	if (vp->v_object == NULL) {
-+ 		printf("u9fs_getpages: called with non-merged cache vnode??\n");
-+ 		return VM_PAGER_ERROR;
-+ 	}
-+ 
-+ 	/*
-+ 	 * We use only the kva address for the buffer, but this is extremely
-+ 	 * convienient and fast.
-+ 	 */
-+ 	bp = getpbuf();
-+ 
-+ 	npages = btoc(count);
-+ 	kva = (vm_offset_t) bp->b_data;
-+ 	pmap_qenter(kva, pages, npages);
-+ 
-+ 	iov.iov_base = (caddr_t) kva;
-+ 	iov.iov_len = count;
-+ 	uio.uio_iov = &iov;
-+ 	uio.uio_iovcnt = 1;
-+ 	uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
-+ 	uio.uio_resid = count;
-+ 	uio.uio_segflg = UIO_SYSSPACE;
-+ 	uio.uio_rw = UIO_READ;
-+ 	uio.uio_procp = p;
-+ 
-+ 	error = u9fs_readrpc(vp, &uio, cred);
-+ 	pmap_qremove(kva, npages);
-+ 
-+ 	relpbuf(bp);
-+ 
-+ 	if (error && (uio.uio_resid == count))
-+ 		return VM_PAGER_ERROR;
-+ 
-+ 	size = count - uio.uio_resid;
-+ 
-+ 	for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
-+ 		vm_page_t m;
-+ 		nextoff = toff + PAGE_SIZE;
-+ 		m = pages[i];
-+ 
-+ 		m->flags &= ~PG_ZERO;
-+ 
-+ 		if (nextoff <= size) {
-+ 			m->valid = VM_PAGE_BITS_ALL;
-+ 			m->dirty = 0;
-+ 		} else {
-+ 			int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1);
-+ 			vm_page_set_validclean(m, 0, nvalid);
-+ 		}
-+ 		
-+ 		if (i != ap->a_reqpage) {
-+ 			/*
-+ 			 * Whether or not to leave the page activated is up in
-+ 			 * the air, but we should put the page on a page queue
-+ 			 * somewhere (it already is in the object).  Result:
-+ 			 * It appears that emperical results show that
-+ 			 * deactivating pages is best.
-+ 			 */
-+ 
-+ 			/*
-+ 			 * Just in case someone was asking for this page we
-+ 			 * now tell them that it is ok to use.
-+ 			 */
-+ 			if (!error) {
-+ 				if (m->flags & PG_WANTED)
-+ 					vm_page_activate(m);
-+ 				else
-+ 					vm_page_deactivate(m);
-+ 				vm_page_wakeup(m);
-+ 			} else {
-+ 				vnode_pager_freepage(m);
-+ 			}
-+ 		}
-+ 	}
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * Vnode op for VM putpages.
-+  */
-+ static int
-+ u9fs_putpages(ap)
-+ 	struct vop_putpages_args /* {
-+ 		struct vnode *a_vp;
-+ 		vm_page_t *a_m;
-+ 		int a_count;
-+ 		int a_sync;
-+ 		int *a_rtvals;
-+ 		vm_ooffset_t a_offset;
-+ 	} */ *ap;
-+ {
-+   panic("u9fs_putpages");
-+   return 0;
-+ }
-+ 
-+ static int
-+ u9fs_inactive(ap)
-+ 	struct vop_inactive_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct proc *a_p;
-+ 	} */ *ap;
-+ {
-+   VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
-+   return 0;
-+ }
-+ 
-+ /*
-+  * Reclaim an u9fsnode so that it can be used for other purposes.
-+  */
-+ static int
-+ u9fs_reclaim(ap)
-+ 	struct vop_reclaim_args /* {
-+ 		struct vnode *a_vp;
-+ 	} */ *ap;
-+ {
-+ 	register struct vnode *vp = ap->a_vp;
-+ 	register struct u9fsnode *np = VTOU9FS(vp);
-+ 	register struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+ 	struct proc * p = curproc;
-+ 
-+ 	/* some vnodes do not have fids due to previous access failure */
-+ 	if( np->n_fid ) {
-+ 	  /* clunk fids */
-+ 	  u9fs_free_fid(np->n_fid, nmp, p);
-+ 	  if( np->n_rdfid )
-+ 	    u9fs_free_fid(np->n_rdfid, nmp, p);
-+ 	  if( np->n_wrfid )
-+ 	    u9fs_free_fid(np->n_wrfid, nmp, p);
-+ 	}
-+ 
-+ 	LIST_REMOVE(np, n_hash);
-+ 	cache_purge(vp);
-+ 	zfree(u9fsnode_zone, vp->v_data);
-+ 	vp->v_data = (void *)0;
-+ 
-+ 	return (0);
-+ }
-+ 
-+ /*
-+  * Vnode op for write using bio
-+  */
-+ static int
-+ u9fs_write(ap)
-+ 	struct vop_write_args /* {
-+ 		struct vnode *a_vp;
-+ 		struct uio *a_uio;
-+ 		int  a_ioflag;
-+ 		struct ucred *a_cred;
-+ 	} */ *ap;
-+ {
-+   if (ap->a_vp->v_type != VREG)
-+     return (EIO);
-+ 
-+   return u9fs_biowrite(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
-+ }
-+ 
-+ /*
-+  * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
-+  * done. Currently nothing to do.
-+  */
-+ /* ARGSUSED */
-+ static int
-+ u9fs_abortop(ap)
-+ 	struct vop_abortop_args /* {
-+ 		struct vnode *a_dvp;
-+ 		struct componentname *a_cnp;
-+ 	} */ *ap;
-+ {
-+ 	return (0);
-+ }
-+ 
-+ /*
-+  * u9fs write call
-+  */
-+ int
-+ u9fs_writerpc(vp, uiop, cred)
-+ 	register struct vnode *vp;
-+ 	register struct uio *uiop;
-+ 	struct ucred *cred;
-+ {
-+   struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+   int error = 0, len, tsiz, rlen;
-+   struct u9fsreq req, rep;
-+   struct u9fsnode * np = VTOU9FS(vp);
-+   struct proc * p = uiop->uio_procp;
-+   struct mbuf * top;
-+ 
-+   tsiz = uiop->uio_resid;
-+   if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
-+     return (EFBIG);
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = p;
-+   req.r_type = Twrite;
-+   req.r_fid = np->n_wrfid;
-+   while (tsiz > 0) {
-+     len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
-+     req.r_offset = uiop->uio_offset;
-+     req.r_count = len;
-+     error = u9fs_uiotombuf(uiop, &top, len);
-+     if( error )
-+       break;
-+     req.r_data = (char *)top;
-+     error = u9fs_request(&req, &rep, 1);
-+     if( error )
-+       break;
-+     rlen = rep.r_count;
-+     if( rlen < len ) {
-+       error = EIO;
-+       break;
-+     }
-+     tsiz -= len;
-+ 
-+     /* each write message increments version number by one.
-+        to avoid flushing our write cache, update the version */
-+     if( np->n_qid.vers )
-+       np->n_qid.vers++;
-+     else 
-+       np->n_qid.vers = np->n_dir.dir_qid.vers + 1;
-+   }
-+   if (error)
-+     uiop->uio_resid = tsiz;
-+   return (error);
-+ }
-+ 
-+ /*
-+  * Readdir rpc call.
-+  * Called from below the buffer cache by u9fs_doio().
-+  */
-+ int
-+ u9fs_readdirrpc(vp, uiop, cred)
-+ 	struct vnode *vp;
-+ 	register struct uio *uiop;
-+ 	struct ucred *cred;
-+ 
-+ {
-+ 	register int len, left;
-+ 	register struct dirent *dp;
-+ 	struct u9fsmount *nmp = VFSTOU9FS(vp->v_mount);
-+ 	struct u9fsnode *np = VTOU9FS(vp);
-+ 	int error = 0, tlen, more_dirs = 1, bigenough;
-+ 	struct u9fsreq req, rep;
-+ 	int count;
-+ 	struct u9fsdir u9dir;
-+ 
-+ 	bigenough = uiop->uio_resid >= sizeof(struct dirent);
-+ 	bzero(&req, sizeof(req));
-+ 	req.r_nmp = nmp;
-+ 	req.r_type = Tread;
-+ 	req.r_fid = np->n_rdfid;
-+ 	req.r_count = nmp->nm_readdirsize;
-+ 	while ( more_dirs && bigenough ) {
-+ 	  req.r_offset = uiop->uio_offset;
-+ 	  error = u9fs_request(&req, &rep, 0);
-+ 	  if( error )
-+ 	    return error;
-+ 
-+ 	  count = rep.r_count;
-+ 	  more_dirs = (count == req.r_count);
-+ 	  len = 0;
-+ 	  dp = (struct dirent *)uiop->uio_iov->iov_base;
-+ 	  left = uiop->uio_resid;
-+ 	  while( len < count ) {
-+ 	    /* XXX: too conservative, but OK */
-+ 	    if( left < sizeof(*dp) ) {
-+ 	      bigenough = 0;
-+ 	      break;
-+ 	    }
-+ 	    if( u9p_m_m2d(&req.r_mrep, & u9dir) ) {
-+ 	      printf("u9p_m_m2d failed!\n");
-+ 	      return (EIO);
-+ 	    }
-+ 	    
-+ 	    dp->d_fileno = u9dir.dir_qid.path;
-+ 	    if( U9P_PERM_CHDIR(u9dir.dir_mode) )
-+ 	      dp->d_type = DT_DIR;
-+ 	    else
-+ 	      dp->d_type = DT_REG;
-+ 	    u9dir.dir_name[U9FS_NAMELEN-1] = 0; /* just to be sure */
-+ 	    dp->d_namlen = strlen(u9dir.dir_name);
-+ 	    memcpy(dp->d_name, u9dir.dir_name, dp->d_namlen+1);
-+ 	    tlen = DIRHDSIZ + dp->d_namlen + 4;
-+ 	    tlen = tlen - (tlen & 0x3);
-+ 	    dp->d_reclen = tlen;
-+ 	    dp = (struct dirent *)(((char *)dp) + tlen);
-+ 	    left -= tlen;
-+ 	    len += sizeof(u9dir);
-+ 	  }
-+ 	  tlen = uiop->uio_resid - left;
-+ 	  uiop->uio_resid = left;
-+ 	  uiop->uio_iov->iov_base += tlen;
-+ 	  uiop->uio_iov->iov_len -= tlen;
-+ 	  uiop->uio_offset += len;
-+ 	  m_freem(req.r_mrep);
-+ 	}
-+ 	return 0;
-+ }
-+ 
-+ /*
-+  * u9fs read rpc call
-+  * Ditto above
-+  */
-+ int
-+ u9fs_readrpc(vp, uiop, cred)
-+ 	register struct vnode *vp;
-+ 	struct uio *uiop;
-+ 	struct ucred *cred;
-+ {
-+   struct u9fsmount *nmp;
-+   struct u9fsnode *np = VTOU9FS(vp);
-+   int error = 0, len, retlen, tsiz;
-+   struct u9fsreq req, rep;
-+ 
-+   nmp = VFSTOU9FS(vp->v_mount);
-+   tsiz = uiop->uio_resid;
-+   if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
-+     return (EFBIG);
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_type = Tread;
-+   req.r_fid = np->n_rdfid;
-+   while (tsiz > 0) {
-+     len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
-+     req.r_count = len;
-+     req.r_offset = uiop->uio_offset;
-+     error = u9fs_request(&req, &rep, 0);
-+     if( error )
-+       return error;
-+     retlen = rep.r_count;
-+     if( retlen && (error = u9fs_mbuftouio(req.r_mrep, uiop, retlen)) ) {
-+       m_freem(req.r_mrep);
-+       return error;
-+     }
-+     
-+     m_freem(req.r_mrep);
-+     req.r_mrep = 0;
-+     tsiz -= retlen;
-+     if (retlen < len)
-+       tsiz = 0;
-+   }
-+   return (0);
-+ }
-+ 
-+ static void u9fs_free_fid(fid, nmp, p)
-+      u_short fid;
-+      struct u9fsmount * nmp;
-+      struct proc * p;
-+ {
-+   struct u9fsreq req, rep;
-+ 
-+   /* clunk fid */
-+   bzero(&req, sizeof(req));
-+   req.r_nmp = nmp;
-+   req.r_procp = p;
-+   req.r_type = Tclunk;
-+   req.r_fid = fid;
-+   u9fs_request(&req, &rep, 1);
-+   u9fs_id_free(nmp->nm_fids, fid);
-+ }
-diff -N -c -r /usr/src/sys/9fs/9p.c ./9fs/9p.c
-*** /usr/src/sys/9fs/9p.c	Wed Dec 31 19:00:00 1969
---- ./9fs/9p.c	Thu Nov 25 15:04:16 1999
-***************
-*** 0 ****
---- 1,974 ----
-+ #include <sys/param.h>
-+ #include <sys/systm.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <netinet/in.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/malloc.h>
-+ #include <sys/vnode.h>
-+ #include <sys/mount.h>
-+ 
-+ #include <9fs/bitstring.h>
-+ #include <9fs/9p.h>
-+ #include <9fs/9auth.h>
-+ #include <9fs/9fs.h>
-+ 
-+ int u9p_usetcp = 0;
-+ struct u9fs_reqq u9fs_reqq;
-+ 
-+ #define	N2HCHAR(x)		x = *p++
-+ #define	N2HSHORT(x)	x = (p[0] | (p[1]<<8)); p += 2
-+ #define	N2HLONG(x)		x = (p[0] | (p[1]<<8) |\
-+ 				(p[2]<<16) | (p[3]<<24)); p += 4
-+ #define	N2HQUAD(x)	x = (u_int64_t)(p[0] | (p[1]<<8) |\
-+ 					(p[2]<<16) | (p[3]<<24)) |\
-+ 				((u_int64_t)(p[4] | (p[5]<<8) |\
-+ 					(p[6]<<16) | (p[7]<<24)) << 32); p += 8
-+ #define	N2HSTRING(x,n)	bcopy(p, x, n); p += n
-+ 
-+ #define	H2NCHAR(x)	*p++ = x
-+ #define	H2NSHORT(x)	p[0]=x; p[1]=x>>8; p += 2
-+ #define	H2NLONG(x)		p[0]=x; p[1]=x>>8; p[2]=x>>16; p[3]=x>>24; p += 4
-+ #define	H2NQUAD(x)	p[0]=x;	p[1]=x>>8;\
-+ 			p[2]=x>>16;	p[3]=x>>24;\
-+ 			p[4]=x>>32;	p[5]=x>>40;\
-+ 			p[6]=x>>48;	p[7]=x>>56;\
-+ 			p += 8
-+ #define	H2NSTRING(x,n)	bcopy(x, p, n); p += n
-+ 
-+ static void u9p_print __P((u_char * m, int len, struct u9fsreq * f));
-+ 
-+ static char * u9p_types[] = {
-+   "Tnop",
-+   "Rnop",
-+   "Tosession",
-+   "Rosession",
-+   "Terror",
-+   "Rerror",
-+   "Tflush",
-+   "Rflush",
-+   "Toattach",
-+   "Roattach",
-+   "Tclone",
-+   "Rclone",
-+   "Twalk",
-+   "Rwalk",
-+   "Topen",
-+   "Ropen",
-+   "Tcreate",
-+   "Rcreate",
-+   "Tread",
-+   "Rread",
-+   "Twrite",
-+   "Rwrite",
-+   "Tclunk",
-+   "Rclunk",
-+   "Tremove",
-+   "Rremove",
-+   "Tstat",
-+   "Rstat",
-+   "Twstat",
-+   "Rwstat",
-+   "Tclwalk",
-+   "Rclwalk",
-+   "Tauth",
-+   "Rauth",
-+   "Tsession",
-+   "Rsession",
-+   "Tattach",
-+   "Rattach",
-+   "Ttunnel",
-+   "Rtunnel",
-+   "Tmax"
-+ };
-+ 
-+ int u9p_m2s(char *ap, int n, struct u9fsreq *f)
-+ {
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+ 	N2HCHAR(f->r_type);
-+ 	N2HSHORT(f->r_tag);
-+ 	switch(f->r_type)
-+ 	{
-+ 	default:
-+ 		return 0;
-+ 
-+ 	case Tnop:
-+ 	case Tosession:
-+ 		break;
-+ 
-+ 	case Tsession:
-+ 		N2HSTRING(f->r_chal, sizeof(f->r_chal));
-+ 		break;
-+ 
-+ 	case Tflush:
-+ 		N2HSHORT(f->r_oldtag);
-+ 		break;
-+ 
-+ 	case Tattach:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		N2HSTRING(f->r_aname, sizeof(f->r_aname));
-+ 		N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
-+ 		N2HSTRING(f->r_auth, sizeof(f->r_auth));
-+ 		break;
-+ 
-+ 	case Toattach:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		N2HSTRING(f->r_aname, sizeof(f->r_aname));
-+ 		N2HSTRING(f->r_ticket, U9FS_NAMELEN);
-+ 		break;
-+ 
-+ 	case Tauth:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		N2HSTRING(f->r_ticket, 8+U9FS_NAMELEN);
-+ 		break;
-+ 
-+ 	case Tclone:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSHORT(f->r_newfid);
-+ 		break;
-+ 
-+ 	case Twalk:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_name, sizeof(f->r_name));
-+ 		break;
-+ 
-+ 	case Topen:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HCHAR(f->r_mode);
-+ 		break;
-+ 
-+ 	case Tcreate:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_name, sizeof(f->r_name));
-+ 		N2HLONG(f->r_perm);
-+ 		N2HCHAR(f->r_mode);
-+ 		break;
-+ 
-+ 	case Tread:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HQUAD(f->r_offset);
-+ 		N2HSHORT(f->r_count);
-+ 		break;
-+ 
-+ 	case Twrite:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HQUAD(f->r_offset);
-+ 		N2HSHORT(f->r_count);
-+ 		p++;	/* pad(1) */
-+ 		f->r_data = (char*)p; p += f->r_count;
-+ 		break;
-+ 
-+ 	case Ttunnel:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tclunk:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tremove:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tstat:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Twstat:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_stat, sizeof(f->r_stat));
-+ 		break;
-+ 
-+ 	case Tclwalk:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSHORT(f->r_newfid);
-+ 		N2HSTRING(f->r_name, sizeof(f->r_name));
-+ 		break;
-+ /*
-+  */
-+ 	case Rnop:
-+ 	case Rosession:
-+ 		break;
-+ 
-+ 	case Rsession:
-+ 		N2HSTRING(f->r_chal, sizeof(f->r_chal));
-+ 		N2HSTRING(f->r_authid, sizeof(f->r_authid));
-+ 		N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
-+ 		break;
-+ 
-+ 	case Rerror:
-+ 		N2HSTRING(f->r_ename, sizeof(f->r_ename));
-+ 		break;
-+ 
-+ 	case Rflush:
-+ 		break;
-+ 
-+ 	case Rattach:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HLONG(f->r_qid.path);
-+ 		N2HLONG(f->r_qid.vers);
-+ 		N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
-+ 		break;
-+ 
-+ 	case Roattach:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HLONG(f->r_qid.path);
-+ 		N2HLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rauth:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_ticket, 8+8+7+7);
-+ 		break;
-+ 
-+ 	case Rclone:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rwalk:
-+ 	case Rclwalk:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HLONG(f->r_qid.path);
-+ 		N2HLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Ropen:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HLONG(f->r_qid.path);
-+ 		N2HLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rcreate:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HLONG(f->r_qid.path);
-+ 		N2HLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rread:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSHORT(f->r_count);
-+ 		p++;	/* pad(1) */
-+ 		f->r_data = (char*)p; p += f->r_count;
-+ 		break;
-+ 
-+ 	case Rwrite:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSHORT(f->r_count);
-+ 		break;
-+ 
-+ 	case Rtunnel:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rclunk:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rremove:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rstat:
-+ 		N2HSHORT(f->r_fid);
-+ 		N2HSTRING(f->r_stat, sizeof(f->r_stat));
-+ 		break;
-+ 
-+ 	case Rwstat:
-+ 		N2HSHORT(f->r_fid);
-+ 		break;
-+ 	}
-+ 	if((u_char*)ap+n == p)
-+ 		return n;
-+ 	return 0;
-+ }
-+ 
-+ void u9p_print(u_char * m, int len, struct u9fsreq * f)
-+ {
-+   struct u9fsreq u9fsreq;
-+ 
-+   if( f == 0 )
-+     f = & u9fsreq;
-+ 
-+   if( len < 3 ) {
-+     printf("truncated-9p %d", len);
-+     return;
-+   }
-+ 
-+   if( u9p_m2s((char *)m, len, f) == 0 )
-+     return;
-+ 
-+   printf("%s tag %d ", u9p_types[f->r_type-Tnop], f->r_tag);
-+ 
-+   switch( f->r_type ) {
-+ 	default:
-+ 	  return;
-+ 
-+ 	case Tnop:
-+ 	case Tosession:
-+ 	case Toattach:
-+ 	case Tauth:
-+ 		break;
-+ 
-+ 	case Tsession:
-+ 	case Rsession:
-+ 	  printf("chal 0x%x 0x%x", *(u_int *)&f->r_chal[0], *(u_int *)&f->r_chal[4]);
-+ 		break;
-+ 
-+ 	case Tflush:
-+ 	  printf("oldtag %d", f->r_oldtag);
-+ 		break;
-+ 
-+ 	case Tclone:
-+ 	  printf("fid %d newfid %d", f->r_fid, f->r_newfid);
-+ 		break;
-+ 
-+ 	case Twalk:
-+ 	  printf("fid %d name %s", f->r_fid, f->r_name);
-+ 		break;
-+ 
-+ 	case Topen:
-+ 	  printf("fid %d %c", f->r_fid, f->r_mode);
-+ 		break;
-+ 
-+ 	case Tcreate:
-+ 	  printf("fid %d name %s perm 0x%x mode %c", f->r_fid,
-+ 		 f->r_name, f->r_perm, f->r_mode);
-+ 		break;
-+ 
-+ 	case Tread:
-+ 	case Twrite:
-+ 	  printf("fid %d offset 0x%llx count %d", f->r_fid,
-+ 		 f->r_offset, f->r_count);
-+ 		break;
-+ 
-+ 	case Tattach:
-+ 	case Ttunnel:
-+ 	case Tclunk:
-+ 	case Tremove:
-+ 	case Tstat:
-+ 	case Twstat:
-+ 	case Rclone:
-+ 	case Rtunnel:
-+ 	case Rclunk:
-+ 	case Rremove:
-+ 	case Rstat:
-+ 	case Rwstat:
-+ 	  printf("fid %d", f->r_fid);
-+ 		break;
-+ 
-+ 	case Tclwalk:
-+ 	  printf("fid %d ", f->r_fid);
-+ 	  printf("newfid  %d ", f->r_newfid);
-+ 	  printf("name %s", f->r_name);
-+ 		break;
-+ /*
-+  */
-+ 	case Rnop:
-+ 	case Rosession:
-+ 	case Rflush:
-+ 	case Roattach:
-+ 	case Rauth:
-+ 		break;
-+ 
-+ 	case Rerror:
-+ 	  printf("ename %s", f->r_ename);
-+ 		break;
-+ 
-+ 	case Rattach:
-+ 	case Rwalk:
-+ 	case Rclwalk:
-+ 	case Ropen:
-+ 	case Rcreate:
-+ 	  printf("fid %d ", f->r_fid);
-+ 	  printf("qid 0x%x 0x%x", f->r_qid.path, f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rread:
-+ 	  printf("fid %d count %d ", f->r_fid, f->r_count);
-+ 	  break;
-+ 
-+ 	case Rwrite:
-+ 	  printf("fid %d count %d", f->r_fid, f->r_count);
-+ 		break;
-+   }
-+ }
-+ 
-+ int
-+ u9p_s2m(struct u9fsreq *f, char *ap, int copydata)
-+ {
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+ 	H2NCHAR(f->r_type);
-+ 	H2NSHORT(f->r_tag);
-+ 	switch(f->r_type)
-+ 	{
-+ 	default:
-+ 		return 0;
-+ 
-+ 	case Tosession:
-+ 	case Tnop:
-+ 		break;
-+ 
-+ 	case Tsession:
-+ 		H2NSTRING(f->r_chal, sizeof(f->r_chal));
-+ 		break;
-+ 
-+ 	case Tflush:
-+ 		H2NSHORT(f->r_oldtag);
-+ 		break;
-+ 
-+ 	case Tattach:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		H2NSTRING(f->r_aname, sizeof(f->r_aname));
-+ 		H2NSTRING(f->r_ticket, sizeof(f->r_ticket));
-+ 		H2NSTRING(f->r_auth, sizeof(f->r_auth));
-+ 		break;
-+ 
-+ 	case Toattach:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		H2NSTRING(f->r_aname, sizeof(f->r_aname));
-+ 		H2NSTRING(f->r_ticket, U9FS_NAMELEN);
-+ 		break;
-+ 
-+ 	case Tauth:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_uname, sizeof(f->r_uname));
-+ 		H2NSTRING(f->r_ticket, 8+U9FS_NAMELEN);
-+ 		break;
-+ 
-+ 	case Tclone:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSHORT(f->r_newfid);
-+ 		break;
-+ 
-+ 	case Twalk:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_name, sizeof(f->r_name));
-+ 		break;
-+ 
-+ 	case Topen:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NCHAR(f->r_mode);
-+ 		break;
-+ 
-+ 	case Tcreate:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_name, sizeof(f->r_name));
-+ 		H2NLONG(f->r_perm);
-+ 		H2NCHAR(f->r_mode);
-+ 		break;
-+ 
-+ 	case Tread:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NQUAD(f->r_offset);
-+ 		H2NSHORT(f->r_count);
-+ 		break;
-+ 
-+ 	case Twrite:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NQUAD(f->r_offset);
-+ 		H2NSHORT(f->r_count);
-+ 		p++;	/* pad(1) */
-+ 		if( copydata ) {
-+ 		  H2NSTRING(f->r_data, f->r_count);
-+ 		}
-+ 		break;
-+ 
-+ 	case Ttunnel:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tclunk:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tremove:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Tstat:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Twstat:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_stat, sizeof(f->r_stat));
-+ 		break;
-+ 
-+ 	case Tclwalk:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSHORT(f->r_newfid);
-+ 		H2NSTRING(f->r_name, sizeof(f->r_name));
-+ 		break;
-+ /*
-+  */
-+ 	case Rosession:
-+ 	case Rnop:
-+ 		break;
-+ 
-+ 	case Rsession:
-+ 		H2NSTRING(f->r_chal, sizeof(f->r_chal));
-+ 		H2NSTRING(f->r_authid, sizeof(f->r_authid));
-+ 		H2NSTRING(f->r_authdom, sizeof(f->r_authdom));
-+ 		break;
-+ 
-+ 	case Rerror:
-+ 		H2NSTRING(f->r_ename, sizeof(f->r_ename));
-+ 		break;
-+ 
-+ 	case Rflush:
-+ 		break;
-+ 
-+ 	case Rattach:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NLONG(f->r_qid.path);
-+ 		H2NLONG(f->r_qid.vers);
-+ 		H2NSTRING(f->r_rauth, sizeof(f->r_rauth));
-+ 		break;
-+ 
-+ 	case Roattach:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NLONG(f->r_qid.path);
-+ 		H2NLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rauth:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSTRING(f->r_ticket, 8+8+7+7);
-+ 		break;
-+ 
-+ 	case Rclone:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rwalk:
-+ 	case Rclwalk:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NLONG(f->r_qid.path);
-+ 		H2NLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Ropen:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NLONG(f->r_qid.path);
-+ 		H2NLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rcreate:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NLONG(f->r_qid.path);
-+ 		H2NLONG(f->r_qid.vers);
-+ 		break;
-+ 
-+ 	case Rread:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSHORT(f->r_count);
-+ 		p++;	/* pad(1) */
-+ 		if( copydata ) {
-+ 		  H2NSTRING(f->r_data, f->r_count);
-+ 		}
-+ 		break;
-+ 
-+ 	case Rwrite:
-+ 		H2NSHORT(f->r_fid);
-+ 		H2NSHORT(f->r_count);
-+ 		break;
-+ 
-+ 	case Rtunnel:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rclunk:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rremove:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 
-+ 	case Rstat:
-+ 		H2NSHORT(f->r_fid);
-+ 		if( copydata )
-+ 		  H2NSTRING(f->r_stat, sizeof(f->r_stat));
-+ 		break;
-+ 
-+ 	case Rwstat:
-+ 		H2NSHORT(f->r_fid);
-+ 		break;
-+ 	}
-+ 	return p - (u_char*)ap;
-+ }
-+ 
-+ int
-+ u9p_m2d(char *ap, struct u9fsdir *f)
-+ {
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+ 	N2HSTRING(f->dir_name, sizeof(f->dir_name));
-+ 	N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
-+ 	N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
-+ 	N2HLONG(f->dir_qid.path);
-+ 	N2HLONG(f->dir_qid.vers);
-+ 	N2HLONG(f->dir_mode);
-+ 	N2HLONG(f->dir_atime);
-+ 	N2HLONG(f->dir_mtime);
-+ 	N2HQUAD(f->dir_length);
-+ 	N2HSHORT(f->dir_type);
-+ 	N2HSHORT(f->dir_dev);
-+ 	return p - (u_char*)ap;
-+ }
-+ 
-+ int
-+ u9p_d2m(struct u9fsdir *f, char *ap)
-+ {
-+ 	u_char *p;
-+ 
-+ 	p = (u_char*)ap;
-+ 	H2NSTRING(f->dir_name, sizeof(f->dir_name));
-+ 	H2NSTRING(f->dir_uid, sizeof(f->dir_uid));
-+ 	H2NSTRING(f->dir_gid, sizeof(f->dir_gid));
-+ 	H2NLONG(f->dir_qid.path);
-+ 	H2NLONG(f->dir_qid.vers);
-+ 	H2NLONG(f->dir_mode);
-+ 	H2NLONG(f->dir_atime);
-+ 	H2NLONG(f->dir_mtime);
-+ 	H2NQUAD(f->dir_length);
-+ 	H2NSHORT(f->dir_type);
-+ 	H2NSHORT(f->dir_dev);
-+ 	return p - (u_char*)ap;
-+ }
-+ 
-+ /* parse 9P types */
-+ int u9p_type(char * t)
-+ {
-+   int i;
-+ 
-+   for(i = 0; i < sizeof(u9p_types)/sizeof(u9p_types[0]); i++) {
-+     if( strcmp(u9p_types[i], t) == 0 )
-+       return (i+Tnop);
-+   }
-+   return 0;
-+ }
-+ 
-+ /* m is freed if shorter than s */
-+ #if 1
-+ #define U9P_PULLUP(m,s)  if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) return 1; p = mtod((*(m)), u_char *)
-+ #else
-+ #define U9P_PULLUP(m,s)  if( (*(m))->m_len < (s) && ((*(m)) = m_pullup((*(m)),(s))) == 0 ) panic("PULLUP"); p = mtod((*(m)), u_char *)
-+ #endif
-+ 
-+ #define U9P_ADJ(m,s) (*(m))->m_len -= (s); (*(m))->m_data += (s)
-+ 
-+ u_short u9p_m_tag(struct mbuf ** m)
-+ {
-+   char * p;
-+   u_short t;
-+ 
-+   U9P_PULLUP(m,3);
-+   p = mtod(*m, char *);
-+   p++;
-+   N2HSHORT(t);
-+ 
-+   return t;
-+ }
-+ 
-+ int 
-+ u9p_m_m2s(struct mbuf **m, struct u9fsreq *f)
-+ {
-+   u_char *p;
-+ 
-+   U9P_PULLUP(m,3);
-+   N2HCHAR(f->r_type);
-+   N2HSHORT(f->r_tag);
-+   U9P_ADJ(m, sizeof(f->r_type)+sizeof(f->r_tag));
-+ 
-+   switch(f->r_type) {
-+   default:
-+     goto drop;
-+ 
-+   case Tnop:
-+     break;
-+ 
-+   case Tsession:
-+     U9P_PULLUP(m,sizeof(f->r_chal));
-+     N2HSTRING(f->r_chal, sizeof(f->r_chal));
-+     U9P_ADJ(m, sizeof(f->r_chal));
-+     break;
-+ 
-+   case Tflush:
-+     U9P_PULLUP(m,sizeof(f->r_oldtag));
-+     N2HSHORT(f->r_oldtag);
-+     U9P_ADJ(m, f->r_oldtag);
-+     break;
-+ 
-+   case Tattach:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
-+     N2HSHORT(f->r_fid);
-+     N2HSTRING(f->r_uname, sizeof(f->r_uname));
-+     N2HSTRING(f->r_aname, sizeof(f->r_aname));
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_uname)+sizeof(f->r_aname));
-+     
-+     U9P_PULLUP(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
-+     N2HSTRING(f->r_ticket, sizeof(f->r_ticket));
-+     N2HSTRING(f->r_auth, sizeof(f->r_auth));
-+     U9P_ADJ(m, sizeof(f->r_ticket)+sizeof(f->r_auth));
-+     break;
-+ 
-+   case Tclone:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
-+     N2HSHORT(f->r_fid);
-+     N2HSHORT(f->r_newfid);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid));
-+     break;
-+ 
-+   case Twalk:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name));
-+     N2HSHORT(f->r_fid);
-+     N2HSTRING(f->r_name, sizeof(f->r_name));
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name));
-+     break;
-+ 
-+   case Topen:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_mode));
-+     N2HSHORT(f->r_fid);
-+     N2HCHAR(f->r_mode);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_mode));
-+     break;
-+ 
-+   case Tcreate:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_name)
-+ 	       +sizeof(f->r_perm)+sizeof(f->r_mode));
-+     N2HSHORT(f->r_fid);
-+     N2HSTRING(f->r_name, sizeof(f->r_name));
-+     N2HLONG(f->r_perm);
-+     N2HCHAR(f->r_mode);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_name)
-+ 	    +sizeof(f->r_perm)+sizeof(f->r_mode));
-+     break;
-+ 
-+   case Tread:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
-+     N2HSHORT(f->r_fid);
-+     N2HQUAD(f->r_offset);
-+     N2HSHORT(f->r_count);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
-+     break;
-+ 
-+   case Twrite:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count));
-+     N2HSHORT(f->r_fid);
-+     N2HQUAD(f->r_offset);
-+     N2HSHORT(f->r_count);
-+     p++;	/* pad(1) */
-+     f->r_data = (char*)p; p += f->r_count;
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_offset)+sizeof(f->r_count)+1);
-+     break;
-+ 
-+   case Tclunk:
-+   case Tremove:
-+   case Tstat: 
-+    U9P_PULLUP(m, sizeof(f->r_fid));
-+     N2HSHORT(f->r_fid);
-+     U9P_ADJ(m, sizeof(f->r_fid));
-+     break;
-+ 
-+   case Twstat:
-+     U9P_PULLUP(m, sizeof(f->r_fid));
-+     N2HSHORT(f->r_fid);
-+     m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
-+     m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
-+     break;
-+ 
-+   case Tclwalk:
-+      U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
-+      N2HSHORT(f->r_fid);
-+      N2HSHORT(f->r_newfid);
-+      N2HSTRING(f->r_name, sizeof(f->r_name));
-+      U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_newfid)+sizeof(f->r_name));
-+      break;
-+ /*
-+  */
-+   case Rnop:
-+     break;
-+ 
-+   case Rsession:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
-+     N2HSTRING(f->r_chal, sizeof(f->r_chal));
-+     N2HSTRING(f->r_authid, sizeof(f->r_authid));
-+     N2HSTRING(f->r_authdom, sizeof(f->r_authdom));
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_authid)+sizeof(f->r_authdom));
-+     break;
-+ 
-+   case Rerror:
-+     U9P_PULLUP(m, sizeof(f->r_ename));
-+     N2HSTRING(f->r_ename, sizeof(f->r_ename));
-+     U9P_ADJ(m, sizeof(f->r_ename));
-+     break;
-+ 
-+   case Rflush:
-+     break;
-+ 
-+   case Rattach:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
-+ 	       +sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
-+     N2HSHORT(f->r_fid);
-+     N2HLONG(f->r_qid.path);
-+     N2HLONG(f->r_qid.vers);
-+     N2HSTRING(f->r_rauth, sizeof(f->r_rauth));
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
-+ 	    +sizeof(f->r_qid.vers)+sizeof(f->r_rauth));
-+     break;
-+ 
-+   case Rclone:
-+     U9P_PULLUP(m, sizeof(f->r_fid));
-+     N2HSHORT(f->r_fid);
-+     U9P_ADJ(m, sizeof(f->r_fid));
-+     break;
-+ 
-+   case Rwalk:
-+   case Rclwalk:
-+   case Ropen:
-+   case Rcreate:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
-+                +sizeof(f->r_qid.vers));
-+     N2HSHORT(f->r_fid);
-+     N2HLONG(f->r_qid.path);
-+     N2HLONG(f->r_qid.vers);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_qid.path)
-+             +sizeof(f->r_qid.vers));
-+     break;
-+ 
-+   case Rread:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
-+     N2HSHORT(f->r_fid);
-+     N2HSHORT(f->r_count);
-+     p++;	/* pad(1) */
-+     f->r_data = (char*)p; p += f->r_count;
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count)+1);
-+     break;
-+ 
-+   case Rwrite:
-+     U9P_PULLUP(m, sizeof(f->r_fid)+sizeof(f->r_count));
-+     N2HSHORT(f->r_fid);
-+     N2HSHORT(f->r_count);
-+     U9P_ADJ(m, sizeof(f->r_fid)+sizeof(f->r_count));
-+     break;
-+ 
-+   case Rclunk:
-+   case Rremove:
-+   case Rwstat:
-+     U9P_PULLUP(m, sizeof(f->r_fid));
-+     N2HSHORT(f->r_fid);
-+     U9P_ADJ(m, sizeof(f->r_fid));
-+     break;
-+ 
-+   case Rstat:
-+     U9P_PULLUP(m, sizeof(f->r_fid));
-+     N2HSHORT(f->r_fid);
-+     m_copydata(*m, sizeof(f->r_fid), sizeof(f->r_stat), f->r_stat);
-+     m_adj(*m, sizeof(f->r_fid)+sizeof(f->r_stat));
-+     break;
-+     
-+   }
-+   return 0;
-+ 
-+  drop:
-+   m_freem(*m);
-+   return 1;
-+ }
-+ 
-+ struct mbuf * 
-+ u9p_m_s2m (struct u9fsreq *f)
-+ {
-+   register struct mbuf * m;
-+   struct mbuf * m0;
-+   char * ap;
-+   int sz;
-+   
-+   /* we want one contiguous piece */
-+   if( f->r_type == Tattach || f->r_type == Rstat || f->r_type == Twstat )
-+     sz = 146; /* sizeof a Tattach */
-+   else
-+     sz = 87; /* sizeof a Tsession */
-+   
-+   MGETHDR(m, M_WAIT, MT_DATA);  
-+   if( sz > MHLEN )
-+     MCLGET(m, M_WAIT);
-+   m->m_len = 0;
-+   
-+   if ( M_TRAILINGSPACE(m) < sz )
-+     panic("u9p_m_s2m");
-+   
-+   ap = mtod(m, char *);
-+   m->m_len = u9p_s2m(f, ap, 0);
-+   m->m_pkthdr.len = m->m_len;
-+   
-+   /* append data mbufs  */
-+   switch ( f->r_type ) {
-+   default:
-+     break;
-+   case Twrite:
-+   case Rread:
-+     m0 = (struct mbuf *)f->r_data;
-+     m->m_next = m0;
-+     m->m_pkthdr.len += f->r_count;
-+     break;
-+   }
-+ 
-+   return m;
-+ }
-+ 
-+ int 
-+ u9p_m_m2d (struct mbuf **m, struct u9fsdir *f)
-+ {
-+   u_char *p;
-+   
-+   U9P_PULLUP(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
-+   N2HSTRING(f->dir_name, sizeof(f->dir_name));
-+   N2HSTRING(f->dir_uid, sizeof(f->dir_uid));
-+   N2HSTRING(f->dir_gid, sizeof(f->dir_gid));
-+   U9P_ADJ(m, sizeof(f->dir_name)+sizeof(f->dir_uid)+sizeof(f->dir_gid));
-+ 
-+   U9P_PULLUP(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
-+ 	     +sizeof(f->dir_atime)+sizeof(f->dir_mtime)
-+ 	     +sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
-+   N2HLONG(f->dir_qid.path);
-+   N2HLONG(f->dir_qid.vers);
-+   N2HLONG(f->dir_mode);
-+   N2HLONG(f->dir_atime);
-+   N2HLONG(f->dir_mtime);
-+   N2HQUAD(f->dir_length);
-+   N2HSHORT(f->dir_type);
-+   N2HSHORT(f->dir_dev);
-+   U9P_ADJ(m, sizeof(f->dir_qid)+sizeof(f->dir_mode)
-+ 	     +sizeof(f->dir_atime)+sizeof(f->dir_mtime)
-+ 	     +sizeof(f->dir_length)+sizeof(f->dir_type)+sizeof(f->dir_dev));
-+ 
-+   return 0;
-+ }
-+ 
-+ struct mbuf * u9p_m_d2m (struct u9fsdir *f)
-+ {
-+   char * ap;
-+   struct mbuf * m;
-+   MGET(m, M_WAIT, MT_DATA);
-+   MCLGET(m, M_WAIT);
-+   m->m_len = 0;
-+ 
-+   if ( M_TRAILINGSPACE(m) < sizeof(struct u9fsdir) )
-+     panic("u9p_m_d2m");
-+ 
-+   ap = mtod(m, char *);
-+   m->m_len = u9p_d2m(f, ap);  
-+ 
-+   return m;
-+ }
-diff -N -c -r /usr/src/sys/9fs/9p.h ./9fs/9p.h
-*** /usr/src/sys/9fs/9p.h	Wed Dec 31 19:00:00 1969
---- ./9fs/9p.h	Thu Nov 25 15:45:46 1999
-***************
-*** 0 ****
---- 1,183 ----
-+ #ifndef _9FS_9P_H_
-+ #define _9FS_9P_H_
-+ 
-+ 
-+ #define U9FS_AUTHLEN 13
-+ #define U9FS_NAMELEN    28
-+ #define U9FS_TICKETLEN  72
-+ #define U9FS_ERRLEN     64
-+ #define U9FS_DOMLEN     48
-+ #define U9FS_CHALLEN    8
-+ #define U9FS_DIRLEN     116
-+ #define U9FS_MAXFDATA  8192
-+ #define U9FS_MAXDDATA  (((int)U9FS_MAXFDATA/U9FS_DIRLEN)*U9FS_DIRLEN)
-+ 
-+ #define U9P_MODE_RD    0x0
-+ #define U9P_MODE_WR    0x1
-+ #define U9P_MODE_RDWR  0x2
-+ #define U9P_MODE_EX    0x3
-+ #define U9P_MODE_TRUNC 0x10
-+ #define U9P_MODE_CLOSE 0x40
-+ 
-+ #define U9P_PERM_CHDIR(m) (0x80000000&(m))
-+ #define U9P_PERM_OWNER(m) ((m)&0x7)
-+ #define U9P_PERM_GROUP(m) (((m)>>3)&0x7)
-+ #define U9P_PERM_OTHER(m) (((m)>>6)&0x7)
-+ #define U9P_PERM_ALL(m)   ((m)&0777)
-+ #define U9P_PERM_EXCL(m)    ((m)&0x20000000)
-+ #define U9P_PERM_APPEND(m)  ((m)&0x40000000)
-+ #define U9P_PERM_NONPERM(m) ((m)&0xfffffe00)
-+ 
-+ /* this is too small */
-+ typedef u_int32_t u9fsfh_t;
-+ 
-+ struct u9fs_qid {
-+ 	u9fsfh_t	path;
-+ 	u_int32_t	vers;
-+ };
-+ 
-+ struct	u9fsreq {
-+   TAILQ_ENTRY(u9fsreq) r_chain;
-+   struct u9fsreq * r_rep;
-+   struct mbuf * r_mrep;
-+   struct proc	*r_procp;	/* Proc that did I/O system call */
-+   struct u9fsmount *r_nmp;
-+ 
-+   /* actual content of the 9P message */
-+ 	char	r_type;
-+ 	short	r_fid;
-+ 	u_short	r_tag;
-+ 	union {
-+ 		struct {
-+ 			u_short	oldtag;		/* Tflush */
-+ 			struct u9fs_qid qid;		/* Rattach, Rwalk, Ropen, Rcreate */
-+ 			char	rauth[U9FS_AUTHLEN];	/* Rattach */
-+ 		} u1;
-+ 		struct {
-+ 			char	uname[U9FS_NAMELEN];		/* Tattach */
-+ 			char	aname[U9FS_NAMELEN];		/* Tattach */
-+ 			char	ticket[U9FS_TICKETLEN];	/* Tattach */
-+ 			char	auth[U9FS_AUTHLEN];	/* Tattach */
-+ 		} u2;
-+ 		struct {
-+ 			char	ename[U9FS_ERRLEN];		/* Rerror */
-+ 			char	authid[U9FS_NAMELEN];	/* Rsession */
-+ 			char	authdom[U9FS_DOMLEN];	/* Rsession */
-+ 			char	chal[U9FS_CHALLEN];		/* Tsession/Rsession */
-+ 		} u3;
-+ 		struct {
-+ 			u_int32_t	perm;		/* Tcreate */ 
-+ 			short	newfid;		/* Tclone, Tclwalk */
-+ 			char	name[U9FS_NAMELEN];	/* Twalk, Tclwalk, Tcreate */
-+ 			char	mode;		/* Tcreate, Topen */
-+ 		} u4;
-+ 		struct {
-+ 			u_int64_t	offset;		/* Tread, Twrite */
-+ 			u_short	        count;		/* Tread, Twrite, Rread */
-+ 			char	*data;		/* Twrite, Rread */
-+ 		} u5;
-+ 			char	stat[U9FS_DIRLEN];	/* Twstat, Rstat */
-+ 	} u;
-+ };
-+ 
-+ #define r_oldtag u.u1.oldtag
-+ #define r_qid u.u1.qid
-+ #define r_rauth u.u1.rauth
-+ #define r_uname u.u2.uname
-+ #define r_aname u.u2.aname
-+ #define r_ticket  u.u2.ticket
-+ #define r_auth  u.u2.auth
-+ #define r_ename  u.u3.ename
-+ #define r_authid  u.u3.authid
-+ #define r_authdom  u.u3.authdom
-+ #define r_chal  u.u3.chal
-+ #define r_perm  u.u4.perm
-+ #define r_newfid  u.u4.newfid
-+ #define r_name  u.u4.name
-+ #define r_mode  u.u4.mode
-+ #define r_offset  u.u5.offset
-+ #define r_count  u.u5.count
-+ #define r_data  u.u5.data
-+ #define r_stat  u.stat
-+ 
-+ struct u9fsdir {
-+   char	dir_name[U9FS_NAMELEN];
-+   char	dir_uid[U9FS_NAMELEN];
-+   char	dir_gid[U9FS_NAMELEN];
-+   struct u9fs_qid	dir_qid;
-+   u_int32_t	dir_mode;
-+   u_int32_t	dir_atime;
-+   u_int32_t	dir_mtime;
-+   union {
-+     u_int64_t	length;
-+     struct {	/* little endian */
-+       u_int32_t	llength;
-+       u_int32_t	hlength;
-+     } l;
-+   } u;
-+   u_short	dir_type;
-+   u_short	dir_dev;
-+ };
-+ 
-+ #define dir_length u.length
-+ #define dir_llength u.l.llength
-+ #define dir_hlength u.l.hlength
-+ 
-+ enum
-+ {
-+ 	Tnop =		50,
-+ 	Rnop,
-+ 	Tosession =	52,	/* illegal */
-+ 	Rosession,		/* illegal */
-+ 	Terror =	54,	/* illegal */
-+ 	Rerror,
-+ 	Tflush =	56,
-+ 	Rflush,
-+ 	Toattach =	58,	/* illegal */
-+ 	Roattach,		/* illegal */
-+ 	Tclone =	60,
-+ 	Rclone,
-+ 	Twalk =		62,
-+ 	Rwalk,
-+ 	Topen =		64,
-+ 	Ropen,
-+ 	Tcreate =	66,
-+ 	Rcreate,
-+ 	Tread =		68,
-+ 	Rread,
-+ 	Twrite =	70,
-+ 	Rwrite,
-+ 	Tclunk =	72,
-+ 	Rclunk,
-+ 	Tremove =	74,
-+ 	Rremove,
-+ 	Tstat =		76,
-+ 	Rstat,
-+ 	Twstat =	78,
-+ 	Rwstat,
-+ 	Tclwalk =	80,
-+ 	Rclwalk,
-+ 	Tauth =		82,	/* illegal */
-+ 	Rauth,			/* illegal */
-+ 	Tsession =	84,
-+ 	Rsession,
-+ 	Tattach =	86,
-+ 	Rattach,
-+ 	Ttunnel =	88,
-+ 	Rtunnel,
-+ 	Tmax
-+ };
-+ 
-+ int u9p_m2s __P((char *ap, int n, struct u9fsreq *f));
-+ int u9p_s2m __P((struct u9fsreq *f, char *ap, int copydata));
-+ int u9p_m2d __P((char *ap, struct u9fsdir *f));
-+ int u9p_d2m __P((struct u9fsdir *f, char *ap));
-+ int u9p_type __P((char * t));
-+ 
-+ int u9p_m_m2s __P((struct mbuf **m, struct u9fsreq *f));
-+ struct mbuf * u9p_m_s2m __P((struct u9fsreq *f));
-+ int u9p_m_m2d __P((struct mbuf **m, struct u9fsdir *f));
-+ struct mbuf * u9p_m_d2m __P((struct u9fsdir *f));
-+ u_short u9p_m_tag __P((struct mbuf **m));
-+ 
-+ #endif
-diff -N -c -r /usr/src/sys/9fs/bitstring.h ./9fs/bitstring.h
-*** /usr/src/sys/9fs/bitstring.h	Wed Dec 31 19:00:00 1969
---- ./9fs/bitstring.h	Thu Oct 21 12:34:50 1999
-***************
-*** 0 ****
---- 1,143 ----
-+ /*
-+  * Copyright (c) 1989, 1993
-+  *	The Regents of the University of California.  All rights reserved.
-+  *
-+  * This code is derived from software contributed to Berkeley by
-+  * Paul Vixie.
-+  *
-+  * Redistribution and use in source and binary forms, with or without
-+  * modification, are permitted provided that the following conditions
-+  * are met:
-+  * 1. Redistributions of source code must retain the above copyright
-+  *    notice, this list of conditions and the following disclaimer.
-+  * 2. Redistributions in binary form must reproduce the above copyright
-+  *    notice, this list of conditions and the following disclaimer in the
-+  *    documentation and/or other materials provided with the distribution.
-+  * 3. All advertising materials mentioning features or use of this software
-+  *    must display the following acknowledgement:
-+  *	This product includes software developed by the University of
-+  *	California, Berkeley and its contributors.
-+  * 4. Neither the name of the University nor the names of its contributors
-+  *    may be used to endorse or promote products derived from this software
-+  *    without specific prior written permission.
-+  *
-+  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+  * SUCH DAMAGE.
-+  *
-+  *	@(#)bitstring.h	8.1 (Berkeley) 7/19/93
-+  */
-+ 
-+ #ifndef _BITSTRING_H_
-+ #define	_BITSTRING_H_
-+ 
-+ typedef	unsigned char bitstr_t;
-+ 
-+ /* internal macros */
-+ 				/* byte of the bitstring bit is in */
-+ #define	_bit_byte(bit) \
-+ 	((bit) >> 3)
-+ 
-+ 				/* mask for the bit within its byte */
-+ #define	_bit_mask(bit) \
-+ 	(1 << ((bit)&0x7))
-+ 
-+ /* external macros */
-+ 				/* bytes in a bitstring of nbits bits */
-+ #define	bitstr_size(nbits) \
-+ 	((((nbits) - 1) >> 3) + 1)
-+ 
-+ 				/* allocate a bitstring */
-+ #define	bit_alloc(space, nbits, type, flags) \
-+ 	MALLOC((space), bitstr_t *, \
-+         (u_int)bitstr_size(nbits)*sizeof(bitstr_t), (type), (flags))
-+ 
-+ 				/* allocate a bitstring on the stack */
-+ #define	bit_decl(name, nbits) \
-+ 	(name)[bitstr_size(nbits)]
-+ 
-+ 				/* is bit N of bitstring name set? */
-+ #define	bit_test(name, bit) \
-+ 	((name)[_bit_byte(bit)] & _bit_mask(bit))
-+ 
-+ 				/* set bit N of bitstring name */
-+ #define	bit_set(name, bit) \
-+ 	(name)[_bit_byte(bit)] |= _bit_mask(bit)
-+ 
-+ 				/* clear bit N of bitstring name */
-+ #define	bit_clear(name, bit) \
-+ 	(name)[_bit_byte(bit)] &= ~_bit_mask(bit)
-+ 
-+ 				/* clear bits start ... stop in bitstring */
-+ #define	bit_nclear(name, start, stop) { \
-+ 	register bitstr_t *_name = name; \
-+ 	register int _start = start, _stop = stop; \
-+ 	register int _startbyte = _bit_byte(_start); \
-+ 	register int _stopbyte = _bit_byte(_stop); \
-+ 	if (_startbyte == _stopbyte) { \
-+ 		_name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \
-+ 				      (0xff << ((_stop&0x7) + 1))); \
-+ 	} else { \
-+ 		_name[_startbyte] &= 0xff >> (8 - (_start&0x7)); \
-+ 		while (++_startbyte < _stopbyte) \
-+ 			_name[_startbyte] = 0; \
-+ 		_name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \
-+ 	} \
-+ }
-+ 
-+ 				/* set bits start ... stop in bitstring */
-+ #define	bit_nset(name, start, stop) { \
-+ 	register bitstr_t *_name = name; \
-+ 	register int _start = start, _stop = stop; \
-+ 	register int _startbyte = _bit_byte(_start); \
-+ 	register int _stopbyte = _bit_byte(_stop); \
-+ 	if (_startbyte == _stopbyte) { \
-+ 		_name[_startbyte] |= ((0xff << (_start&0x7)) & \
-+ 				    (0xff >> (7 - (_stop&0x7)))); \
-+ 	} else { \
-+ 		_name[_startbyte] |= 0xff << ((_start)&0x7); \
-+ 		while (++_startbyte < _stopbyte) \
-+ 	    		_name[_startbyte] = 0xff; \
-+ 		_name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \
-+ 	} \
-+ }
-+ 
-+ 				/* find first bit clear in name */
-+ #define	bit_ffc(name, nbits, value) { \
-+ 	register bitstr_t *_name = name; \
-+ 	register int _byte, _nbits = nbits; \
-+ 	register int _stopbyte = _bit_byte(_nbits), _value = -1; \
-+ 	for (_byte = 0; _byte <= _stopbyte; ++_byte) \
-+ 		if (_name[_byte] != 0xff) { \
-+ 			_value = _byte << 3; \
-+ 			for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \
-+ 			    ++_value, _stopbyte >>= 1); \
-+ 			break; \
-+ 		} \
-+ 	*(value) = _value; \
-+ }
-+ 
-+ 				/* find first bit set in name */
-+ #define	bit_ffs(name, nbits, value) { \
-+ 	register bitstr_t *_name = name; \
-+ 	register int _byte, _nbits = nbits; \
-+ 	register int _stopbyte = _bit_byte(_nbits), _value = -1; \
-+ 	for (_byte = 0; _byte <= _stopbyte; ++_byte) \
-+ 		if (_name[_byte]) { \
-+ 			_value = _byte << 3; \
-+ 			for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \
-+ 			    ++_value, _stopbyte >>= 1); \
-+ 			break; \
-+ 		} \
-+ 	*(value) = _value; \
-+ }
-+ 
-+ #endif /* !_BITSTRING_H_ */
-diff -N -c -r /usr/src/sys/conf/files ./conf/files
-*** /usr/src/sys/conf/files	Fri Apr 30 15:32:40 1999
---- ./conf/files	Thu Nov 25 15:34:34 1999
-***************
-*** 535,540 ****
---- 535,541 ----
-  netinet/tcp_timer.c	optional inet
-  netinet/tcp_usrreq.c	optional inet
-  netinet/udp_usrreq.c	optional inet
-+ netinet/il.c		optional  il
-  netipx/ipx.c		optional ipx
-  netipx/ipx_cksum.c	optional ipx
-  netipx/ipx_input.c	optional ipx
-***************
-*** 571,576 ****
---- 572,586 ----
-  nfs/nfs_syscalls.c	optional nfs
-  nfs/nfs_vfsops.c	optional nfs
-  nfs/nfs_vnops.c		optional nfs
-+ 9fs/9fs_vfsops.c	optional u9fs
-+ 9fs/9fs_vnops.c		optional u9fs
-+ 9fs/9p.c		optional u9fs
-+ 9fs/9auth.c		optional u9fs
-+ 9fs/9crypt.c		optional u9fs
-+ 9fs/9fs_subr.c		optional u9fs
-+ 9fs/9fs_socket.c	optional u9fs
-+ 9fs/9fs_bio.c		optional u9fs
-+ 9fs/9fs_node.c		optional u9fs
-  nfs/bootp_subr.c	optional bootp
-  nfs/krpc_subr.c		optional bootp
-  pccard/pccard.c		optional card
-diff -N -c -r /usr/src/sys/conf/options ./conf/options
-*** /usr/src/sys/conf/options	Tue May 11 01:35:28 1999
---- ./conf/options	Mon Oct 11 19:59:14 1999
-***************
-*** 202,207 ****
---- 202,208 ----
-  BRIDGE			opt_bdg.h
-  MROUTING		opt_mrouting.h
-  INET			opt_inet.h
-+ IL			opt_inet.h
-  IPDIVERT
-  DUMMYNET		opt_ipdn.h
-  IPFIREWALL		opt_ipfw.h
-***************
-*** 314,319 ****
---- 315,322 ----
-  NFS_MUIDHASHSIZ		opt_nfs.h
-  NFS_NOSERVER		opt_nfs.h
-  NFS_DEBUG		opt_nfs.h
-+ 
-+ U9FS
-  
-  # give bktr an opt_bktr.h file
-  OVERRIDE_CARD		opt_bktr.h
-diff -N -c -r /usr/src/sys/i386/conf/IL ./i386/conf/IL
-*** /usr/src/sys/i386/conf/IL	Wed Dec 31 19:00:00 1969
---- ./i386/conf/IL	Sat Oct 23 14:01:36 1999
-***************
-*** 0 ****
---- 1,234 ----
-+ #
-+ # GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
-+ #
-+ # For more information read the handbook part System Administration -> 
-+ # Configuring the FreeBSD Kernel -> The Configuration File. 
-+ # The handbook is available in /usr/share/doc/handbook or online as
-+ # latest version from the FreeBSD World Wide Web server 
-+ # <URL:http://www.FreeBSD.ORG/>
-+ #
-+ # An exhaustive list of options and more detailed explanations of the 
-+ # device lines is present in the ./LINT configuration file. If you are 
-+ # in doubt as to the purpose or necessity of a line, check first in LINT.
-+ #
-+ #	$Id: GENERIC,v 1.143.2.2 1999/02/15 02:50:07 des Exp $
-+ 
-+ machine		"i386"
-+ cpu		"I586_CPU"
-+ cpu		"I686_CPU"
-+ ident		GENERIC
-+ maxusers	128
-+ 
-+ #options		DDB
-+ options		IL			# plan9's IL
-+ options		"U9FS"			# plan9's 9fs client
-+ options		INET			#InterNETworking
-+ options		FFS			#Berkeley Fast Filesystem
-+ options		FFS_ROOT		#FFS usable as root device [keep this!]
-+ options		MFS			#Memory Filesystem
-+ options		MFS_ROOT		#MFS usable as root device, "MFS" req'ed
-+ options		NFS			#Network Filesystem
-+ options		NFS_ROOT		#NFS usable as root device, "NFS" req'ed
-+ options		"CD9660"		#ISO 9660 Filesystem
-+ options		"CD9660_ROOT"		#CD-ROM usable as root. "CD9660" req'ed
-+ options		PROCFS			#Process filesystem
-+ options         FDESC                   #File descriptor filesystem
-+ options		"COMPAT_43"		#Compatible with BSD 4.3 [KEEP THIS!]
-+ options		SCSI_DELAY=15000	#Be pessimistic about Joe SCSI device
-+ options		UCONSOLE		#Allow users to grab the console
-+ options		FAILSAFE		#Be conservative
-+ options		USERCONFIG		#boot -c editor
-+ options		VISUAL_USERCONFIG	#visual boot -c editor
-+ options		NMBCLUSTERS=4096
-+ options		MAXFILES=10000
-+ 
-+ config		kernel	root on wd0
-+ 
-+ # To make an SMP kernel, the next two are needed
-+ #options	SMP			# Symmetric MultiProcessor Kernel
-+ #options	APIC_IO			# Symmetric (APIC) I/O
-+ # Optionally these may need tweaked, (defaults shown):
-+ #options	NCPU=2			# number of CPUs
-+ #options	NBUS=4			# number of busses
-+ #options	NAPIC=1			# number of IO APICs
-+ #options	NINTR=24		# number of INTs
-+ 
-+ controller	isa0
-+ controller	eisa0
-+ controller	pci0
-+ 
-+ controller	fdc0	at isa? port "IO_FD1" bio irq 6 drq 2
-+ disk		fd0	at fdc0 drive 0
-+ disk		fd1	at fdc0 drive 1
-+ 
-+ options		"CMD640"	# work around CMD640 chip deficiency
-+ controller	wdc0	at isa? port "IO_WD1" bio irq 14 flags 0xa0ff vector wdintr
-+ disk		wd0	at wdc0 drive 0
-+ disk		wd1	at wdc0 drive 1
-+ 
-+ controller	wdc1	at isa? port "IO_WD2" bio irq 15 flags 0xa0ff vector wdintr
-+ disk		wd2	at wdc1 drive 0
-+ disk		wd3	at wdc1 drive 1
-+ 
-+ options		ATAPI		#Enable ATAPI support for IDE bus
-+ options		ATAPI_STATIC	#Don't do it as an LKM
-+ #device		acd0		#IDE CD-ROM
-+ #device		wfd0		#IDE Floppy (e.g. LS-120)
-+ 
-+ # A single entry for any of these controllers (ncr, ahb, ahc) is
-+ # sufficient for any number of installed devices.
-+ #controller	ncr0
-+ #controller	ahb0
-+ #controller	ahc0
-+ #controller	isp0
-+ 
-+ # This controller offers a number of configuration options, too many to
-+ # document here  - see the LINT file in this directory and look up the
-+ # dpt0 entry there for much fuller documentation on this.
-+ controller      dpt0
-+ 
-+ #controller	adv0	at isa? port ? cam irq ?
-+ #controller	adw0
-+ #controller	bt0	at isa? port ? cam irq ?
-+ #controller	aha0	at isa? port ? cam irq ?
-+ #controller	aic0	at isa? port 0x340 bio irq 11
-+ 
-+ controller	scbus0
-+ 
-+ device		da0
-+ 
-+ device		sa0
-+ 
-+ device		pass0
-+ 
-+ device		cd0	#Only need one of these, the code dynamically grows
-+ 
-+ #device		wt0	at isa? port 0x300 bio irq 5 drq 1
-+ #device		mcd0	at isa? port 0x300 bio irq 10
-+ 
-+ #controller	matcd0	at isa? port 0x230 bio
-+ 
-+ #device		scd0	at isa? port 0x230 bio
-+ 
-+ # atkbdc0 controlls both the keyboard and the PS/2 mouse
-+ controller	atkbdc0	at isa? port IO_KBD tty
-+ device		atkbd0	at isa? tty irq 1
-+ device		psm0	at isa? tty irq 12
-+ 
-+ device		vga0	at isa? port ? conflicts
-+ 
-+ # splash screen/screen saver
-+ pseudo-device	splash
-+ 
-+ # syscons is the default console driver, resembling an SCO console
-+ device		sc0	at isa? tty
-+ # Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver
-+ #device		vt0	at isa? tty
-+ #options		XSERVER			# support for X server
-+ #options		FAT_CURSOR		# start with block cursor
-+ # If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines
-+ #options		PCVT_SCANSET=2		# IBM keyboards are non-std
-+ 
-+ device		npx0	at isa? port IO_NPX irq 13
-+ 
-+ #
-+ # Laptop support (see LINT for more options)
-+ #
-+ device		apm0    at isa?	disable	flags 0x31 # Advanced Power Management
-+ 
-+ # PCCARD (PCMCIA) support
-+ #controller	card0
-+ #device		pcic0	at card?
-+ #device		pcic1	at card?
-+ 
-+ device		sio0	at isa? port "IO_COM1" flags 0x10 tty irq 4
-+ device		sio1	at isa? port "IO_COM2" tty irq 3
-+ device		sio2	at isa? disable port "IO_COM3" tty irq 5
-+ device		sio3	at isa? disable port "IO_COM4" tty irq 9
-+ 
-+ # Parallel port
-+ device		ppc0	at isa? port? net irq 7
-+ controller	ppbus0
-+ device		nlpt0	at ppbus?
-+ device		plip0	at ppbus?
-+ device		ppi0	at ppbus?
-+ #controller	vpo0	at ppbus?
-+ 
-+ #
-+ # The following Ethernet NICs are all PCI devices.
-+ #
-+ device ax0		# ASIX AX88140A
-+ device de0		# DEC/Intel DC21x4x (``Tulip'')
-+ device fxp0		# Intel EtherExpress PRO/100B (82557, 82558)
-+ device mx0		# Macronix 98713/98715/98725 (``PMAC'')
-+ device pn0		# Lite-On 82c168/82c169 (``PNIC'')
-+ device rl0		# RealTek 8129/8139
-+ device tl0		# Texas Instruments ThunderLAN
-+ device tx0		# SMC 9432TX (83c170 ``EPIC'')
-+ device vr0		# VIA Rhine, Rhine II
-+ device vx0		# 3Com 3c590, 3c595 (``Vortex'')
-+ device wb0		# Winbond W89C840F
-+ device xl0		# 3Com 3c90x (``Boomerang'', ``Cyclone'')
-+ 
-+ # Order is important here due to intrusive probes, do *not* alphabetize
-+ # this list of network interfaces until the probes have been fixed.
-+ # Right now it appears that the ie0 must be probed before ep0. See
-+ # revision 1.20 of this file.
-+ 
-+ #device ed0 at isa? port 0x280 net irq 10 iomem 0xd8000
-+ #device ie0 at isa? port 0x300 net irq 10 iomem 0xd0000
-+ #device ep0 at isa? port 0x300 net irq 10
-+ #device ex0 at isa? port? net irq?
-+ #device fe0 at isa? port 0x300 net irq ?
-+ #device le0 at isa? port 0x300 net irq 5 iomem 0xd0000
-+ #device lnc0 at isa? port 0x280 net irq 10 drq 0
-+ #device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
-+ #device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
-+ #device cs0 at isa? port 0x300 net irq ?
-+ 
-+ pseudo-device	loop
-+ pseudo-device	ether
-+ pseudo-device	sl	1
-+ pseudo-device	ppp	1
-+ pseudo-device	tun	1
-+ pseudo-device	pty	32
-+ pseudo-device	gzip		# Exec gzipped a.out's
-+ 
-+ # KTRACE enables the system-call tracing facility ktrace(2).
-+ # This adds 4 KB bloat to your kernel, and slightly increases
-+ # the costs of each syscall.
-+ options		KTRACE		#kernel tracing
-+ 
-+ # This provides support for System V shared memory and message queues.
-+ #
-+ options		SYSVSHM
-+ options		SYSVMSG
-+ 
-+ #  The `bpfilter' pseudo-device enables the Berkeley Packet Filter.  Be
-+ #  aware of the legal and administrative consequences of enabling this
-+ #  option.  The number of devices determines the maximum number of
-+ #  simultaneous BPF clients programs runnable.
-+ pseudo-device	bpfilter 4	#Berkeley packet filter
-+ 
-+ 
-+ # USB support
-+ #controller    uhci0
-+ #controller    ohci0
-+ #controller    usb0
-+ #
-+ # for the moment we have to specify the priorities of the device
-+ # drivers explicitly by the ordering in the list below. This will
-+ # be changed in the future.
-+ #
-+ #device        ums0
-+ #device        ukbd0
-+ #device        ulpt0
-+ #device        uhub0
-+ #device        ucom0
-+ #device        umodem0
-+ #device        hid0
-+ #device        ugen0
-+ 
-+ #
-+ #options       USB_DEBUG
-+ #options       USBVERBOSE
-diff -N -c -r /usr/src/sys/netinet/il.c ./netinet/il.c
-*** /usr/src/sys/netinet/il.c	Wed Dec 31 19:00:00 1969
---- ./netinet/il.c	Tue Nov 23 19:16:13 1999
-***************
-*** 0 ****
---- 1,1147 ----
-+ #include <unistd.h>
-+ #include <ctype.h>
-+ #include <sys/types.h>
-+ #include <sys/param.h>
-+ #include <sys/time.h>
-+ #include <sys/systm.h>
-+ #include <vm/vm_zone.h>
-+ 
-+ #include <sys/malloc.h>
-+ #include <machine/param.h>
-+ #include <sys/mbuf.h>
-+ #include <sys/protosw.h>
-+ #include <sys/socket.h>
-+ #include <sys/socketvar.h>
-+ #include <sys/proc.h>
-+ #include <net/if.h>
-+ #include <net/route.h>
-+ #include <netinet/in_systm.h>
-+ #include <netinet/in.h>
-+ #include <netinet/in_var.h>
-+ #include <netinet/if_ether.h>
-+ #include <netinet/ip.h>
-+ #include <netinet/ip_var.h>
-+ #include <netinet/in_pcb.h>
-+ #include <errno.h>
-+ 
-+ #include <netinet/il.h>
-+ #include <netinet/il_var.h>
-+ 
-+ struct ilpcb * il_drop(struct ilpcb *ilpcb, int errno0);
-+ static struct ilpcb * il_close(struct ilpcb *ilpcb);
-+ 
-+ /* kernel protocol states needed */
-+ static struct inpcbhead ilb;
-+ static struct inpcbinfo ilbinfo;
-+ 
-+ u_long il_sendspace = 1024*64;
-+ u_long il_recvspace = 1024*64;
-+ 
-+ /*
-+  * Target size of IL PCB hash tables. Must be a power of two.
-+  *
-+  * Note that this can be overridden by the kernel environment
-+  * variable net.inet.tcp.tcbhashsize
-+  */
-+ #ifndef ILBHASHSIZE
-+ #define ILBHASHSIZE	512
-+ #endif
-+ 
-+ enum				/* Connection state */
-+ {
-+ 	ILS_CLOSED,
-+ 	ILS_SYNCER,
-+ 	ILS_SYNCEE,
-+ 	ILS_ESTABLISHED,
-+ 	ILS_LISTENING,
-+ 	ILS_CLOSING,
-+ 	ILS_OPENING,		/* only for file server */
-+ };
-+ 
-+ char	*ilstates[] = 
-+ { 
-+ 	"Closed",
-+ 	"Syncer",
-+ 	"Syncee",
-+ 	"Established",
-+ 	"Listening",
-+ 	"Closing",
-+ 	"Opening",		/* only for file server */
-+ };
-+ 
-+ enum				/* Packet types */
-+ {
-+ 	ILT_SYNC,
-+ 	ILT_DATA,
-+ 	ILT_DATAQUERY,
-+ 	ILT_ACK,
-+ 	ILT_QUERY,
-+ 	ILT_STATE,
-+ 	ILT_CLOSE
-+ };
-+ 
-+ char	*iltype[] = 
-+ {	
-+ 	"sync",
-+ 	"data",
-+ 	"dataquery",
-+ 	"ack",
-+ 	"query",
-+ 	"state",
-+ 	"close",
-+ };
-+ 
-+ /*
-+  * This is the actual shape of what we allocate using the zone
-+  * allocator.  Doing it this way allows us to protect both structures
-+  * using the same generation count, and also eliminates the overhead
-+  * of allocating tcpcbs separately.  By hiding the structure here,
-+  * we avoid changing most of the rest of the code (although it needs
-+  * to be changed, eventually, for greater efficiency).
-+  */
-+ #define	ALIGNMENT	32
-+ #define	ALIGNM1		(ALIGNMENT - 1)
-+ struct	inp_ilpcb {
-+ 	union {
-+ 		struct	inpcb inp;
-+ 		char	align[(sizeof(struct inpcb) + ALIGNM1) & ~ALIGNM1];
-+ 	} inp_tp_u;
-+ 	struct	ilpcb ilpcb;
-+ };
-+ #undef ALIGNMENT
-+ #undef ALIGNM1
-+ 
-+ static __inline struct mbuf * il_segq_top(struct ilpcb * ilpcb)
-+ {
-+   return (ilpcb->segq);
-+ }
-+ 
-+ static __inline void il_segq_dequeue(struct ilpcb * ilpcb)
-+ {
-+   struct mbuf * m = ilpcb->segq;
-+   ilpcb->segq = m->m_nextpkt;
-+   m->m_nextpkt = 0;
-+ }
-+ 
-+ static __inline void il_segq_insert(struct ilpcb * ilpcb, struct mbuf * m, u_long seq, struct ilhdr * il)
-+ {
-+   u_long pseq;
-+   struct mbuf * mp, * mq;
-+ 
-+   m->m_pkthdr.header = il;
-+ 
-+   mp = 0;
-+   mq = ilpcb->segq;
-+   while ( mq ) {
-+     il = mq->m_pkthdr.header;
-+     pseq = ntohl(*(u_long *)il->ilid);
-+     if( pseq > seq )
-+       break;
-+     if( pseq == seq ) { /* we already got this packet */
-+       m_freem(m);
-+       return;
-+     }
-+     mp = mq;
-+     mq = mq->m_nextpkt;
-+   }
-+ 
-+   if( mp == 0 ) {
-+     m->m_nextpkt = ilpcb->segq;
-+     ilpcb->segq = m;
-+     return;
-+   }
-+   mp->m_nextpkt = m;
-+   m->m_nextpkt = mq;
-+ }
-+ 
-+ void il_init()
-+ {  
-+   LIST_INIT(&ilb);
-+   ilbinfo.listhead = &ilb;
-+   ilbinfo.hashbase = hashinit(ILBHASHSIZE, M_PCB, &ilbinfo.hashmask);
-+   ilbinfo.porthashbase = hashinit(ILBHASHSIZE, M_PCB,
-+ 				  &ilbinfo.porthashmask);
-+   ilbinfo.ipi_zone = zinit("ilpcb", sizeof(struct inp_ilpcb), maxsockets,
-+ 			   ZONE_INTERRUPT, 0);
-+ }
-+ 
-+ /* fill in il header and cksum, ip src/dst addresses */
-+ static int il_output(struct ilpcb * ilpcb, struct mbuf *m, int type, u_long seq, u_char spec)
-+ {
-+   struct ilhdr * il;
-+   struct ip * ip;
-+   int illen;
-+   struct inpcb * inp;
-+   struct socket * so;
-+ 
-+   /* XXX: check total size is less than IP_MAXPACKET */
-+ 
-+   if( m == 0 ) {
-+     inp = ilpcb->inpcb;
-+     so = inp->inp_socket;
-+     m = m_copypacket(so->so_snd.sb_mb, M_DONTWAIT);
-+   } 
-+ 
-+   /*
-+    * Calculate data length and get a mbuf
-+    * for IL and IP headers.
-+    */
-+   illen = m->m_pkthdr.len; /* size of il payload */
-+   M_PREPEND(m, sizeof(struct ip) + sizeof(struct ilhdr), M_DONTWAIT);
-+   if( m == 0 )
-+     return ENOBUFS;
-+ 
-+   ip = mtod(m, struct ip *);
-+   il = (struct ilhdr *) (ip+1);
-+   bzero(ip, sizeof(*ip));
-+ 
-+   ip->ip_p = IPPROTO_IL;
-+   ip->ip_src = ilpcb->inpcb->inp_laddr;
-+   ip->ip_dst = ilpcb->inpcb->inp_faddr;
-+   ip->ip_len = m->m_pkthdr.len;
-+   ip->ip_ttl = ilpcb->inpcb->inp_ip_ttl;	/* XXX */
-+   ip->ip_tos = ilpcb->inpcb->inp_ip_tos;	/* XXX */
-+ 
-+   *(u_short *)il->illen = htons(illen + sizeof(struct ilhdr));
-+   il->iltype = type;
-+   il->ilspec = spec;
-+   *(u_short *)il->ilsrc = ilpcb->inpcb->inp_lport;
-+   *(u_short *)il->ildst = ilpcb->inpcb->inp_fport;
-+   if ( type != ILT_SYNC )
-+     *(u_long *)il->ilid = htonl(seq);
-+   else
-+     *(u_long *)il->ilid = htonl(ilpcb->start);
-+ 
-+   if( type != ILT_ACK && type != ILT_STATE) {
-+     if( ilpcb->rxt_timer == 0 )
-+       ilpcb->rxt_timer = ilpcb->rxt_timer_cur;
-+     if( ilpcb->death_timer == 0 )
-+       ilpcb->death_timer = ilpcb->death_timer_cur;
-+   }
-+ 
-+   *(u_long *)il->ilack = htonl(ilpcb->recvd);
-+   il->ilsum[0] = il->ilsum[1] = 0;
-+ 
-+   /* IL checksum does not cover IP header */
-+   m->m_data += sizeof(struct ip);
-+   m->m_len  -= sizeof(struct ip);
-+   *(u_short *)il->ilsum = in_cksum(m, illen + sizeof(struct ilhdr));
-+   m->m_data -= sizeof(struct ip);
-+   m->m_len  += sizeof(struct ip);
-+ 
-+   return ip_output(m, ilpcb->inpcb->inp_options, &ilpcb->inpcb->inp_route, 
-+ 		   ilpcb->inpcb->inp_socket->so_options & SO_DONTROUTE ,0);
-+ }
-+ 
-+ static int il_send_empty(struct ilpcb * ilpcb, int type, u_char spec)
-+ {
-+   struct mbuf * m0;
-+ 
-+   MGETHDR(m0, M_DONTWAIT, MT_DATA);
-+   m0->m_len = 0;
-+   m0->m_pkthdr.len = 0;
-+   MH_ALIGN(m0, 0); /* leave space for the packet header */
-+ 
-+   return il_output(ilpcb, m0, type, ilpcb->next, spec);
-+ }
-+ 
-+ static int il_respond(struct ilpcb * ilpcb, struct ip * ip, struct ilhdr *il, int type, u_char spec)
-+ {
-+   struct mbuf * m;
-+   int illen;
-+   struct ip * ip0;
-+   struct ilhdr *il0;
-+   struct route * ro;
-+   struct route sro;
-+ 
-+   if( ilpcb ) {
-+     ro = & ilpcb->inpcb->inp_route;
-+   } else {
-+     ro = &sro;
-+     bzero(ro, sizeof *ro);
-+   }
-+ 	      
-+   MGETHDR(m, M_DONTWAIT, MT_DATA);
-+   m->m_len = 0;
-+   m->m_pkthdr.len = 0;
-+   MH_ALIGN(m, 0); /* leave space for the packet header */
-+   illen = m->m_pkthdr.len; /* size of il payload */
-+   M_PREPEND(m, sizeof(struct ip) + sizeof(struct ilhdr), M_DONTWAIT);
-+   if( m == 0 )
-+     return ENOBUFS;
-+ 
-+   ip0 = mtod(m, struct ip *);
-+   il0 = (struct ilhdr *) (ip0+1);
-+   bzero(ip0, sizeof(*ip0));
-+ 
-+   ip0->ip_p = IPPROTO_IL;
-+   ip0->ip_src = ip->ip_dst;
-+   ip0->ip_dst = ip->ip_src;
-+   ip0->ip_ttl = ip_defttl;
-+   ip0->ip_len = sizeof(struct ip) + sizeof(struct ilhdr);
-+   *(u_short *)il0->illen = htons(illen + sizeof(struct ilhdr));
-+   il0->iltype = type;
-+   il0->ilspec = spec;
-+   bcopy(il->ilsrc, il0->ildst, 2);
-+   bcopy(il->ildst, il0->ilsrc, 2);
-+   *(u_long *)il0->ilid = 0;
-+   bcopy(il->ilid, il0->ilack, 4);
-+   il0->ilsum[0] = il0->ilsum[1] = 0;
-+ 
-+   /* IL checksum does not cover IP header */
-+   m->m_data += sizeof(struct ip);
-+   m->m_len  -= sizeof(struct ip);
-+   *(u_short *)il0->ilsum = in_cksum(m, illen + sizeof(struct ilhdr));
-+   m->m_data -= sizeof(struct ip);
-+   m->m_len  += sizeof(struct ip);
-+ 
-+   return ip_output(m, 0, ro, 0 ,0);
-+ }
-+ 
-+ static struct ilpcb *
-+ il_newconn(struct ilpcb * ilpcb, struct in_addr ti_dst, u_short ti_dport,
-+ 	   struct in_addr ti_src, u_short ti_sport)
-+ {
-+   register struct ilpcb * ilpcb0;
-+   struct socket *so2, * so;
-+   struct inpcb * inp;
-+   struct sockaddr_in sin;
-+ 
-+   so = ilpcb->inpcb->inp_socket;
-+   so2 = sonewconn(so, 0);
-+   if (so2 == 0) {
-+     so2 = sodropablereq(so);
-+     if (so2) {
-+       il_drop(sotoilpcb(so2), ETIMEDOUT);
-+       so2 = sonewconn(so, 0);
-+     }
-+     if (!so2)
-+       return 0;
-+   }
-+   so = so2;
-+ 
-+   inp = (struct inpcb *)so->so_pcb;
-+   inp->inp_laddr = ti_dst;
-+   inp->inp_lport = ti_dport;
-+   if (in_pcbinshash(inp) != 0) {
-+ 				/*
-+ 				 * Undo the assignments above if we failed to put
-+ 				 * the PCB on the hash lists.
-+ 				 */
-+     inp->inp_laddr.s_addr = INADDR_ANY;
-+     inp->inp_lport = 0;
-+ 
-+     soabort(so);
-+     return 0;
-+   }
-+ 
-+   bzero((char *)&sin, sizeof(sin));
-+   sin.sin_family = AF_INET;
-+   sin.sin_len = sizeof(sin);
-+   sin.sin_addr = ti_src;
-+   sin.sin_port = ti_sport;
-+   if (in_pcbconnect(inp, (struct sockaddr *)&sin, &proc0)) {
-+     inp->inp_laddr.s_addr = INADDR_ANY;
-+     soabort(so);
-+     return 0;
-+   }
-+ 
-+   ilpcb0 = intoilpcb(inp);
-+   ilpcb0->state = ILS_LISTENING;
-+ 
-+   return ilpcb0;
-+ }
-+ 
-+ /* ack processing */
-+ static void il_proc_ack(struct ilpcb * ilpcb, struct socket * so, u_long ack)
-+ {
-+   if( ack >= ilpcb->unacked ) {
-+     ilpcb->rxt_timer = 0;
-+     ilpcb->death_timer = 0;
-+ 
-+     /* the rxt timer is not prop. to RTT */
-+     /* reset it so that the first rxt is always 1 second */
-+     ilpcb->rxt_timer_cur = 2;
-+ 
-+     if( ack >= ilpcb->next )
-+       ack = ilpcb->next - 1;
-+     while (ilpcb->unacked <= ack ) {
-+       sbdroprecord(&so->so_snd);
-+       ilpcb->unacked++;
-+     }
-+     if( ilpcb->unacked != ilpcb->next ) {
-+       ilpcb->rxt_timer = ilpcb->rxt_timer_cur;
-+       ilpcb->death_timer = ilpcb->death_timer_cur; /* do we need this here? */
-+     }
-+     sowwakeup(so);
-+   }
-+ }
-+ 
-+ static int il_proc_data(struct ilpcb * ilpcb, struct socket * so, struct mbuf * m, u_long seq, int spec)
-+ {
-+   struct mbuf * m0;
-+   struct ip * ip;
-+   int hlen = sizeof(struct ip) + sizeof(struct ilhdr);
-+   struct ilhdr * il;
-+   int needack = 0;
-+ 
-+   ip = mtod(m, struct ip *);
-+   il = (struct ilhdr *)(ip+1);
-+   if( seq == ilpcb->recvd + 1 ) {
-+     needack = 1;
-+     while(1) {
-+       ilpcb->recvd = seq;
-+       
-+       m->m_len -= hlen;
-+       m->m_pkthdr.len -= hlen;
-+       m->m_data += hlen;
-+       sbappendrecord(&so->so_rcv, m);
-+ 
-+       if( (m0 = il_segq_top(ilpcb)) == 0 )
-+ 	break;
-+       ip = mtod(m0, struct ip *);
-+       il = (struct ilhdr *)(ip+1);
-+       seq = ntohl(*(u_long *)il->ilid);
-+       if( seq != ilpcb->recvd + 1 )
-+ 	break;
-+       il_segq_dequeue(ilpcb);
-+       m = m0;
-+     };      
-+     sorwakeup(so);
-+   } else {
-+     if( seq > ilpcb->recvd ) 
-+       il_segq_insert(ilpcb, m, seq, il);
-+     else
-+       m_freem(m);
-+   }
-+ 
-+   return needack;
-+ }
-+ 
-+ /* assume we only have one connection */
-+ void il_input(struct mbuf * m, int iphlen)
-+ {
-+   struct ilhdr * il;
-+   struct ilpcb * ilpcb = 0;
-+   int len, type;
-+   u_long seq, ack;
-+   struct ip * ip;
-+   struct inpcb * inp;
-+   u_short sport, dport;
-+   struct socket * so;
-+   u_char spec;
-+ 
-+   /*
-+    * Strip IP options, if any; should skip this,
-+    * make available to user, and use on returned packets,
-+    * but we don't yet have a way to check the checksum
-+    * with options still present.
-+    */
-+   if (iphlen > sizeof (struct ip)) {
-+     ip_stripoptions(m, (struct mbuf *)0);
-+     iphlen = sizeof(struct ip);
-+   }
-+ 
-+   /*
-+    * Get IP and IL header together in first mbuf.
-+    */
-+   ip = mtod(m, struct ip *);
-+   if (m->m_len < iphlen + sizeof(struct ilhdr)) {
-+     if ((m = m_pullup(m, iphlen + sizeof(struct ilhdr))) == 0) {
-+       return;
-+     }
-+     ip = mtod(m, struct ip *);
-+   }
-+   il = (struct ilhdr *)((caddr_t)ip + iphlen);
-+ 
-+   len = ntohs(*(u_short *)il->illen);
-+   seq = ntohl(*(u_long *)il->ilid);
-+   ack = ntohl(*(u_long *)il->ilack);
-+   sport = *(u_short *)il->ilsrc;
-+   dport = *(u_short *)il->ildst;  
-+   type = il->iltype;
-+   spec = il->ilspec;
-+ 
-+   inp = in_pcblookup_hash(&ilbinfo, ip->ip_src, sport, ip->ip_dst, dport, 1);
-+   if ( inp == 0 && type == ILT_SYNC )
-+     goto dropwithrest;
-+   if( inp == 0 )
-+     goto drop;
-+ 
-+   ilpcb = intoilpcb(inp);
-+   if( ilpcb == 0 )
-+     goto drop;
-+ 
-+   so = inp->inp_socket;
-+   if( type == ILT_QUERY ) { /* XXX: can we use the same mbuf to send? */
-+     il_send_empty(ilpcb, ILT_STATE, il->ilspec);
-+     goto drop;
-+   }  
-+ 
-+  again:
-+   /* FSM transition */
-+   switch( ilpcb->state ) {
-+   case ILS_SYNCER:
-+     if( ack != ilpcb->start )
-+       goto drop;
-+     switch( type ) {
-+     case ILT_SYNC:
-+       ilpcb->unacked++;
-+       ilpcb->recvd = seq;
-+       il_send_empty(ilpcb, ILT_ACK, 0);
-+       ilpcb->state = ILS_ESTABLISHED;
-+       ilpcb->rxt_timer = 0;
-+       ilpcb->death_timer = 0;
-+       soisconnected(inp->inp_socket);
-+       break;
-+     case ILT_CLOSE:
-+       il_drop(ilpcb, ECONNREFUSED);
-+       break;
-+     }
-+     break;
-+ 
-+   case ILS_LISTENING:
-+     if( type == ILT_SYNC && ack == 0 && so->so_options & SO_ACCEPTCONN ) {
-+       ilpcb = il_newconn(ilpcb, ip->ip_dst, dport, ip->ip_src, sport);
-+ 
-+       ilpcb->next = ilpcb->start = random();
-+       ilpcb->unacked = ilpcb->next;
-+       ilpcb->rstart = ilpcb->recvd = seq;
-+       ilpcb->state = ILS_SYNCEE;
-+       il_send_empty(ilpcb, ILT_SYNC, 0);
-+       ilpcb->next++;
-+     } else
-+       il_respond(ilpcb, ip, il, ILT_CLOSE, 0);
-+     break;
-+ 
-+   case ILS_SYNCEE:
-+     if( ack == ilpcb->start ) {      
-+       ilpcb->rxt_timer = 0;
-+       ilpcb->unacked++;
-+       ilpcb->state = ILS_ESTABLISHED;
-+       soisconnected(so);
-+       goto again;
-+       break;
-+     }
-+     if( type == ILT_SYNC && seq == ilpcb->recvd && ack == 0 )
-+       il_send_empty(ilpcb, ILT_SYNC, 0);
-+     break;
-+ 
-+   case ILS_ESTABLISHED:
-+     il_proc_ack(ilpcb, so, ack);
-+     switch( type ) {
-+     case ILT_DATA:
-+       if( il_proc_data(ilpcb, so, m, seq, spec) ) 
-+ 	ilpcb->flags |= ILF_NEEDACK;
-+       goto done;
-+       break;
-+     case ILT_DATAQUERY:
-+       il_proc_data(ilpcb, so, m, seq, spec);
-+       il_send_empty(ilpcb, ILT_STATE, spec);
-+       goto done;
-+       break;
-+     case ILT_CLOSE:
-+       if( ack < ilpcb->next && ack >= ilpcb->start ) {
-+ 	if( ilpcb->recvd+1 == seq )
-+ 	  ilpcb->recvd = seq;
-+ 	il_send_empty(ilpcb, ILT_CLOSE, 0);
-+ 	ilpcb->state = ILS_CLOSING;
-+       }
-+       break;
-+     case ILT_STATE:
-+       if( ack < ilpcb->rxt_max ) {
-+ 	ilpcb->rxt_max = ilpcb->next;
-+ 	il_output(ilpcb, 0, ILT_DATAQUERY, ilpcb->unacked, 1);
-+       }
-+       break;
-+     case ILT_SYNC:
-+       il_send_empty(ilpcb, ILT_ACK, 0);
-+       break;
-+     }
-+     break;
-+ 
-+   case	ILS_CLOSED:
-+     goto drop;
-+     break;
-+ 
-+   case ILS_CLOSING:
-+     if( type == ILT_CLOSE ) {
-+       if( ilpcb->recvd+1 == seq )
-+ 	ilpcb->recvd = seq;
-+       il_send_empty(ilpcb, ILT_CLOSE, 0);
-+       ilpcb->state = ILS_CLOSED;
-+       il_close(ilpcb);
-+     }
-+     break;
-+   }
-+ 
-+   m_freem(m);
-+  done:
-+   return;
-+ 
-+  dropwithrest:
-+   il_respond(ilpcb, ip, il, ILT_CLOSE, 0);
-+  drop:
-+   m_freem(m);
-+ }
-+ 
-+ static void il_sendseqinit(struct ilpcb * ilpcb)
-+ {
-+   ilpcb->start = ilpcb->next = random();
-+   ilpcb->unacked = ilpcb->next;
-+   ilpcb->state = ILS_SYNCER;
-+   ilpcb->next++;
-+ }
-+ 
-+ static void il_rxt_timeout(struct ilpcb * ilpcb)
-+ {
-+   switch ( ilpcb->state ) {
-+   case ILS_ESTABLISHED:
-+     il_output(ilpcb, 0, ILT_DATAQUERY, ilpcb->unacked, 1);
-+     ilpcb->rxtot++;
-+     break;
-+   case ILS_SYNCER:
-+   case ILS_SYNCEE:
-+     il_send_empty(ilpcb, ILT_SYNC, 0);
-+     break;
-+   case ILS_CLOSING:
-+     il_send_empty(ilpcb, ILT_CLOSE, 0);
-+     break;
-+   }
-+   ilpcb->rxt_timer = ilpcb->rxt_timer_cur;
-+ }
-+ 
-+ void il_ctlinput(int cmd, struct sockaddr *sa, void *vip)
-+ {}
-+ 
-+ int  il_ctloutput(struct socket *so, struct sockopt *sopt)
-+ { return 0; }
-+ 
-+ void il_drain()
-+ {}
-+ 
-+ void il_slowtimo()
-+ {
-+   struct ilpcb * ilpcb;
-+   struct inpcb * inp;
-+   int s;
-+ 
-+   s = splnet();
-+   for(inp = ilb.lh_first; inp; inp = inp->inp_list.le_next) {
-+     ilpcb = intoilpcb(inp);
-+     if(ilpcb->death_timer &&  --ilpcb->death_timer == 0 )
-+       il_drop(ilpcb, ETIMEDOUT);
-+     
-+     if(ilpcb->rxt_timer &&  --ilpcb->rxt_timer == 0 ) {
-+       ilpcb->rxt_timer_cur <<= 1;
-+       il_rxt_timeout(ilpcb);
-+     }
-+   }
-+   splx(s);
-+ }
-+ 
-+ void il_fasttimo()
-+ {
-+   struct ilpcb * ilpcb;
-+   struct inpcb * inp;
-+   int s;
-+ 
-+   s = splnet();
-+   for(inp = ilb.lh_first; inp; inp = inp->inp_list.le_next) {
-+     ilpcb = intoilpcb(inp);
-+     if(ilpcb->flags & ILF_NEEDACK) {
-+       ilpcb->flags &= ~ILF_NEEDACK;
-+       il_send_empty(ilpcb, ILT_ACK, 0);
-+     }
-+   }
-+   splx(s);
-+ }
-+ 
-+ static struct ilpcb * il_newilpcb(struct inpcb * inp)
-+ {
-+   struct inp_ilpcb *it;
-+   register struct ilpcb *ilpcb;
-+   
-+   it = (struct inp_ilpcb *)inp;
-+   ilpcb = &it->ilpcb;
-+   bzero((char *) ilpcb, sizeof(struct ilpcb));
-+   
-+   ilpcb->state = ILS_CLOSED;
-+   ilpcb->inpcb = inp;
-+   ilpcb->rxt_timer_cur = 2;
-+   ilpcb->death_timer_cur = 20;
-+   
-+   ilpcb->inpcb = inp;	/* XXX */
-+   inp->inp_ip_ttl = ip_defttl;
-+   inp->inp_ppcb = (caddr_t)ilpcb;
-+   return (ilpcb);		/* XXX */
-+ }
-+ 
-+ /*
-+  * Common subroutine to open a TCP connection to remote host specified
-+  * by struct sockaddr_in in mbuf *nam.  Call in_pcbbind to assign a local
-+  * port number if needed.  Call in_pcbladdr to do the routing and to choose
-+  * a local host address (interface).  If there is an existing incarnation
-+  * of the same connection in TIME-WAIT state and if the remote host was
-+  * sending CC options and if the connection duration was < MSL, then
-+  * truncate the previous TIME-WAIT state and proceed.
-+  * Initialize connection parameters and enter SYN-SENT state.
-+  */
-+ static int
-+ il_connect(struct ilpcb *ilpcb, struct sockaddr *nam, struct proc *p)
-+ {
-+ 	struct inpcb *inp = ilpcb->inpcb, *oinp;
-+ 	struct socket *so = inp->inp_socket;
-+ 	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
-+ 	struct sockaddr_in *ifaddr;
-+ 	int error;
-+ 
-+ 	if (inp->inp_lport == 0) {
-+ 		error = in_pcbbind(inp, (struct sockaddr *)0, p);
-+ 		if (error)
-+ 			return error;
-+ 	}
-+ 
-+ 	/*
-+ 	 * Cannot simply call in_pcbconnect, because there might be an
-+ 	 * earlier incarnation of this same connection still in
-+ 	 * TIME_WAIT state, creating an ADDRINUSE error.
-+ 	 */
-+ 	error = in_pcbladdr(inp, nam, &ifaddr);
-+ 	if (error)
-+ 		return error;
-+ 	oinp = in_pcblookup_hash(inp->inp_pcbinfo,
-+ 	    sin->sin_addr, sin->sin_port,
-+ 	    inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr
-+ 						: ifaddr->sin_addr,
-+ 	    inp->inp_lport,  0);
-+ 	if (oinp) {
-+ 			return EADDRINUSE;
-+ 	}
-+ 	if (inp->inp_laddr.s_addr == INADDR_ANY)
-+ 		inp->inp_laddr = ifaddr->sin_addr;
-+ 	inp->inp_faddr = sin->sin_addr;
-+ 	inp->inp_fport = sin->sin_port;
-+ 	in_pcbrehash(inp);
-+ 
-+ #if 0
-+ 	ilpcb->t_template = tcp_template(tp);
-+ 	if (ilpcb->t_template == 0) {
-+ 		in_pcbdisconnect(inp);
-+ 		return ENOBUFS;
-+ 	}
-+ #endif
-+ 
-+ 	soisconnecting(so);
-+ 	il_sendseqinit(ilpcb);
-+ 
-+ 	return 0;
-+ }
-+ 
-+ static int il_usr_send(struct socket *so, int flags, struct mbuf * m, struct sockaddr *addr, struct mbuf *control, struct proc *p)
-+ {
-+   struct ilpcb * ilpcb;
-+   struct inpcb * inp = sotoinpcb(so);
-+   int error;
-+   struct mbuf * m0;
-+ 
-+   if (inp == 0) {
-+     m_freem(m);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+ 
-+   if (sbspace(&so->so_snd) < -512) {
-+     m_freem(m);
-+     error = ENOBUFS;
-+     goto out;
-+   }
-+ 
-+   sbappendrecord(&so->so_snd, m);
-+   m0 = m_copypacket(m, M_DONTWAIT);
-+   error = il_output(ilpcb, m0, ILT_DATA, ilpcb->next++, 0); 
-+ 
-+  out:
-+   return error;
-+ }
-+ 
-+ static int il_usr_attach(struct socket *so, int proto, struct proc *p)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb *ilpcb = 0;
-+ 
-+   if (inp) {
-+     error = EISCONN;
-+     goto out;
-+   }
-+   
-+   if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
-+     error = soreserve(so, il_sendspace, il_recvspace);
-+     if (error)
-+       goto out;
-+   }
-+ 
-+   error = in_pcballoc(so, &ilbinfo, p);
-+ 
-+   if (error)
-+     goto out;
-+ 
-+   inp = sotoinpcb(so);
-+   ilpcb = il_newilpcb(inp);
-+   if (ilpcb == 0) {
-+     int nofd = so->so_state & SS_NOFDREF;	/* XXX */
-+     
-+     so->so_state &= ~SS_NOFDREF;	/* don't free the socket yet */
-+     in_pcbdetach(inp);
-+     so->so_state |= nofd;
-+     error = ENOBUFS;
-+     goto out;
-+   }
-+   ilpcb->state = ILS_CLOSED;
-+   ilpcb->segq = 0;
-+   
-+  out:
-+   splx(s);
-+   return error;
-+ 
-+ }
-+ 
-+ static int il_usr_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb *ilpcb;
-+   struct sockaddr_in *sinp;
-+ 
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+ 
-+ 	/*
-+ 	 * Must check for multicast addresses and disallow binding
-+ 	 * to them.
-+ 	 */
-+   sinp = (struct sockaddr_in *)nam;
-+   if (sinp->sin_family == AF_INET &&
-+       IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
-+     error = EAFNOSUPPORT;
-+     goto out;
-+   }
-+   error = in_pcbbind(inp, nam, p);
-+  out: splx(s); 
-+   return error; 
-+ }
-+ 
-+ /*
-+  * Initiate connection to peer.
-+  * Create a template for use in transmissions on this connection.
-+  * Enter SYN_SENT state, and mark socket as connecting.
-+  * Start keep-alive timer, and seed output sequence space.
-+  * Send initial segment on connection.
-+  */
-+ static int
-+ il_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb *ilpcb;
-+   struct sockaddr_in *sinp;
-+   
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+     
-+   /*
-+    * Must disallow TCP ``connections'' to multicast addresses.
-+    */
-+   sinp = (struct sockaddr_in *)nam;
-+   if (sinp->sin_family == AF_INET
-+       && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
-+     error = EAFNOSUPPORT;
-+     goto out;
-+   }
-+   
-+   if ((error = il_connect(ilpcb, nam, p)) != 0)
-+     goto out;
-+ 
-+   error = il_send_empty(ilpcb, ILT_SYNC, 0);
-+ 
-+  out: splx(s); 
-+   return error; 
-+ }
-+ 
-+ /*
-+  * Close a TCP control block:
-+  *	discard all space held by the tcp
-+  *	discard internet protocol block
-+  *	wake up any sleepers
-+  */
-+ static struct ilpcb *
-+ il_close(struct ilpcb *ilpcb)
-+ {
-+ 	register struct mbuf *q;
-+ 	register struct mbuf *nq;
-+ 	struct inpcb *inp = ilpcb->inpcb;
-+ 	struct socket *so = inp->inp_socket;
-+ 
-+ 	/* free the reassembly queue, if any */
-+ 	for (q = ilpcb->segq; q; q = nq) {
-+ 		nq = q->m_nextpkt;
-+ 		ilpcb->segq = nq;
-+ 		m_freem(q);
-+ 	}
-+ 	inp->inp_ppcb = NULL;
-+ 	soisdisconnected(so);
-+ 	in_pcbdetach(inp);
-+ 	return ((struct ilpcb *)0);
-+ }
-+ 
-+ /*
-+  * User issued close, and wish to trail through shutdown states:
-+  * if never received SYN, just forget it.  If got a SYN from peer,
-+  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
-+  * If already got a FIN from peer, then almost done; go to LAST_ACK
-+  * state.  In all other cases, have already sent FIN to peer (e.g.
-+  * after PRU_SHUTDOWN), and just have to play tedious game waiting
-+  * for peer to send FIN or not respond to keep-alives, etc.
-+  * We can let the user exit from the close as soon as the FIN is acked.
-+  */
-+ static struct ilpcb *
-+ il_usrclosed(struct ilpcb *ilpcb)
-+ {
-+ 
-+ 	switch (ilpcb->state) {
-+ 	case ILS_CLOSED:
-+ 	case ILS_LISTENING:
-+ 		ilpcb->state = ILS_CLOSED;
-+ 		ilpcb = il_close(ilpcb);
-+ 		break;
-+ 
-+ 	case ILS_SYNCER:
-+ 	case ILS_SYNCEE:
-+ 	case ILS_ESTABLISHED:
-+ 	  il_send_empty(ilpcb, ILT_CLOSE, 0);
-+ 	  ilpcb->state = ILS_CLOSING;
-+ 	  break;
-+ 
-+ 	case ILS_CLOSING:
-+ 		break;
-+ 	}
-+ 	return (ilpcb);
-+ }
-+ 
-+ /*
-+  * Drop a TCP connection, reporting
-+  * the specified error.  If connection is synchronized,
-+  * then send a RST to peer.
-+  */
-+ struct ilpcb *
-+ il_drop(ilpcb, errno0)
-+      register struct ilpcb *ilpcb;
-+      int errno0;
-+ {
-+   struct socket *so = ilpcb->inpcb->inp_socket;
-+ 
-+   panic("il_drop");
-+   
-+   switch(ilpcb->state) {
-+   case ILS_SYNCEE:
-+   case ILS_ESTABLISHED:
-+   case ILS_CLOSING:
-+     il_send_empty(ilpcb, ILT_CLOSE, 0);
-+   default:
-+     break;
-+   }
-+   ilpcb->state = ILS_CLOSED;
-+   so->so_error = errno0;
-+   return (il_close(ilpcb));
-+ }
-+ 
-+ /*
-+  * Initiate (or continue) disconnect.
-+  * If embryonic state, just send reset (once).
-+  * If in ``let data drain'' option and linger null, just drop.
-+  * Otherwise (hard), mark socket disconnecting and drop
-+  * current input data; switch states based on user close, and
-+  * send segment to peer (with FIN).
-+  */
-+ static struct ilpcb *
-+ il_disconnect(struct ilpcb *ilpcb)
-+ {
-+   struct socket *so = ilpcb->inpcb->inp_socket;
-+   
-+   soisdisconnecting(so);
-+   sbflush(&so->so_rcv);
-+   ilpcb = il_usrclosed(ilpcb);
-+   
-+   return (ilpcb);
-+ }
-+ 
-+ 
-+ /*
-+  * pru_detach() detaches the IL protocol from the socket.
-+  * If the protocol state is non-embryonic, then can't
-+  * do this directly: have to initiate a pru_disconnect(),
-+  * which may finish later; embryonic TCB's can just
-+  * be discarded here.
-+  */
-+ static int
-+ il_usr_detach(struct socket *so)
-+ {
-+ 	int s = splnet();
-+ 	int error = 0;
-+ 	struct inpcb *inp = sotoinpcb(so);
-+ 	struct ilpcb *ilpcb;
-+ 
-+ 	if (inp == 0) {
-+ 		splx(s);
-+ 		return EINVAL;	/* XXX */
-+ 	}
-+ 	ilpcb = intoilpcb(inp);
-+ 	ilpcb = il_disconnect(ilpcb);
-+ 	splx(s);
-+ 	return error;
-+ }
-+ 
-+ /*
-+  * Mark the connection as being incapable of further output.
-+  */
-+ static int
-+ il_usr_shutdown(struct socket *so)
-+ {
-+ 	int s = splnet();
-+ 	int error = 0;
-+ 	struct inpcb *inp = sotoinpcb(so);
-+ 	struct ilpcb *ilpcb;
-+ 
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+   
-+   socantsendmore(so);
-+   ilpcb = il_usrclosed(ilpcb);
-+   splx(s); 
-+   return error;
-+ }
-+ 
-+ /*
-+  * Initiate disconnect from peer.
-+  * If connection never passed embryonic stage, just drop;
-+  * else if don't need to let data drain, then can just drop anyways,
-+  * else have to begin TCP shutdown process: mark socket disconnecting,
-+  * drain unread data, state switch to reflect user close, and
-+  * send segment (e.g. FIN) to peer.  Socket will be really disconnected
-+  * when peer sends FIN and acks ours.
-+  *
-+  * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
-+  */
-+ static int
-+ il_usr_disconnect(struct socket *so)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb * ilpcb;
-+ 
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+     
-+   il_disconnect(ilpcb);
-+   splx(s); 
-+   return error;
-+ }
-+ 
-+ /*
-+  * Abort the TCP.
-+  */
-+ static int
-+ il_usr_abort(struct socket *so)
-+ {
-+ 	int s = splnet();
-+ 	int error = 0;
-+ 	struct inpcb *inp = sotoinpcb(so);
-+ 	struct ilpcb * ilpcb;
-+ 
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+     
-+   ilpcb = il_drop(ilpcb, ECONNABORTED);
-+   splx(s); 
-+   return error;
-+ 
-+ }
-+ 
-+ /*
-+  * Prepare to accept connections.
-+  */
-+ static int
-+ il_usr_listen(struct socket *so, struct proc *p)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb *ilpcb;
-+   
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+   
-+   if (inp->inp_lport == 0)
-+     error = in_pcbbind(inp, (struct sockaddr *)0, p);
-+   if (error == 0)
-+     ilpcb->state = ILS_LISTENING;
-+ 
-+   splx(s); 
-+   return error;
-+ }
-+ 
-+ /*
-+  * Accept a connection.  Essentially all the work is
-+  * done at higher levels; just return the address
-+  * of the peer, storing through addr.
-+  */
-+ static int
-+ il_usr_accept(struct socket *so, struct sockaddr **nam)
-+ {
-+   int s = splnet();
-+   int error = 0;
-+   struct inpcb *inp = sotoinpcb(so);
-+   struct ilpcb * ilpcb;
-+   
-+   if (inp == 0) {
-+     splx(s);
-+     return EINVAL;
-+   }
-+   ilpcb = intoilpcb(inp);
-+   
-+   in_setpeeraddr(so, nam);
-+   splx(s); 
-+   return error;
-+ }
-+ 
-+ /* xxx - should be const */
-+ struct pr_usrreqs il_usrreqs = {
-+ 	il_usr_abort, il_usr_accept, il_usr_attach, il_usr_bind,
-+ 	il_usr_connect, pru_connect2_notsupp, in_control, il_usr_detach,
-+ 	il_usr_disconnect, il_usr_listen, in_setpeeraddr, pru_rcvd_notsupp,
-+ 	pru_rcvoob_notsupp, il_usr_send, pru_sense_null, il_usr_shutdown,
-+ 	in_setsockaddr, sosend, soreceive, sopoll
-+ };
-diff -N -c -r /usr/src/sys/netinet/il.h ./netinet/il.h
-*** /usr/src/sys/netinet/il.h	Wed Dec 31 19:00:00 1969
---- ./netinet/il.h	Thu Sep 30 11:24:51 1999
-***************
-*** 0 ****
---- 1,17 ----
-+ 
-+ #ifndef NETINET_IL_H_
-+ #define NETINET_IL_H_
-+ 
-+ struct ilhdr
-+ {
-+ 	u_char	ilsum[2];	/* Checksum including header */
-+ 	u_char	illen[2];	/* Packet length */
-+ 	u_char	iltype;		/* Packet type */
-+ 	u_char	ilspec;		/* Special */
-+ 	u_char	ilsrc[2];	/* Src port */
-+ 	u_char	ildst[2];	/* Dst port */
-+ 	u_char	ilid[4];	/* Sequence id */
-+ 	u_char	ilack[4];	/* Acked sequence */
-+ };
-+ 
-+ #endif
-diff -N -c -r /usr/src/sys/netinet/il_var.h ./netinet/il_var.h
-*** /usr/src/sys/netinet/il_var.h	Wed Dec 31 19:00:00 1969
---- ./netinet/il_var.h	Thu Oct  7 10:45:05 1999
-***************
-*** 0 ****
---- 1,46 ----
-+ #ifndef NETINET_IL_VAR_H_
-+ #define NETINET_IL_VAR_H_
-+ 
-+ struct ilpcb			/* Control block */
-+ {
-+   int	state;		/* Connection state */
-+   struct inpcb * inpcb;  /* back pointer to internet pcb */
-+   u_long unacked;
-+ 
-+ #define ILF_NEEDACK 1
-+   u_long flags;
-+ 
-+   u_long rxt_max;
-+   int rxt_timer;  /* number of ticks to the next timeout */
-+   int rxt_timer_cur;  /* current rxt timer period */
-+ 
-+   int death_timer;
-+   int death_timer_cur;
-+   
-+   u_long	next;		/* Id of next to send */
-+   u_long	recvd;		/* Last packet received */
-+   
-+   u_long	start;		/* Local start id */
-+   u_long	rstart;		/* Remote start id */
-+   int	rxtot;		/* number of retransmits on this connection */
-+ 
-+   struct mbuf * segq;
-+ };
-+ 
-+ #define	intoilpcb(ip)	((struct ilpcb *)(ip)->inp_ppcb)
-+ #define	sotoilpcb(so)	(intoilpcb(sotoinpcb(so)))
-+ 
-+ #ifdef KERNEL
-+ void il_init __P((void));
-+ void il_input __P((struct mbuf * m, int iphlen));
-+ void il_slowtimo __P((void));
-+ void il_fasttimo __P((void));
-+ void il_ctlinput __P((int cmd, struct sockaddr *sa, void *vip));
-+ int  il_ctloutput __P((struct socket *so, struct sockopt *sopt));
-+ void il_drain __P((void));
-+ 
-+ extern struct pr_usrreqs il_usrreqs;
-+ 
-+ #endif
-+ 
-+ #endif
-diff -N -c -r /usr/src/sys/netinet/in_proto.c ./netinet/in_proto.c
-*** /usr/src/sys/netinet/in_proto.c	Sat Aug 22 23:07:14 1998
---- ./netinet/in_proto.c	Wed Oct  6 17:55:12 1999
-***************
-*** 36,41 ****
---- 36,42 ----
-  
-  #include "opt_ipdivert.h"
-  #include "opt_ipx.h"
-+ #include "opt_inet.h"
-  
-  #include <sys/param.h>
-  #include <sys/kernel.h>
-***************
-*** 71,76 ****
---- 72,82 ----
-  #include <netns/ns_if.h>
-  #endif
-  
-+ #ifdef IL
-+ #include <netinet/il.h>
-+ #include <netinet/il_var.h>
-+ #endif
-+ 
-  extern	struct domain inetdomain;
-  static	struct pr_usrreqs nousrreqs;
-  
-***************
-*** 161,166 ****
---- 167,181 ----
-    0,
-    0,		0,		0,		0,
-    &rip_usrreqs
-+ },
-+ #endif
-+ #ifdef IL
-+ { SOCK_SEQPACKET,	&inetdomain,	IPPROTO_IL,
-+ 	PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD|PR_ATOMIC,
-+   il_input,	0,		il_ctlinput,	il_ctloutput,
-+   0,
-+   il_init,	il_fasttimo,	il_slowtimo,	il_drain,
-+   &il_usrreqs
-  },
-  #endif
-  	/* raw wildcard */
-diff -N -c -r /usr/src/sys/sys/vnode.h ./sys/vnode.h
-*** /usr/src/sys/sys/vnode.h	Sat Mar 20 04:37:49 1999
---- ./sys/vnode.h	Fri Oct 15 17:44:42 1999
-***************
-*** 62,68 ****
-  enum vtagtype	{
-  	VT_NON, VT_UFS, VT_NFS, VT_MFS, VT_PC, VT_LFS, VT_LOFS, VT_FDESC,
-  	VT_PORTAL, VT_NULL, VT_UMAP, VT_KERNFS, VT_PROCFS, VT_AFS, VT_ISOFS,
-! 	VT_UNION, VT_MSDOSFS, VT_DEVFS, VT_TFS, VT_VFS, VT_CODA, VT_NTFS
-  };
-  
-  /*
---- 62,68 ----
-  enum vtagtype	{
-  	VT_NON, VT_UFS, VT_NFS, VT_MFS, VT_PC, VT_LFS, VT_LOFS, VT_FDESC,
-  	VT_PORTAL, VT_NULL, VT_UMAP, VT_KERNFS, VT_PROCFS, VT_AFS, VT_ISOFS,
-! 	VT_UNION, VT_MSDOSFS, VT_DEVFS, VT_TFS, VT_VFS, VT_CODA, VT_NTFS, VT_U9FS
-  };
-  
-  /*
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h
+++ /dev/null
@@ -1,158 +1,0 @@
-typedef struct	Ticket		Ticket;
-typedef struct	Ticketreq	Ticketreq;
-typedef struct	Authenticator	Authenticator;
-typedef struct	Nvrsafe		Nvrsafe;
-typedef struct	Passwordreq	Passwordreq;
-typedef struct	Chalstate	Chalstate;
-typedef struct	Apopchalstate	Apopchalstate;
-typedef struct	Chapreply	Chapreply;
-typedef struct	MSchapreply	MSchapreply;
-
-enum
-{
-	DOMLEN=		48,		/* length of an authentication domain name */
-	U9AUTH_DESKEYLEN=	7,		/* length of a des key for encrypt/decrypt */
-	CHALLEN=	8,		/* length of a challenge */
-	NETCHLEN=	16,		/* max network challenge length	*/
-	CONFIGLEN=	14,
-	SECRETLEN=	32,		/* max length of a secret */
-	APOPCHLEN=	256,
-	MD5LEN=		16,
-
-	KEYDBOFF=	8,		/* length of random data at the start of key file */
-	OKEYDBLEN=	U9FS_NAMELEN+U9AUTH_DESKEYLEN+4+2,	/* length of an entry in old key file */
-	KEYDBLEN=	OKEYDBLEN+SECRETLEN,	/* length of an entry in key file */
-	U9AUTH_TCPPORT= 567,
-	U9AUTH_ILPORT=  566,
-};
-
-/* encryption numberings (anti-replay) */
-enum
-{
-	AuthTreq=1,	/* ticket request */
-	AuthChal=2,	/* challenge box request */
-	AuthPass=3,	/* change password */
-	AuthOK=4,	/* fixed length reply follows */
-	AuthErr=5,	/* error follows */
-	AuthMod=6,	/* modify user */
-	AuthApop=7,	/* apop authentication for pop3 */
-	AuthOKvar=9,	/* variable length reply follows */
-	AuthChap=10,	/* chap authentication for ppp */
-	AuthMSchap=11,	/* MS chap authentication for ppp */
-
-
-	AuthTs=64,	/* ticket encrypted with server's key */
-	AuthTc,		/* ticket encrypted with client's key */
-	AuthAs,		/* server generated authenticator */
-	AuthAc,		/* client generated authenticator */
-	AuthTp,		/* ticket encrypted with clien's key for password change */
-};
-
-struct Ticketreq
-{
-	char	type;
-	char	authid[U9FS_NAMELEN];	/* server's encryption id */
-	char	authdom[DOMLEN];	/* server's authentication domain */
-	char	chal[CHALLEN];		/* challenge from server */
-	char	hostid[U9FS_NAMELEN];	/* host's encryption id */
-	char	uid[U9FS_NAMELEN];		/* uid of requesting user on host */
-};
-#define	TICKREQLEN	(3*U9FS_NAMELEN+CHALLEN+DOMLEN+1)
-
-struct Ticket
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];		/* server challenge */
-	char	cuid[U9FS_NAMELEN];		/* uid on client */
-	char	suid[U9FS_NAMELEN];		/* uid on server */
-	char	key[U9AUTH_DESKEYLEN];		/* nonce DES key */
-};
-#define	TICKETLEN	(CHALLEN+2*U9FS_NAMELEN+U9AUTH_DESKEYLEN+1)
-
-struct Authenticator
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];
-	u_long	id;			/* authenticator id, ++'d with each auth */
-};
-#define	AUTHENTLEN	(CHALLEN+4+1)
-
-struct Passwordreq
-{
-	char	num;
-	char	old[U9FS_NAMELEN];
-	char	new[U9FS_NAMELEN];
-	char	changesecret;
-	char	secret[SECRETLEN];	/* new secret */
-};
-#define	PASSREQLEN	(2*U9FS_NAMELEN+1+1+SECRETLEN)
-
-struct Nvrsafe
-{
-	char	machkey[U9AUTH_DESKEYLEN];
-	u_char	machsum;
-	char	authkey[U9AUTH_DESKEYLEN];
-	u_char	authsum;
-	char	config[CONFIGLEN];
-	u_char	configsum;
-	char	authid[U9FS_NAMELEN];
-	u_char	authidsum;
-	char	authdom[DOMLEN];
-	u_char	authdomsum;
-};
-
-struct Chalstate
-{
-	int	afd;			/* /dev/authenticate */
-	int	asfd;			/* authdial() */
-	char	chal[NETCHLEN];		/* challenge/response */
-};
-
-struct Apopchalstate
-{
-	int	afd;			/* /dev/authenticate */
-	int	asfd;			/* authdial() */
-	char	chal[APOPCHLEN];	/* challenge/response */
-};
-
-struct	Chapreply
-{
-	u_char	id;
-	char	uid[U9FS_NAMELEN];
-	char	resp[MD5LEN];
-};
-
-struct	MSchapreply
-{
-	char	uid[U9FS_NAMELEN];
-	char	LMresp[24];		/* Lan Manager response */
-	char	NTresp[24];		/* NT response */
-};
-
-extern	int	convT2M(Ticket*, char*, char*);
-extern	void	convM2T(char*, Ticket*, char*);
-extern	void	convM2Tnoenc(char*, Ticket*);
-extern	int	convA2M(Authenticator*, char*, char*);
-extern	void	convM2A(char*, Authenticator*, char*);
-extern	int	convTR2M(Ticketreq*, char*);
-extern	void	convM2TR(char*, Ticketreq*);
-extern	int	convPR2M(Passwordreq*, char*, char*);
-extern	void	convM2PR(char*, Passwordreq*, char*);
-extern	u_char	nvcsum(void*, int);
-extern	int	passtokey(char*, char*);
-extern	int	authenticate(int, int);
-extern	int	newns(char*, char*);
-extern	int	addns(char*, char*);
-extern	int	authdial(void);
-extern	int	auth(int);
-extern	int	srvauth(int, char*);
-extern	int	nauth(int, Ticket*);
-extern	int	nsrvauth(int, char*, Ticket*);
-extern	int	getchal(Chalstate*, char*);
-extern	int	chalreply(Chalstate*, char*);
-extern	int	amount(int, char*, int, char*);
-extern	int	apopchal(Apopchalstate*);
-extern	int	apopreply(Apopchalstate*, char*, char*);
-extern	int	login(char*, char*, char*);
-extern	int	sslnegotiate(int, Ticket*, char**, char**);
-extern	int	srvsslnegotiate(int, Ticket*, char**, char**);
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h
+++ /dev/null
@@ -1,219 +1,0 @@
-/*
- * Copyright (c) 1989, 1993, 1995
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $Id: nfs.h,v 1.44 1998/09/07 05:42:15 bde Exp $
- */
-
-#ifndef _9FS_H_
-#define _9FS_H_
-
-#ifdef KERNEL
-#include "opt_u9fs.h"
-#endif
-
-#define U9FS_FABLKSIZE   512
-#define U9FS_PORT        17008
-
-/*
- * U9FS mount option flags
- */
-#define	U9FSMNT_SOFT		0x00000001  /* soft mount (hard is default) */
-#define	U9FSMNT_MAXGRPS		0x00000020  /* set maximum grouplist size */
-#define	U9FSMNT_INT		0x00000040  /* allow interrupts on hard mount */
-#define	U9FSMNT_KERB		0x00000400  /* Use Kerberos authentication */
-#define	U9FSMNT_READAHEAD	0x00002000  /* set read ahead */
-
-struct p9user {
-  uid_t p9_uid;
-  char p9_name[U9FS_NAMELEN];
-};
-
-/*
- * Arguments to mount 9FS
- */
-#define U9FS_ARGSVERSION	1	/* change when nfs_args changes */
-struct u9fs_args {
-	int		version;	/* args structure version number */
-	struct sockaddr	*addr;		/* file server address */
-	int		addrlen;	/* length of address */
-	int		sotype;		/* Socket type */
-	int		proto;		/* and Protocol */
-	int		fhsize;		/* Size, in bytes, of fh */
-	int		flags;		/* flags */
-	int		wsize;		/* write size in bytes */
-	int		rsize;		/* read size in bytes */
-	int		readdirsize;	/* readdir size in bytes */
-	char		*hostname;	/* server's name */
-        struct sockaddr * authaddr;
-        int             authaddrlen;
-        int             authsotype;
-        int             authsoproto;
-        int             nusers;
-        char            uname[U9FS_NAMELEN];
-        char            key[U9AUTH_DESKEYLEN];
-        struct p9user * users;
-};
-
-/*
- * The u9fsnode is the u9fs equivalent to ufs's inode. Any similarity
- * is purely coincidental.
- * There is a unique u9fsnode allocated for each active file,
- * each current directory, each mounted-on file, text file, and the root.
- * An u9fsnode is 'named' by its file handle. (nget/u9fs_node.c)
- * If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite
- * type definitions), file handles of > 32 bytes should probably be split out
- * into a separate MALLOC()'d data structure. (Reduce the size of u9fsfh_t by
- * changing the definition in u9fsproto.h of U9FS_SMALLFH.)
- * NB: Hopefully the current order of the fields is such that everything will
- *     be well aligned and, therefore, tightly packed.
- */
-struct u9fsnode {
-	LIST_ENTRY(u9fsnode)	n_hash;		/* Hash chain */
-	u_quad_t		n_size;		/* Current size of file */
-	u_quad_t		n_lrev;		/* Modify rev for lease */
-	struct vattr		n_vattr;	/* Vnode attribute cache */
-	time_t			n_attrstamp;	/* Attr. cache timestamp */
-	u_int32_t		n_mode;		/* ACCESS mode cache */
-	uid_t			n_modeuid;	/* credentials having mode */
-	time_t			n_modestamp;	/* mode cache timestamp */
-	time_t			n_mtime;	/* Prev modify time. */
-	time_t			n_ctime;	/* Prev create time. */
-	u_short			*n_fid;		/* U9FS FID */
-	struct vnode		*n_vnode;	/* associated vnode */
-	struct lockf		*n_lockf;	/* Locking record of file */
-	int			n_error;	/* Save write error value */
-#if 0
-	union {
-		struct timespec	nf_atim;	/* Special file times */
-		u9fsuint64	nd_cookieverf;	/* Cookie verifier (dir only) */
-	} n_un1;
-	union {
-		struct timespec	nf_mtim;
-		off_t		nd_direof;	/* Dir. EOF offset cache */
-	} n_un2;
-	union {
-		struct sillyrename *nf_silly;	/* Ptr to silly rename struct */
-		LIST_HEAD(, u9fsdmap) nd_cook;	/* cookies */
-	} n_un3;
-#endif
-	short			n_flag;		/* Flag for locking.. */
-};
-
-#define n_atim		n_un1.nf_atim
-#define n_mtim		n_un2.nf_mtim
-#define n_sillyrename	n_un3.nf_silly
-#define n_cookieverf	n_un1.nd_cookieverf
-#define n_direofoffset	n_un2.nd_direof
-#define n_cookies	n_un3.nd_cook
-
-/*
- * Flags for n_flag
- */
-#define	NFLUSHWANT	0x0001	/* Want wakeup from a flush in prog. */
-#define	NFLUSHINPROG	0x0002	/* Avoid multiple calls to vinvalbuf() */
-#define	NMODIFIED	0x0004	/* Might have a modified buffer in bio */
-#define	NWRITEERR	0x0008	/* Flag write errors so close will know */
-#define	NQU9FSNONCACHE	0x0020	/* Non-cachable lease */
-#define	NQU9FSWRITE	0x0040	/* Write lease */
-#define	NQU9FSEVICTED	0x0080	/* Has been evicted */
-#define	NACC		0x0100	/* Special file accessed */
-#define	NUPD		0x0200	/* Special file updated */
-#define	NCHG		0x0400	/* Special file times changed */
-#define NLOCKED		0x0800  /* node is locked */
-#define NWANTED		0x0100  /* someone wants to lock */
-
-/*
- * Convert between u9fsnode pointers and vnode pointers
- */
-#define VTOU9FS(vp)	((struct u9fsnode *)(vp)->v_data)
-#define U9FSTOV(np)	((struct vnode *)(np)->n_vnode)
-
-/*
- * Mount structure.
- * One allocated on every U9FS mount.
- * Holds U9FS specific information for mount.
- */
-struct	u9fsmount {
-	int	nm_flag;		/* Flags for soft/hard... */
-	int	nm_state;		/* Internal state flags */
-	struct	mount *nm_mountp;	/* Vfs structure for this filesystem */
-	int	nm_numgrps;		/* Max. size of groupslist */
-	u_short	nm_fid;	                /* fid of root dir */
-	struct	socket *nm_so;		/* Rpc socket */
-	int	nm_sotype;		/* Type of socket */
-	int	nm_soproto;		/* and protocol */
-	int	nm_soflags;		/* pr_flags for socket protocol */
-	struct	sockaddr *nm_nam;	/* Addr of server */
-	int	nm_sent;		/* Request send count */
-	int	nm_cwnd;		/* Request send window */
-	int	nm_rsize;		/* Max size of read rpc */
-	int	nm_wsize;		/* Max size of write rpc */
-	int	nm_readdirsize;		/* Size of a readdir rpc */
-#if 0
-	struct vnode *nm_inprog;	/* Vnode in prog by nqu9fs_clientd() */
-	uid_t	nm_authuid;		/* Uid for authenticator */
-	int	nm_authtype;		/* Authenticator type */
-	int	nm_authlen;		/* and length */
-	char	*nm_authstr;		/* Authenticator string */
-	char	*nm_verfstr;		/* and the verifier */
-	int	nm_verflen;
-	u_char	nm_verf[U9FSX_V3WRITEVERF]; /* V3 write verifier */
-	U9FSKERBKEY_T nm_key;		/* and the session key */
-	int	nm_numuids;		/* Number of u9fsuid mappings */
-	TAILQ_HEAD(, u9fsuid) nm_uidlruhead; /* Lists of u9fsuid mappings */
-	LIST_HEAD(, u9fsuid) nm_uidhashtbl[U9FS_MUIDHASHSIZ];
-	TAILQ_HEAD(, buf) nm_bufq;	/* async io buffer queue */
-	short	nm_bufqlen;		/* number of buffers in queue */
-	short	nm_bufqwant;		/* process wants to add to the queue */
-	int	nm_bufqiods;		/* number of iods processing queue */
-#endif
-	u_int64_t nm_maxfilesize;	/* maximum file size */
-};
-
-#ifdef KERNEL
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_U9FSHASH);
-#endif
-
-/*
- * Convert mount ptr to u9fsmount ptr.
- */
-#define VFSTOU9FS(mp)	((struct u9fsmount *)((mp)->mnt_data))
-
-#endif	/* KERNEL */
-
-#endif
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h
+++ /dev/null
@@ -1,226 +1,0 @@
-#ifndef _9FS_9P_H_
-#define _9FS_9P_H_
-
-
-#define U9FS_AUTHLEN 13
-#define U9FS_NAMELEN    28
-#define U9FS_TICKETLEN  72
-#define U9FS_ERRLEN     64
-#define U9FS_DOMLEN     48
-#define U9FS_CHALLEN    8
-#define U9FS_DIRLEN     116
-#define U9FS_MAXFDATA  8192
-#define U9FS_MAXDDATA  (((int)U9FS_MAXFDATA/U9FS_DIRLEN)*U9FS_DIRLEN)
-
-#define U9P_MODE_RD    0x0
-#define U9P_MODE_WR    0x1
-#define U9P_MODE_RDWR  0x2
-#define U9P_MODE_EX    0x3
-#define U9P_MODE_TRUNC 0x10
-#define U9P_MODE_CLOSE 0x40
-
-#define U9P_PERM_CHDIR(m) (0x80000000&(m))
-#define U9P_PERM_OWNER(m) ((m)&0x7)
-#define U9P_PERM_GROUP(m) (((m)>>3)&0x7)
-#define U9P_PERM_OTHER(m) (((m)>>6)&0x7)
-#define U9P_PERM_ALL(m)   ((m)&0777)
-
-/* this is too small */
-typedef u_int32_t u9fsfh_t;
-
-struct u9fd_qid {
-	u9fsfh_t	path;
-	u_int32_t	vers;
-};
-
-struct	u9fsreq {
-  TAILQ_ENTRY(u9fsreq) r_chain;
-  struct u9fsreq * r_rep;
-  struct mbuf * r_mrep;
-  struct proc	*r_procp;	/* Proc that did I/O system call */
-  struct u9fsmount *r_nmp;
-
-  /* actual content of the 9P message */
-	char	r_type;
-	short	r_fid;
-	u_short	r_tag;
-	union {
-		struct {
-			u_short	oldtag;		/* Tflush */
-			struct u9fd_qid qid;		/* Rattach, Rwalk, Ropen, Rcreate */
-			char	rauth[U9FS_AUTHLEN];	/* Rattach */
-		} u1;
-		struct {
-			char	uname[U9FS_NAMELEN];		/* Tattach */
-			char	aname[U9FS_NAMELEN];		/* Tattach */
-			char	ticket[U9FS_TICKETLEN];	/* Tattach */
-			char	auth[U9FS_AUTHLEN];	/* Tattach */
-		} u2;
-		struct {
-			char	ename[U9FS_ERRLEN];		/* Rerror */
-			char	authid[U9FS_NAMELEN];	/* Rsession */
-			char	authdom[U9FS_DOMLEN];	/* Rsession */
-			char	chal[U9FS_CHALLEN];		/* Tsession/Rsession */
-		} u3;
-		struct {
-			u_int32_t	perm;		/* Tcreate */ 
-			short	newfid;		/* Tclone, Tclwalk */
-			char	name[U9FS_NAMELEN];	/* Twalk, Tclwalk, Tcreate */
-			char	mode;		/* Tcreate, Topen */
-		} u4;
-		struct {
-			u_int64_t	offset;		/* Tread, Twrite */
-			u_short	        count;		/* Tread, Twrite, Rread */
-			char	*data;		/* Twrite, Rread */
-		} u5;
-			char	stat[U9FS_DIRLEN];	/* Twstat, Rstat */
-	} u;
-};
-
-#define r_oldtag u.u1.oldtag
-#define r_qid u.u1.qid
-#define r_rauth u.u1.rauth
-#define r_uname u.u2.uname
-#define r_aname u.u2.aname
-#define r_ticket  u.u2.ticket
-#define r_auth  u.u2.auth
-#define r_ename  u.u3.ename
-#define r_authid  u.u3.authid
-#define r_authdom  u.u3.authdom
-#define r_chal  u.u3.chal
-#define r_perm  u.u4.perm
-#define r_newfid  u.u4.newfid
-#define r_name  u.u4.name
-#define r_mode  u.u4.mode
-#define r_offset  u.u5.offset
-#define r_count  u.u5.count
-#define r_data  u.u5.data
-#define r_stat  u.stat
-
-extern TAILQ_HEAD(u9fs_reqq, u9fsreq) u9fs_reqq;
-
-struct u9fsdir {
-  char	dir_name[U9FS_NAMELEN];
-  char	dir_uid[U9FS_NAMELEN];
-  char	dir_gid[U9FS_NAMELEN];
-  struct u9fd_qid	dir_qid;
-  u_int32_t	dir_mode;
-  u_int32_t	dir_atime;
-  u_int32_t	dir_mtime;
-  union {
-    u_int64_t	length;
-    struct {	/* little endian */
-      u_int32_t	llength;
-      u_int32_t	hlength;
-    } l;
-  } u;
-  u_short	dir_type;
-  u_short	dir_dev;
-};
-
-#define dir_length u.length
-#define dir_llength u.l.llength
-#define dir_hlength u.l.hlength
-
-enum
-{
-	Tnop =		50,
-	Rnop,
-	Tosession =	52,	/* illegal */
-	Rosession,		/* illegal */
-	Terror =	54,	/* illegal */
-	Rerror,
-	Tflush =	56,
-	Rflush,
-	Toattach =	58,	/* illegal */
-	Roattach,		/* illegal */
-	Tclone =	60,
-	Rclone,
-	Twalk =		62,
-	Rwalk,
-	Topen =		64,
-	Ropen,
-	Tcreate =	66,
-	Rcreate,
-	Tread =		68,
-	Rread,
-	Twrite =	70,
-	Rwrite,
-	Tclunk =	72,
-	Rclunk,
-	Tremove =	74,
-	Rremove,
-	Tstat =		76,
-	Rstat,
-	Twstat =	78,
-	Rwstat,
-	Tclwalk =	80,
-	Rclwalk,
-	Tauth =		82,	/* illegal */
-	Rauth,			/* illegal */
-	Tsession =	84,
-	Rsession,
-	Tattach =	86,
-	Rattach,
-	Ttunnel =	88,
-	Rtunnel,
-	Tmax
-};
-
-static char * u9p_types[] = {
-  "Tnop",
-  "Rnop",
-  "Tosession",
-  "Rosession",
-  "Terror",
-  "Rerror",
-  "Tflush",
-  "Rflush",
-  "Toattach",
-  "Roattach",
-  "Tclone",
-  "Rclone",
-  "Twalk",
-  "Rwalk",
-  "Topen",
-  "Ropen",
-  "Tcreate",
-  "Rcreate",
-  "Tread",
-  "Rread",
-  "Twrite",
-  "Rwrite",
-  "Tclunk",
-  "Rclunk",
-  "Tremove",
-  "Rremove",
-  "Tstat",
-  "Rstat",
-  "Twstat",
-  "Rwstat",
-  "Tclwalk",
-  "Rclwalk",
-  "Tauth",
-  "Rauth",
-  "Tsession",
-  "Rsession",
-  "Tattach",
-  "Rattach",
-  "Ttunnel",
-  "Rtunnel",
-  "Tmax"
-};
-
-int u9p_m2s __P((char *ap, int n, struct u9fsreq *f));
-int u9p_s2m __P((struct u9fsreq *f, char *ap, int copydata));
-int u9p_m2d __P((char *ap, struct u9fsdir *f));
-int u9p_d2m __P((struct u9fsdir *f, char *ap));
-int u9p_type __P((char * t));
-
-int u9p_m_m2s __P((struct mbuf **m, struct u9fsreq *f));
-struct mbuf * u9p_m_s2m __P((struct u9fsreq *f));
-int u9p_m_m2d __P((struct mbuf **m, struct u9fsdir *f));
-struct mbuf * u9p_m_d2m __P((struct u9fsdir *f));
-u_short u9p_m_tag __P((struct mbuf **m));
-
-#endif
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile
+++ /dev/null
@@ -1,21 +1,0 @@
-#	@(#)Makefile	8.2 (Berkeley) 3/27/94
-
-PROG=	mount_9fs
-SRCS=	mount_9fs.c getmntopts.c crypt.c
-MAN8=	mount_9fs.8.man
-
-CFLAGS = -ggdb -O0
-
-MOUNT=	/usr/src/sbin/mount
-CFLAGS+= -DNFS -I${MOUNT}
-.PATH:	${MOUNT}
-
-.if exists(${DESTDIR}/usr/lib/libkrb.a) && (defined(MAKE_KERBEROS) \
-	|| defined(MAKE_EBONES))
-CFLAGS+=-DKERBEROS
-DPADD=	${LIBKRB} ${LIBDES}
-LDADD=	-lkrb -ldes
-DISTRIBUTION=	krb
-.endif
-
-.include <bsd.prog.mk>
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c
+++ /dev/null
@@ -1,415 +1,0 @@
-/*
- *	Data Encryption Standard
- *	D.P.Mitchell  83/06/08.
- *
- *	block_cipher(key, block, decrypting)
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-typedef unsigned char uchar;
-typedef unsigned long ulong;
-#define U9FS_NAMELEN 28      /* length of path element, including '\0' */
-#include "9auth.h"
-
-static	long	ip_low(char [8]);
-static	long	ip_high(char [8]);
-static	void	fp(long, long, char[8]);
-static	void	key_setup(char[U9AUTH_DESKEYLEN], char[128]);
-static	void	block_cipher(char[128], char[8], int);
-
-/*
- * destructively encrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-encrypt9(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	for(i = 0; i < n; i++){
-		block_cipher(ekey, buf, 0);
-		buf += 7;
-	}
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 0);
-	return 1;
-}
-
-/*
- * destructively decrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-decrypt(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	buf += n * 7;
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 1);
-	for(i = 0; i < n; i++){
-		buf -= 7;
-		block_cipher(ekey, buf, 1);
-	}
-	return 1;
-}
-
-/*
- *	Tables for Combined S and P Boxes
- */
-
-static long  s0p[] = {
-0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
-0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
-0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
-0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
-0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
-0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
-0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
-0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
-};
-
-static long  s1p[] = {
-0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
-0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
-0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
-0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
-0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
-0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
-0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
-0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
-};
-
-static long  s2p[] = {
-0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
-0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
-0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
-0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
-0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
-0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
-0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
-0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
-};
-
-static long  s3p[] = {
-0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
-0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
-0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
-0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
-0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
-0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
-0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
-0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
-};
-
-static long  s4p[] = {
-0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
-0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
-0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
-0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
-0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
-0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
-0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
-0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
-};
-
-static long  s5p[] = {
-0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
-0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
-0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
-0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
-0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
-0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
-0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
-0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
-};
-
-static long  s6p[] = {
-0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
-0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
-0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
-0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
-0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
-0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
-0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
-0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
-};
-
-static long  s7p[] = {
-0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
-0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
-0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
-0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
-0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
-0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
-0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
-0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
-};
-
-/*
- *	DES electronic codebook encryption of one block
- */
-static void
-block_cipher(char expanded_key[128], char text[8], int decrypting)
-{
-	char *key;
-	long crypto, temp, right, left;
-	int i, key_offset;
-
-	key = expanded_key;
-	left = ip_low(text);
-	right = ip_high(text);
-	if (decrypting) {
-		key_offset = 16;
-		key = key + 128 - 8;
-	} else
-		key_offset = 0;
-	for (i = 0; i < 16; i++) {
-		temp = (right << 1) | ((right >> 31) & 1);
-		crypto  = s0p[(temp         & 0x3f) ^ *key++];
-		crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
-		crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
-		crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
-		crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
-		crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
-		crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
-		temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
-		crypto |= s7p[temp ^ *key++];
-		temp = left;
-		left = right;
-		right = temp ^ crypto;
-		key -= key_offset;
-	}
-	/*
-	 *	standard final permutation (IPI)
-	 *	left and right are reversed here
-	 */
-	fp(right, left, text);
-}
-
-/*
- *	Initial Permutation
- */
-static long iptab[] = {
-	0x00000000, 0x00008000, 0x00000000, 0x00008000,
-	0x00000080, 0x00008080, 0x00000080, 0x00008080
-};
-
-static long
-ip_low(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 4) & 7] >> i;
-		l |= iptab[block[i] & 7] << (16 - i);
-	}
-	return l;
-}
-
-static long
-ip_high(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 5) & 7] >> i;
-		l |= iptab[(block[i] >> 1) & 7] << (16 - i);
-	}
-	return l;
-}
-
-/*
- *	Final Permutation
- */
-static unsigned long	fptab[] = {
-0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
-0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
-};
-
-static void
-fp(long left, long right, char text[8])
-{
-	unsigned long ta[2], t, v[2];
-	int i, j, sh;
-
-	ta[0] = right;
-	ta[1] = left;
-	v[0] = v[1] = 0;
-	for(i = 0; i < 2; i++){
-		t = ta[i];
-		sh = i;
-		for(j = 0; j < 4; j++){
-			v[1] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			v[0] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			sh += 2;
-		}
-	}
-	for(i = 0; i < 2; i++)
-		for(j = 0; j < 4; j++){
-			*text++ = v[i];
-			v[i] >>= 8;
-		}
-}
-
-/*
- *	Key set-up
- */
-static uchar keyexpand[][15][2] = {
-	{   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 16, 
-	   74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
-	{   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 32, 
-	   64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
-	{   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 32, 
-	   89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
-	{   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  1, 
-	   78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
-	{   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  8, 
-	   85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
-	{  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 32, 
-	   86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
-	{  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 16, 
-	   85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
-	{   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  8, 
-	   83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
-	{   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  2, 
-	   74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
-	{   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  8, 
-	   82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
-	{  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  8, 
-	   94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
-	{   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  8, 
-	   78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
-	{   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  8, 
-	   84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
-	{   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  2, 
-	   69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
-	{   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  2, 
-	   72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
-	{   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  2, 
-	   67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
-	{   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  2, 
-	   72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
-	{   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  2, 
-	   70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
-	{   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 16, 
-	   84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
-	{   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 32, 
-	   78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
-	{   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 16, 
-	   77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
-	{   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  1, 
-	   80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
-	{   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 16, 
-	   72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
-	{   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  8, 
-	   74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
-	{   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  8, 
-	   86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
-	{   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 32, 
-	   85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
-	{   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  2, 
-	   87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
-	{   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 16, 
-	   71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
-	{   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  4, 
-	   83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
-	{   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 16, 
-	   74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
-	{   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 32, 
-	   73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
-	{   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  4, 
-	   91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
-	{   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 16, 
-	   76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
-	{   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  4, 
-	   86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
-	{   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  8, 
-	   84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
-	{   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  1, 
-	   72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
-	{   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  8, 
-	   99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
-	{   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 32, 
-	   81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
-	{   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  4, 
-	   73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
-	{   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  1, 
-	   86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
-	{  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  4, 
-	   85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
-	{   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  8, 
-	   70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
-	{   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 16, 
-	   80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
-	{  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  1, 
-	   73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
-	{   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  8, 
-	   65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
-	{   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 32, 
-	   97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
-	{   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  4, 
-	   79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
-	{   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  4, 
-	   78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
-	{   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  1, 
-	   86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
-	{   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  1, 
-	   74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
-	{   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  8, 
-	   91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
-	{   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 32, 
-	   73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
-	{   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  4, 
-	   65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
-	{   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  8, 
-	   92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
-	{   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  4, 
-	   77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
-	{   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  2, 
-	   77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
-};
-
-static void
-key_setup(char key[U9AUTH_DESKEYLEN], char *ek)
-{
-	int i, j, k, mask;
-	uchar (*x)[2];
-
-	memset(ek, 0, 128);
-	x = keyexpand[0];
-	for(i = 0; i < 7; i++){
-		k = key[i];
-		for(mask = 0x80; mask; mask >>= 1){
-			if(k & mask)
-				for(j = 0; j < 15; j++)
-					ek[x[j][0]] |= x[j][1];
-			x += 15;
-		}
-	}
-}
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8.man
+++ /dev/null
@@ -1,319 +1,0 @@
-.\" Copyright (c) 1992, 1993, 1994, 1995
-.\"	The Regents of the University of California.  All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"	This product includes software developed by the University of
-.\"	California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\"    may be used to endorse or promote products derived from this software
-.\"    without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"	@(#)mount_nfs.8	8.3 (Berkeley) 3/29/95
-.\"
-.\" $Id: mount_nfs.8,v 1.14 1998/07/06 07:15:53 charnier Exp $
-.\""
-.Dd March 29, 1995
-.Dt MOUNT_NFS 8
-.Os BSD 4.4
-.Sh NAME
-.Nm mount_nfs
-.Nd mount nfs file systems
-.Sh SYNOPSIS
-.Nm mount_nfs
-.Op Fl 23KNPTUbcdilqs
-.Op Fl D Ar deadthresh
-.Op Fl I Ar readdirsize
-.Op Fl L Ar leaseterm
-.Op Fl R Ar retrycnt
-.Op Fl a Ar maxreadahead
-.Op Fl g Ar maxgroups
-.Op Fl m Ar realm
-.Op Fl o Ar options
-.Op Fl r Ar readsize
-.Op Fl t Ar timeout
-.Op Fl w Ar writesize
-.Op Fl x Ar retrans
-.Ar rhost:path node
-.Sh DESCRIPTION
-The
-.Nm
-command
-calls the
-.Xr mount 2
-system call to prepare and graft a remote nfs file system (rhost:path)
-on to the file system tree at the point
-.Ar node.
-This command is normally executed by
-.Xr mount 8 .
-It implements the mount protocol as described in RFC 1094, Appendix A and
-.%T "NFS: Network File System Version 3 Protocol Specification" ,
-Appendix I.
-.Pp
-The options are:
-.Bl -tag -width indent
-.It Fl 2
-Use the NFS Version 2 protocol (the default is to try version 3 first
-then version 2).  Note that NFS version 2 has a file size limit of 2
-gigabytes.
-.It Fl 3
-Use the NFS Version 3 protocol.
-.It Fl D
-Used with NQNFS to set the
-.Dq "dead server threshold"
-to the specified number of round trip timeout intervals.
-After a
-.Dq "dead server threshold"
-of retransmit timeouts,
-cached data for the unresponsive server is assumed to still be valid.
-Values may be set in the range of 1 - 9, with 9 referring to an
-.Dq "infinite dead threshold"
-(i.e. never assume cached data still valid).
-This option is not generally recommended and is really an experimental
-feature.
-.It Fl I
-Set the readdir read size to the specified value. The value should normally
-be a multiple of DIRBLKSIZ that is <= the read size for the mount.
-.It Fl K
-Pass Kerberos authenticators to the server for client-to-server
-user-credential mapping.
-This requires that the kernel be built with the NFSKERB option.
-(Refer to the INTERNET-DRAFT titled
-.%T "Authentication Mechanisms for ONC RPC" ,
-for more information.)
-.It Fl L
-Used with NQNFS to set the lease term to the specified number of seconds.
-Only use this argument for mounts with a large round trip delay.
-Values are normally in the 10-30 second range.
-.It Fl N
-Do
-.Em not
-use a reserved socket port number (see below).
-.It Fl P
-Use a reserved socket port number.
-This flag is obsolete, and only retained for compatibility reasons.
-Reserved port numbers are used by default now.
-This is useful for mounting servers that require clients to use a
-reserved port number on the mistaken belief that this makes NFS
-more secure. (For the rare case where the client has a trusted root account
-but untrustworthy users and the network cables are in secure areas this does
-help, but for normal desktop clients this does not apply.)
-.It Fl R
-Set the retry count for doing the mount to the specified value.
-.It Fl T
-Use TCP transport instead of UDP.
-This is recommended for servers that are not on the same LAN cable as
-the client.
-(NB: This is NOT supported by most non-BSD servers.)
-.It Fl U
-Force the mount protocol to use UDP transport, even for TCP NFS mounts.
-(Necessary for some old BSD servers.)
-.It Fl a
-Set the read-ahead count to the specified value.
-This may be in the range of 0 - 4, and determines how many blocks
-will be read ahead when a large file is being read sequentially.
-Trying a value greater than 1 for this is suggested for
-mounts with a large bandwidth * delay product.
-.It Fl b
-If an initial attempt to contact the server fails, fork off a child to keep
-trying the mount in the background.
-Useful for
-.Xr fstab 5 ,
-where the filesystem mount is not critical to multiuser operation.
-.It Fl c
-For UDP mount points, do not do a
-.Xr connect 2 .
-This must be used for servers that do not reply to requests from the
-standard NFS port number 2049.
-.It Fl d
-Turn off the dynamic retransmit timeout estimator.
-This may be useful for UDP mounts that exhibit high retry rates,
-since it is possible that the dynamically estimated timeout interval is too
-short.
-.It Fl g
-Set the maximum size of the group list for the credentials to the
-specified value.
-This should be used for mounts on old servers that cannot handle a
-group list size of 16, as specified in RFC 1057.
-Try 8, if users in a lot of groups cannot get response from the mount
-point.
-.It Fl i
-Make the mount interruptible, which implies that file system calls that
-are delayed due to an unresponsive server will fail with EINTR when a
-termination signal is posted for the process.
-.It Fl l
-Used with NQNFS and NFSV3 to specify that the \fBReaddirPlus\fR RPC should
-be used.
-This option reduces RPC traffic for cases such as
-.Dq "ls -l" ,
-but tends to flood the attribute and name caches with prefetched entries.
-Try this option and see whether performance improves or degrades. Probably
-most useful for client to server network interconnects with a large bandwidth
-times delay product.
-.It Fl m
-Set the Kerberos realm to the string argument.
-Used with the
-.Fl K
-option for mounts to other realms.
-.It Fl o
-Options are specified with a
-.Fl o
-flag followed by a comma separated string of options.
-See the
-.Xr mount 8
-man page for possible options and their meanings.
-The following NFS specific option is also available:
-.Bl -tag -width indent
-.It port=<port_number>
-Use specified port number for NFS requests.
-The default is to query the portmapper for the NFS port.
-.It acregmin=<seconds>
-.It acregmax=<seconds>
-.It acdirmin=<seconds>
-.It acdirmax=<seconds>
-When attributes of files are cached, a timeout calculated to determine
-whether a given cache entry has expired.  These four values determine the
-upper and lower bounds of the timeouts for ``directory'' attributes and
-``regular'' (ie: everything else).  The default values are 3 -> 60 seconds
-for regular files, and 30 -> 60 seconds for directories.  The algorithm to
-calculate the timeout is based on the age of the file.  The older the file,
-the longer the cache is considered valid, subject to the limits above.
-.El
-.Pp
-.Bl -tag -width "dumbtimerXX"
-\fBHistoric \&-o options\fR
-.Pp
-Use of these options is deprecated, they are only mentioned here for
-compatibility with historic versions of
-.Nm Ns .
-.It bg
-Same as
-.Fl b .
-.It conn
-Same as not specifying 
-.Fl c .
-.It dumbtimer
-Same as
-.Fl d .
-.It intr
-Same as
-.Fl i .
-.It kerb
-Same as
-.Fl K .
-.It nfsv2
-Same as
-.Fl 2 .
-.It nfsv3
-Same as
-.Fl 3 .
-.It rdirplus
-Same as
-.Fl l .
-.It mntudp
-Same as
-.Fl U .
-.It resvport
-Same as
-.Fl P .
-.It seqpacket
-Same as
-.Fl p .
-.It nqnfs
-Same as
-.Fl q .
-.It soft
-Same as
-.Fl s .
-.It tcp
-Same as
-.Fl T.
-.El
-.It Fl q
-Use the leasing extensions to the NFS Version 3 protocol
-to maintain cache consistency.
-This protocol Version 2, referred to as Not Quite Nfs (NQNFS),
-is only supported by this updated release of NFS code.
-(It is not backwards compatible with the release of NQNFS that went out on
-4.4BSD-Lite. To interoperate with a 4.4BSD-Lite NFS system you will have to
-avoid this option until you have had an opportunity to upgrade the NFS code
-on all your 4.4BSD-Lite based systems.)
-.It Fl r
-Set the read data size to the specified value.
-It should normally be a power of 2 greater than or equal to 1024.
-This should be used for UDP mounts when the
-.Dq "fragments dropped due to timeout"
-value is getting large while actively using a mount point.
-(Use
-.Xr netstat 1
-with the
-.Fl s
-option to see what the
-.Dq "fragments dropped due to timeout"
-value is.)
-See the
-.Fl w
-option as well.
-.It Fl s
-A soft mount, which implies that file system calls will fail
-after \fBRetry\fR round trip timeout intervals.
-.It Fl t
-Set the initial retransmit timeout to the specified value.
-May be useful for fine tuning UDP mounts over internetworks
-with high packet loss rates or an overloaded server.
-Try increasing the interval if
-.Xr nfsstat 1
-shows high retransmit rates while the file system is active or reducing the
-value if there is a low retransmit rate but long response delay observed.
-(Normally, the -d option should be specified when using this option to manually
-tune the timeout
-interval.)
-.It Fl w
-Set the write data size to the specified value.
-Ditto the comments w.r.t. the
-.Fl r
-option, but using the
-.Dq "fragments dropped due to timeout"
-value on the server instead of the client.
-Note that both the
-.Fl r
-and
-.Fl w
-options should only be used as a last ditch effort at improving performance
-when mounting servers that do not support TCP mounts.
-.It Fl x
-Set the retransmit timeout count for soft mounts to the specified value.
-.El
-.Sh SEE ALSO
-.Xr mount 2 ,
-.Xr unmount 2 ,
-.Xr fstab 5 ,
-.Xr mount 8
-.Sh BUGS
-Due to the way that Sun RPC is implemented on top of UDP (unreliable datagram)
-transport, tuning such mounts is really a black art that can only be expected
-to have limited success.
-For clients mounting servers that are not on the same
-LAN cable or that tend to be overloaded,
-TCP transport is strongly recommended,
-but unfortunately this is restricted to mostly 4.4BSD servers.
--- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c
+++ /dev/null
@@ -1,1045 +1,0 @@
-/*
- * Copyright (c) 1992, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1992, 1993, 1994\n\
-	The Regents of the University of California.  All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)mount_nfs.c	8.11 (Berkeley) 5/4/95";
-#endif
-static const char rcsid[] =
-	"$Id: mount_nfs.c,v 1.29 1998/07/06 07:15:53 charnier Exp $";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/syslog.h>
-
-#include <rpc/rpc.h>
-#include <rpc/pmap_clnt.h>
-#include <rpc/pmap_prot.h>
-
-#ifdef ISO
-#include <netiso/iso.h>
-#endif
-
-#ifdef NFSKERB
-#include <kerberosIV/des.h>
-#include <kerberosIV/krb.h>
-#endif
-
-#include <sys/vnode.h>
-#include "9p.h"
-#include "9auth.h"
-#include "9fs.h"
-#include <pwd.h>
-
-#include <nfs/rpcv2.h>
-#include <nfs/nfsproto.h>
-#include <nfs/nfs.h>
-#include <nfs/nqnfs.h>
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "mntopts.h"
-
-#define	ALTF_BG		0x1
-#define ALTF_NOCONN	0x2
-#define ALTF_DUMBTIMR	0x4
-#define ALTF_INTR	0x8
-#define ALTF_KERB	0x10
-#define ALTF_NFSV3	0x20
-#define ALTF_RDIRPLUS	0x40
-#define	ALTF_MNTUDP	0x80
-#define ALTF_RESVPORT	0x100
-#define ALTF_SEQPACKET	0x200
-#define ALTF_NQNFS	0x400
-#define ALTF_SOFT	0x800
-#define ALTF_TCP	0x1000
-#define ALTF_PORT	0x2000
-#define ALTF_NFSV2	0x4000
-#define ALTF_ACREGMIN	0x8000
-#define ALTF_ACREGMAX	0x10000
-#define ALTF_ACDIRMIN	0x20000
-#define ALTF_ACDIRMAX	0x40000
-
-struct mntopt mopts[] = {
-	MOPT_STDOPTS,
-	MOPT_FORCE,
-	MOPT_UPDATE,
-	MOPT_ASYNC,
-	{ "bg", 0, ALTF_BG, 1 },
-	{ "conn", 1, ALTF_NOCONN, 1 },
-	{ "dumbtimer", 0, ALTF_DUMBTIMR, 1 },
-	{ "intr", 0, ALTF_INTR, 1 },
-#ifdef NFSKERB
-	{ "kerb", 0, ALTF_KERB, 1 },
-#endif
-	{ "nfsv3", 0, ALTF_NFSV3, 1 },
-	{ "rdirplus", 0, ALTF_RDIRPLUS, 1 },
-	{ "mntudp", 0, ALTF_MNTUDP, 1 },
-	{ "resvport", 0, ALTF_RESVPORT, 1 },
-#ifdef ISO
-	{ "seqpacket", 0, ALTF_SEQPACKET, 1 },
-#endif
-	{ "nqnfs", 0, ALTF_NQNFS, 1 },
-	{ "soft", 0, ALTF_SOFT, 1 },
-	{ "tcp", 0, ALTF_TCP, 1 },
-	{ "port=", 0, ALTF_PORT, 1 },
-	{ "nfsv2", 0, ALTF_NFSV2, 1 },
-	{ "acregmin=", 0, ALTF_ACREGMIN, 1 },
-	{ "acregmax=", 0, ALTF_ACREGMAX, 1 },
-	{ "acdirmin=", 0, ALTF_ACDIRMIN, 1 },
-	{ "acdirmax=", 0, ALTF_ACDIRMAX, 1 },
-	{ NULL }
-};
-
-struct u9fs_args u9fsdefargs = {
-        1,
-	(struct sockaddr *)0,
-	sizeof (struct sockaddr_in),
-	SOCK_SEQPACKET,
-	IPPROTO_IL,
-	0,
-	0,
-	0,
-	0,
-	0,
-	(char *)0,
-	0,
-	0,
-	SOCK_SEQPACKET,
-	IPPROTO_IL,
-};
-
-struct nfhret {
-	u_long		stat;
-	long		vers;
-	long		auth;
-	long		fhsize;
-	u_char		nfh[NFSX_V3FHMAX];
-};
-#define	DEF_RETRY	10000
-#define	BGRND	1
-#define	ISBGRND	2
-int retrycnt = DEF_RETRY;
-int opflags = 0;
-int nfsproto = IPPROTO_UDP;
-int mnttcp_ok = 1;
-u_short port_no = 0;
-enum {
-	ANY,
-	V2,
-	V3
-} mountmode = ANY;
-
-#ifdef NFSKERB
-char inst[INST_SZ];
-char realm[REALM_SZ];
-struct {
-	u_long		kind;
-	KTEXT_ST	kt;
-} ktick;
-struct nfsrpc_nickverf kverf;
-struct nfsrpc_fullblock kin, kout;
-NFSKERBKEY_T kivec;
-CREDENTIALS kcr;
-struct timeval ktv;
-NFSKERBKEYSCHED_T kerb_keysched;
-#endif
-
-int	getnfsargs __P((char *, struct u9fs_args *));
-#ifdef ISO
-struct	iso_addr *iso_addr __P((const char *));
-#endif
-void	set_rpc_maxgrouplist __P((int));
-void	usage __P((void)) __dead2;
-int	xdr_dir __P((XDR *, char *));
-int	xdr_fh __P((XDR *, struct nfhret *));
-
-void gethostaddr(char * hostp, struct sockaddr_in * saddr);
-
-/*
- * Used to set mount flags with getmntopts.  Call with dir=TRUE to
- * initialize altflags from the current mount flags.  Call with
- * dir=FALSE to update mount flags with the new value of altflags after
- * the call to getmntopts.
- */
-static void
-setflags(int* altflags, int* nfsflags, int dir)
-{
-#define F2(af, nf)					\
-	if (dir) {					\
-		if (*nfsflags & NFSMNT_##nf)		\
-			*altflags |= ALTF_##af;		\
-		else					\
-			*altflags &= ~ALTF_##af;	\
-	} else {					\
-		if (*altflags & ALTF_##af)		\
-			*nfsflags |= NFSMNT_##nf;	\
-		else					\
-			*nfsflags &= ~NFSMNT_##nf;	\
-	}
-#define F(f)	F2(f,f)
-
-	F(NOCONN);
-	F(DUMBTIMR);
-	F2(INTR, INT);
-#ifdef NFSKERB
-	F(KERB);
-#endif
-	F(RDIRPLUS);
-	F(RESVPORT);
-	F(NQNFS);
-	F(SOFT);
-
-#undef F
-#undef F2
-}
-
-int
-main(argc, argv)
-	int argc;
-	char *argv[];
-{
-	register int c;
-	register struct u9fs_args *nfsargsp;
-	struct u9fs_args u9fsargs;
-	struct nfsd_cargs ncd;
-	int mntflags, altflags, i, nfssvc_flag, num;
-	char *name, *p, *spec;
-	struct vfsconf vfc;
-	int error = 0;
-	static struct sockaddr_in authaddr;
-
-#ifdef NFSKERB
-	uid_t last_ruid;
-
-	last_ruid = -1;
-	(void)strcpy(realm, KRB_REALM);
-	if (sizeof (struct nfsrpc_nickverf) != RPCX_NICKVERF ||
-	    sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK ||
-	    ((char *)&ktick.kt) - ((char *)&ktick) != NFSX_UNSIGNED ||
-	    ((char *)ktick.kt.dat) - ((char *)&ktick) != 2 * NFSX_UNSIGNED)
-		fprintf(stderr, "Yikes! NFSKERB structs not packed!!\n");
-#endif /* NFSKERB */
-	retrycnt = DEF_RETRY;
-
-	mntflags = 0;
-	altflags = 0;
-	u9fsargs = u9fsdefargs;
-	nfsargsp = &u9fsargs;
-	while ((c = getopt(argc, argv,
-	    "23a:bcdD:g:I:iKL:lm:No:PpqR:r:sTt:w:x:Uu:")) != -1)
-		switch (c) {
-		case '2':
-			mountmode = V2;
-			break;
-		case '3':
-			mountmode = V3;
-			break;
-		case 'a':
-			num = strtol(optarg, &p, 10);
-			if (*p || num < 0)
-				errx(1, "illegal -a value -- %s", optarg);
-#if 0
-			nfsargsp->readahead = num;
-			nfsargsp->flags |= NFSMNT_READAHEAD;
-#endif
-			break;
-		case 'b':
-			opflags |= BGRND;
-			break;
-		case 'c':
-			nfsargsp->flags |= NFSMNT_NOCONN;
-			break;
-		case 'D':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -D value -- %s", optarg);
-#if 0
-			nfsargsp->deadthresh = num;
-			nfsargsp->flags |= NFSMNT_DEADTHRESH;
-#endif
-			break;
-		case 'd':
-			nfsargsp->flags |= NFSMNT_DUMBTIMR;
-			break;
-		case 'g':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -g value -- %s", optarg);
-#ifdef __FreeBSD__
-			set_rpc_maxgrouplist(num);
-#endif
-#if 0
-			nfsargsp->maxgrouplist = num;
-			nfsargsp->flags |= NFSMNT_MAXGRPS;
-#endif
-			break;
-		case 'I':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -I value -- %s", optarg);
-			nfsargsp->readdirsize = num;
-			nfsargsp->flags |= NFSMNT_READDIRSIZE;
-			break;
-		case 'i':
-			nfsargsp->flags |= NFSMNT_INT;
-			break;
-#ifdef NFSKERB
-		case 'K':
-			nfsargsp->flags |= NFSMNT_KERB;
-			break;
-#endif
-		case 'L':
-			num = strtol(optarg, &p, 10);
-			if (*p || num < 2)
-				errx(1, "illegal -L value -- %s", optarg);
-#if 0
-			nfsargsp->leaseterm = num;
-			nfsargsp->flags |= NFSMNT_LEASETERM;
-#endif
-			break;
-		case 'l':
-			nfsargsp->flags |= NFSMNT_RDIRPLUS;
-			break;
-#ifdef NFSKERB
-		case 'm':
-			(void)strncpy(realm, optarg, REALM_SZ - 1);
-			realm[REALM_SZ - 1] = '\0';
-			break;
-#endif
-		case 'N':
-			nfsargsp->flags &= ~NFSMNT_RESVPORT;
-			break;
-		case 'o':
-			altflags = 0;
-			setflags(&altflags, &nfsargsp->flags, TRUE);
-			if (mountmode == V2)
-				altflags |= ALTF_NFSV2;
-			else if (mountmode == V3)
-				altflags |= ALTF_NFSV3;
-			getmntopts(optarg, mopts, &mntflags, &altflags);
-			setflags(&altflags, &nfsargsp->flags, FALSE);
-			/*
-			 * Handle altflags which don't map directly to
-			 * mount flags.
-			 */
-			if(altflags & ALTF_BG)
-				opflags |= BGRND;
-			if(altflags & ALTF_MNTUDP)
-				mnttcp_ok = 0;
-#ifdef ISO
-			if(altflags & ALTF_SEQPACKET)
-				nfsargsp->sotype = SOCK_SEQPACKET;
-#endif
-			if(altflags & ALTF_TCP) {
-				nfsargsp->sotype = SOCK_STREAM;
-				nfsproto = IPPROTO_TCP;
-			}
-			if(altflags & ALTF_PORT)
-				port_no = atoi(strstr(optarg, "port=") + 5);
-			mountmode = ANY;
-			if(altflags & ALTF_NFSV2)
-				mountmode = V2;
-			if(altflags & ALTF_NFSV3)
-				mountmode = V3;
-#if 0
-			if(altflags & ALTF_ACREGMIN)
-				nfsargsp->acregmin = atoi(strstr(optarg,
-				    "acregmin=") + 9);
-			if(altflags & ALTF_ACREGMAX)
-				nfsargsp->acregmax = atoi(strstr(optarg,
-				    "acregmax=") + 9);
-			if(altflags & ALTF_ACDIRMIN)
-				nfsargsp->acdirmin = atoi(strstr(optarg,
-				    "acdirmin=") + 9);
-			if(altflags & ALTF_ACDIRMAX)
-				nfsargsp->acdirmax = atoi(strstr(optarg,
-				    "acdirmax=") + 9);
-#endif
-			break;
-		case 'P':
-			/* obsolete for NFSMNT_RESVPORT, now default */
-			break;
-#ifdef ISO
-		case 'p':
-			nfsargsp->sotype = SOCK_SEQPACKET;
-			break;
-#endif
-		case 'q':
-			mountmode = V3;
-			nfsargsp->flags |= NFSMNT_NQNFS;
-			break;
-		case 'R':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -R value -- %s", optarg);
-			retrycnt = num;
-			break;
-		case 'r':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -r value -- %s", optarg);
-			nfsargsp->rsize = num;
-			nfsargsp->flags |= NFSMNT_RSIZE;
-			break;
-		case 's':
-			nfsargsp->flags |= NFSMNT_SOFT;
-			break;
-		case 'T':
-			nfsargsp->sotype = SOCK_STREAM;
-			nfsproto = IPPROTO_TCP;
-			break;
-		case 't':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -t value -- %s", optarg);
-#if 0
-			nfsargsp->timeo = num;
-			nfsargsp->flags |= NFSMNT_TIMEO;
-#endif
-			break;
-		case 'w':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -w value -- %s", optarg);
-			nfsargsp->wsize = num;
-			nfsargsp->flags |= NFSMNT_WSIZE;
-			break;
-		case 'x':
-			num = strtol(optarg, &p, 10);
-			if (*p || num <= 0)
-				errx(1, "illegal -x value -- %s", optarg);
-#if 0
-			nfsargsp->retrans = num;
-			nfsargsp->flags |= NFSMNT_RETRANS;
-#endif
-			break;
-		case 'U':
-			mnttcp_ok = 0;
-			break;
-		case 'u':
-		        if( (p = index(optarg, '@')) ) {
-			  *p++ = 0;
-			  strncpy(nfsargsp->uname, optarg, U9FS_NAMELEN);
-			  gethostaddr(p, & authaddr);
-			  authaddr.sin_family = AF_INET;
-			  authaddr.sin_port = htons(U9AUTH_ILPORT);
-			  nfsargsp->authaddr = (struct sockaddr *) & authaddr;
-			  nfsargsp->authaddrlen = sizeof(authaddr);
-			} else
-			  strncpy(nfsargsp->uname, optarg, U9FS_NAMELEN);
- 		        break;
-		default:
-			usage();
-			break;
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (argc != 2) {
-		usage();
-		/* NOTREACHED */
-	}
-
-	spec = *argv++;
-	name = *argv;
-
-	if (!getnfsargs(spec, nfsargsp))
-		exit(1);
-
-#ifdef __FreeBSD__
-	error = getvfsbyname("u9fs", &vfc);
-	if (error && vfsisloadable("nfs")) {
-		if(vfsload("nfs"))
-			err(EX_OSERR, "vfsload(nfs)");
-		endvfsent();	/* clear cache */
-		error = getvfsbyname("nfs", &vfc);
-	}
-	if (error)
-		errx(EX_OSERR, "nfs filesystem is not available");
-
-	if (mount(vfc.vfc_name, name, mntflags, nfsargsp))
-		err(1, "%s", name);
-#else
-	if (mount("nfs", name, mntflags, nfsargsp))
-		err(1, "%s", name);
-#endif
-	if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) {
-		if ((opflags & ISBGRND) == 0) {
-			if ((i = fork())) {
-				if (i == -1)
-					err(1, "nqnfs 1");
-				exit(0);
-			}
-			(void) setsid();
-			(void) close(STDIN_FILENO);
-			(void) close(STDOUT_FILENO);
-			(void) close(STDERR_FILENO);
-			(void) chdir("/");
-		}
-		openlog("mount_nfs:", LOG_PID, LOG_DAEMON);
-		nfssvc_flag = NFSSVC_MNTD;
-		ncd.ncd_dirp = name;
-		while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) {
-			if (errno != ENEEDAUTH) {
-				syslog(LOG_ERR, "nfssvc err %m");
-				continue;
-			}
-			nfssvc_flag =
-			    NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL;
-#ifdef NFSKERB
-			/*
-			 * Set up as ncd_authuid for the kerberos call.
-			 * Must set ruid to ncd_authuid and reset the
-			 * ticket name iff ncd_authuid is not the same
-			 * as last time, so that the right ticket file
-			 * is found.
-			 * Get the Kerberos credential structure so that
-			 * we have the session key and get a ticket for
-			 * this uid.
-			 * For more info see the IETF Draft "Authentication
-			 * in ONC RPC".
-			 */
-			if (ncd.ncd_authuid != last_ruid) {
-				char buf[512];
-				(void)sprintf(buf, "%s%d",
-					      TKT_ROOT, ncd.ncd_authuid);
-				krb_set_tkt_string(buf);
-				last_ruid = ncd.ncd_authuid;
-			}
-			setreuid(ncd.ncd_authuid, 0);
-			kret = krb_get_cred(NFS_KERBSRV, inst, realm, &kcr);
-			if (kret == RET_NOTKT) {
-		            kret = get_ad_tkt(NFS_KERBSRV, inst, realm,
-				DEFAULT_TKT_LIFE);
-			    if (kret == KSUCCESS)
-				kret = krb_get_cred(NFS_KERBSRV, inst, realm,
-				    &kcr);
-			}
-			if (kret == KSUCCESS)
-			    kret = krb_mk_req(&ktick.kt, NFS_KERBSRV, inst,
-				realm, 0);
-
-			/*
-			 * Fill in the AKN_FULLNAME authenticator and verifier.
-			 * Along with the Kerberos ticket, we need to build
-			 * the timestamp verifier and encrypt it in CBC mode.
-			 */
-			if (kret == KSUCCESS &&
-			    ktick.kt.length <= (RPCAUTH_MAXSIZ-3*NFSX_UNSIGNED)
-			    && gettimeofday(&ktv, (struct timezone *)0) == 0) {
-			    ncd.ncd_authtype = RPCAUTH_KERB4;
-			    ncd.ncd_authstr = (u_char *)&ktick;
-			    ncd.ncd_authlen = nfsm_rndup(ktick.kt.length) +
-				3 * NFSX_UNSIGNED;
-			    ncd.ncd_verfstr = (u_char *)&kverf;
-			    ncd.ncd_verflen = sizeof (kverf);
-			    memmove(ncd.ncd_key, kcr.session,
-				sizeof (kcr.session));
-			    kin.t1 = htonl(ktv.tv_sec);
-			    kin.t2 = htonl(ktv.tv_usec);
-			    kin.w1 = htonl(NFS_KERBTTL);
-			    kin.w2 = htonl(NFS_KERBTTL - 1);
-			    bzero((caddr_t)kivec, sizeof (kivec));
-
-			    /*
-			     * Encrypt kin in CBC mode using the session
-			     * key in kcr.
-			     */
-			    XXX
-
-			    /*
-			     * Finally, fill the timestamp verifier into the
-			     * authenticator and verifier.
-			     */
-			    ktick.kind = htonl(RPCAKN_FULLNAME);
-			    kverf.kind = htonl(RPCAKN_FULLNAME);
-			    NFS_KERBW1(ktick.kt) = kout.w1;
-			    ktick.kt.length = htonl(ktick.kt.length);
-			    kverf.verf.t1 = kout.t1;
-			    kverf.verf.t2 = kout.t2;
-			    kverf.verf.w2 = kout.w2;
-			    nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH;
-			}
-			setreuid(0, 0);
-#endif /* NFSKERB */
-		}
-	}
-	exit(0);
-}
-
-/*
- * Return RPC_SUCCESS if server responds.
- */
-enum clnt_stat
-pingnfsserver(addr, version, sotype)
-	struct sockaddr_in *addr;
-	int version;
-	int sotype;
-{
-	struct sockaddr_in sin;
-	int tport;
-	CLIENT *clp;
-	int so = RPC_ANYSOCK;
-	enum clnt_stat stat;
-	struct timeval pertry, try;
-
-	sin = *addr;
-
-	if ((tport = port_no ? port_no :
-	     pmap_getport(&sin, RPCPROG_NFS, version, nfsproto)) == 0) {
-		return rpc_createerr.cf_stat;
-	}
-
-	sin.sin_port = htons(tport);
-
-	pertry.tv_sec = 10;
-	pertry.tv_usec = 0;
-	if (sotype == SOCK_STREAM)
-		clp = clnttcp_create(&sin, RPCPROG_NFS, version,
-				     &so, 0, 0);
-	else
-		clp = clntudp_create(&sin, RPCPROG_NFS, version,
-				     pertry, &so);
-	if (clp == NULL)
-		return rpc_createerr.cf_stat;
-	
-	try.tv_sec = 10;
-	try.tv_usec = 0;
-	stat = clnt_call(clp, NFSPROC_NULL,
-			 xdr_void, NULL, xdr_void, NULL, try);
-
-	clnt_destroy(clp);
-
-	return stat;
-}
-
-int load_9uid(struct u9fs_args * nfsargsp)
-{
-  FILE * fd;
-  char line[80], * cp;
-  int nusers, siz, n;
-  struct p9user * p9p, * p9alloc;
-
-  if( (fd = fopen("/etc/9uid.conf", "r")) == 0 ) 
-    errx(1, "fopen");
-
-  siz = 128;
-  if( (p9alloc = malloc(siz*sizeof(struct p9user))) == 0 )
-    errx(1, "malloc");
-
-  nusers = 0;
-  p9p = p9alloc;
-  while(1) {    
-    if( nusers < siz ) {
-      if ( fgets(line, 80, fd) == 0 )
-	break;
-      cp = line;
-      if ( strsep(&cp, " \t") == 0 )
-	errx(1, "bad format in 9uid.conf");
-      p9p->p9_uid = atoi(cp);
-      strncpy(p9p->p9_name, line, U9FS_NAMELEN);
-      nusers++;
-      p9p++;
-    } else {
-      if( (p9p = realloc(p9alloc, 2*siz*sizeof(struct p9user))) == 0 )
-	errx(1, "realloc");
-      p9alloc = p9p;
-      p9p = p9alloc + siz;
-      siz <<= 1;
-    }
-  }
-  
-  nfsargsp->nusers = nusers;
-  nfsargsp->users = p9alloc;
-  
-  return 0;
-}
-
-int
-passtokey(char *key, char *p)
-{
-	u_char buf[U9FS_NAMELEN], *t;
-	int i, n;
-
-	n = strlen(p);
-	if(n >= U9FS_NAMELEN)
-		n = U9FS_NAMELEN-1;
-	memset(buf, ' ', 8);
-	t = buf;
-	strncpy((char*)t, p, n);
-	t[n] = '\0';
-	memset(key, 0, U9AUTH_DESKEYLEN);
-	for(;;){
-		for(i = 0; i < U9AUTH_DESKEYLEN; i++)
-			key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
-		if(n <= 8)
-			return 1;
-		n -= 8;
-		t += 8;
-		if(n < 8){
-			t -= 8 - n;
-			n = 8;
-		}
-		encrypt9(key, t, 8);
-	}
-	return 1;	/* not reached */
-}
-
-void load_9key(struct u9fs_args * nfsargsp)
-{
-  char * p;
-
-  p = getpass("Plan 9 Password: ");
-  passtokey(nfsargsp->key, p);
-}
-
-void gethostaddr(char * hostp, struct sockaddr_in * saddr)
-{
-  struct hostent *hp;
-	/*
-	 * Handle an internet host address and reverse resolve it if
-	 * doing Kerberos.
-	 */
-	if (isdigit(*hostp)) {
-		if ((saddr->sin_addr.s_addr = inet_addr(hostp)) == -1) {
-			warnx("bad net address %s", hostp);
-		}
-	} else if ((hp = gethostbyname(hostp)) != NULL)
-		memmove(&saddr->sin_addr, hp->h_addr, 
-		    MIN(hp->h_length, sizeof(saddr->sin_addr)));
-	else {
-		warnx("can't get net id for host");
-        }
-}
-
-int
-getnfsargs(spec, nfsargsp)
-	char *spec;
-	struct u9fs_args *nfsargsp;
-{
-	register CLIENT *clp;
-	struct hostent *hp;
-	static struct sockaddr_in saddr;
-#ifdef ISO
-	static struct sockaddr_iso isoaddr;
-	struct iso_addr *isop;
-	int isoflag = 0;
-#endif
-	struct timeval pertry, try;
-	enum clnt_stat clnt_stat;
-	int so = RPC_ANYSOCK, i, nfsvers, mntvers, orgcnt;
-	char *hostp, *delimp;
-#ifdef NFSKERB
-	char *cp;
-#endif
-	u_short tport;
-	static struct nfhret nfhret;
-	static char nam[MNAMELEN + 1];
-
-	strncpy(nam, spec, MNAMELEN);
-	nam[MNAMELEN] = '\0';
-	if ((delimp = strchr(spec, '@')) != NULL) {
-		hostp = delimp + 1;
-	} else if ((delimp = strchr(spec, ':')) != NULL) {
-		hostp = spec;
-		spec = delimp + 1;
-	} else {
-		warnx("no <host>:<dirpath> or <dirpath>@<host> spec");
-		return (0);
-	}
-	*delimp = '\0';
-	/*
-	 * DUMB!! Until the mount protocol works on iso transport, we must
-	 * supply both an iso and an inet address for the host.
-	 */
-#ifdef ISO
-	if (!strncmp(hostp, "iso=", 4)) {
-		u_short isoport;
-
-		hostp += 4;
-		isoflag++;
-		if ((delimp = strchr(hostp, '+')) == NULL) {
-			warnx("no iso+inet address");
-			return (0);
-		}
-		*delimp = '\0';
-		if ((isop = iso_addr(hostp)) == NULL) {
-			warnx("bad ISO address");
-			return (0);
-		}
-		memset(&isoaddr, 0, sizeof (isoaddr));
-		memmove(&isoaddr.siso_addr, isop, sizeof (struct iso_addr));
-		isoaddr.siso_len = sizeof (isoaddr);
-		isoaddr.siso_family = AF_ISO;
-		isoaddr.siso_tlen = 2;
-		isoport = htons(NFS_PORT);
-		memmove(TSEL(&isoaddr), &isoport, isoaddr.siso_tlen);
-		hostp = delimp + 1;
-	}
-#endif /* ISO */
-
-	gethostaddr(hostp, & saddr);
-#ifdef NFSKERB
-	if ((nfsargsp->flags & NFSMNT_KERB)) {
-		if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr,
-		    sizeof (u_long), AF_INET)) == (struct hostent *)0) {
-			warnx("can't reverse resolve net address");
-			return (0);
-		}
-		memmove(&saddr.sin_addr, hp->h_addr, 
-		    MIN(hp->h_length, sizeof(saddr.sin_addr)));
-		strncpy(inst, hp->h_name, INST_SZ);
-		inst[INST_SZ - 1] = '\0';
-		if (cp = strchr(inst, '.'))
-			*cp = '\0';
-	}
-#endif /* NFSKERB */
-
-	orgcnt = retrycnt;
-tryagain:
-	if (mountmode == ANY || mountmode == V3) {
-		nfsvers = 3;
-		mntvers = 3;
-		nfsargsp->flags |= NFSMNT_NFSV3;
-	} else {
-		nfsvers = 2;
-		mntvers = 1;
-		nfsargsp->flags &= ~NFSMNT_NFSV3;
-	}
-	tport = port_no ? port_no : U9FS_PORT;
-
-#if 0
-	nfhret.stat = EACCES;	/* Mark not yet successful */
-	while (retrycnt > 0) {
-		saddr.sin_family = AF_INET;
-		saddr.sin_port = htons(PMAPPORT);
-		if ((tport = port_no ? port_no :
-		     pmap_getport(&saddr, RPCPROG_NFS,
-		    		  nfsvers, nfsproto)) == 0) {
-			if ((opflags & ISBGRND) == 0)
-				clnt_pcreateerror("NFS Portmap");
-		} else {
-			/*
-			 * First ping the nfs server to see if it supports
-			 * the version of the protocol we want to use.
-			 */
-			clnt_stat = pingnfsserver(&saddr, nfsvers,
-						  nfsargsp->sotype);
-			if (clnt_stat == RPC_PROGVERSMISMATCH) {
-				if (mountmode == ANY) {
-					mountmode = V2;
-					goto tryagain;
-				} else {
-					errx(1, "can't contact NFS server");
-				}
-			}
-			saddr.sin_port = 0;
-			pertry.tv_sec = 10;
-			pertry.tv_usec = 0;
-			if (mnttcp_ok && nfsargsp->sotype == SOCK_STREAM)
-			    clp = clnttcp_create(&saddr, RPCPROG_MNT, mntvers,
-				&so, 0, 0);
-			else
-			    clp = clntudp_create(&saddr, RPCPROG_MNT, mntvers,
-				pertry, &so);
-			if (clp == NULL) {
-				if ((opflags & ISBGRND) == 0)
-					clnt_pcreateerror("Cannot MNT RPC");
-			} else {
-				clp->cl_auth = authunix_create_default();
-				try.tv_sec = 10;
-				try.tv_usec = 0;
-				if (nfsargsp->flags & NFSMNT_KERB)
-				    nfhret.auth = RPCAUTH_KERB4;
-				else
-				    nfhret.auth = RPCAUTH_UNIX;
-				nfhret.vers = mntvers;
-				clnt_stat = clnt_call(clp, RPCMNT_MOUNT,
-				    xdr_dir, spec, xdr_fh, &nfhret, try);
-				if (clnt_stat != RPC_SUCCESS) {
-					if (clnt_stat == RPC_PROGVERSMISMATCH) {
-						if (mountmode == ANY) {
-							mountmode = V2;
-							goto tryagain;
-						} else {
-							errx(1, "%s",
-							     clnt_sperror(clp, "MNT RPC"));
-						}
-					}
-					if ((opflags & ISBGRND) == 0)
-						warnx("%s", clnt_sperror(clp,
-						    "bad MNT RPC"));
-				} else {
-					auth_destroy(clp->cl_auth);
-					clnt_destroy(clp);
-					retrycnt = 0;
-				}
-			}
-		}
-		if (--retrycnt > 0) {
-			if (opflags & BGRND) {
-				opflags &= ~BGRND;
-				if ((i = fork())) {
-					if (i == -1)
-						err(1, "nqnfs 2");
-					exit(0);
-				}
-				(void) setsid();
-				(void) close(STDIN_FILENO);
-				(void) close(STDOUT_FILENO);
-				(void) close(STDERR_FILENO);
-				(void) chdir("/");
-				opflags |= ISBGRND;
-			}
-			sleep(60);
-		}
-	}
-	if (nfhret.stat) {
-		if (opflags & ISBGRND)
-			exit(1);
-		warnx("can't access %s: %s", spec, strerror(nfhret.stat));
-		return (0);
-	}
-#endif
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons(tport);
-#ifdef ISO
-	if (isoflag) {
-		nfsargsp->addr = (struct sockaddr *) &isoaddr;
-		nfsargsp->addrlen = sizeof (isoaddr);
-	} else
-#endif /* ISO */
-	{
-		nfsargsp->addr = (struct sockaddr *) &saddr;
-		nfsargsp->addrlen = sizeof (saddr);
-	}
-#if 0
-	nfsargsp->fh = nfhret.nfh;
-#endif
-	nfsargsp->fhsize = nfhret.fhsize;
-	nfsargsp->hostname = nam;
-	
-	load_9key(nfsargsp);
-	if( load_9uid(nfsargsp) )
-	  errx(1, "can't load 9uid.conf");
-
-	return (1);
-}
-
-/*
- * xdr routines for mount rpc's
- */
-int
-xdr_dir(xdrsp, dirp)
-	XDR *xdrsp;
-	char *dirp;
-{
-	return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
-}
-
-int
-xdr_fh(xdrsp, np)
-	XDR *xdrsp;
-	register struct nfhret *np;
-{
-	register int i;
-	long auth, authcnt, authfnd = 0;
-
-	if (!xdr_u_long(xdrsp, &np->stat))
-		return (0);
-	if (np->stat)
-		return (1);
-	switch (np->vers) {
-	case 1:
-		np->fhsize = NFSX_V2FH;
-		return (xdr_opaque(xdrsp, (caddr_t)np->nfh, NFSX_V2FH));
-	case 3:
-		if (!xdr_long(xdrsp, &np->fhsize))
-			return (0);
-		if (np->fhsize <= 0 || np->fhsize > NFSX_V3FHMAX)
-			return (0);
-		if (!xdr_opaque(xdrsp, (caddr_t)np->nfh, np->fhsize))
-			return (0);
-		if (!xdr_long(xdrsp, &authcnt))
-			return (0);
-		for (i = 0; i < authcnt; i++) {
-			if (!xdr_long(xdrsp, &auth))
-				return (0);
-			if (auth == np->auth)
-				authfnd++;
-		}
-		/*
-		 * Some servers, such as DEC's OSF/1 return a nil authenticator
-		 * list to indicate RPCAUTH_UNIX.
-		 */
-		if (!authfnd && (authcnt > 0 || np->auth != RPCAUTH_UNIX))
-			np->stat = EAUTH;
-		return (1);
-	};
-	return (0);
-}
-
-void
-usage()
-{
-	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
-"usage: mount_nfs [-23KNPTUbcdilqs] [-D deadthresh] [-I readdirsize]",
-"                 [-L leaseterm] [-R retrycnt] [-a maxreadahead]",
-"                 [-g maxgroups] [-m realm] [-o options] [-r readsize]",
-"                 [-t timeout] [-w writesize] [-x retrans] rhost:path node");
-	exit(1);
-}
-
--- a/sys/src/cmd/unix/README
+++ /dev/null
@@ -1,51 +1,0 @@
-
-This directory contains source for some programs that
-help Plan 9 co-exist with the non-Plan 9 world.
-
-	9pfreebsd/
-		Patches to FreeBSD 3.2 to add the IL network protocol
-		and the pre-9P2000 version of 9P.
-
-	drawterm/
-		Drawterm is a Unix and Windows program that simulates
-		a Plan 9 terminal to connect to a Plan 9 cpu server.
-
-		See drawterm/README for details.
-
-	u9fs/
-		U9fs is a simple 9P server that runs on Unix.
-		It serves both 9P2000 and the older 9P.
-
-	netkey.c
-		A standalone Unix version of Plan 9's netkey(1).
-
-	winstart
-	winplumb.c
-	winplumb.exe
-		Winstart is a shell script to be used with the plumber
-		to relay plumbing messages (typically URLs) to a Windows
-		machine.  It is particularly useful with VMware.
-
-The following programs at external locations may also be of interest:
-
-	Plan 9 from User Space
-		a Unix port of acme, sam, tcs, and many other Plan 9 programs
-		- http://swtch.com/plan9port
-
-	V9fs
-		a project to write 9P drivers for other operating systems
-		- 9p2000.ko is now part of the standard Linux 2.6 tree
-		- http://v9fs.sourceforge.net/
-
-	spin, the protocol verifier
-		- http://spinroot.com/
-
-	sam
-		older ports of Sam to Unix and Windows
-		- ftp://ftp.demon.co.uk/pub/unix/plan9
-		- ftp://plan9.bell-labs.com/netlib/research/
-
-	9pm
-		an old port of much of the Plan 9 tools to Windows
-		- http://plan9.bell-labs.com/plan9dist/ureg.html
-
--- a/sys/src/cmd/unix/netkey.c
+++ /dev/null
@@ -1,587 +1,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-extern long read(int, void*, long);
-typedef unsigned char uchar;
-typedef unsigned long ulong;
-#define NAMELEN 28
-
-/*********** auth.h ************/
-typedef struct	Ticket		Ticket;
-typedef struct	Ticketreq	Ticketreq;
-typedef struct	Authenticator	Authenticator;
-typedef struct	Nvrsafe		Nvrsafe;
-typedef struct	Passwordreq	Passwordreq;
-typedef struct	Chalstate	Chalstate;
-
-enum
-{
-	DOMLEN=		48,		/* length of an authentication domain name */
-	DESKEYLEN=	7,		/* length of a des key for encrypt/decrypt */
-	CHALLEN=	8,		/* length of a challenge */
-	NETCHLEN=	16,		/* max network challenge length	*/
-	CONFIGLEN=	14,
-
-	KEYDBLEN=	NAMELEN+DESKEYLEN+4+2
-};
-
-/* encryption numberings (anti-replay) */
-enum
-{
-	AuthTreq=1,	/* ticket request */
-	AuthChal=2,	/* challenge box request */
-	AuthPass=3,	/* change password */
-
-	AuthOK=4,	/* reply follows */
-	AuthErr=5,	/* error follows */
-
-	AuthTs=64,	/* ticket encrypted with server's key */
-	AuthTc,		/* ticket encrypted with client's key */
-	AuthAs,		/* server generated authenticator */
-	AuthAc		/* client generated authenticator */
-};
-
-struct Ticketreq
-{
-	char	type;
-	char	authid[NAMELEN];	/* server's encryption id */
-	char	authdom[DOMLEN];	/* server's authentication domain */
-	char	chal[CHALLEN];		/* challenge from server */
-	char	hostid[NAMELEN];	/* host's encryption id */
-	char	uid[NAMELEN];		/* uid of requesting user on host */
-};
-#define	TICKREQLEN	(3*NAMELEN+CHALLEN+DOMLEN+1)
-
-struct Ticket
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];		/* server challenge */
-	char	cuid[NAMELEN];		/* uid on client */
-	char	suid[NAMELEN];		/* uid on server */
-	char	key[DESKEYLEN];		/* nonce DES key */
-};
-#define	TICKETLEN	(CHALLEN+2*NAMELEN+DESKEYLEN+1)
-
-struct Authenticator
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];
-	ulong	id;			/* authenticator id, ++'d with each auth */
-};
-#define	AUTHENTLEN	(CHALLEN+4+1)
-
-struct Passwordreq
-{
-	char	num;
-	char	old[NAMELEN];
-	char	new[NAMELEN];
-};
-#define	PASSREQLEN	(2*NAMELEN+1)
-
-struct Nvrsafe
-{
-	char	machkey[DESKEYLEN];
-	uchar	machsum;
-	char	authkey[DESKEYLEN];
-	uchar	authsum;
-	char	config[CONFIGLEN];
-	uchar	configsum;
-	char	authid[NAMELEN];
-	uchar	authidsum;
-	char	authdom[DOMLEN];
-	uchar	authdomsum;
-};
-
-struct Chalstate
-{
-	int	afd;			/* /dev/authenticate */
-	int	asfd;			/* authdial() */
-	char	chal[NETCHLEN];		/* challenge/response */
-};
-
-
-/************ crypt.c *************/
-/*
- *	Data Encryption Standard
- *	D.P.Mitchell  83/06/08.
- *
- *	block_cipher(key, block, decrypting)
- */
-static	long	ip_low(char [8]);
-static	long	ip_high(char [8]);
-static	void	fp(long, long, char[8]);
-static	void	key_setup(char[DESKEYLEN], char[128]);
-static	void	block_cipher(char[128], char[8], int);
-
-/*
- * destructively encrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-encrypt9(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	for(i = 0; i < n; i++){
-		block_cipher(ekey, buf, 0);
-		buf += 7;
-	}
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 0);
-	return 1;
-}
-
-/*
- * destructively decrypt the buffer, which
- * must be at least 8 characters long.
- */
-int
-decrypt(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	buf += n * 7;
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 1);
-	for(i = 0; i < n; i++){
-		buf -= 7;
-		block_cipher(ekey, buf, 1);
-	}
-	return 1;
-}
-
-/*
- *	Tables for Combined S and P Boxes
- */
-
-static long  s0p[] = {
-0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
-0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
-0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
-0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
-0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
-0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
-0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
-0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
-};
-
-static long  s1p[] = {
-0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
-0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
-0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
-0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
-0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
-0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
-0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
-0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
-};
-
-static long  s2p[] = {
-0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
-0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
-0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
-0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
-0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
-0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
-0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
-0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
-};
-
-static long  s3p[] = {
-0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
-0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
-0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
-0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
-0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
-0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
-0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
-0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
-};
-
-static long  s4p[] = {
-0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
-0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
-0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
-0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
-0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
-0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
-0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
-0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
-};
-
-static long  s5p[] = {
-0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
-0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
-0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
-0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
-0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
-0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
-0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
-0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
-};
-
-static long  s6p[] = {
-0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
-0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
-0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
-0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
-0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
-0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
-0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
-0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
-};
-
-static long  s7p[] = {
-0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
-0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
-0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
-0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
-0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
-0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
-0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
-0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
-};
-
-/*
- *	DES electronic codebook encryption of one block
- */
-static void
-block_cipher(char expanded_key[128], char text[8], int decrypting)
-{
-	char *key;
-	long crypto, temp, right, left;
-	int i, key_offset;
-
-	key = expanded_key;
-	left = ip_low(text);
-	right = ip_high(text);
-	if (decrypting) {
-		key_offset = 16;
-		key = key + 128 - 8;
-	} else
-		key_offset = 0;
-	for (i = 0; i < 16; i++) {
-		temp = (right << 1) | ((right >> 31) & 1);
-		crypto  = s0p[(temp         & 0x3f) ^ *key++];
-		crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
-		crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
-		crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
-		crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
-		crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
-		crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
-		temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
-		crypto |= s7p[temp ^ *key++];
-		temp = left;
-		left = right;
-		right = temp ^ crypto;
-		key -= key_offset;
-	}
-	/*
-	 *	standard final permutation (IPI)
-	 *	left and right are reversed here
-	 */
-	fp(right, left, text);
-}
-
-/*
- *	Initial Permutation
- */
-static long iptab[] = {
-	0x00000000, 0x00008000, 0x00000000, 0x00008000,
-	0x00000080, 0x00008080, 0x00000080, 0x00008080
-};
-
-static long
-ip_low(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 4) & 7] >> i;
-		l |= iptab[block[i] & 7] << (16 - i);
-	}
-	return l;
-}
-
-static long
-ip_high(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 5) & 7] >> i;
-		l |= iptab[(block[i] >> 1) & 7] << (16 - i);
-	}
-	return l;
-}
-
-/*
- *	Final Permutation
- */
-static unsigned long	fptab[] = {
-0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
-0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
-};
-
-static void
-fp(long left, long right, char text[8])
-{
-	unsigned long ta[2], t, v[2];
-	int i, j, sh;
-
-	ta[0] = right;
-	ta[1] = left;
-	v[0] = v[1] = 0;
-	for(i = 0; i < 2; i++){
-		t = ta[i];
-		sh = i;
-		for(j = 0; j < 4; j++){
-			v[1] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			v[0] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			sh += 2;
-		}
-	}
-	for(i = 0; i < 2; i++)
-		for(j = 0; j < 4; j++){
-			*text++ = (char)(v[i]&0xff);
-			v[i] >>= 8;
-		}
-}
-
-/*
- *	Key set-up
- */
-static uchar keyexpand[][15][2] = {
-	{   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 16, 
-	   74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
-	{   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 32, 
-	   64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
-	{   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 32, 
-	   89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
-	{   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  1, 
-	   78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
-	{   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  8, 
-	   85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
-	{  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 32, 
-	   86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
-	{  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 16, 
-	   85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
-	{   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  8, 
-	   83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
-	{   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  2, 
-	   74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
-	{   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  8, 
-	   82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
-	{  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  8, 
-	   94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
-	{   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  8, 
-	   78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
-	{   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  8, 
-	   84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
-	{   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  2, 
-	   69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
-	{   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  2, 
-	   72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
-	{   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  2, 
-	   67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
-	{   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  2, 
-	   72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
-	{   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  2, 
-	   70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
-	{   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 16, 
-	   84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
-	{   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 32, 
-	   78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
-	{   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 16, 
-	   77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
-	{   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  1, 
-	   80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
-	{   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 16, 
-	   72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
-	{   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  8, 
-	   74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
-	{   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  8, 
-	   86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
-	{   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 32, 
-	   85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
-	{   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  2, 
-	   87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
-	{   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 16, 
-	   71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
-	{   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  4, 
-	   83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
-	{   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 16, 
-	   74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
-	{   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 32, 
-	   73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
-	{   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  4, 
-	   91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
-	{   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 16, 
-	   76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
-	{   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  4, 
-	   86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
-	{   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  8, 
-	   84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
-	{   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  1, 
-	   72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
-	{   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  8, 
-	   99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
-	{   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 32, 
-	   81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
-	{   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  4, 
-	   73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
-	{   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  1, 
-	   86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
-	{  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  4, 
-	   85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
-	{   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  8, 
-	   70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
-	{   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 16, 
-	   80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
-	{  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  1, 
-	   73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
-	{   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  8, 
-	   65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
-	{   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 32, 
-	   97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
-	{   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  4, 
-	   79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
-	{   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  4, 
-	   78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
-	{   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  1, 
-	   86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
-	{   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  1, 
-	   74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
-	{   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  8, 
-	   91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
-	{   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 32, 
-	   73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
-	{   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  4, 
-	   65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
-	{   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  8, 
-	   92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
-	{   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  4, 
-	   77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
-	{   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  2, 
-	   77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
-};
-
-static void
-key_setup(char key[DESKEYLEN], char *ek)
-{
-	int i, j, k, mask;
-	uchar (*x)[2];
-
-	memset(ek, 0, 128);
-	x = keyexpand[0];
-	for(i = 0; i < 7; i++){
-		k = key[i];
-		for(mask = 0x80; mask; mask >>= 1){
-			if(k & mask)
-				for(j = 0; j < 15; j++)
-					ek[x[j][0]] |= x[j][1];
-			x += 15;
-		}
-	}
-}
-
-
-/************ netkey main.c *************/
-int
-passtokey(char *key, char *p)
-{
-	uchar buf[NAMELEN], *t;
-	int i, n;
-
-	n = strlen(p);
-	if(n >= NAMELEN)
-		n = NAMELEN-1;
-	memset(buf, ' ', 8);
-	t = buf;
-	strncpy((char*)t, p, n);
-	t[n] = '\0';
-	memset(key, 0, DESKEYLEN);
-	for(;;){
-		for(i = 0; i < DESKEYLEN; i++)
-			key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
-		if(n <= 8)
-			return 1;
-		n -= 8;
-		t += 8;
-		if(n < 8){
-			t -= 8 - n;
-			n = 8;
-		}
-		encrypt9(key, t, 8);
-	}
-}
-
-int
-netcrypt(void *key, void *chal)
-{
-        uchar buf[8], *p;
-
-        strncpy((char*)buf, chal, 7);
-        buf[7] = '\0';
-        for(p = buf; *p && *p != '\n'; p++)
-                ;
-        *p = '\0';
-        encrypt9(key, buf, 8);
-        sprintf(chal, "%.2x%.2x%.2x%.2x", buf[0], buf[1], buf[2], buf[3]);
-        return 1;
-}
-
-void
-main(int argc, char *argv[])
-{
-	char buf[32], pass[32], key[DESKEYLEN];
-	int n;
-
-	printf("Run this directly on the local processor, NOT in a\n");
-	printf("      window to a computer across the network.\n");
-	printf("Type when no one else is looking.\n\n");
-	printf("password: ");
-	fflush(stdout);
-	n = read(0, pass, sizeof pass - 1);
-	if(n <= 0)
-		exit(0);
-	pass[n] = 0;
-	if(pass[n-1]=='\n')
-		pass[--n] = 0;
-	if(pass[n-1]=='\r')
-		pass[--n] = 0;
-	passtokey(key,pass);
-	for(;;){
-		printf("challenge: ");
-		fflush(stdout);
-		n = read(0, buf, sizeof buf - 1);
-		if(n <= 0)
-			exit(0);
-		buf[n] = '\0';
-		netcrypt(key, buf);
-		printf("response: %s\n", buf);
-	}
-}
--- a/sys/src/cmd/unix/u9fs/LICENSE
+++ /dev/null
@@ -1,16 +1,0 @@
-The authors of this software are Bob Flandrena, Ken Thompson,
-Rob Pike, and Russ Cox.
-
-		Copyright (c) 1992-2002 by Lucent Technologies.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose without fee is hereby granted, provided that this entire notice
-is included in all copies of any software which is or includes a copy
-or modification of this software and in all copies of the supporting
-documentation for such software.
-
-THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
-REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
-OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-
--- a/sys/src/cmd/unix/u9fs/authnone.c
+++ /dev/null
@@ -1,25 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-#include <u9fs.h>
-
-static char*
-noneauth(Fcall *rx, Fcall *tx)
-{
-	USED(rx);
-	USED(tx);
-	return "u9fs authnone: no authentication required";
-}
-
-static char*
-noneattach(Fcall *rx, Fcall *tx)
-{
-	USED(rx);
-	USED(tx);
-	return nil;
-}
-
-Auth authnone = {
-	"none",
-	noneauth,
-	noneattach,
-};
--- a/sys/src/cmd/unix/u9fs/authp9any.c
+++ /dev/null
@@ -1,540 +1,0 @@
-/*
- * 4th Edition p9any/p9sk1 authentication based on auth9p1.c
- * Nigel Roles ([email protected]) 2003
- */
-
-#include <plan9.h>
-#include <fcall.h>
-#include <u9fs.h>
-#include <stdlib.h>	/* for random stuff */
-
-typedef struct	Ticket		Ticket;
-typedef struct	Ticketreq	Ticketreq;
-typedef struct	Authenticator	Authenticator;
-
-enum
-{
-	DOMLEN=		48,		/* length of an authentication domain name */
-	CHALLEN=	8		/* length of a challenge */
-};
-
-enum {
-	HaveProtos,
-	NeedProto,
-	NeedChal,
-	HaveTreq,
-	NeedTicket,
-	HaveAuth,
-	Established,
-};
-
-/* encryption numberings (anti-replay) */
-enum
-{
-	AuthTreq=1,	/* ticket request */
-	AuthChal=2,	/* challenge box request */
-	AuthPass=3,	/* change password */
-	AuthOK=4,	/* fixed length reply follows */
-	AuthErr=5,	/* error follows */
-	AuthMod=6,	/* modify user */
-	AuthApop=7,	/* apop authentication for pop3 */
-	AuthOKvar=9,	/* variable length reply follows */
-	AuthChap=10,	/* chap authentication for ppp */
-	AuthMSchap=11,	/* MS chap authentication for ppp */
-	AuthCram=12,	/* CRAM verification for IMAP (RFC2195 & rfc2104) */
-	AuthHttp=13,	/* http domain login */
-	AuthVNC=14,	/* http domain login */
-
-
-	AuthTs=64,	/* ticket encrypted with server's key */
-	AuthTc,		/* ticket encrypted with client's key */
-	AuthAs,		/* server generated authenticator */
-	AuthAc,		/* client generated authenticator */
-	AuthTp,		/* ticket encrypted with client's key for password change */
-	AuthHr		/* http reply */
-};
-
-struct Ticketreq
-{
-	char	type;
-	char	authid[NAMELEN];	/* server's encryption id */
-	char	authdom[DOMLEN];	/* server's authentication domain */
-	char	chal[CHALLEN];		/* challenge from server */
-	char	hostid[NAMELEN];	/* host's encryption id */
-	char	uid[NAMELEN];		/* uid of requesting user on host */
-};
-#define	TICKREQLEN	(3*NAMELEN+CHALLEN+DOMLEN+1)
-
-struct Ticket
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];		/* server challenge */
-	char	cuid[NAMELEN];		/* uid on client */
-	char	suid[NAMELEN];		/* uid on server */
-	char	key[DESKEYLEN];		/* nonce DES key */
-};
-#define	TICKETLEN	(CHALLEN+2*NAMELEN+DESKEYLEN+1)
-
-struct Authenticator
-{
-	char	num;			/* replay protection */
-	char	chal[CHALLEN];
-	ulong	id;			/* authenticator id, ++'d with each auth */
-};
-#define	AUTHENTLEN	(CHALLEN+4+1)
-
-extern int chatty9p;
-
-static	int	convT2M(Ticket*, char*, char*);
-static	void	convM2T(char*, Ticket*, char*);
-static	void	convM2Tnoenc(char*, Ticket*);
-static	int	convA2M(Authenticator*, char*, char*);
-static	void	convM2A(char*, Authenticator*, char*);
-static	int	convTR2M(Ticketreq*, char*);
-static	void	convM2TR(char*, Ticketreq*);
-static	int	passtokey(char*, char*);
-
-/*
- * destructively encrypt the buffer, which
- * must be at least 8 characters long.
- */
-static int
-encrypt9p(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	for(i = 0; i < n; i++){
-		block_cipher(ekey, buf, 0);
-		buf += 7;
-	}
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 0);
-	return 1;
-}
-
-/*
- * destructively decrypt the buffer, which
- * must be at least 8 characters long.
- */
-static int
-decrypt9p(void *key, void *vbuf, int n)
-{
-	char ekey[128], *buf;
-	int i, r;
-
-	if(n < 8)
-		return 0;
-	key_setup(key, ekey);
-	buf = vbuf;
-	n--;
-	r = n % 7;
-	n /= 7;
-	buf += n * 7;
-	if(r)
-		block_cipher(ekey, buf - 7 + r, 1);
-	for(i = 0; i < n; i++){
-		buf -= 7;
-		block_cipher(ekey, buf, 1);
-	}
-	return 1;
-}
-
-#define	CHAR(x)		*p++ = f->x
-#define	SHORT(x)	p[0] = f->x; p[1] = f->x>>8; p += 2
-#define	VLONG(q)	p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
-#define	LONG(x)		VLONG(f->x)
-#define	STRING(x,n)	memmove(p, f->x, n); p += n
-
-static int
-convTR2M(Ticketreq *f, char *ap)
-{
-	int n;
-	uchar *p;
-
-	p = (uchar*)ap;
-	CHAR(type);
-	STRING(authid, NAMELEN);
-	STRING(authdom, DOMLEN);
-	STRING(chal, CHALLEN);
-	STRING(hostid, NAMELEN);
-	STRING(uid, NAMELEN);
-	n = p - (uchar*)ap;
-	return n;
-}
-
-static int
-convT2M(Ticket *f, char *ap, char *key)
-{
-	int n;
-	uchar *p;
-
-	p = (uchar*)ap;
-	CHAR(num);
-	STRING(chal, CHALLEN);
-	STRING(cuid, NAMELEN);
-	STRING(suid, NAMELEN);
-	STRING(key, DESKEYLEN);
-	n = p - (uchar*)ap;
-	if(key)
-		encrypt9p(key, ap, n);
-	return n;
-}
-
-int
-convA2M(Authenticator *f, char *ap, char *key)
-{
-	int n;
-	uchar *p;
-
-	p = (uchar*)ap;
-	CHAR(num);
-	STRING(chal, CHALLEN);
-	LONG(id);
-	n = p - (uchar*)ap;
-	if(key)
-		encrypt9p(key, ap, n);
-	return n;
-}
-
-#undef CHAR
-#undef SHORT
-#undef VLONG
-#undef LONG
-#undef STRING
-
-#define	CHAR(x)		f->x = *p++
-#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
-#define	VLONG(q)	q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
-#define	LONG(x)		VLONG(f->x)
-#define	STRING(x,n)	memmove(f->x, p, n); p += n
-
-void
-convM2A(char *ap, Authenticator *f, char *key)
-{
-	uchar *p;
-
-	if(key)
-		decrypt9p(key, ap, AUTHENTLEN);
-	p = (uchar*)ap;
-	CHAR(num);
-	STRING(chal, CHALLEN);
-	LONG(id);
-	USED(p);
-}
-
-void
-convM2T(char *ap, Ticket *f, char *key)
-{
-	uchar *p;
-
-	if(key)
-		decrypt9p(key, ap, TICKETLEN);
-	p = (uchar*)ap;
-	CHAR(num);
-	STRING(chal, CHALLEN);
-	STRING(cuid, NAMELEN);
-	f->cuid[NAMELEN-1] = 0;
-	STRING(suid, NAMELEN);
-	f->suid[NAMELEN-1] = 0;
-	STRING(key, DESKEYLEN);
-	USED(p);
-}
-
-#undef CHAR
-#undef SHORT
-#undef LONG
-#undef VLONG
-#undef STRING
-
-static int
-passtokey(char *key, char *p)
-{
-	uchar buf[NAMELEN], *t;
-	int i, n;
-
-	n = strlen(p);
-	if(n >= NAMELEN)
-		n = NAMELEN-1;
-	memset(buf, ' ', 8);
-	t = buf;
-	strncpy((char*)t, p, n);
-	t[n] = 0;
-	memset(key, 0, DESKEYLEN);
-	for(;;){
-		for(i = 0; i < DESKEYLEN; i++)
-			key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
-		if(n <= 8)
-			return 1;
-		n -= 8;
-		t += 8;
-		if(n < 8){
-			t -= 8 - n;
-			n = 8;
-		}
-		encrypt9p(key, t, 8);
-	}
-	return 1;	/* not reached */
-}
-
-static char authkey[DESKEYLEN];
-static char *authid;
-static char *authdom;
-static char *haveprotosmsg;
-static char *needprotomsg;
-
-static void
-p9anyinit(void)
-{
-	int n, fd;
-	char abuf[200];
-	char *af, *f[4];
-
-	af = autharg;
-	if(af == nil)
-		af = "/etc/u9fs.key";
-
-	if((fd = open(af, OREAD)) < 0)
-		sysfatal("can't open key file '%s'", af);
-
-	if((n = readn(fd, abuf, sizeof(abuf)-1)) < 0)
-		sysfatal("can't read key file '%s'", af);
-	if (n > 0 && abuf[n - 1] == '\n')
-		n--;
-	abuf[n] = '\0';
-
-	if(getfields(abuf, f, nelem(f), 0, "\n") != 3)
-		sysfatal("key file '%s' not exactly 3 lines", af);
-
-	passtokey(authkey, f[0]);
-	authid = strdup(f[1]);
-	authdom = strdup(f[2]);
-	haveprotosmsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);
-	sprint(haveprotosmsg, "p9sk1@%s", authdom);
-	needprotomsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);
-	sprint(needprotomsg, "p9sk1 %s", authdom);
-}
-
-typedef struct AuthSession {
-	int state;
-	char *uname;
-	char *aname;
-	char cchal[CHALLEN];
-	Ticketreq tr;
-	Ticket t;
-} AuthSession;
-
-static char*
-p9anyauth(Fcall *rx, Fcall *tx)
-{
-	AuthSession *sp;
-	Fid *f;
-	char *ep;
-
-	sp = malloc(sizeof(AuthSession));
-	f = newauthfid(rx->afid, sp, &ep);
-	if (f == nil) {
-		free(sp);
-		return ep;
-	}
-	if (chatty9p)
-		fprint(2, "p9anyauth: afid %d\n", rx->afid);
-	sp->state = HaveProtos;
-	sp->uname = strdup(rx->uname);
-	sp->aname = strdup(rx->aname);
-	tx->aqid.type = QTAUTH;
-	tx->aqid.path = 1;
-	tx->aqid.vers = 0;
-	return nil;
-}
-
-static char *
-p9anyattach(Fcall *rx, Fcall *tx)
-{
-	AuthSession *sp;
-	Fid *f;
-	char *ep;
-
-	f = oldauthfid(rx->afid, (void **)&sp, &ep);
-	if (f == nil)
-		return ep;
-	if (chatty9p)
-		fprint(2, "p9anyattach: afid %d state %d\n", rx->afid, sp->state);
-	if(sp->state == Established && strcmp(rx->uname, sp->uname) == 0
-		&& strcmp(rx->aname, sp->aname) == 0){
-		rx->uname = sp->t.suid;
-		return nil;
-	}
-	return "authentication failed";
-}
-
-static int
-readstr(Fcall *rx, Fcall *tx, char *s, int len)
-{
-	if (rx->offset >= len)
-		return 0;
-	tx->count = len - rx->offset;
-	if (tx->count > rx->count)
-		tx->count = rx->count;
-	memcpy(tx->data, s + rx->offset, tx->count);
-	return tx->count;
-}
-
-static char *
-p9anyread(Fcall *rx, Fcall *tx)
-{
-	AuthSession *sp;
-	char *ep;
-
-	Fid *f;
-	f = oldauthfid(rx->fid, (void **)&sp, &ep);
-	if (f == nil)
-		return ep;
-	if (chatty9p)
-		fprint(2, "p9anyread: afid %d state %d\n", rx->fid, sp->state);
-	switch (sp->state) {
-	case HaveProtos:
-		readstr(rx, tx, haveprotosmsg, strlen(haveprotosmsg) + 1);
-		if (rx->offset + tx->count == strlen(haveprotosmsg) + 1)
-			sp->state = NeedProto;
-		return nil;
-	case HaveTreq:
-		if (rx->count != TICKREQLEN)
-			goto botch;
-		convTR2M(&sp->tr, tx->data);
-		tx->count = TICKREQLEN;
-		sp->state = NeedTicket;
-		return nil;
-	case HaveAuth: {
-		Authenticator a;
-		if (rx->count != AUTHENTLEN)
-			goto botch;
-		a.num = AuthAs;
-		memmove(a.chal, sp->cchal, CHALLEN);
-		a.id = 0;
-		convA2M(&a, (char*)tx->data, sp->t.key);
-		memset(sp->t.key, 0, sizeof(sp->t.key));
-		tx->count = rx->count;
-		sp->state = Established;
-		return nil;
-	}
-	default:
-	botch:
-		return "protocol botch";
-	}
-}
-
-static char *
-p9anywrite(Fcall *rx, Fcall *tx)
-{
-	AuthSession *sp;
-	char *ep;
-
-	Fid *f;
-
-	f = oldauthfid(rx->fid, (void **)&sp, &ep);
-	if (f == nil)
-		return ep;
-	if (chatty9p)
-		fprint(2, "p9anywrite: afid %d state %d\n", rx->fid, sp->state);
-	switch (sp->state) {
-	case NeedProto:
-		if (rx->count != strlen(needprotomsg) + 1)
-			return "protocol response wrong length";
-		if (memcmp(rx->data, needprotomsg, rx->count) != 0)
-			return "unacceptable protocol";
-		sp->state = NeedChal;
-		tx->count = rx->count;
-		return nil;
-	case NeedChal:
-		if (rx->count != CHALLEN)
-			goto botch;
-		memmove(sp->cchal, rx->data, CHALLEN);
-		sp->tr.type = AuthTreq;
-		safecpy(sp->tr.authid, authid, sizeof(sp->tr.authid));
-		safecpy(sp->tr.authdom, authdom, sizeof(sp->tr.authdom));
-		randombytes((uchar *)sp->tr.chal, CHALLEN);
-		safecpy(sp->tr.hostid, "", sizeof(sp->tr.hostid));
-		safecpy(sp->tr.uid, "", sizeof(sp->tr.uid));
-		tx->count = rx->count;
-		sp->state = HaveTreq;
-		return nil;
-	case NeedTicket: {
-		Authenticator a;
-
-		if (rx->count != TICKETLEN + AUTHENTLEN) {
-			fprint(2, "bad length in attach");
-			goto botch;
-		}
-		convM2T((char*)rx->data, &sp->t, authkey);
-		if (sp->t.num != AuthTs) {
-			fprint(2, "bad AuthTs in attach\n");
-			goto botch;
-		}
-		if (memcmp(sp->t.chal, sp->tr.chal, CHALLEN) != 0) {
-			fprint(2, "bad challenge in attach\n");
-			goto botch;
-		}
-		convM2A((char*)rx->data + TICKETLEN, &a, sp->t.key);
-		if (a.num != AuthAc) {
-			fprint(2, "bad AuthAs in attach\n");
-			goto botch;
-		}
-		if(memcmp(a.chal, sp->tr.chal, CHALLEN) != 0) {
-			fprint(2, "bad challenge in attach 2\n");
-			goto botch;
-		}
-		sp->state = HaveAuth;
-		tx->count = rx->count;
-		return nil;
-	}
-	default:
-	botch:
-		return "protocol botch";
-	}
-}
-
-static void
-safefree(char *p)
-{
-	if (p) {
-		memset(p, 0, strlen(p));
-		free(p);
-	}
-}
-
-static char *
-p9anyclunk(Fcall *rx, Fcall *tx)
-{
-	Fid *f;
-	AuthSession *sp;
-	char *ep;
-
-	f = oldauthfid(rx->fid, (void **)&sp, &ep);
-	if (f == nil)
-		return ep;
-	if (chatty9p)
-		fprint(2, "p9anyclunk: afid %d\n", rx->fid);
-	safefree(sp->uname);
-	safefree(sp->aname);
-	memset(sp, 0, sizeof(sp));
-	free(sp);
-	return nil;
-}
-
-Auth authp9any = {
-	"p9any",
-	p9anyauth,
-	p9anyattach,
-	p9anyinit,
-	p9anyread,
-	p9anywrite,
-	p9anyclunk,
-};
--- a/sys/src/cmd/unix/u9fs/authrhosts.c
+++ /dev/null
@@ -1,38 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-#include <u9fs.h>
-
-/*
- * return whether the user is authenticated.
- * uses berkeley-style rhosts ``authentication''.
- * this is only a good idea behind a firewall,
- * where you trust your network, and even then
- * not such a great idea.  it's grandfathered.
- */
-
-static char*
-rhostsauth(Fcall *rx, Fcall *tx)
-{
-	USED(rx);
-	USED(tx);
-
-	return "u9fs rhostsauth: no authentication required";
-}
-
-static char*
-rhostsattach(Fcall *rx, Fcall *tx)
-{
-	USED(tx);
-
-	if(ruserok(remotehostname, 0, rx->uname, rx->uname) < 0){
-		fprint(2, "ruserok(%s, %s) not okay\n", remotehostname, rx->uname);
-		return "u9fs: rhosts authentication failed";
-	}
-	return 0;
-}
-
-Auth authrhosts = {
-	"rhosts",
-	rhostsauth,
-	rhostsattach,
-};
--- a/sys/src/cmd/unix/u9fs/convD2M.c
+++ /dev/null
@@ -1,89 +1,0 @@
-#include	<plan9.h>
-#include	<fcall.h>
-
-uint
-sizeD2M(Dir *d)
-{
-	char *sv[4];
-	int i, ns;
-
-	sv[0] = d->name;
-	sv[1] = d->uid;
-	sv[2] = d->gid;
-	sv[3] = d->muid;
-
-	ns = 0;
-	for(i = 0; i < 4; i++)
-		ns += strlen(sv[i]);
-
-	return STATFIXLEN + ns;
-}
-
-uint
-convD2M(Dir *d, uchar *buf, uint nbuf)
-{
-	uchar *p, *ebuf;
-	char *sv[4];
-	int i, ns, nsv[4], ss;
-
-	if(nbuf < BIT16SZ)
-		return 0;
-
-	p = buf;
-	ebuf = buf + nbuf;
-
-	sv[0] = d->name;
-	sv[1] = d->uid;
-	sv[2] = d->gid;
-	sv[3] = d->muid;
-
-	ns = 0;
-	for(i = 0; i < 4; i++){
-		nsv[i] = strlen(sv[i]);
-		ns += nsv[i];
-	}
-
-	ss = STATFIXLEN + ns;
-
-	/* set size befor erroring, so user can know how much is needed */
-	/* note that length excludes count field itself */
-	PBIT16(p, ss-BIT16SZ);
-	p += BIT16SZ;
-
-	if(ss > nbuf)
-		return BIT16SZ;
-
-	PBIT16(p, d->type);
-	p += BIT16SZ;
-	PBIT32(p, d->dev);
-	p += BIT32SZ;
-	PBIT8(p, d->qid.type);
-	p += BIT8SZ;
-	PBIT32(p, d->qid.vers);
-	p += BIT32SZ;
-	PBIT64(p, d->qid.path);
-	p += BIT64SZ;
-	PBIT32(p, d->mode);
-	p += BIT32SZ;
-	PBIT32(p, d->atime);
-	p += BIT32SZ;
-	PBIT32(p, d->mtime);
-	p += BIT32SZ;
-	PBIT64(p, d->length);
-	p += BIT64SZ;
-
-	for(i = 0; i < 4; i++){
-		ns = nsv[i];
-		if(p + ns + BIT16SZ > ebuf)
-			return 0;
-		PBIT16(p, ns);
-		p += BIT16SZ;
-		memmove(p, sv[i], ns);
-		p += ns;
-	}
-
-	if(ss != p - buf)
-		return 0;
-
-	return p - buf;
-}
--- a/sys/src/cmd/unix/u9fs/convM2D.c
+++ /dev/null
@@ -1,92 +1,0 @@
-#include	<plan9.h>
-#include	<fcall.h>
-
-int
-statcheck(uchar *buf, uint nbuf)
-{
-	uchar *ebuf;
-	int i;
-
-	ebuf = buf + nbuf;
-
-	buf += STATFIXLEN - 4 * BIT16SZ;
-
-	for(i = 0; i < 4; i++){
-		if(buf + BIT16SZ > ebuf)
-			return -1;
-		buf += BIT16SZ + GBIT16(buf);
-	}
-
-	if(buf != ebuf)
-		return -1;
-
-	return 0;
-}
-
-static char nullstring[] = "";
-
-uint
-convM2D(uchar *buf, uint nbuf, Dir *d, char *strs)
-{
-	uchar *p, *ebuf;
-	char *sv[4];
-	int i, ns;
-
-	p = buf;
-	ebuf = buf + nbuf;
-
-	p += BIT16SZ;	/* ignore size */
-	d->type = GBIT16(p);
-	p += BIT16SZ;
-	d->dev = GBIT32(p);
-	p += BIT32SZ;
-	d->qid.type = GBIT8(p);
-	p += BIT8SZ;
-	d->qid.vers = GBIT32(p);
-	p += BIT32SZ;
-	d->qid.path = GBIT64(p);
-	p += BIT64SZ;
-	d->mode = GBIT32(p);
-	p += BIT32SZ;
-	d->atime = GBIT32(p);
-	p += BIT32SZ;
-	d->mtime = GBIT32(p);
-	p += BIT32SZ;
-	d->length = GBIT64(p);
-	p += BIT64SZ;
-
-	d->name = nil;
-	d->uid = nil;
-	d->gid = nil;
-	d->muid = nil;
-
-	for(i = 0; i < 4; i++){
-		if(p + BIT16SZ > ebuf)
-			return 0;
-		ns = GBIT16(p);
-		p += BIT16SZ;
-		if(p + ns > ebuf)
-			return 0;
-		if(strs){
-			sv[i] = strs;
-			memmove(strs, p, ns);
-			strs += ns;
-			*strs++ = '\0';
-		}
-		p += ns;
-	}
-
-	if(strs){
-		d->name = sv[0];
-		d->uid = sv[1];
-		d->gid = sv[2];
-		d->muid = sv[3];
-	}else{
-		d->name = nullstring;
-		d->uid = nullstring;
-		d->gid = nullstring;
-		d->muid = nullstring;
-	}
-	
-	return p - buf;
-}
--- a/sys/src/cmd/unix/u9fs/convM2S.c
+++ /dev/null
@@ -1,382 +1,0 @@
-#include	<plan9.h>
-#include	<fcall.h>
-
-static
-uchar*
-gstring(uchar *p, uchar *ep, char **s)
-{
-	uint n;
-
-	if(p+BIT16SZ > ep)
-		return nil;
-	n = GBIT16(p);
-	p += BIT16SZ - 1;
-	if(p+n+1 > ep)
-		return nil;
-	/* move it down, on top of count, to make room for '\0' */
-	memmove(p, p + 1, n);
-	p[n] = '\0';
-	*s = (char*)p;
-	p += n+1;
-	return p;
-}
-
-static
-uchar*
-gqid(uchar *p, uchar *ep, Qid *q)
-{
-	if(p+QIDSZ > ep)
-		return nil;
-	q->type = GBIT8(p);
-	p += BIT8SZ;
-	q->vers = GBIT32(p);
-	p += BIT32SZ;
-	q->path = GBIT64(p);
-	p += BIT64SZ;
-	return p;
-}
-
-/*
- * no syntactic checks.
- * three causes for error:
- *  1. message size field is incorrect
- *  2. input buffer too short for its own data (counts too long, etc.)
- *  3. too many names or qids
- * gqid() and gstring() return nil if they would reach beyond buffer.
- * main switch statement checks range and also can fall through
- * to test at end of routine.
- */
-uint
-convM2S(uchar *ap, uint nap, Fcall *f)
-{
-	uchar *p, *ep;
-	uint i, size;
-
-	p = ap;
-	ep = p + nap;
-
-	if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
-		return 0;
-	size = GBIT32(p);
-	p += BIT32SZ;
-
-	if(size > nap)
-		return 0;
-	if(size < BIT32SZ+BIT8SZ+BIT16SZ)
-		return 0;
-
-	f->type = GBIT8(p);
-	p += BIT8SZ;
-	f->tag = GBIT16(p);
-	p += BIT16SZ;
-
-	switch(f->type)
-	{
-	default:
-		return 0;
-
-	case Tversion:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->msize = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->version);
-		break;
-
-/*
-	case Tsession:
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nchal = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nchal > ep)
-			return 0;
-		f->chal = p;
-		p += f->nchal;
-		break;
-*/
-
-	case Tflush:
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->oldtag = GBIT16(p);
-		p += BIT16SZ;
-		break;
-
-	case Tauth:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->afid = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->uname);
-		if(p == nil)
-			break;
-		p = gstring(p, ep, &f->aname);
-		if(p == nil)
-			break;
-		break;
-
-/*
-b
-	case Tattach:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->uname);
-		if(p == nil)
-			break;
-		p = gstring(p, ep, &f->aname);
-		if(p == nil)
-			break;
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nauth = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nauth > ep)
-			return 0;
-		f->auth = p;
-		p += f->nauth;
-		break;
-*/
-
-	case Tattach:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->afid = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->uname);
-		if(p == nil)
-			break;
-		p = gstring(p, ep, &f->aname);
-		if(p == nil)
-			break;
-		break;
-
-
-	case Twalk:
-		if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		f->newfid = GBIT32(p);
-		p += BIT32SZ;
-		f->nwname = GBIT16(p);
-		p += BIT16SZ;
-		if(f->nwname > MAXWELEM)
-			return 0;
-		for(i=0; i<f->nwname; i++){
-			p = gstring(p, ep, &f->wname[i]);
-			if(p == nil)
-				break;
-		}
-		break;
-
-	case Topen:
-		if(p+BIT32SZ+BIT8SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		f->mode = GBIT8(p);
-		p += BIT8SZ;
-		break;
-
-	case Tcreate:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->name);
-		if(p == nil)
-			break;
-		if(p+BIT32SZ+BIT8SZ > ep)
-			return 0;
-		f->perm = GBIT32(p);
-		p += BIT32SZ;
-		f->mode = GBIT8(p);
-		p += BIT8SZ;
-		break;
-
-	case Tread:
-		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		f->offset = GBIT64(p);
-		p += BIT64SZ;
-		f->count = GBIT32(p);
-		p += BIT32SZ;
-		break;
-
-	case Twrite:
-		if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		f->offset = GBIT64(p);
-		p += BIT64SZ;
-		f->count = GBIT32(p);
-		p += BIT32SZ;
-		if(p+f->count > ep)
-			return 0;
-		f->data = (char*)p;
-		p += f->count;
-		break;
-
-	case Tclunk:
-	case Tremove:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		break;
-
-	case Tstat:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		break;
-
-	case Twstat:
-		if(p+BIT32SZ+BIT16SZ > ep)
-			return 0;
-		f->fid = GBIT32(p);
-		p += BIT32SZ;
-		f->nstat = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nstat > ep)
-			return 0;
-		f->stat = p;
-		p += f->nstat;
-		break;
-
-/*
- */
-	case Rversion:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->msize = GBIT32(p);
-		p += BIT32SZ;
-		p = gstring(p, ep, &f->version);
-		break;
-
-/*
-	case Rsession:
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nchal = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nchal > ep)
-			return 0;
-		f->chal = p;
-		p += f->nchal;
-		p = gstring(p, ep, &f->authid);
-		if(p == nil)
-			break;
-		p = gstring(p, ep, &f->authdom);
-		break;
-*/
-
-	case Rerror:
-		p = gstring(p, ep, &f->ename);
-		break;
-
-	case Rflush:
-		break;
-
-/*
-	case Rattach:
-		p = gqid(p, ep, &f->qid);
-		if(p == nil)
-			break;
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nrauth = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nrauth > ep)
-			return 0;
-		f->rauth = p;
-		p += f->nrauth;
-		break;
-*/
-
-	case Rattach:
-		p = gqid(p, ep, &f->qid);
-		if(p == nil)
-			break;
-		break;
-
-
-	case Rwalk:
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nwqid = GBIT16(p);
-		p += BIT16SZ;
-		if(f->nwqid > MAXWELEM)
-			return 0;
-		for(i=0; i<f->nwqid; i++){
-			p = gqid(p, ep, &f->wqid[i]);
-			if(p == nil)
-				break;
-		}
-		break;
-
-	case Ropen:
-	case Rcreate:
-		p = gqid(p, ep, &f->qid);
-		if(p == nil)
-			break;
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->iounit = GBIT32(p);
-		p += BIT32SZ;
-		break;
-
-	case Rread:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->count = GBIT32(p);
-		p += BIT32SZ;
-		if(p+f->count > ep)
-			return 0;
-		f->data = (char*)p;
-		p += f->count;
-		break;
-
-	case Rwrite:
-		if(p+BIT32SZ > ep)
-			return 0;
-		f->count = GBIT32(p);
-		p += BIT32SZ;
-		break;
-
-	case Rclunk:
-	case Rremove:
-		break;
-
-	case Rstat:
-		if(p+BIT16SZ > ep)
-			return 0;
-		f->nstat = GBIT16(p);
-		p += BIT16SZ;
-		if(p+f->nstat > ep)
-			return 0;
-		f->stat = p;
-		p += f->nstat;
-		break;
-
-	case Rwstat:
-		break;
-	}
-
-	if(p==nil || p>ep)
-		return 0;
-	if(ap+size == p)
-		return size;
-	return 0;
-}
--- a/sys/src/cmd/unix/u9fs/convS2M.c
+++ /dev/null
@@ -1,423 +1,0 @@
-#include	<plan9.h>
-#include	<fcall.h>
-
-static
-uchar*
-pstring(uchar *p, char *s)
-{
-	uint n;
-
-	n = strlen(s);
-	PBIT16(p, n);
-	p += BIT16SZ;
-	memmove(p, s, n);
-	p += n;
-	return p;
-}
-
-static
-uchar*
-pqid(uchar *p, Qid *q)
-{
-	PBIT8(p, q->type);
-	p += BIT8SZ;
-	PBIT32(p, q->vers);
-	p += BIT32SZ;
-	PBIT64(p, q->path);
-	p += BIT64SZ;
-	return p;
-}
-
-static
-uint
-stringsz(char *s)
-{
-	return BIT16SZ+strlen(s);
-}
-
-static
-uint
-sizeS2M(Fcall *f)
-{
-	uint n;
-	int i;
-
-	n = 0;
-	n += BIT32SZ;	/* size */
-	n += BIT8SZ;	/* type */
-	n += BIT16SZ;	/* tag */
-
-	switch(f->type)
-	{
-	default:
-		return 0;
-
-	case Tversion:
-		n += BIT32SZ;
-		n += stringsz(f->version);
-		break;
-
-/*
-	case Tsession:
-		n += BIT16SZ;
-		n += f->nchal;
-		break;
-*/
-
-	case Tflush:
-		n += BIT16SZ;
-		break;
-
-	case Tauth:
-		n += BIT32SZ;
-		n += stringsz(f->uname);
-		n += stringsz(f->aname);
-		break;
-
-	case Tattach:
-		n += BIT32SZ;
-		n += BIT32SZ;
-		n += stringsz(f->uname);
-		n += stringsz(f->aname);
-		break;
-
-
-	case Twalk:
-		n += BIT32SZ;
-		n += BIT32SZ;
-		n += BIT16SZ;
-		for(i=0; i<f->nwname; i++)
-			n += stringsz(f->wname[i]);
-		break;
-
-	case Topen:
-		n += BIT32SZ;
-		n += BIT8SZ;
-		break;
-
-	case Tcreate:
-		n += BIT32SZ;
-		n += stringsz(f->name);
-		n += BIT32SZ;
-		n += BIT8SZ;
-		break;
-
-	case Tread:
-		n += BIT32SZ;
-		n += BIT64SZ;
-		n += BIT32SZ;
-		break;
-
-	case Twrite:
-		n += BIT32SZ;
-		n += BIT64SZ;
-		n += BIT32SZ;
-		n += f->count;
-		break;
-
-	case Tclunk:
-	case Tremove:
-		n += BIT32SZ;
-		break;
-
-	case Tstat:
-		n += BIT32SZ;
-		break;
-
-	case Twstat:
-		n += BIT32SZ;
-		n += BIT16SZ;
-		n += f->nstat;
-		break;
-/*
- */
-
-	case Rversion:
-		n += BIT32SZ;
-		n += stringsz(f->version);
-		break;
-
-/*
-	case Rsession:
-		n += BIT16SZ;
-		n += f->nchal;
-		n += stringsz(f->authid);
-		n += stringsz(f->authdom);
-		break;
-
-*/
-	case Rerror:
-		n += stringsz(f->ename);
-		break;
-
-	case Rflush:
-		break;
-
-	case Rauth:
-		n += QIDSZ;
-		break;
-
-/*
-	case Rattach:
-		n += QIDSZ;
-		n += BIT16SZ;
-		n += f->nrauth;
-		break;
-*/
-
-	case Rattach:
-		n += QIDSZ;
-		break;
-
-
-	case Rwalk:
-		n += BIT16SZ;
-		n += f->nwqid*QIDSZ;
-		break;
-
-	case Ropen:
-	case Rcreate:
-		n += QIDSZ;
-		n += BIT32SZ;
-		break;
-
-	case Rread:
-		n += BIT32SZ;
-		n += f->count;
-		break;
-
-	case Rwrite:
-		n += BIT32SZ;
-		break;
-
-	case Rclunk:
-		break;
-
-	case Rremove:
-		break;
-
-	case Rstat:
-		n += BIT16SZ;
-		n += f->nstat;
-		break;
-
-	case Rwstat:
-		break;
-	}
-	return n;
-}
-
-uint
-convS2M(Fcall *f, uchar *ap, uint nap)
-{
-	uchar *p;
-	uint i, size;
-
-	size = sizeS2M(f);
-	if(size == 0)
-		return 0;
-	if(size > nap)
-		return 0;
-
-	p = (uchar*)ap;
-
-	PBIT32(p, size);
-	p += BIT32SZ;
-	PBIT8(p, f->type);
-	p += BIT8SZ;
-	PBIT16(p, f->tag);
-	p += BIT16SZ;
-
-	switch(f->type)
-	{
-	default:
-		return 0;
-
-	case Tversion:
-		PBIT32(p, f->msize);
-		p += BIT32SZ;
-		p = pstring(p, f->version);
-		break;
-
-/*
-	case Tsession:
-		PBIT16(p, f->nchal);
-		p += BIT16SZ;
-		f->chal = p;
-		p += f->nchal;
-		break;
-*/
-
-	case Tflush:
-		PBIT16(p, f->oldtag);
-		p += BIT16SZ;
-		break;
-
-	case Tauth:
-		PBIT32(p, f->afid);
-		p += BIT32SZ;
-		p  = pstring(p, f->uname);
-		p  = pstring(p, f->aname);
-		break;
-
-	case Tattach:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT32(p, f->afid);
-		p += BIT32SZ;
-		p  = pstring(p, f->uname);
-		p  = pstring(p, f->aname);
-		break;
-
-	case Twalk:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT32(p, f->newfid);
-		p += BIT32SZ;
-		PBIT16(p, f->nwname);
-		p += BIT16SZ;
-		if(f->nwname > MAXWELEM)
-			return 0;
-		for(i=0; i<f->nwname; i++)
-			p = pstring(p, f->wname[i]);
-		break;
-
-	case Topen:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT8(p, f->mode);
-		p += BIT8SZ;
-		break;
-
-	case Tcreate:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		p = pstring(p, f->name);
-		PBIT32(p, f->perm);
-		p += BIT32SZ;
-		PBIT8(p, f->mode);
-		p += BIT8SZ;
-		break;
-
-	case Tread:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT64(p, f->offset);
-		p += BIT64SZ;
-		PBIT32(p, f->count);
-		p += BIT32SZ;
-		break;
-
-	case Twrite:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT64(p, f->offset);
-		p += BIT64SZ;
-		PBIT32(p, f->count);
-		p += BIT32SZ;
-		memmove(p, f->data, f->count);
-		p += f->count;
-		break;
-
-	case Tclunk:
-	case Tremove:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		break;
-
-	case Tstat:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		break;
-
-	case Twstat:
-		PBIT32(p, f->fid);
-		p += BIT32SZ;
-		PBIT16(p, f->nstat);
-		p += BIT16SZ;
-		memmove(p, f->stat, f->nstat);
-		p += f->nstat;
-		break;
-/*
- */
-
-	case Rversion:
-		PBIT32(p, f->msize);
-		p += BIT32SZ;
-		p = pstring(p, f->version);
-		break;
-
-/*
-	case Rsession:
-		PBIT16(p, f->nchal);
-		p += BIT16SZ;
-		f->chal = p;
-		p += f->nchal;
-		p = pstring(p, f->authid);
-		p = pstring(p, f->authdom);
-		break;
-*/
-
-	case Rerror:
-		p = pstring(p, f->ename);
-		break;
-
-	case Rflush:
-		break;
-
-	case Rauth:
-		p = pqid(p, &f->aqid);
-		break;
-
-	case Rattach:
-		p = pqid(p, &f->qid);
-		break;
-
-	case Rwalk:
-		PBIT16(p, f->nwqid);
-		p += BIT16SZ;
-		if(f->nwqid > MAXWELEM)
-			return 0;
-		for(i=0; i<f->nwqid; i++)
-			p = pqid(p, &f->wqid[i]);
-		break;
-
-	case Ropen:
-	case Rcreate:
-		p = pqid(p, &f->qid);
-		PBIT32(p, f->iounit);
-		p += BIT32SZ;
-		break;
-
-	case Rread:
-		PBIT32(p, f->count);
-		p += BIT32SZ;
-		memmove(p, f->data, f->count);
-		p += f->count;
-		break;
-
-	case Rwrite:
-		PBIT32(p, f->count);
-		p += BIT32SZ;
-		break;
-
-	case Rclunk:
-		break;
-
-	case Rremove:
-		break;
-
-	case Rstat:
-		PBIT16(p, f->nstat);
-		p += BIT16SZ;
-		memmove(p, f->stat, f->nstat);
-		p += f->nstat;
-		break;
-
-	case Rwstat:
-		break;
-	}
-	if(size != p-ap)
-		return 0;
-	return size;
-}
--- a/sys/src/cmd/unix/u9fs/cygwin.c
+++ /dev/null
@@ -1,62 +1,0 @@
-/* compatability layer for u9fs support on CYGWIN */
-
-#include <unistd.h>
-#include <errno.h>
-
-ssize_t
-pread(int fd, void *p, size_t n, off_t off)
-{
-	off_t ooff;
-	int oerrno;
-
-	if ((ooff  = lseek(fd, off, SEEK_SET)) == -1)
-		return -1;
-
-	n = read(fd, p, n);
-
-	oerrno = errno;
-	lseek(fd, ooff, SEEK_SET);
-	errno = oerrno;
-
-	return n;
-}
-
-ssize_t
-pwrite(int fd, const void *p, size_t n, off_t off)
-{
-	off_t ooff;
-	int oerrno;
-
-	if ((ooff  = lseek(fd, off, SEEK_SET)) == -1)
-		return -1;
-
-	n = write(fd, p, n);
-
-	oerrno = errno;
-	lseek(fd, ooff, SEEK_SET);
-	errno = oerrno;
-
-	return n;
-}
-
-int
-setreuid(int ruid, int euid)
-{
-	if (ruid != -1)
-		if (setuid(ruid) == -1)
-			return(-1);
-	if (euid != -1)
-		if (seteuid(euid) == -1)
-			return(-1);
-}
-
-int
-setregid(int rgid, int egid)
-{
-	if (rgid != -1)
-		if (setgid(rgid) == -1)
-			return(-1);
-	if (egid != -1)
-		if (setegid(egid) == -1)
-			return(-1);
-}
--- a/sys/src/cmd/unix/u9fs/des.c
+++ /dev/null
@@ -1,355 +1,0 @@
-#include <plan9.h>
-
-/*
- *	Data Encryption Standard
- *	D.P.Mitchell  83/06/08.
- *
- *	block_cipher(key, block, decrypting)
- */
-
-static	long	ip_low(char [8]);
-static	long	ip_high(char [8]);
-static	void	fp(long, long, char[8]);
-
-extern int chatty9p;
-
-/*
- *	Tables for Combined S and P Boxes
- */
-
-static long  s0p[] = {
-0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
-0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
-0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
-0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
-0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
-0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
-0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
-0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
-};
-
-static long  s1p[] = {
-0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
-0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
-0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
-0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
-0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
-0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
-0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
-0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
-};
-
-static long  s2p[] = {
-0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
-0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
-0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
-0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
-0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
-0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
-0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
-0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
-};
-
-static long  s3p[] = {
-0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
-0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
-0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
-0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
-0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
-0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
-0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
-0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
-};
-
-static long  s4p[] = {
-0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
-0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
-0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
-0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
-0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
-0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
-0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
-0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
-};
-
-static long  s5p[] = {
-0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
-0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
-0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
-0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
-0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
-0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
-0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
-0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
-};
-
-static long  s6p[] = {
-0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
-0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
-0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
-0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
-0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
-0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
-0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
-0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
-};
-
-static long  s7p[] = {
-0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
-0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
-0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
-0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
-0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
-0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
-0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
-0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
-};
-
-/*
- *	DES electronic codebook encryption of one block
- */
-void
-block_cipher(char expanded_key[128], char text[8], int decrypting)
-{
-	char *key;
-	long crypto, temp, right, left;
-	int i, key_offset;
-
-	key = expanded_key;
-	left = ip_low(text);
-	right = ip_high(text);
-	if (decrypting) {
-		key_offset = 16;
-		key = key + 128 - 8;
-	} else
-		key_offset = 0;
-	for (i = 0; i < 16; i++) {
-		temp = (right << 1) | ((right >> 31) & 1);
-		crypto  = s0p[(temp         & 0x3f) ^ *key++];
-		crypto |= s1p[((temp >>  4) & 0x3f) ^ *key++];
-		crypto |= s2p[((temp >>  8) & 0x3f) ^ *key++];
-		crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
-		crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
-		crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
-		crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
-		temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
-		crypto |= s7p[temp ^ *key++];
-		temp = left;
-		left = right;
-		right = temp ^ crypto;
-		key -= key_offset;
-	}
-	/*
-	 *	standard final permutation (IPI)
-	 *	left and right are reversed here
-	 */
-	fp(right, left, text);
-}
-
-/*
- *	Initial Permutation
- */
-static long iptab[] = {
-	0x00000000, 0x00008000, 0x00000000, 0x00008000,
-	0x00000080, 0x00008080, 0x00000080, 0x00008080
-};
-
-static long
-ip_low(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 4) & 7] >> i;
-		l |= iptab[block[i] & 7] << (16 - i);
-	}
-	return l;
-}
-
-static long
-ip_high(char block[8])
-{
-	int i;
-	long l;
-
-	l = 0;
-	for(i = 0; i < 8; i++){
-		l |= iptab[(block[i] >> 5) & 7] >> i;
-		l |= iptab[(block[i] >> 1) & 7] << (16 - i);
-	}
-	return l;
-}
-
-/*
- *	Final Permutation
- */
-static unsigned long	fptab[] = {
-0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
-0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
-};
-
-static void
-fp(long left, long right, char text[8])
-{
-	unsigned long ta[2], t, v[2];
-	int i, j, sh;
-
-	ta[0] = right;
-	ta[1] = left;
-	v[0] = v[1] = 0;
-	for(i = 0; i < 2; i++){
-		t = ta[i];
-		sh = i;
-		for(j = 0; j < 4; j++){
-			v[1] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			v[0] |= fptab[t & 0xf] >> sh;
-			t >>= 4;
-			sh += 2;
-		}
-	}
-	for(i = 0; i < 2; i++)
-		for(j = 0; j < 4; j++){
-			*text++ = v[i];
-			v[i] >>= 8;
-		}
-}
-
-/*
- *	Key set-up
- */
-static uchar keyexpand[][15][2] = {
-	{   3,  2,   9,  8,  18,  8,  27, 32,  33,  2,  42, 16,  48,  8,  65, 16, 
-	   74,  2,  80,  2,  89,  4,  99, 16, 104,  4, 122, 32,   0,  0, },
-	{   1,  4,   8,  1,  18,  4,  25, 32,  34, 32,  41,  8,  50,  8,  59, 32, 
-	   64, 16,  75,  4,  90,  1,  97, 16, 106,  2, 112,  2, 123,  1, },
-	{   2,  1,  19,  8,  35,  1,  40,  1,  50,  4,  57, 32,  75,  2,  80, 32, 
-	   89,  1,  96, 16, 107,  4, 120,  8,   0,  0,   0,  0,   0,  0, },
-	{   4, 32,  20,  2,  31,  4,  37, 32,  47,  1,  54,  1,  63,  2,  68,  1, 
-	   78,  4,  84,  8, 101, 16, 108,  4, 119, 16, 126,  8,   0,  0, },
-	{   5,  4,  15,  4,  21, 32,  31,  1,  38,  1,  47,  2,  53,  2,  68,  8, 
-	   85, 16,  92,  4, 103, 16, 108, 32, 118, 32, 124,  2,   0,  0, },
-	{  15,  2,  21,  2,  39,  8,  46, 16,  55, 32,  61,  1,  71, 16,  76, 32, 
-	   86, 32,  93,  4, 102,  2, 108, 16, 117,  8, 126,  1,   0,  0, },
-	{  14, 16,  23, 32,  29,  1,  38,  8,  52,  2,  63,  4,  70,  2,  76, 16, 
-	   85,  8, 100,  1, 110,  4, 116,  8, 127,  8,   0,  0,   0,  0, },
-	{   1,  8,   8, 32,  17,  1,  24, 16,  35,  4,  50,  1,  57, 16,  67,  8, 
-	   83,  1,  88,  1,  98,  4, 105, 32, 114, 32, 123,  2,   0,  0, },
-	{   0,  1,  11, 16,  16,  4,  35,  2,  40, 32,  49,  1,  56, 16,  65,  2, 
-	   74, 16,  80,  8,  99,  8, 115,  1, 121,  4,   0,  0,   0,  0, },
-	{   9, 16,  18,  2,  24,  2,  33,  4,  43, 16,  48,  4,  66, 32,  73,  8, 
-	   82,  8,  91, 32,  97,  2, 106, 16, 112,  8, 122,  1,   0,  0, },
-	{  14, 32,  21,  4,  30,  2,  36, 16,  45,  8,  60,  1,  69,  2,  87,  8, 
-	   94, 16, 103, 32, 109,  1, 118,  8, 124, 32,   0,  0,   0,  0, },
-	{   7,  4,  14,  2,  20, 16,  29,  8,  44,  1,  54,  4,  60,  8,  71,  8, 
-	   78, 16,  87, 32,  93,  1, 102,  8, 116,  2, 125,  4,   0,  0, },
-	{   7,  2,  12,  1,  22,  4,  28,  8,  45, 16,  52,  4,  63, 16,  70,  8, 
-	   84,  2,  95,  4, 101, 32, 111,  1, 118,  1,   0,  0,   0,  0, },
-	{   6, 16,  13, 16,  20,  4,  31, 16,  36, 32,  46, 32,  53,  4,  62,  2, 
-	   69, 32,  79,  1,  86,  1,  95,  2, 101,  2, 119,  8,   0,  0, },
-	{   0, 32,  10,  8,  19, 32,  25,  2,  34, 16,  40,  8,  59,  8,  66,  2, 
-	   72,  2,  81,  4,  91, 16,  96,  4, 115,  2, 121,  8,   0,  0, },
-	{   3, 16,  10,  4,  17, 32,  26, 32,  33,  8,  42,  8,  51, 32,  57,  2, 
-	   67,  4,  82,  1,  89, 16,  98,  2, 104,  2, 113,  4, 120,  1, },
-	{   1, 16,  11,  8,  27,  1,  32,  1,  42,  4,  49, 32,  58, 32,  67,  2, 
-	   72, 32,  81,  1,  88, 16,  99,  4, 114,  1,   0,  0,   0,  0, },
-	{   6, 32,  12,  2,  23,  4,  29, 32,  39,  1,  46,  1,  55,  2,  61,  2, 
-	   70,  4,  76,  8,  93, 16, 100,  4, 111, 16, 116, 32,   0,  0, },
-	{   6,  2,  13, 32,  23,  1,  30,  1,  39,  2,  45,  2,  63,  8,  77, 16, 
-	   84,  4,  95, 16, 100, 32, 110, 32, 117,  4, 127,  4,   0,  0, },
-	{   4,  1,  13,  2,  31,  8,  38, 16,  47, 32,  53,  1,  62,  8,  68, 32, 
-	   78, 32,  85,  4,  94,  2, 100, 16, 109,  8, 127,  2,   0,  0, },
-	{   5, 16,  15, 32,  21,  1,  30,  8,  44,  2,  55,  4,  61, 32,  68, 16, 
-	   77,  8,  92,  1, 102,  4, 108,  8, 126, 16,   0,  0,   0,  0, },
-	{   2,  8,   9,  1,  16, 16,  27,  4,  42,  1,  49, 16,  58,  2,  75,  1, 
-	   80,  1,  90,  4,  97, 32, 106, 32, 113,  8, 120, 32,   0,  0, },
-	{   2,  4,   8,  4,  27,  2,  32, 32,  41,  1,  48, 16,  59,  4,  66, 16, 
-	   72,  8,  91,  8, 107,  1, 112,  1, 123, 16,   0,  0,   0,  0, },
-	{   3,  8,  10,  2,  16,  2,  25,  4,  35, 16,  40,  4,  59,  2,  65,  8, 
-	   74,  8,  83, 32,  89,  2,  98, 16, 104,  8, 121, 16,   0,  0, },
-	{   4,  2,  13,  4,  22,  2,  28, 16,  37,  8,  52,  1,  62,  4,  79,  8, 
-	   86, 16,  95, 32, 101,  1, 110,  8, 126, 32,   0,  0,   0,  0, },
-	{   5, 32,  12, 16,  21,  8,  36,  1,  46,  4,  52,  8,  70, 16,  79, 32, 
-	   85,  1,  94,  8, 108,  2, 119,  4, 126,  2,   0,  0,   0,  0, },
-	{   5,  2,  14,  4,  20,  8,  37, 16,  44,  4,  55, 16,  60, 32,  76,  2, 
-	   87,  4,  93, 32, 103,  1, 110,  1, 119,  2, 124,  1,   0,  0, },
-	{   7, 32,  12,  4,  23, 16,  28, 32,  38, 32,  45,  4,  54,  2,  60, 16, 
-	   71,  1,  78,  1,  87,  2,  93,  2, 111,  8, 118, 16, 125, 16, },
-	{   1,  1,  11, 32,  17,  2,  26, 16,  32,  8,  51,  8,  64,  2,  73,  4, 
-	   83, 16,  88,  4, 107,  2, 112, 32, 122,  8,   0,  0,   0,  0, },
-	{   0,  4,   9, 32,  18, 32,  25,  8,  34,  8,  43, 32,  49,  2,  58, 16, 
-	   74,  1,  81, 16,  90,  2,  96,  2, 105,  4, 115, 16, 122,  4, },
-	{   2,  2,  19,  1,  24,  1,  34,  4,  41, 32,  50, 32,  57,  8,  64, 32, 
-	   73,  1,  80, 16,  91,  4, 106,  1, 113, 16, 123,  8,   0,  0, },
-	{   3,  4,  10, 16,  16,  8,  35,  8,  51,  1,  56,  1,  67, 16,  72,  4, 
-	   91,  2,  96, 32, 105,  1, 112, 16, 121,  2,   0,  0,   0,  0, },
-	{   4, 16,  15,  1,  22,  1,  31,  2,  37,  2,  55,  8,  62, 16,  69, 16, 
-	   76,  4,  87, 16,  92, 32, 102, 32, 109,  4, 118,  2, 125, 32, },
-	{   6,  4,  23,  8,  30, 16,  39, 32,  45,  1,  54,  8,  70, 32,  77,  4, 
-	   86,  2,  92, 16, 101,  8, 116,  1, 125,  2,   0,  0,   0,  0, },
-	{   4,  4,  13,  1,  22,  8,  36,  2,  47,  4,  53, 32,  63,  1,  69,  8, 
-	   84,  1,  94,  4, 100,  8, 117, 16, 127, 32,   0,  0,   0,  0, },
-	{   3, 32,   8, 16,  19,  4,  34,  1,  41, 16,  50,  2,  56,  2,  67,  1, 
-	   72,  1,  82,  4,  89, 32,  98, 32, 105,  8, 114,  8, 121,  1, },
-	{   1, 32,  19,  2,  24, 32,  33,  1,  40, 16,  51,  4,  64,  8,  83,  8, 
-	   99,  1, 104,  1, 114,  4, 120,  4,   0,  0,   0,  0,   0,  0, },
-	{   8,  2,  17,  4,  27, 16,  32,  4,  51,  2,  56, 32,  66,  8,  75, 32, 
-	   81,  2,  90, 16,  96,  8, 115,  8, 122,  2,   0,  0,   0,  0, },
-	{   2, 16,  18,  1,  25, 16,  34,  2,  40,  2,  49,  4,  59, 16,  66,  4, 
-	   73, 32,  82, 32,  89,  8,  98,  8, 107, 32, 113,  2, 123,  4, },
-	{   7,  1,  13,  8,  28,  1,  38,  4,  44,  8,  61, 16,  71, 32,  77,  1, 
-	   86,  8, 100,  2, 111,  4, 117, 32, 124, 16,   0,  0,   0,  0, },
-	{  12,  8,  29, 16,  36,  4,  47, 16,  52, 32,  62, 32,  68,  2,  79,  4, 
-	   85, 32,  95,  1, 102,  1, 111,  2, 117,  2, 126,  4,   0,  0, },
-	{   5,  1,  15, 16,  20, 32,  30, 32,  37,  4,  46,  2,  52, 16,  61,  8, 
-	   70,  1,  79,  2,  85,  2, 103,  8, 110, 16, 119, 32, 124,  4, },
-	{   0, 16,   9,  2,  18, 16,  24,  8,  43,  8,  59,  1,  65,  4,  75, 16, 
-	   80,  4,  99,  2, 104, 32, 113,  1, 123, 32,   0,  0,   0,  0, },
-	{  10, 32,  17,  8,  26,  8,  35, 32,  41,  2,  50, 16,  56,  8,  66,  1, 
-	   73, 16,  82,  2,  88,  2,  97,  4, 107, 16, 112,  4, 121, 32, },
-	{   0,  2,  11,  1,  16,  1,  26,  4,  33, 32,  42, 32,  49,  8,  58,  8, 
-	   65,  1,  72, 16,  83,  4,  98,  1, 105, 16, 114,  2,   0,  0, },
-	{   8,  8,  27,  8,  43,  1,  48,  1,  58,  4,  64,  4,  83,  2,  88, 32, 
-	   97,  1, 104, 16, 115,  4, 122, 16,   0,  0,   0,  0,   0,  0, },
-	{   5,  8,  14,  1,  23,  2,  29,  2,  47,  8,  54, 16,  63, 32,  68,  4, 
-	   79, 16,  84, 32,  94, 32, 101,  4, 110,  2, 116, 16, 127,  1, },
-	{   4,  8,  15,  8,  22, 16,  31, 32,  37,  1,  46,  8,  60,  2,  69,  4, 
-	   78,  2,  84, 16,  93,  8, 108,  1, 118,  4,   0,  0,   0,  0, },
-	{   7, 16,  14,  8,  28,  2,  39,  4,  45, 32,  55,  1,  62,  1,  76,  1, 
-	   86,  4,  92,  8, 109, 16, 116,  4, 125,  1,   0,  0,   0,  0, },
-	{   1,  2,  11,  4,  26,  1,  33, 16,  42,  2,  48,  2,  57,  4,  64,  1, 
-	   74,  4,  81, 32,  90, 32,  97,  8, 106,  8, 115, 32, 120, 16, },
-	{   2, 32,  11,  2,  16, 32,  25,  1,  32, 16,  43,  4,  58,  1,  75,  8, 
-	   91,  1,  96,  1, 106,  4, 113, 32,   0,  0,   0,  0,   0,  0, },
-	{   3,  1,   9,  4,  19, 16,  24,  4,  43,  2,  48, 32,  57,  1,  67, 32, 
-	   73,  2,  82, 16,  88,  8, 107,  8, 120,  2,   0,  0,   0,  0, },
-	{   0,  8,  10,  1,  17, 16,  26,  2,  32,  2,  41,  4,  51, 16,  56,  4, 
-	   65, 32,  74, 32,  81,  8,  90,  8,  99, 32, 105,  2, 114, 16, },
-	{   6,  1,  20,  1,  30,  4,  36,  8,  53, 16,  60,  4,  69,  1,  78,  8, 
-	   92,  2, 103,  4, 109, 32, 119,  1, 125,  8,   0,  0,   0,  0, },
-	{   7,  8,  21, 16,  28,  4,  39, 16,  44, 32,  54, 32,  61,  4,  71,  4, 
-	   77, 32,  87,  1,  94,  1, 103,  2, 109,  2, 124,  8,   0,  0, },
-	{   6,  8,  12, 32,  22, 32,  29,  4,  38,  2,  44, 16,  53,  8,  71,  2, 
-	   77,  2,  95,  8, 102, 16, 111, 32, 117,  1, 127, 16,   0,  0, }
-};
-
-void
-key_setup(char key[DESKEYLEN], char *ek)
-{
-	int i, j, k, mask;
-	uchar (*x)[2];
-
-	memset(ek, 0, 128);
-	x = keyexpand[0];
-	for(i = 0; i < 7; i++){
-		k = key[i];
-		for(mask = 0x80; mask; mask >>= 1){
-			if(k & mask)
-				for(j = 0; j < 15; j++)
-					ek[x[j][0]] |= x[j][1];
-			x += 15;
-		}
-	}
-}
--- a/sys/src/cmd/unix/u9fs/dirmodeconv.c
+++ /dev/null
@@ -1,47 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-
-static char *modes[] =
-{
-	"---",
-	"--x",
-	"-w-",
-	"-wx",
-	"r--",
-	"r-x",
-	"rw-",
-	"rwx",
-};
-
-static void
-rwx(long m, char *s)
-{
-	strncpy(s, modes[m], 3);
-}
-
-int
-dirmodeconv(va_list *arg, Fconv *f)
-{
-	static char buf[16];
-	ulong m;
-
-	m = va_arg(*arg, ulong);
-
-	if(m & DMDIR)
-		buf[0]='d';
-	else if(m & DMAPPEND)
-		buf[0]='a';
-	else
-		buf[0]='-';
-	if(m & DMEXCL)
-		buf[1]='l';
-	else
-		buf[1]='-';
-	rwx((m>>6)&7, buf+2);
-	rwx((m>>3)&7, buf+5);
-	rwx((m>>0)&7, buf+8);
-	buf[11] = 0;
-
-	strconv(buf, f);
-	return 0;
-}
--- a/sys/src/cmd/unix/u9fs/doprint.c
+++ /dev/null
@@ -1,610 +1,0 @@
-#include	<plan9.h>
-
-#define lock(x)
-#define unlock(x)
-
-enum
-{
-	IDIGIT	= 40,
-	MAXCONV	= 40,
-	FDIGIT	= 30,
-	FDEFLT	= 6,
-	NONE	= -1000,
-	MAXFMT	= 512,
-
-	FPLUS	= 1<<0,
-	FMINUS	= 1<<1,
-	FSHARP	= 1<<2,
-	FLONG	= 1<<3,
-	FUNSIGN	= 1<<5,
-	FVLONG	= 1<<6,
-	FPOINTER= 1<<7
-};
-
-int	printcol;
-
-static struct
-{
-/*	Lock;	*/
-	int	convcount;
-	char	index[MAXFMT];
-	int	(*conv[MAXCONV])(va_list*, Fconv*);
-} fmtalloc;
-
-static	int	noconv(va_list*, Fconv*);
-static	int	flags(va_list*, Fconv*);
-
-static	int	cconv(va_list*, Fconv*);
-static	int	sconv(va_list*, Fconv*);
-static	int	percent(va_list*, Fconv*);
-static	int	column(va_list*, Fconv*);
-
-extern	int	numbconv(va_list*, Fconv*);
-
-
-static	void
-initfmt(void)
-{
-	int cc;
-
-	lock(&fmtalloc);
-	if(fmtalloc.convcount <= 0) {
-		cc = 0;
-		fmtalloc.conv[cc] = noconv;
-		cc++;
-
-		fmtalloc.conv[cc] = flags;
-		fmtalloc.index['+'] = cc;
-		fmtalloc.index['-'] = cc;
-		fmtalloc.index['#'] = cc;
-		fmtalloc.index['l'] = cc;
-		fmtalloc.index['u'] = cc;
-		cc++;
-
-		fmtalloc.conv[cc] = numbconv;
-		fmtalloc.index['d'] = cc;
-		fmtalloc.index['o'] = cc;
-		fmtalloc.index['x'] = cc;
-		fmtalloc.index['X'] = cc;
-		fmtalloc.index['p'] = cc;
-		cc++;
-
-
-		fmtalloc.conv[cc] = cconv;
-		fmtalloc.index['c'] = cc;
-		fmtalloc.index['C'] = cc;
-		cc++;
-
-		fmtalloc.conv[cc] = sconv;
-		fmtalloc.index['s'] = cc;
-		fmtalloc.index['S'] = cc;
-		cc++;
-
-		fmtalloc.conv[cc] = percent;
-		fmtalloc.index['%'] = cc;
-		cc++;
-
-		fmtalloc.conv[cc] = column;
-		fmtalloc.index['|'] = cc;
-		cc++;
-
-		fmtalloc.convcount = cc;
-	}
-	unlock(&fmtalloc);
-}
-
-int
-fmtinstall(int c, int (*f)(va_list*, Fconv*))
-{
-
-	if(fmtalloc.convcount <= 0)
-		initfmt();
-
-	lock(&fmtalloc);
-	if(c < 0 || c >= MAXFMT) {
-		unlock(&fmtalloc);
-		return -1;
-	}
-	if(fmtalloc.convcount >= MAXCONV) {
-		unlock(&fmtalloc);
-		return -1;
-	}
-	fmtalloc.conv[fmtalloc.convcount] = f;
-	fmtalloc.index[c] = fmtalloc.convcount;
-	fmtalloc.convcount++;
-
-	unlock(&fmtalloc);
-	return 0;
-}
-
-static	void
-pchar(Rune c, Fconv *fp)
-{
-	int n;
-
-	n = fp->eout - fp->out;
-	if(n > 0) {
-		if(c < Runeself) {
-			*fp->out++ = c;
-			return;
-		}
-		if(n >= UTFmax || n >= runelen(c)) {
-			n = runetochar(fp->out, &c);
-			fp->out += n;
-			return;
-		}
-		fp->eout = fp->out;
-	}
-}
-
-char*
-doprint(char *s, char *es, char *fmt, va_list *argp)
-{
-	int n, c;
-	Rune rune;
-	Fconv local;
-
-	if(fmtalloc.convcount <= 0)
-		initfmt();
-
-	if(s >= es)
-		return s;
-	local.out = s;
-	local.eout = es-1;
-
-loop:
-	c = *fmt & 0xff;
-	if(c >= Runeself) {
-		n = chartorune(&rune, fmt);
-		fmt += n;
-		c = rune;
-	} else
-		fmt++;
-	switch(c) {
-	case 0:
-		*local.out = 0;
-		return local.out;
-	
-	default:
-		printcol++;
-		goto common;
-
-	case '\n':
-		printcol = 0;
-		goto common;
-
-	case '\t':
-		printcol = (printcol+8) & ~7;
-		goto common;
-
-	common:
-		pchar(c, &local);
-		goto loop;
-
-	case '%':
-		break;
-	}
-	local.f1 = NONE;
-	local.f2 = NONE;
-	local.f3 = 0;
-
-	/*
-	 * read one of the following
-	 *	1. number, => f1, f2 in order.
-	 *	2. '*' same as number (from args)
-	 *	3. '.' ignored (separates numbers)
-	 *	4. flag => f3
-	 *	5. verb and terminate
-	 */
-l0:
-	c = *fmt & 0xff;
-	if(c >= Runeself) {
-		n = chartorune(&rune, fmt);
-		fmt += n;
-		c = rune;
-	} else
-		fmt++;
-
-l1:
-	if(c == 0) {
-		fmt--;
-		goto loop;
-	}
-	if(c == '.') {
-		if(local.f1 == NONE)
-			local.f1 = 0;
-		local.f2 = 0;
-		goto l0;
-	}
-	if((c >= '1' && c <= '9') ||
-	   (c == '0' && local.f1 != NONE)) {	/* '0' is a digit for f2 */
-		n = 0;
-		while(c >= '0' && c <= '9') {
-			n = n*10 + c-'0';
-			c = *fmt++;
-		}
-		if(local.f1 == NONE)
-			local.f1 = n;
-		else
-			local.f2 = n;
-		goto l1;
-	}
-	if(c == '*') {
-		n = va_arg(*argp, int);
-		if(local.f1 == NONE)
-			local.f1 = n;
-		else
-			local.f2 = n;
-		goto l0;
-	}
-	n = 0;
-	if(c >= 0 && c < MAXFMT)
-		n = fmtalloc.index[c];
-	local.chr = c;
-	n = (*fmtalloc.conv[n])(argp, &local);
-	if(n < 0) {
-		local.f3 |= -n;
-		goto l0;
-	}
-	goto loop;
-}
-
-int
-numbconv(va_list *arg, Fconv *fp)
-{
-	char s[IDIGIT];
-	int i, f, n, b, ucase;
-	long v;
-	vlong vl;
-
-	SET(v);
-	SET(vl);
-
-	ucase = 0;
-	b = fp->chr;
-	switch(fp->chr) {
-	case 'u':
-		fp->f3 |= FUNSIGN;
-	case 'd':
-		b = 10;
-		break;
-
-	case 'b':
-		b = 2;
-		break;
-
-	case 'o':
-		b = 8;
-		break;
-
-	case 'X':
-		ucase = 1;
-	case 'x':
-		b = 16;
-		break;
-	case 'p':
-		fp->f3 |= FPOINTER|FUNSIGN;
-		b = 16;
-		break;
-	}
-
-	f = 0;
-	switch(fp->f3 & (FVLONG|FLONG|FUNSIGN|FPOINTER)) {
-	case FVLONG|FLONG:
-		vl = va_arg(*arg, vlong);
-		break;
-
-	case FUNSIGN|FVLONG|FLONG:
-		vl = va_arg(*arg, uvlong);
-		break;
-
-	case FUNSIGN|FPOINTER:
-		v = (ulong)va_arg(*arg, void*);
-		break;
-
-	case FLONG:
-		v = va_arg(*arg, long);
-		break;
-
-	case FUNSIGN|FLONG:
-		v = va_arg(*arg, ulong);
-		break;
-
-	default:
-		v = va_arg(*arg, int);
-		break;
-
-	case FUNSIGN:
-		v = va_arg(*arg, unsigned);
-		break;
-	}
-	if(fp->f3 & FVLONG) {
-		if(!(fp->f3 & FUNSIGN) && vl < 0) {
-			vl = -vl;
-			f = 1;
-		}
-	} else {
-		if(!(fp->f3 & FUNSIGN) && v < 0) {
-			v = -v;
-			f = 1;
-		}
-	}
-	s[IDIGIT-1] = 0;
-	for(i = IDIGIT-2;; i--) {
-		if(fp->f3 & FVLONG)
-			n = (uvlong)vl % b;
-		else
-			n = (ulong)v % b;
-		n += '0';
-		if(n > '9') {
-			n += 'a' - ('9'+1);
-			if(ucase)
-				n += 'A'-'a';
-		}
-		s[i] = n;
-		if(i < 2)
-			break;
-		if(fp->f3 & FVLONG)
-			vl = (uvlong)vl / b;
-		else
-			v = (ulong)v / b;
-		if(fp->f2 != NONE && i >= IDIGIT-fp->f2)
-			continue;
-		if(fp->f3 & FVLONG) {
-			if(vl <= 0)
-				break;
-			continue;
-		}
-		if(v <= 0)
-			break;
-	}
-
-	if(fp->f3 & FSHARP) {
-		if(b == 8 && s[i] != '0')
-			s[--i] = '0';
-		if(b == 16) {
-			if(ucase)
-				s[--i] = 'X';
-			else
-				s[--i] = 'x';
-			s[--i] = '0';
-		}
-	}
-	if(f)
-		s[--i] = '-';
-	else if(fp->f3 & FPLUS)
-		s[--i] = '+';
-
-	fp->f2 = NONE;
-	strconv(s+i, fp);
-	return 0;
-}
-
-void
-Strconv(Rune *s, Fconv *fp)
-{
-	int n, c;
-
-	if(fp->f3 & FMINUS)
-		fp->f1 = -fp->f1;
-	n = 0;
-	if(fp->f1 != NONE && fp->f1 >= 0) {
-		for(; s[n]; n++)
-			;
-		while(n < fp->f1) {
-			pchar(' ', fp);
-			printcol++;
-			n++;
-		}
-	}
-	for(;;) {
-		c = *s++;
-		if(c == 0)
-			break;
-		n++;
-		if(fp->f2 == NONE || fp->f2 > 0) {
-			pchar(c, fp);
-			if(fp->f2 != NONE)
-				fp->f2--;
-			switch(c) {
-			default:
-				printcol++;
-				break;
-			case '\n':
-				printcol = 0;
-				break;
-			case '\t':
-				printcol = (printcol+8) & ~7;
-				break;
-			}
-		}
-	}
-	if(fp->f1 != NONE && fp->f1 < 0) {
-		fp->f1 = -fp->f1;
-		while(n < fp->f1) {
-			pchar(' ', fp);
-			printcol++;
-			n++;
-		}
-	}
-}
-
-void
-strconv(char *s, Fconv *fp)
-{
-	int n, c, i;
-	Rune rune;
-
-	if(fp->f3 & FMINUS)
-		fp->f1 = -fp->f1;
-	n = 0;
-	if(fp->f1 != NONE && fp->f1 >= 0) {
-		n = utflen(s);
-		while(n < fp->f1) {
-			pchar(' ', fp);
-			printcol++;
-			n++;
-		}
-	}
-	for(;;) {
-		c = *s & 0xff;
-		if(c >= Runeself) {
-			i = chartorune(&rune, s);
-			s += i;
-			c = rune;
-		} else
-			s++;
-		if(c == 0)
-			break;
-		n++;
-		if(fp->f2 == NONE || fp->f2 > 0) {
-			pchar(c, fp);
-			if(fp->f2 != NONE)
-				fp->f2--;
-			switch(c) {
-			default:
-				printcol++;
-				break;
-			case '\n':
-				printcol = 0;
-				break;
-			case '\t':
-				printcol = (printcol+8) & ~7;
-				break;
-			}
-		}
-	}
-	if(fp->f1 != NONE && fp->f1 < 0) {
-		fp->f1 = -fp->f1;
-		while(n < fp->f1) {
-			pchar(' ', fp);
-			printcol++;
-			n++;
-		}
-	}
-}
-
-static int
-noconv(va_list *va, Fconv *fp)
-{
-	char s[10];
-
-	USED(va);
-	s[0] = '*';
-	s[1] = fp->chr;
-	s[2] = '*';
-	s[3] = 0;
-	fp->f1 = 0;
-	fp->f2 = NONE;
-	fp->f3 = 0;
-	strconv(s, fp);
-	return 0;
-}
-
-static int
-cconv(va_list *arg, Fconv *fp)
-{
-	char s[10];
-	Rune rune;
-
-	rune = va_arg(*arg, int);
-	if(fp->chr == 'c')
-		rune &= 0xff;
-	s[runetochar(s, &rune)] = 0;
-
-	fp->f2 = NONE;
-	strconv(s, fp);
-	return 0;
-}
-
-static Rune null[] = { L'<', L'n', L'u', L'l', L'l', L'>', L'\0' };
-
-static	int
-sconv(va_list *arg, Fconv *fp)
-{
-	char *s;
-	Rune *r;
-
-	if(fp->chr == 's') {
-		s = va_arg(*arg, char*);
-		if(s == 0)
-			s = "<null>";
-		strconv(s, fp);
-	} else {
-		r = va_arg(*arg, Rune*);
-		if(r == 0)
-			r = null;
-		Strconv(r, fp);
-	}
-	return 0;
-}
-
-static	int
-percent(va_list *va, Fconv *fp)
-{
-	USED(va);
-
-	pchar('%', fp);
-	printcol++;
-	return 0;
-}
-
-static	int
-column(va_list *arg, Fconv *fp)
-{
-	int col, pc;
-
-	col = va_arg(*arg, int);
-	while(printcol < col) {
-		pc = (printcol+8) & ~7;
-		if(pc <= col) {
-			pchar('\t', fp);
-			printcol = pc;
-		} else {
-			pchar(' ', fp);
-			printcol++;
-		}
-	}
-	return 0;
-}
-
-static int
-flags(va_list *va, Fconv *fp)
-{
-	int f;
-
-	USED(va);
-	f = 0;
-	switch(fp->chr) {
-	case '+':
-		f = FPLUS;
-		break;
-
-	case '-':
-		f = FMINUS;
-		break;
-
-	case '#':
-		f = FSHARP;
-		break;
-
-	case 'l':
-		f = FLONG;
-		if(fp->f3 & FLONG)
-			f = FVLONG;
-		break;
-
-	case 'u':
-		f = FUNSIGN;
-		break;
-	}
-	return -f;
-}
-
-/*
- * This code is superseded by the more accurate (but more complex)
- * algorithm in fltconv.c and dtoa.c.  Uncomment this routine to avoid
- * using the more complex code.
- *
- */
-
--- a/sys/src/cmd/unix/u9fs/fcall.h
+++ /dev/null
@@ -1,123 +1,0 @@
-#define	VERSION9P	"9P2000"
-#define	MAXWELEM	16
-
-typedef
-struct	Fcall
-{
-	uchar	type;
-	u32int	fid;
-	ushort	tag;
-
-	u32int	msize;		/* Tversion, Rversion */
-	char	*version;	/* Tversion, Rversion */
-
-	u32int	oldtag;		/* Tflush */
-
-	char	*ename;		/* Rerror */
-
-	Qid	qid;		/* Rattach, Ropen, Rcreate */
-	u32int	iounit;		/* Ropen, Rcreate */
-
-	char	*uname;		/* Tattach, Tauth */
-	char	*aname;		/* Tattach, Tauth */
-
-
-	u32int	perm;		/* Tcreate */ 
-	char	*name;		/* Tcreate */
-	uchar	mode;		/* Tcreate, Topen */
-
-	u32int	newfid;		/* Twalk */
-	ushort	nwname;		/* Twalk */
-	char	*wname[MAXWELEM];	/* Twalk */
-
-	ushort	nwqid;		/* Rwalk */
-	Qid	wqid[MAXWELEM];		/* Rwalk */
-
-	vlong	offset;		/* Tread, Twrite */
-	u32int	count;		/* Tread, Twrite, Rread */
-	char	*data;		/* Twrite, Rread */
-
-	ushort	nstat;		/* Twstat, Rstat */
-	uchar	*stat;		/* Twstat, Rstat */
-
-	u32int	afid;		/* Tauth, Tattach */
-	Qid aqid;		/* Rauth */
-} Fcall;
-
-
-#define	GBIT8(p)	((p)[0])
-#define	GBIT16(p)	((p)[0]|((p)[1]<<8))
-#define	GBIT32(p)	((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
-#define	GBIT64(p)	((ulong)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
-				((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
-
-#define	PBIT8(p,v)	(p)[0]=(v)
-#define	PBIT16(p,v)	(p)[0]=(v);(p)[1]=(v)>>8
-#define	PBIT32(p,v)	(p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
-#define	PBIT64(p,v)	(p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
-			(p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
-
-#define	BIT8SZ		1
-#define	BIT16SZ		2
-#define	BIT32SZ		4
-#define	BIT64SZ		8
-#define	QIDSZ	(BIT8SZ+BIT32SZ+BIT64SZ)
-
-/* STATFIXLEN includes leading 16-bit count */
-/* The count, however, excludes itself; total size is BIT16SZ+count */
-#define STATFIXLEN	(BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+1*BIT64SZ)	/* amount of fixed length data in a stat buffer */
-
-#define	MAXMSG		10000	/* max header sans data */
-#define	NOTAG		~0U	/* Dummy tag */
-#define	IOHDRSZ		24	/* ample room for Twrite/Rread header (iounit) */
-
-enum
-{
-	Tversion =	100,
-	Rversion,
-	Tauth =		102,
-	Rauth,
-	Tattach =	104,
-	Rattach,
-	Terror =	106,	/* illegal */
-	Rerror,
-	Tflush =	108,
-	Rflush,
-	Twalk =		110,
-	Rwalk,
-	Topen =		112,
-	Ropen,
-	Tcreate =	114,
-	Rcreate,
-	Tread =		116,
-	Rread,
-	Twrite =	118,
-	Rwrite,
-	Tclunk =	120,
-	Rclunk,
-	Tremove =	122,
-	Rremove,
-	Tstat =		124,
-	Rstat,
-	Twstat =	126,
-	Rwstat,
-	Tmax
-};
-
-uint	convM2S(uchar*, uint, Fcall*);
-uint	convS2M(Fcall*, uchar*, uint);
-
-int	statcheck(uchar *abuf, uint nbuf);
-uint	convM2D(uchar*, uint, Dir*, char*);
-uint	convD2M(Dir*, uchar*, uint);
-uint	sizeD2M(Dir*);
-
-int	fcallconv(va_list*, Fconv*);
-int	dirconv(va_list*, Fconv*);
-int	dirmodeconv(va_list*, Fconv*);
-
-int	read9pmsg(int, void*, uint);
-
-enum {
-	NOFID = 0xFFFFFFFF,
-};
--- a/sys/src/cmd/unix/u9fs/fcallconv.c
+++ /dev/null
@@ -1,228 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-#include <oldfcall.h>
-
-extern int old9p;
-
-static uint dumpsome(char*, char*, long);
-static void fdirconv(char*, Dir*);
-static char *qidtype(char*, uchar);
-
-#define	QIDFMT	"(%.16llux %lud %s)"
-
-int
-fcallconv(va_list *arg, Fconv *f1)
-{
-	Fcall *f;
-	int fid, type, tag, n, i;
-	char buf[512], tmp[200];
-	Dir *d;
-	Qid *q;
-
-	f = va_arg(*arg, Fcall*);
-	type = f->type;
-	fid = f->fid;
-	tag = f->tag;
-	switch(type){
-	case Tversion:	/* 100 */
-		sprint(buf, "Tversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
-		break;
-	case Rversion:
-		sprint(buf, "Rversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
-		break;
-	case Tauth:	/* 102 */
-		sprint(buf, "Tauth tag %ud afid %d uname %s aname %s", tag,
-			f->afid, f->uname, f->aname);
-		break;
-	case Rauth:
-		sprint(buf, "Rauth tag %ud qid " QIDFMT, tag,
-			f->aqid.path, f->aqid.vers, qidtype(tmp, f->aqid.type));
-		break;
-	case Tattach:	/* 104 */
-		sprint(buf, "Tattach tag %ud fid %d afid %d uname %s aname %s", tag,
-			fid, f->afid, f->uname, f->aname);
-		break;
-	case Rattach:
-		sprint(buf, "Rattach tag %ud qid " QIDFMT, tag,
-			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type));
-		break;
-	case Rerror:	/* 107; 106 (Terror) illegal */
-		sprint(buf, "Rerror tag %ud ename %s", tag, f->ename);
-		break;
-	case Tflush:	/* 108 */
-		sprint(buf, "Tflush tag %ud oldtag %ud", tag, f->oldtag);
-		break;
-	case Rflush:
-		sprint(buf, "Rflush tag %ud", tag);
-		break;
-	case Twalk:	/* 110 */
-		n = sprint(buf, "Twalk tag %ud fid %d newfid %d nwname %d ", tag, fid, f->newfid, f->nwname);
-			for(i=0; i<f->nwname; i++)
-				n += sprint(buf+n, "%d:%s ", i, f->wname[i]);
-		break;
-	case Rwalk:
-		n = sprint(buf, "Rwalk tag %ud nwqid %ud ", tag, f->nwqid);
-		for(i=0; i<f->nwqid; i++){
-			q = &f->wqid[i];
-			n += sprint(buf+n, "%d:" QIDFMT " ", i,
-				q->path, q->vers, qidtype(tmp, q->type));
-		}
-		break;
-	case Topen:	/* 112 */
-		sprint(buf, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
-		break;
-	case Ropen:
-		sprint(buf, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
-			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
-		break;
-	case Tcreate:	/* 114 */
-		sprint(buf, "Tcreate tag %ud fid %ud perm %M mode %d", tag, fid, (ulong)f->perm, f->mode);
-		break;
-	case Rcreate:
-		sprint(buf, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
-			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
-		break;
-	case Tread:	/* 116 */
-		sprint(buf, "Tread tag %ud fid %d offset %lld count %ud",
-			tag, fid, f->offset, f->count);
-		break;
-	case Rread:
-		n = sprint(buf, "Rread tag %ud count %ud ", tag, f->count);
-			dumpsome(buf+n, f->data, f->count);
-		break;
-	case Twrite:	/* 118 */
-		n = sprint(buf, "Twrite tag %ud fid %d offset %lld count %ud ",
-			tag, fid, f->offset, f->count);
-		dumpsome(buf+n, f->data, f->count);
-		break;
-	case Rwrite:
-		sprint(buf, "Rwrite tag %ud count %ud", tag, f->count);
-		break;
-	case Tclunk:	/* 120 */
-		sprint(buf, "Tclunk tag %ud fid %ud", tag, fid);
-		break;
-	case Rclunk:
-		sprint(buf, "Rclunk tag %ud", tag);
-		break;
-	case Tremove:	/* 122 */
-		sprint(buf, "Tremove tag %ud fid %ud", tag, fid);
-		break;
-	case Rremove:
-		sprint(buf, "Rremove tag %ud", tag);
-		break;
-	case Tstat:	/* 124 */
-		sprint(buf, "Tstat tag %ud fid %ud", tag, fid);
-		break;
-	case Rstat:
-		n = sprint(buf, "Rstat tag %ud ", tag);
-		if(f->nstat > sizeof tmp)
-			sprint(buf+n, " stat(%d bytes)", f->nstat);
-		else{
-			d = (Dir*)tmp;
-			(old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
-			sprint(buf+n, " stat ");
-			fdirconv(buf+n+6, d);
-		}
-		break;
-	case Twstat:	/* 126 */
-		n = sprint(buf, "Twstat tag %ud fid %ud", tag, fid);
-		if(f->nstat > sizeof tmp)
-			sprint(buf+n, " stat(%d bytes)", f->nstat);
-		else{
-			d = (Dir*)tmp;
-			(old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
-			sprint(buf+n, " stat ");
-			fdirconv(buf+n+6, d);
-		}
-		break;
-	case Rwstat:
-		sprint(buf, "Rwstat tag %ud", tag);
-		break;
-	default:
-		sprint(buf,  "unknown type %d", type);
-	}
-	strconv(buf, f1);
-	return(sizeof(Fcall*));
-}
-
-static char*
-qidtype(char *s, uchar t)
-{
-	char *p;
-
-	p = s;
-	if(t & QTDIR)
-		*p++ = 'd';
-	if(t & QTAPPEND)
-		*p++ = 'a';
-	if(t & QTEXCL)
-		*p++ = 'l';
-	if(t & QTMOUNT)
-		*p++ = 'm';
-	if(t & QTAUTH)
-		*p++ = 'A';
-	*p = '\0';
-	return s;
-}
-
-int
-dirconv(va_list *arg, Fconv *f)
-{
-	char buf[160];
-
-	fdirconv(buf, va_arg(*arg, Dir*));
-	strconv(buf, f);
-	return(sizeof(Dir*));
-}
-
-static void
-fdirconv(char *buf, Dir *d)
-{
-	char tmp[16];
-
-	sprint(buf, "'%s' '%s' '%s' '%s' "
-		"q " QIDFMT " m %#luo "
-		"at %ld mt %ld l %lld "
-		"t %d d %d",
-			d->name, d->uid, d->gid, d->muid,
-			d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
-			d->atime, d->mtime, d->length,
-			d->type, d->dev);
-}
-
-/*
- * dump out count (or DUMPL, if count is bigger) bytes from
- * buf to ans, as a string if they are all printable,
- * else as a series of hex bytes
- */
-#define DUMPL 64
-
-static uint
-dumpsome(char *ans, char *buf, long count)
-{
-	int i, printable;
-	char *p;
-
-	printable = 1;
-	if(count > DUMPL)
-		count = DUMPL;
-	for(i=0; i<count && printable; i++)
-		if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
-			printable = 0;
-	p = ans;
-	*p++ = '\'';
-	if(printable){
-		memmove(p, buf, count);
-		p += count;
-	}else{
-		for(i=0; i<count; i++){
-			if(i>0 && i%4==0)
-				*p++ = ' ';
-			sprint(p, "%2.2ux", (uchar)buf[i]);
-			p += 2;
-		}
-	}
-	*p++ = '\'';
-	*p = 0;
-	return p - ans;
-}
--- a/sys/src/cmd/unix/u9fs/makefile
+++ /dev/null
@@ -1,64 +1,0 @@
-#
-# The goal is to keep as much per-system stuff autodetected in plan9.h
-# as possible.  Still, sometimes you can't help it.  Look for your system.
-#
-
-# SGI
-#
-# To correctly handle 64-bit files and offsets, add -64 to CFLAGS and LDFLAGS
-# On Irix 5.X, add -DIRIX5X to hack around their own #include problems (see plan9.h).
-#
-# SunOS
-#
-# SunOS 5.5.1 does not provide inttypes.h; add -lsunos to CFLAGS and
-# change CC and LD to gcc.  Add -lsocket, -lnsl to LDTAIL.
-# If you need <inttypes.h> copy sun-inttypes.h to inttypes.h.
-#
-#CC=cc
-CFLAGS=-g -I.
-LD=cc
-LDFLAGS=
-LDTAIL=
-
-OFILES=\
-	authnone.o\
-	authrhosts.o\
-	authp9any.o\
-	convD2M.o\
-	convM2D.o\
-	convM2S.o\
-	convS2M.o\
-	des.o\
-	dirmodeconv.o\
-	doprint.o\
-	fcallconv.o\
-	oldfcall.o\
-	print.o\
-	random.o\
-	readn.o\
-	remotehost.o\
-	rune.o\
-	safecpy.o\
-	strecpy.o\
-	tokenize.o\
-	u9fs.o\
-	utflen.o\
-	utfrune.o\
-
-HFILES=\
-	fcall.h\
-	plan9.h
-
-u9fs: $(OFILES)
-	$(LD) $(LDFLAGS) -o u9fs $(OFILES) $(LDTAIL)
-
-%.o: %.c $(HFILES)
-	$(CC) $(CFLAGS) -c $*.c
-
-clean:
-	rm -f *.o u9fs
-
-install: u9fs
-	cp u9fs ../../bin
-
-.PHONY: clean install
--- a/sys/src/cmd/unix/u9fs/oldfcall.c
+++ /dev/null
@@ -1,522 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-#include <oldfcall.h>
-#include <stdlib.h>
-
-/*
- * routines to package the old protocol in the new structures.
- */
-
-#define	SHORT(x)	p[0]=f->x; p[1]=f->x>>8; p += 2
-#define	LONG(x)		p[0]=f->x; p[1]=f->x>>8; p[2]=f->x>>16; p[3]=f->x>>24; p += 4
-#define	VLONG(x)	p[0]=f->x;	p[1]=f->x>>8;\
-			p[2]=f->x>>16;	p[3]=f->x>>24;\
-			p[4]=f->x>>32;	p[5]=f->x>>40;\
-			p[6]=f->x>>48;	p[7]=f->x>>56;\
-			p += 8
-#define	STRING(x,n)	strecpy((char*)p, (char*)p+n, f->x); p += n;
-#define	FIXQID(q)		q.path ^= (q.path>>33); q.path &= 0x7FFFFFFF; q.path |= (q.type&0x80)<<24
-
-uint
-oldhdrsize(uchar type)
-{
-	switch(type){
-	default:
-		return 0;
-	case oldTnop:
-		return 3;
-	case oldTflush:
-		return 3+2;
-	case oldTclone:
-		return 3+2+2;
-	case oldTwalk:
-		return 3+2+28;
-	case oldTopen:
-		return 3+2+1;
-	case oldTcreate:
-		return 3+2+28+4+1;
-	case oldTread:
-		return 3+2+8+2;
-	case oldTwrite:
-		return 3+2+8+2+1;
-	case oldTclunk:
-		return 3+2;
-	case oldTremove:
-		return 3+2;
-	case oldTstat:
-		return 3+2;
-	case oldTwstat:
-		return 3+2+116;
-	case oldTsession:
-		return 3+8;
-	case oldTattach:
-		return 3+2+28+28+72+13;
-	}
-}
-
-uint
-iosize(uchar *p)
-{
-	if(p[0] != oldTwrite)
-		return 0;
-	return p[3+2+8] | (p[3+2+8+1]<<8);
-}
-
-uint
-sizeS2M(Fcall *f)
-{
-	switch(f->type)
-	{
-	default:
-		abort();
-		return 0;
-
-	/* no T messages */
-
-/*
- */
-	case Rversion:
-		return 1+2;
-
-/*
-	case Rsession:
-		return 1+2+8+28+48;
-*/
-
-	case Rattach:
-		return 1+2+2+4+4+13;
-
-	case Rerror:
-		return 1+2+64;
-
-	case Rflush:
-		if(f->tag&0x8000)
-			return 1+2+8+28+48;	/* session */
-		return 1+2;
-
-	/* assumes we don't ever see Tclwalk requests ... */
-	case Rwalk:
-		if(f->nwqid == 0)
-			return 1+2+2;
-		else
-			return 1+2+2+4+4;
-
-	case Ropen:
-		return 1+2+2+4+4;
-
-	case Rcreate:
-		return 1+2+2+4+4;
-
-	case Rread:
-		return 1+2+2+2+1+f->count;
-
-	case Rwrite:
-		return 1+2+2+2;
-
-	case Rclunk:
-		return 1+2+2;
-
-	case Rremove:
-		return 1+2+2;
-
-	case Rstat:
-		return 1+2+2+116;
-
-	case Rwstat:
-		return 1+2+2;
-	}
-}
-
-uint
-convS2Mold(Fcall *f, uchar *ap, uint nap)
-{
-	uchar *p;
-
-	if(nap < sizeS2M(f))
-		return 0;
-
-	p = ap;
-	switch(f->type)
-	{
-	default:
-		abort();
-		return 0;
-
-	/* no T messages */
-
-/*
- */
-	case Rversion:
-		*p++ = oldRnop;
-		SHORT(tag);
-		break;
-
-/*
-	case Rsession:
-		*p++ = oldRsession;
-		SHORT(tag);
-
-		if(f->nchal > 8)
-			f->nchal = 8;
-		memmove(p, f->chal, f->nchal);
-		p += f->nchal;
-		if(f->nchal < 8){
-			memset(p, 0, 8 - f->nchal);
-			p += 8 - f->nchal;
-		}
-
-		STRING(authid, 28);
-		STRING(authdom, 48);
-		break;
-*/
-
-	case Rattach:
-		*p++ = oldRattach;
-		SHORT(tag);
-		SHORT(fid);
-		FIXQID(f->qid);
-		LONG(qid.path);
-		LONG(qid.vers);
-		memset(p, 0, 13);
-		p += 13;
-		break;
-
-	case Rerror:
-		*p++ = oldRerror;
-		SHORT(tag);
-		STRING(ename, 64);
-		break;
-
-	case Rflush:
-		if(f->tag&0x8000){
-			*p++ = oldRsession;
-			f->tag &= ~0x8000;
-			SHORT(tag);
-			memset(p, 0, 8+28+48);
-			p += 8+28+48;
-		}else{
-			*p++ = oldRflush;
-			SHORT(tag);
-		}
-		break;
-
-	/* assumes we don't ever see Tclwalk requests ... */
-	case Rwalk:
-		if(f->nwqid == 0){	/* successful clone */
-			*p++ = oldRclone;
-			SHORT(tag);
-			SHORT(fid);
-		}else{			/* successful 1-element walk */
-			*p++ = oldRwalk;
-			SHORT(tag);
-			SHORT(fid);
-			FIXQID(f->wqid[0]);
-			LONG(wqid[0].path);
-			LONG(wqid[0].vers);
-		}
-		break;
-
-	case Ropen:
-		*p++ = oldRopen;
-		SHORT(tag);
-		SHORT(fid);
-		FIXQID(f->qid);
-		LONG(qid.path);
-		LONG(qid.vers);
-		break;
-
-	case Rcreate:
-		*p++ = oldRcreate;
-		SHORT(tag);
-		SHORT(fid);
-		FIXQID(f->qid);
-		LONG(qid.path);
-		LONG(qid.vers);
-		break;
-
-	case Rread:
-		*p++ = oldRread;
-		SHORT(tag);
-		SHORT(fid);
-		SHORT(count);
-		p++;	/* pad(1) */
-		memmove(p, f->data, f->count);
-		p += f->count;
-		break;
-
-	case Rwrite:
-		*p++ = oldRwrite;
-		SHORT(tag);
-		SHORT(fid);
-		SHORT(count);
-		break;
-
-	case Rclunk:
-		*p++ = oldRclunk;
-		SHORT(tag);
-		SHORT(fid);
-		break;
-
-	case Rremove:
-		*p++ = oldRremove;
-		SHORT(tag);
-		SHORT(fid);
-		break;
-
-	case Rstat:
-		*p++ = oldRstat;
-		SHORT(tag);
-		SHORT(fid);
-		memmove(p, f->stat, 116);
-		p += 116;
-		break;
-
-	case Rwstat:
-		*p++ = oldRwstat;
-		SHORT(tag);
-		SHORT(fid);
-		break;
-	}
-	return p - ap;
-}
-
-uint
-sizeD2Mold(Dir *d)
-{
-	return 116;
-}
-
-uint
-convD2Mold(Dir *f, uchar *ap, uint nap)
-{
-	uchar *p;
-
-	if(nap < 116)
-		return 0;
-
-	p = ap;
-	STRING(name, 28);
-	STRING(uid, 28);
-	STRING(gid, 28);
-	FIXQID(f->qid);
-	LONG(qid.path);
-	LONG(qid.vers);
-	LONG(mode);
-	LONG(atime);
-	LONG(mtime);
-	VLONG(length);
-	SHORT(type);
-	SHORT(dev);
-
-	return p - ap;
-}
-
-#undef SHORT
-#undef LONG
-#undef VLONG
-#undef STRING
-#define	CHAR(x)	f->x = *p++
-#define	SHORT(x)	f->x = (p[0] | (p[1]<<8)); p += 2
-#define	LONG(x)		f->x = (p[0] | (p[1]<<8) |\
-				(p[2]<<16) | (p[3]<<24)); p += 4
-#define	VLONG(x)	f->x = (ulong)(p[0] | (p[1]<<8) |\
-					(p[2]<<16) | (p[3]<<24)) |\
-				((vlong)(p[4] | (p[5]<<8) |\
-					(p[6]<<16) | (p[7]<<24)) << 32); p += 8
-#define	STRING(x,n)	f->x = (char*)p; p += n
-
-uint
-convM2Sold(uchar *ap, uint nap, Fcall *f)
-{
-	uchar *p, *q, *ep;
-
-	p = ap;
-	ep = p + nap;
-
-	if(p+3 > ep)
-		return 0;
-
-	switch(*p++){
-	case oldTnop:
-		f->type = Tversion;
-		SHORT(tag);
-		f->msize = 0;
-		f->version = "9P1";
-		break;
-
-	case oldTflush:
-		f->type = Tflush;
-		SHORT(tag);
-		if(p+2 > ep)
-			return 0;
-		SHORT(oldtag);
-		break;
-
-	case oldTclone:
-		f->type = Twalk;
-		SHORT(tag);
-		if(p+2+2 > ep)
-			return 0;
-		SHORT(fid);
-		SHORT(newfid);
-		f->nwname = 0;
-		break;
-
-	case oldTwalk:
-		f->type = Twalk;
-		SHORT(tag);
-		if(p+2+28 > ep)
-			return 0;
-		SHORT(fid);
-		f->newfid = f->fid;
-		f->nwname = 1;
-		f->wname[0] = (char*)p;
-		p += 28;
-		break;
-
-	case oldTopen:
-		f->type = Topen;
-		SHORT(tag);
-		if(p+2+1 > ep)
-			return 0;
-		SHORT(fid);
-		CHAR(mode);
-		break;
-
-	case oldTcreate:
-		f->type = Tcreate;
-		SHORT(tag);
-		if(p+2+28+4+1 > ep)
-			return 0;
-		SHORT(fid);
-		f->name = (char*)p;
-		p += 28;
-		LONG(perm);
-		CHAR(mode);
-		break;
-
-	case oldTread:
-		f->type = Tread;
-		SHORT(tag);
-		if(p+2+8+2 > ep)
-			return 0;
-		SHORT(fid);
-		VLONG(offset);
-		SHORT(count);
-		break;
-
-	case oldTwrite:
-		f->type = Twrite;
-		SHORT(tag);
-		if(p+2+8+2+1 > ep)
-			return 0;
-		SHORT(fid);
-		VLONG(offset);
-		SHORT(count);
-		p++;	/* pad(1) */
-		if(p+f->count > ep)
-			return 0;
-		f->data = (char*)p;
-		p += f->count;
-		break;
-
-	case oldTclunk:
-		f->type = Tclunk;
-		SHORT(tag);
-		if(p+2 > ep)
-			return 0;
-		SHORT(fid);
-		break;
-
-	case oldTremove:
-		f->type = Tremove;
-		SHORT(tag);
-		if(p+2 > ep)
-			return 0;
-		SHORT(fid);
-		break;
-
-	case oldTstat:
-		f->type = Tstat;
-		f->nstat = 116;
-		SHORT(tag);
-		if(p+2 > ep)
-			return 0;
-		SHORT(fid);
-		break;
-
-	case oldTwstat:
-		f->type = Twstat;
-		SHORT(tag);
-		if(p+2+116 > ep)
-			return 0;
-		SHORT(fid);
-		f->stat = p;
-		q = p+28*3+5*4;
-		memset(q, 0xFF, 8);	/* clear length to ``don't care'' */
-		p += 116;
-		break;
-
-/*
-	case oldTsession:
-		f->type = Tsession;
-		SHORT(tag);
-		if(p+8 > ep)
-			return 0;
-		f->chal = p;
-		p += 8;
-		f->nchal = 8;
-		break;
-*/
-	case oldTsession:
-		f->type = Tflush;
-		SHORT(tag);
-		f->tag |= 0x8000;
-		f->oldtag = f->tag;
-		p += 8;
-		break;
-
-	case oldTattach:
-		f->type = Tattach;
-		SHORT(tag);
-		if(p+2+28+28+72+13 > ep)
-			return 0;
-		SHORT(fid);
-		STRING(uname, 28);
-		STRING(aname, 28);
-		p += 72+13;
-		f->afid = NOFID;
-		break;
-
-	default:
-		return 0;
-	}
-
-	return p-ap;
-}
-
-uint
-convM2Dold(uchar *ap, uint nap, Dir *f, char *strs)
-{
-	uchar *p;
-
-	USED(strs);
-
-	if(nap < 116)
-		return 0;
-
-	p = (uchar*)ap;
-	STRING(name, 28);
-	STRING(uid, 28);
-	STRING(gid, 28);
-	LONG(qid.path);
-	LONG(qid.vers);
-	LONG(mode);
-	LONG(atime);
-	LONG(mtime);
-	VLONG(length);
-	SHORT(type);
-	SHORT(dev);
-	f->qid.type = (f->mode>>24)&0xF0;
-	return p - (uchar*)ap;
-}
--- a/sys/src/cmd/unix/u9fs/oldfcall.h
+++ /dev/null
@@ -1,50 +1,0 @@
-uint	convM2Dold(uchar*, uint, Dir*, char*);
-uint	convD2Mold(Dir*, uchar*, uint);
-uint	sizeD2Mold(Dir*);
-uint	convM2Sold(uchar*, uint, Fcall*);
-uint	convS2Mold(Fcall*, uchar*, uint);
-uint	oldhdrsize(uchar);
-uint	iosize(uchar*);
-
-enum
-{
-	oldTnop =		50,
-	oldRnop,
-	oldTosession =	52,	/* illegal */
-	oldRosession,		/* illegal */
-	oldTerror =	54,	/* illegal */
-	oldRerror,
-	oldTflush =	56,
-	oldRflush,
-	oldToattach =	58,	/* illegal */
-	oldRoattach,		/* illegal */
-	oldTclone =	60,
-	oldRclone,
-	oldTwalk =		62,
-	oldRwalk,
-	oldTopen =		64,
-	oldRopen,
-	oldTcreate =	66,
-	oldRcreate,
-	oldTread =		68,
-	oldRread,
-	oldTwrite =	70,
-	oldRwrite,
-	oldTclunk =	72,
-	oldRclunk,
-	oldTremove =	74,
-	oldRremove,
-	oldTstat =		76,
-	oldRstat,
-	oldTwstat =	78,
-	oldRwstat,
-	oldTclwalk =	80,
-	oldRclwalk,
-	oldTauth =		82,	/* illegal */
-	oldRauth,			/* illegal */
-	oldTsession =	84,
-	oldRsession,
-	oldTattach =	86,
-	oldRattach,
-	oldTmax
-};
--- a/sys/src/cmd/unix/u9fs/plan9.h
+++ /dev/null
@@ -1,199 +1,0 @@
-/* magic to get SUSV2 standard, including pread, pwrite*/
-#define _XOPEN_SOURCE 500
-/* magic to get 64-bit pread/pwrite */
-#define _LARGEFILE64_SOURCE
-/* magic to get 64-bit stat on Linux, maybe others */
-#define _FILE_OFFSET_BITS 64
-
-#ifdef sgi
-#define _BSD_TYPES	1	/* for struct timeval */
-#include <sys/select.h>
-#define _BSD_SOURCE	1	/* for ruserok */
-/*
- * SGI IRIX 5.x doesn't allow inclusion of both inttypes.h and
- * sys/types.h.  These definitions are the ones we need from
- * inttypes.h that aren't in sys/types.h.
- *
- * Unlike most of our #ifdef's, IRIX5X must be set in the makefile.
- */
-#ifdef IRIX5X
-#define __inttypes_INCLUDED
-typedef unsigned int            uint32_t;
-typedef signed long long int    int64_t;
-typedef unsigned long long int  uint64_t;
-#endif /* IRIX5X */
-#endif /* sgi */
-
-
-#ifdef sun	/* sparc and __svr4__ are also defined on the offending machine */
-#define __EXTENSIONS__	1	/* for struct timeval */
-#endif
-
-#include <inttypes.h>		/* for int64_t et al. */
-#include <stdarg.h>		/* for va_list, vararg macros */
-#ifndef va_copy
-#ifdef __va_copy
-#define va_copy	__va_copy
-#else
-#define va_copy(d, s)	memmove(&(d), &(s), sizeof(va_list))
-#endif /* __va_copy */
-#endif /* va_copy */
-#include <sys/types.h>
-#include <string.h>		/* for memmove */
-#include <unistd.h>		/* for write */
-
-#define ulong p9ulong		/* because sys/types.h has some of these sometimes */
-#define ushort p9ushort
-#define uchar p9uchar
-#define uint p9uint
-#define vlong p9vlong
-#define uvlong p9uvlong
-#define u32int p9u32int
-
-typedef unsigned char uchar;
-typedef unsigned short ushort;
-typedef unsigned long ulong;
-typedef unsigned int uint;
-typedef int64_t vlong;
-typedef uint64_t uvlong;
-typedef uint32_t u32int;
-typedef uint64_t u64int;
-typedef ushort Rune;
-
-#define nil ((void*)0)
-#define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
-#ifndef offsetof
-#define	offsetof(s, m)	(ulong)(&(((s*)0)->m))
-#endif
-#define	assert(x)	if(x);else _assert("x")
-
-extern char *argv0;
-#define	ARGBEGIN	for((void)(argv0||(argv0=*argv)),argv++,argc--;\
-			    argv[0] && argv[0][0]=='-' && argv[0][1];\
-			    argc--, argv++) {\
-				char *_args, *_argt;\
-				Rune _argc;\
-				_args = &argv[0][1];\
-				if(_args[0]=='-' && _args[1]==0){\
-					argc--; argv++; break;\
-				}\
-				_argc = 0;\
-				while(*_args && (_args += chartorune(&_argc, _args)))\
-				switch(_argc)
-#define	ARGEND		SET(_argt);USED(_argt);USED(_argc);USED(_args);}\
-					USED(argv);USED(argc);
-#define	ARGF()		(_argt=_args, _args="",\
-				(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
-#define	EARGF(x)		(_argt=_args, _args="",\
-				(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
-
-#define	ARGC()		_argc
-
-#define	SET(x)	(x) = 0
-#define	USED(x)	(void)(x)
-
-enum
-{
-	UTFmax		= 3,		/* maximum bytes per rune */
-	Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
-	Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
-	Runeerror	= 0x80,		/* decoding error in UTF */
-	Runemax		= 0xFFFF,	/* 16 bit rune */
-};
-
-extern	int	runetochar(char*, Rune*);
-extern	int	chartorune(Rune*, char*);
-extern	int	runelen(long);
-extern	int	utflen(char*);
-extern	char*	strecpy(char*, char*, char*);
-extern	int	tokenize(char*, char**, int);
-extern	int	getfields(char*, char**, int, int, char*);
-
-/*
- * print routines
- */
-typedef	struct	Fconv	Fconv;
-struct	Fconv
-{
-	char*	out;		/* pointer to next output */
-	char*	eout;		/* pointer to end */
-	int	f1;
-	int	f2;
-	int	f3;
-	int	chr;
-};
-extern	char*	doprint(char*, char*, char*, va_list *argp);
-extern	int	print(char*, ...);
-extern	char*	seprint(char*, char*, char*, ...);
-extern	int	snprint(char*, int, char*, ...);
-extern	int	sprint(char*, char*, ...);
-extern	int	fprint(int, char*, ...);
-
-extern	int	fmtinstall(int, int (*)(va_list*, Fconv*));
-extern	int	numbconv(va_list*, Fconv*);
-extern	void	strconv(char*, Fconv*);
-extern	int	fltconv(va_list*, Fconv*);
-
-#define	OREAD	0	/* open for read */
-#define	OWRITE	1	/* write */
-#define	ORDWR	2	/* read and write */
-#define	OEXEC	3	/* execute, == read but check execute permission */
-#define	OTRUNC	16	/* or'ed in (except for exec), truncate file first */
-#define	OCEXEC	32	/* or'ed in, close on exec */
-#define	ORCLOSE	64	/* or'ed in, remove on close */
-#define	OEXCL	0x1000	/* or'ed in, exclusive use */
-
-/* bits in Qid.type */
-#define QTDIR		0x80		/* type bit for directories */
-#define QTAPPEND	0x40		/* type bit for append only files */
-#define QTEXCL		0x20		/* type bit for exclusive use files */
-#define QTMOUNT		0x10		/* type bit for mounted channel */
-#define QTAUTH		0x08
-#define QTFILE		0x00		/* plain file */
-
-/* bits in Dir.mode */
-#define DMDIR		0x80000000	/* mode bit for directories */
-#define DMAPPEND	0x40000000	/* mode bit for append only files */
-#define DMEXCL		0x20000000	/* mode bit for exclusive use files */
-#define DMMOUNT		0x10000000	/* mode bit for mounted channel */
-#define DMREAD		0x4		/* mode bit for read permission */
-#define DMWRITE		0x2		/* mode bit for write permission */
-#define DMEXEC		0x1		/* mode bit for execute permission */
-
-typedef
-struct Qid
-{
-	vlong	path;
-	ulong	vers;
-	uchar	type;
-} Qid;
-
-typedef
-struct Dir {
-	/* system-modified data */
-	ushort	type;	/* server type */
-	uint	dev;	/* server subtype */
-	/* file data */
-	Qid	qid;	/* unique id from server */
-	ulong	mode;	/* permissions */
-	ulong	atime;	/* last read time */
-	ulong	mtime;	/* last write time */
-	vlong	length;	/* file length: see <u.h> */
-	char	*name;	/* last element of path */
-	char	*uid;	/* owner name */
-	char	*gid;	/* group name */
-	char	*muid;	/* last modifier name */
-} Dir;
-
-long readn(int, void*, long);
-void remotehost(char*, int);
-
-enum {
-	NAMELEN = 28,
-	ERRLEN = 64
-};
-
-/* DES */
-#define DESKEYLEN 7
-void	key_setup(char key[DESKEYLEN], char expandedkey[128]);
-void	block_cipher(char expandedkey[128], char buf[8], int decrypting);
--- a/sys/src/cmd/unix/u9fs/print.c
+++ /dev/null
@@ -1,87 +1,0 @@
-#include <plan9.h>
-
-#define	SIZE	4096
-extern	int	printcol;
-
-int
-print(char *fmt, ...)
-{
-	char buf[SIZE], *out;
-	va_list arg, temp;
-	int n;
-
-	va_start(arg, fmt);
-	va_copy(temp, arg);
-	out = doprint(buf, buf+SIZE, fmt, &temp);
-	va_end(temp);
-	va_end(arg);
-	n = write(1, buf, (long)(out-buf));
-	return n;
-}
-
-int
-fprint(int f, char *fmt, ...)
-{
-	char buf[SIZE], *out;
-	va_list arg, temp;
-	int n;
-
-	va_start(arg, fmt);
-	va_copy(temp, arg);
-	out = doprint(buf, buf+SIZE, fmt, &temp);
-	va_end(temp);
-	va_end(arg);
-	n = write(f, buf, (long)(out-buf));
-	return n;
-}
-
-int
-sprint(char *buf, char *fmt, ...)
-{
-	char *out;
-	va_list arg, temp;
-	int scol;
-
-	scol = printcol;
-	va_start(arg, fmt);
-	va_copy(temp, arg);
-	out = doprint(buf, buf+SIZE, fmt, &temp);
-	va_end(temp);
-	va_end(arg);
-	printcol = scol;
-	return out-buf;
-}
-
-int
-snprint(char *buf, int len, char *fmt, ...)
-{
-	char *out;
-	va_list arg, temp;
-	int scol;
-
-	scol = printcol;
-	va_start(arg, fmt);
-	va_copy(temp, arg);
-	out = doprint(buf, buf+len, fmt, &temp);
-	va_end(temp);
-	va_end(arg);
-	printcol = scol;
-	return out-buf;
-}
-
-char*
-seprint(char *buf, char *e, char *fmt, ...)
-{
-	char *out;
-	va_list arg, temp;
-	int scol;
-
-	scol = printcol;
-	va_start(arg, fmt);
-	va_copy(temp, arg);
-	out = doprint(buf, e, fmt, &temp);
-	va_end(temp);
-	va_end(arg);
-	printcol = scol;
-	return out;
-}
--- a/sys/src/cmd/unix/u9fs/random.c
+++ /dev/null
@@ -1,58 +1,0 @@
-#include <plan9.h>
-#include <fcall.h>
-#include <u9fs.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-static long
-getseed(void)
-{
-	struct timeval tv;
-	long seed;
-	int fd, len;
-
-	len = 0;
-	fd = open("/dev/urandom", O_RDONLY);
-	if(fd > 0){
-		len = readn(fd, &seed, sizeof(seed));
-		close(fd);
-	}
-	if(len != sizeof(seed)){
-		gettimeofday(&tv, nil);
-		seed = tv.tv_sec ^ tv.tv_usec ^ (getpid()<<8);
-	}
-	return seed;
-}
-
-static int seeded;
-
-void
-randombytes(uchar *r, uint nr)
-{
-	int i;
-	ulong l;
-
-	if(!seeded){
-		seeded=1;
-		srand48(getseed());
-	}
-	for(i=0; i+4<=nr; i+=4,r+=4){
-		l = (ulong)mrand48();
-		r[0] = l;
-		r[1] = l>>8;
-		r[2] = l>>16;
-		r[3] = l>>24;
-	}
-	if(i<nr){
-		l = (ulong)mrand48();
-		switch(nr-i){
-		case 3:
-			r[2] = l>>16;
-		case 2:
-			r[1] = l>>8;
-		case 1:
-			r[0] = l;
-		}
-	}
-}
--- a/sys/src/cmd/unix/u9fs/readn.c
+++ /dev/null
@@ -1,21 +1,0 @@
-#include <plan9.h>
-
-long
-readn(int f, void *av, long n)
-{
-	char *a;
-	long m, t;
-
-	a = av;
-	t = 0;
-	while(t < n){
-		m = read(f, a+t, n-t);
-		if(m <= 0){
-			if(t == 0)
-				return m;
-			break;
-		}
-		t += m;
-	}
-	return t;
-}
--- a/sys/src/cmd/unix/u9fs/remotehost.c
+++ /dev/null
@@ -1,32 +1,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>	/* various networking crud */
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <plan9.h>
-
-void
-getremotehostname(char *name, int nname)
-{
-	struct sockaddr_in sock;
-	struct hostent *hp;
-	uint len;
-	int on;
-
-	strecpy(name, name+nname, "unknown");
-	len = sizeof sock;
-	if(getpeername(0, (struct sockaddr*)&sock, (void*)&len) < 0)
-		return;
-
-	hp = gethostbyaddr((char *)&sock.sin_addr, sizeof (struct in_addr),
-		sock.sin_family);
-	if(hp == 0)
-		return;
-
-	strecpy(name, name+nname, hp->h_name);
-	on = 1;
-	setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof(on));
-
-	on = 1;
-	setsockopt(0, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
-}
--- a/sys/src/cmd/unix/u9fs/rune.c
+++ /dev/null
@@ -1,205 +1,0 @@
-#include	<plan9.h>
-
-char *argv0;
-
-enum
-{
-	Bit1	= 7,
-	Bitx	= 6,
-	Bit2	= 5,
-	Bit3	= 4,
-	Bit4	= 3,
-	Bit5	= 2,
-
-	T1	= ((1<<(Bit1+1))-1) ^ 0xFF,	/* 0000 0000 */
-	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
-	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
-	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
-	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
-	T5	= ((1<<(Bit5+1))-1) ^ 0xFF,	/* 1111 1000 */
-
-	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0000 0000 0111 1111 */
-	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0000 0000 0111 1111 1111 */
-	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 0000 0000 1111 1111 1111 1111 */
-	Rune4	= (1<<(Bit4+3*Bitx))-1,		/* 0011 1111 1111 1111 1111 1111 */
-
-	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
-	Testx	= Maskx ^ 0xFF,			/* 1100 0000 */
-
-	Bad	= Runeerror,
-};
-
-int
-chartorune(Rune *rune, char *str)
-{
-	int c, c1, c2, c3;
-	long l;
-
-	/*
-	 * one character sequence
-	 *	00000-0007F => T1
-	 */
-	c = *(uchar*)str;
-	if(c < Tx) {
-		*rune = c;
-		return 1;
-	}
-
-	/*
-	 * two character sequence
-	 *	0080-07FF => T2 Tx
-	 */
-	c1 = *(uchar*)(str+1) ^ Tx;
-	if(c1 & Testx)
-		goto bad;
-	if(c < T3) {
-		if(c < T2)
-			goto bad;
-		l = ((c << Bitx) | c1) & Rune2;
-		if(l <= Rune1)
-			goto bad;
-		*rune = l;
-		return 2;
-	}
-
-	/*
-	 * three character sequence
-	 *	0800-FFFF => T3 Tx Tx
-	 */
-	c2 = *(uchar*)(str+2) ^ Tx;
-	if(c2 & Testx)
-		goto bad;
-	if(c < T4) {
-		l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
-		if(l <= Rune2)
-			goto bad;
-		*rune = l;
-		return 3;
-	}
-
- 	/*
-	 * four character sequence
-	 *	10000-10FFFF => T4 Tx Tx Tx
-	 */
-	if(UTFmax >= 4) {
-		c3 = *(uchar*)(str+3) ^ Tx;
-		if(c3 & Testx)
-			goto bad;
-		if(c < T5) {
-			l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
-			if(l <= Rune3)
-				goto bad;
-			if(l > Runemax)
-				goto bad;
-			*rune = l;
-			return 4;
-		}
-	}
-
-	/*
-	 * bad decoding
-	 */
-bad:
-	*rune = Bad;
-	return 1;
-}
-
-int
-runetochar(char *str, Rune *rune)
-{
-	long c;
-
-	c = *rune;
-	if(c > Runemax)
-		c = Runeerror;
-
-	/*
-	 * one character sequence
-	 *	00000-0007F => 00-7F
-	 */
-	if(c <= Rune1) {
-		str[0] = c;
-		return 1;
-	}
-
-	/*
-	 * two character sequence
-	 *	0080-07FF => T2 Tx
-	 */
-	if(c <= Rune2) {
-		str[0] = T2 | (c >> 1*Bitx);
-		str[1] = Tx | (c & Maskx);
-		return 2;
-	}
-
-	/*
-	 * three character sequence
-	 *	0800-FFFF => T3 Tx Tx
-	 */
-	if(c <= Rune3) {
-		str[0] = T3 |  (c >> 2*Bitx);
-		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
-		str[2] = Tx |  (c & Maskx);
-		return 3;
-	}
-
-	/*
-	 * four character sequence
-	 *	10000-1FFFFF => T4 Tx Tx Tx
-	 */
-	str[0] = T4 |  (c >> 3*Bitx);
-	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
-	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
-	str[3] = Tx |  (c & Maskx);
-	return 4;
-}
-
-int
-runelen(long c)
-{
-	Rune rune;
-	char str[UTFmax];
-
-	rune = c;
-	return runetochar(str, &rune);
-}
-
-int
-runenlen(Rune *r, int nrune)
-{
-	int nb, c;
-
-	nb = 0;
-	while(nrune--) {
-		c = *r++;
-		if(c <= Rune1)
-			nb++;
-		else
-		if(c <= Rune2)
-			nb += 2;
-		else
-		if(c <= Rune3 || c > Runemax)
-			nb += 3;
-		else
-			nb += 4;
-	}
-	return nb;
-}
-
-int
-fullrune(char *str, int n)
-{
-	int c;
-
-	if(n <= 0)
-		return 0;
-	c = *(uchar*)str;
-	if(c < Tx)
-		return 1;
-	if(c < T3)
-		return n >= 2;
-	if(UTFmax == 3 || c < T4)
-		return n >= 3;
-	return n >= 4;
-}
-
--- a/sys/src/cmd/unix/u9fs/safecpy.c
+++ /dev/null
@@ -1,12 +1,0 @@
-#include <string.h>
-
-void
-safecpy(char *to, char *from, int tolen)
-{
-	int fromlen;
-	memset(to, 0, tolen);
-	fromlen = from ? strlen(from) : 0;
-	if (fromlen > tolen)
-		fromlen = tolen;
-	memcpy(to, from, fromlen);
-}
--- a/sys/src/cmd/unix/u9fs/strecpy.c
+++ /dev/null
@@ -1,14 +1,0 @@
-#include <plan9.h>
-
-char*
-strecpy(char *to, char *e, char *from)
-{
-	if(to >= e)
-		return to;
-	to = memccpy(to, from, '\0', e - to);
-	if(to == nil){
-		to = e - 1;
-		*to = '\0';
-	}
-	return to;
-}
--- a/sys/src/cmd/unix/u9fs/sun-inttypes.h
+++ /dev/null
@@ -1,16 +1,0 @@
-/* inttypes.h for SunOS cuff.link.cs.cmu.edu 5.5.1 Generic_103640-29 sun4u sparc SUNW,Ultra-Enterprise */
-#ifndef INTTYPES_H
-#define INTTYPES_H
-
-typedef char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef long long int64_t;
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-typedef long int intptr_t;
-typedef unsigned long int uintptr_t;
-
-#endif
--- a/sys/src/cmd/unix/u9fs/tokenize.c
+++ /dev/null
@@ -1,42 +1,0 @@
-#include <plan9.h>
-
-int
-getfields(char *str, char **args, int max, int mflag, char *set)
-{
-	Rune r;
-	int nr, intok, narg;
-
-	if(max <= 0)
-		return 0;
-
-	narg = 0;
-	args[narg] = str;
-	if(!mflag)
-		narg++;
-	intok = 0;
-	for(;; str += nr) {
-		nr = chartorune(&r, str);
-		if(r == 0)
-			break;
-		if(utfrune(set, r)) {
-			if(narg >= max)
-				break;
-			*str = 0;
-			intok = 0;
-			args[narg] = str + nr;
-			if(!mflag)
-				narg++;
-		} else {
-			if(!intok && mflag)
-				narg++;
-			intok = 1;
-		}
-	}
-	return narg;
-}
-
-int
-tokenize(char *str, char **args, int max)
-{
-	return getfields(str, args, max, 1, " \t\n\r");
-}
--- a/sys/src/cmd/unix/u9fs/u9fs.c
+++ /dev/null
@@ -1,1769 +1,0 @@
-/* already in plan9.h #include <sys/types.h> *//* for struct passwd, struct group, struct stat ... */
-/* plan9.h is first to get the large file support definitions as early as possible */
-#include <plan9.h>
-#include <sys/stat.h>	/* for stat, umask */
-#include <stdlib.h>	/* for malloc */
-#include <string.h>	/* for strcpy, memmove */
-#include <pwd.h>	/* for getpwnam, getpwuid */
-#include <grp.h>	/* for getgrnam, getgrgid */
-#include <unistd.h>	/* for gethostname, pread, pwrite, read, write */
-#include <utime.h>	/* for utime */
-#include <dirent.h>	/* for readdir */
-#include <errno.h>	/* for errno */
-#include <stdio.h>	/* for remove [sic] */
-#include <fcntl.h>	/* for O_RDONLY, etc. */
-
-#include <sys/socket.h>	/* various networking crud */
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <fcall.h>
-#include <oldfcall.h>
-#include <u9fs.h>
-
-/* #ifndef because can be given in makefile */
-#ifndef DEFAULTLOG
-#define DEFAULTLOG "/tmp/u9fs.log"
-#endif
-
-char *logfile = DEFAULTLOG;
-
-#define S_ISSPECIAL(m) (S_ISCHR(m) || S_ISBLK(m) || S_ISFIFO(m))
-
-enum {
-	Tdot = 1,
-	Tdotdot
-};
-
-enum {
-	P9P1,
-	P9P2000
-};
-
-typedef struct User User;
-struct User {
-	int id;
-	gid_t defaultgid;
-	char *name;
-	char **mem;	/* group members */
-	int nmem;
-	User *next;
-};
-
-struct Fid {
-	int fid;
-	char *path;
-	struct stat st;
-	User *u;
-	int omode;
-	DIR *dir;
-	int diroffset;
-	int fd;
-	struct dirent *dirent;
-	int direof;
-	Fid *next;
-	Fid *prev;
-	int auth;
-	void *authmagic;
-};
-
-void*	emalloc(size_t);
-void*	erealloc(void*, size_t);
-char*	estrdup(char*);
-char*	estrpath(char*, char*, int);
-void	sysfatal(char*, ...);
-int	okuser(char*);
-
-void	rversion(Fcall*, Fcall*);
-void	rauth(Fcall*, Fcall*);
-void	rattach(Fcall*, Fcall*);
-void	rflush(Fcall*, Fcall*);
-void	rclone(Fcall*, Fcall*);
-void	rwalk(Fcall*, Fcall*);
-void	ropen(Fcall*, Fcall*);
-void	rcreate(Fcall*, Fcall*);
-void	rread(Fcall*, Fcall*);
-void	rwrite(Fcall*, Fcall*);
-void	rclunk(Fcall*, Fcall*);
-void	rstat(Fcall*, Fcall*);
-void	rwstat(Fcall*, Fcall*);
-void	rclwalk(Fcall*, Fcall*);
-void	rremove(Fcall*, Fcall*);
-
-User*	uname2user(char*);
-User*	gname2user(char*);
-User*	uid2user(int);
-User*	gid2user(int);
-
-Fid*	newfid(int, char**);
-Fid*	oldfidex(int, int, char**);
-Fid*	oldfid(int, char**);
-int	fidstat(Fid*, char**);
-void	freefid(Fid*);
-
-int	userchange(User*, char**);
-int	userwalk(User*, char**, char*, Qid*, char**);
-int	useropen(Fid*, int, char**);
-int	usercreate(Fid*, char*, int, long, char**);
-int	userremove(Fid*, char**);
-int	userperm(User*, char*, int, int);
-int	useringroup(User*, User*);
-
-Qid	stat2qid(struct stat*);
-
-void	getfcallold(int, Fcall*, int);
-void	putfcallold(int, Fcall*);
-
-char	Eauth[] =	"authentication failed";
-char	Ebadfid[] =	"fid unknown or out of range";
-char	Ebadoffset[] =	"bad offset in directory read";
-char	Ebadusefid[] =	"bad use of fid";
-char	Edirchange[] =	"wstat can't convert between files and directories";
-char	Eexist[] =	"file or directory already exists";
-char	Efidactive[] =	"fid already in use";
-char	Enotdir[] =	"not a directory";
-char	Enotingroup[] =	"not a member of proposed group";
-char	Enotowner[] = 	"only owner can change group in wstat";
-char	Eperm[] =	"permission denied";
-char	Especial0[] =	"already attached without access to special files";
-char	Especial1[] =	"already attached with access to special files";
-char	Especial[] =	"no access to special file";
-char	Etoolarge[] =	"i/o count too large";
-char	Eunknowngroup[] = "unknown group";
-char	Eunknownuser[] = "unknown user";
-char	Ewstatbuffer[] = "bogus wstat buffer";
-
-ulong	msize = IOHDRSZ+8192;
-uchar*	rxbuf;
-uchar*	txbuf;
-void*	databuf;
-int	connected;
-int	devallowed;
-char*	autharg;
-char*	defaultuser;
-char	hostname[256];
-char	remotehostname[256];
-int	chatty9p = 0;
-int	network = 1;
-int	old9p = -1;
-int	authed;
-User*	none;
-
-Auth *authmethods[] = {	/* first is default */
-	&authrhosts,
-	&authp9any,
-	&authnone,
-};
-
-Auth *auth;
-
-/*
- * frogs: characters not valid in plan9
- * filenames, keep this list in sync with
- * /sys/src/9/port/chan.c:1656
- */
-char isfrog[256]={
-	/*NUL*/	1, 1, 1, 1, 1, 1, 1, 1,
-	/*BKS*/	1, 1, 1, 1, 1, 1, 1, 1,
-	/*DLE*/	1, 1, 1, 1, 1, 1, 1, 1,
-	/*CAN*/	1, 1, 1, 1, 1, 1, 1, 1,
-	['/']	1,
-	[0x7f]	1,
-};
-
-void
-getfcallnew(int fd, Fcall *fc, int have)
-{
-	int len;
-
-	if(have > BIT32SZ)
-		sysfatal("cannot happen");
-
-	if(have < BIT32SZ && readn(fd, rxbuf+have, BIT32SZ-have) != BIT32SZ-have)
-		sysfatal("couldn't read message");
-
-	len = GBIT32(rxbuf);
-	if(len <= BIT32SZ)
-		sysfatal("bogus message");
-
-	len -= BIT32SZ;
-	if(readn(fd, rxbuf+BIT32SZ, len) != len)
-		sysfatal("short message");
-
-	if(convM2S(rxbuf, len+BIT32SZ, fc) != len+BIT32SZ)
-		sysfatal("badly sized message type %d", rxbuf[0]);
-}
-
-void
-getfcallold(int fd, Fcall *fc, int have)
-{
-	int len, n;
-
-	if(have > 3)
-		sysfatal("cannot happen");
-
-	if(have < 3 && readn(fd, rxbuf, 3-have) != 3-have)
-		sysfatal("couldn't read message");
-
-	len = oldhdrsize(rxbuf[0]);
-	if(len < 3)
-		sysfatal("bad message %d", rxbuf[0]);
-	if(len > 3 && readn(fd, rxbuf+3, len-3) != len-3)
-		sysfatal("couldn't read message");
-
-	n = iosize(rxbuf);
-	if(readn(fd, rxbuf+len, n) != n)
-		sysfatal("couldn't read message");
-	len += n;
-
-	if(convM2Sold(rxbuf, len, fc) != len)
-		sysfatal("badly sized message type %d", rxbuf[0]);
-}
-
-void
-putfcallnew(int wfd, Fcall *tx)
-{
-	uint n;
-
-	if((n = convS2M(tx, txbuf, msize)) == 0)
-		sysfatal("couldn't format message type %d", tx->type);
-	if(write(wfd, txbuf, n) != n)
-		sysfatal("couldn't send message");
-}
-
-void
-putfcallold(int wfd, Fcall *tx)
-{
-	uint n;
-
-	if((n = convS2Mold(tx, txbuf, msize)) == 0)
-		sysfatal("couldn't format message type %d", tx->type);
-	if(write(wfd, txbuf, n) != n)
-		sysfatal("couldn't send message");
-}
-
-void
-getfcall(int fd, Fcall *fc)
-{
-	if(old9p == 1){
-		getfcallold(fd, fc, 0);
-		return;
-	}
-	if(old9p == 0){
-		getfcallnew(fd, fc, 0);
-		return;
-	}
-
-	/* auto-detect */
-	if(readn(fd, rxbuf, 3) != 3)
-		sysfatal("couldn't read message");
-
-	/* is it an old (9P1) message? */
-	if(50 <= rxbuf[0] && rxbuf[0] <= 87 && (rxbuf[0]&1)==0 && GBIT16(rxbuf+1) == 0xFFFF){
-		old9p = 1;
-		getfcallold(fd, fc, 3);
-		return;
-	}
-
-	getfcallnew(fd, fc, 3);
-	old9p = 0;
-}
-
-void
-seterror(Fcall *f, char *error)
-{
-	f->type = Rerror;
-	f->ename = error ? error : "programmer error";
-}
-
-int
-isowner(User *u, Fid *f)
-{
-	return u->id == f->st.st_uid;
-}
-
-
-
-void
-serve(int rfd, int wfd)
-{
-	Fcall rx, tx;
-
-	for(;;){
-		getfcall(rfd, &rx);
-
-		if(chatty9p)
-			fprint(2, "<- %F\n", &rx);
-
-		memset(&tx, 0, sizeof tx);
-		tx.type = rx.type+1;
-		tx.tag = rx.tag;
-		switch(rx.type){
-		case Tflush:
-			break;
-		case Tversion:
-			rversion(&rx, &tx);
-			break;
-		case Tauth:
-			rauth(&rx, &tx);
-			break;
-		case Tattach:
-			rattach(&rx, &tx);
-			break;
-		case Twalk:
-			rwalk(&rx, &tx);
-			break;
-		case Tstat:
-			tx.stat = databuf;
-			rstat(&rx, &tx);
-			break;
-		case Twstat:
-			rwstat(&rx, &tx);
-			break;
-		case Topen:
-			ropen(&rx, &tx);
-			break;
-		case Tcreate:
-			rcreate(&rx, &tx);
-			break;
-		case Tread:
-			tx.data = databuf;
-			rread(&rx, &tx);
-			break;
-		case Twrite:
-			rwrite(&rx, &tx);
-			break;
-		case Tclunk:
-			rclunk(&rx, &tx);
-			break;
-		case Tremove:
-			rremove(&rx, &tx);
-			break;
-		default:
-			fprint(2, "unknown message %F\n", &rx);
-			seterror(&tx, "bad message");
-			break;
-		}
-
-		if(chatty9p)
-			fprint(2, "-> %F\n", &tx);
-
-		(old9p ? putfcallold : putfcallnew)(wfd, &tx);
-	}
-}
-
-void
-rversion(Fcall *rx, Fcall *tx)
-{
-	if(rx->msize < 256){
-		seterror(tx, "version: message size too small");
-		return;
-	}
-	if(msize > rx->msize)
-		msize = rx->msize;
-	tx->msize = msize;
-	if(strncmp(rx->version, "9P", 2) != 0)
-		tx->version = "unknown";
-	else
-		tx->version = "9P2000";
-}
-
-void
-rauth(Fcall *rx, Fcall *tx)
-{
-	char *e;
-
-	if((e = auth->auth(rx, tx)) != nil)
-		seterror(tx, e);
-}
-
-void
-rattach(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-	User *u;
-
-	if(rx->aname == nil)
-		rx->aname = "";
-
-	if(strcmp(rx->aname, "device") == 0){
-		if(connected && !devallowed){
-			seterror(tx, Especial0);
-			return;
-		}
-		devallowed = 1;
-	}else{
-		if(connected && devallowed){
-			seterror(tx, Especial1);
-			return;
-		}
-	}
-
-	if(strcmp(rx->uname, "none") == 0){
-		if(authed == 0){
-			seterror(tx, Eauth);
-			return;
-		}
-	} else {
-		if((e = auth->attach(rx, tx)) != nil){
-			seterror(tx, e);
-			return;
-		}
-		authed++;
-	}
-
-	if((fid = newfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-	fid->path = estrdup("/");
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		freefid(fid);
-		return;
-	}
-
-	if(defaultuser)
-		rx->uname = defaultuser;
-
-	if((u = uname2user(rx->uname)) == nil
-	|| (!defaultuser && u->id == 0)){
-		/* we don't know anyone named root... */
-		seterror(tx, Eunknownuser);
-		freefid(fid);
-		return;
-	}
-
-	fid->u = u;
-	tx->qid = stat2qid(&fid->st);
-	return;
-}
-
-void
-rwalk(Fcall *rx, Fcall *tx)
-{
-	int i;
-	char *path, *e;
-	Fid *fid, *nfid;
-
-	e = nil;
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if(fid->omode != -1){
-		seterror(tx, Ebadusefid);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	if(!S_ISDIR(fid->st.st_mode) && rx->nwname){
-		seterror(tx, Enotdir);
-		return;
-	}
-
-	nfid = nil;
-	if(rx->newfid != rx->fid && (nfid = newfid(rx->newfid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	path = estrdup(fid->path);
-	e = nil;
-	for(i=0; i<rx->nwname; i++)
-		if(userwalk(fid->u, &path, rx->wname[i], &tx->wqid[i], &e) < 0)
-			break;
-
-	if(i == rx->nwname){		/* successful clone or walk */
-		tx->nwqid = i;
-		if(nfid){
-			nfid->path = path;
-			nfid->u = fid->u;
-		}else{
-			free(fid->path);
-			fid->path = path;
-		}
-	}else{
-		if(i > 0)		/* partial walk? */
-			tx->nwqid = i;
-		else
-			seterror(tx, e);
-
-		if(nfid)		/* clone implicit new fid */
-			freefid(nfid);
-		free(path);
-	}
-	return;
-}
-
-void
-ropen(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if(fid->omode != -1){
-		seterror(tx, Ebadusefid);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	if(!devallowed && S_ISSPECIAL(fid->st.st_mode)){
-		seterror(tx, Especial);
-		return;
-	}
-
-	if(useropen(fid, rx->mode, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	tx->iounit = 0;
-	tx->qid = stat2qid(&fid->st);
-}
-
-void
-rcreate(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if(fid->omode != -1){
-		seterror(tx, Ebadusefid);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	if(!S_ISDIR(fid->st.st_mode)){
-		seterror(tx, Enotdir);
-		return;
-	}
-
-	if(usercreate(fid, rx->name, rx->mode, rx->perm, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	tx->iounit = 0;
-	tx->qid = stat2qid(&fid->st);
-}
-
-uchar
-modebyte(struct stat *st)
-{
-	uchar b;
-
-	b = 0;
-
-	if(S_ISDIR(st->st_mode))
-		b |= QTDIR;
-
-	/* no way to test append-only */
-	/* no real way to test exclusive use, but mark devices as such */
-	if(S_ISSPECIAL(st->st_mode))
-		b |= QTEXCL;
-
-	return b;
-}
-
-ulong
-plan9mode(struct stat *st)
-{
-	return ((ulong)modebyte(st)<<24) | (st->st_mode & 0777);
-}
-
-/* 
- * this is for chmod, so don't worry about S_IFDIR
- */
-mode_t
-unixmode(Dir *d)
-{
-	return (mode_t)(d->mode&0777);
-}
-
-Qid
-stat2qid(struct stat *st)
-{
-	uchar *p, *ep, *q;
-	Qid qid;
-
-	/*
-	 * For now, ignore the device number.
-	 */
-	qid.path = 0;
-	p = (uchar*)&qid.path;
-	ep = p+sizeof(qid.path);
-	q = p+sizeof(ino_t);
-	if(q > ep){
-		fprint(2, "warning: inode number too big\n");
-		q = ep;
-	}
-	memmove(p, &st->st_ino, q-p);
-	q = q+sizeof(dev_t);
-	if(q > ep){
-/*
- *		fprint(2, "warning: inode number + device number too big %d+%d\n",
- *			sizeof(ino_t), sizeof(dev_t));
- */
-		q = ep - sizeof(dev_t);
-		if(q < p)
-			fprint(2, "warning: device number too big by itself\n");
-		else
-			*(dev_t*)q ^= st->st_dev;
-	}
-
-	qid.vers = st->st_mtime ^ (st->st_size << 8);
-	qid.type = modebyte(st);
-	return qid;
-}
-
-char *
-enfrog(char *src)
-{
-	char *d, *dst;
-	uchar *s;
-
-	d = dst = emalloc(strlen(src)*3 + 1);
-	for (s = (uchar *)src; *s; s++)
-		if(isfrog[*s] || *s == '\\')
-			d += sprintf(d, "\\%02x", *s);
-		else
-			*d++ = *s;
-	*d = 0;
-	return dst;
-}
-
-char *
-defrog(char *s)
-{
-	char *d, *dst, buf[3];
-
-	d = dst = emalloc(strlen(s) + 1);
-	for(; *s; s++)
-		if(*s == '\\' && strlen(s) >= 3){
-			buf[0] = *++s;			/* skip \ */
-			buf[1] = *++s;
-			buf[2] = 0;
-			*d++ = strtoul(buf, NULL, 16);
-		} else
-			*d++ = *s;
-	*d = 0;
-	return dst;
-}
-
-void
-stat2dir(char *path, struct stat *st, Dir *d)
-{
-	User *u;
-	char *q, *p, *npath;
-
-	memset(d, 0, sizeof(*d));
-	d->qid = stat2qid(st);
-	d->mode = plan9mode(st);
-	d->atime = st->st_atime;
-	d->mtime = st->st_mtime;
-	d->length = st->st_size;
-
-	d->uid = (u = uid2user(st->st_uid)) ? u->name : "???";
-	d->gid = (u = gid2user(st->st_gid)) ? u->name : "???";
-	d->muid = "";
-
-	if((q = strrchr(path, '/')) != nil)
-		d->name = enfrog(q+1);
-	else
-		d->name = enfrog(path);
-}
-
-void
-rread(Fcall *rx, Fcall *tx)
-{
-	char *e, *path;
-	uchar *p, *ep;
-	int n;
-	Fid *fid;
-	Dir d;
-	struct stat st;
-
-	if(rx->count > msize-IOHDRSZ){
-		seterror(tx, Etoolarge);
-		return;
-	}
-
-	if((fid = oldfidex(rx->fid, -1, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if (fid->auth) {
-		char *e;
-		e = auth->read(rx, tx);
-		if (e)
-			seterror(tx, e);
-		return;
-	}
-
-	if(fid->omode == -1 || (fid->omode&3) == OWRITE){
-		seterror(tx, Ebadusefid);
-		return;
-	}
-
-	if(fid->dir){
-		if(rx->offset != fid->diroffset){
-			if(rx->offset != 0){
-				seterror(tx, Ebadoffset);
-				return;
-			}
-			rewinddir(fid->dir);
-			fid->diroffset = 0;
-			fid->direof = 0;
-		}
-		if(fid->direof){
-			tx->count = 0;
-			return;
-		}
-
-		p = (uchar*)tx->data;
-		ep = (uchar*)tx->data+rx->count;
-		for(;;){
-			if(p+BIT16SZ >= ep)
-				break;
-			if(fid->dirent == nil)	/* one entry cache for when convD2M fails */
-				if((fid->dirent = readdir(fid->dir)) == nil){
-					fid->direof = 1;
-					break;
-				}
-			if(strcmp(fid->dirent->d_name, ".") == 0
-			|| strcmp(fid->dirent->d_name, "..") == 0){
-				fid->dirent = nil;
-				continue;
-			}
-			path = estrpath(fid->path, fid->dirent->d_name, 0);
-			memset(&st, 0, sizeof st);
-			if(stat(path, &st) < 0){
-				fprint(2, "dirread: stat(%s) failed: %s\n", path, strerror(errno));
-				fid->dirent = nil;
-				free(path);
-				continue;
-			}
-			free(path);
-			stat2dir(fid->dirent->d_name, &st, &d);
-			if((n=(old9p ? convD2Mold : convD2M)(&d, p, ep-p)) <= BIT16SZ)
-				break;
-			p += n;
-			fid->dirent = nil;
-		}
-		tx->count = p - (uchar*)tx->data;
-		fid->diroffset += tx->count;
-	}else{
-		if((n = pread(fid->fd, tx->data, rx->count, rx->offset)) < 0){
-			seterror(tx, strerror(errno));
-			return;
-		}
-		tx->count = n;
-	}
-}
-
-void
-rwrite(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-	int n;
-
-	if(rx->count > msize-IOHDRSZ){
-		seterror(tx, Etoolarge);
-		return;
-	}
-
-	if((fid = oldfidex(rx->fid, -1, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if (fid->auth) {
-		char *e;
-		e = auth->write(rx, tx);
-		if (e)
-			seterror(tx, e);
-		return;
-	}
-
-	if(fid->omode == -1 || (fid->omode&3) == OREAD || (fid->omode&3) == OEXEC){
-		seterror(tx, Ebadusefid);
-		return;
-	}
-
-	if((n = pwrite(fid->fd, rx->data, rx->count, rx->offset)) < 0){
-		seterror(tx, strerror(errno));
-		return;
-	}
-	tx->count = n;
-}
-
-void
-rclunk(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-
-	if((fid = oldfidex(rx->fid, -1, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-	if (fid->auth) {
-		if (auth->clunk) {
-			e = (*auth->clunk)(rx, tx);
-			if (e) {
-				seterror(tx, e);
-				return;
-			}
-		}
-	}
-	else if(fid->omode != -1 && fid->omode&ORCLOSE)
-		remove(fid->path);
-	freefid(fid);
-}
-
-void
-rremove(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-	if(userremove(fid, &e) < 0)
-		seterror(tx, e);
-	freefid(fid);
-}
-
-void
-rstat(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	Fid *fid;
-	Dir d;
-
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	stat2dir(fid->path, &fid->st, &d);
-	if((tx->nstat=(old9p ? convD2Mold : convD2M)(&d, tx->stat, msize)) <= BIT16SZ)
-		seterror(tx, "convD2M fails");
-}
-
-void
-rwstat(Fcall *rx, Fcall *tx)
-{
-	char *e;
-	char *p, *old, *new, *dir;
-	gid_t gid;
-	Dir d;
-	Fid *fid;
-
-	if((fid = oldfid(rx->fid, &e)) == nil){
-		seterror(tx, e);
-		return;
-	}
-
-	/*
-	 * wstat is supposed to be atomic.
-	 * we check all the things we can before trying anything.
-	 * still, if we are told to truncate a file and rename it and only
-	 * one works, we're screwed.  in such cases we leave things
-	 * half broken and return an error.  it's hardly perfect.
-	 */
-	if((old9p ? convM2Dold : convM2D)(rx->stat, rx->nstat, &d, (char*)rx->stat) <= BIT16SZ){
-		seterror(tx, Ewstatbuffer);
-		return;
-	}
-
-	if(fidstat(fid, &e) < 0){
-		seterror(tx, e);
-		return;
-	}
-
-	/*
-	 * The casting is necessary because d.mode is ulong and might,
-	 * on some systems, be 64 bits.  We only want to compare the
-	 * bottom 32 bits, since that's all that gets sent in the protocol.
-	 * 
-	 * Same situation for d.mtime and d.length (although that last check
-	 * is admittedly superfluous, given the current lack of 128-bit machines).
-	 */
-	gid = (gid_t)-1;
-	if(d.gid[0] != '\0'){
-		User *g;
-
-		g = gname2user(d.gid);
-		if(g == nil){
-			seterror(tx, Eunknowngroup);
-			return;
-		}
-		gid = (gid_t)g->id;
-
-		if(groupchange(fid->u, gid2user(gid), &e) < 0){
-			seterror(tx, e);
-			return;
-		}		
-	}
-
-	if((u32int)d.mode != (u32int)~0 && (((d.mode&DMDIR)!=0) ^ (S_ISDIR(fid->st.st_mode)!=0))){
-		seterror(tx, Edirchange);
-		return;
-	}
-
-	if(strcmp(fid->path, "/") == 0){
-		seterror(tx, "no wstat of root");
-		return;
-	}
-
-	/*
-	 * try things in increasing order of harm to the file.
-	 * mtime should come after truncate so that if you
-	 * do both the mtime actually takes effect, but i'd rather
-	 * leave truncate until last.
-	 * (see above comment about atomicity).
-	 */
-	if((u32int)d.mode != (u32int)~0 && chmod(fid->path, unixmode(&d)) < 0){
-		if(chatty9p)
-			fprint(2, "chmod(%s, 0%luo) failed\n", fid->path, unixmode(&d));
-		seterror(tx, strerror(errno));
-		return;
-	}
-
-	if((u32int)d.mtime != (u32int)~0){
-		struct utimbuf t;
-
-		t.actime = 0;
-		t.modtime = d.mtime;
-		if(utime(fid->path, &t) < 0){
-			if(chatty9p)
-				fprint(2, "utime(%s) failed\n", fid->path);
-			seterror(tx, strerror(errno));
-			return;
-		}
-	}
-
-	if(gid != (gid_t)-1 && gid != fid->st.st_gid){
-		if(chown(fid->path, (uid_t)-1, gid) < 0){
-			if(chatty9p)
-				fprint(2, "chgrp(%s, %d) failed\n", fid->path, gid);
-			seterror(tx, strerror(errno));
-			return;
-		}
-	}
-
-	if(d.name[0]){
-		old = fid->path;
-		dir = estrdup(fid->path);
-		if((p = strrchr(dir, '/')) > dir)
-			*p = '\0';
-		else{
-			seterror(tx, "whoops: can't happen in u9fs");
-			return;
-		}
-		new = estrpath(dir, d.name, 1);
-		if(strcmp(old, new) != 0 && rename(old, new) < 0){
-			if(chatty9p)
-				fprint(2, "rename(%s, %s) failed\n", old, new);
-			seterror(tx, strerror(errno));
-			free(new);
-			free(dir);
-			return;
-		}
-		fid->path = new;
-		free(old);
-		free(dir);
-	}
-
-	if((u64int)d.length != (u64int)~0 && truncate(fid->path, d.length) < 0){
-		fprint(2, "truncate(%s, %lld) failed\n", fid->path, d.length);
-		seterror(tx, strerror(errno));
-		return;
-	}
-}
-
-/*
- * we keep a table by numeric id.  by name lookups happen infrequently
- * while by-number lookups happen once for every directory entry read
- * and every stat request.
- */
-User *utab[64];
-User *gtab[64];
-
-User*
-adduser(struct passwd *p)
-{
-	User *u;
-
-	u = emalloc(sizeof(*u));
-	u->id = p->pw_uid;
-	u->name = estrdup(p->pw_name);
-	u->next = utab[p->pw_uid%nelem(utab)];
-	u->defaultgid = p->pw_gid;
-	utab[p->pw_uid%nelem(utab)] = u;
-	return u;
-}
-
-int
-useringroup(User *u, User *g)
-{
-	int i;
-
-	for(i=0; i<g->nmem; i++)
-		if(strcmp(g->mem[i], u->name) == 0)
-			return 1;
-
-	/*
-	 * Hack around common Unix problem that everyone has
-	 * default group "user" but /etc/group lists no members.
-	 */
-	if(u->defaultgid == g->id)
-		return 1;
-	return 0;
-}
-
-User*
-addgroup(struct group *g)
-{
-	User *u;
-	char **p;
-	int n;
-
-	u = emalloc(sizeof(*u));
-	n = 0;
-	for(p=g->gr_mem; *p; p++)
-		n++;
-	u->mem = emalloc(sizeof(u->mem[0])*n);
-	n = 0;
-	for(p=g->gr_mem; *p; p++)
-		u->mem[n++] = estrdup(*p);
-	u->nmem = n;
-	u->id = g->gr_gid;
-	u->name = estrdup(g->gr_name);
-	u->next = gtab[g->gr_gid%nelem(gtab)];
-	gtab[g->gr_gid%nelem(gtab)] = u;
-	return u;
-}
-
-User*
-uname2user(char *name)
-{
-	int i;
-	User *u;
-	struct passwd *p;
-
-	for(i=0; i<nelem(utab); i++)
-		for(u=utab[i]; u; u=u->next)
-			if(strcmp(u->name, name) == 0)
-				return u;
-
-	if((p = getpwnam(name)) == nil)
-		return nil;
-	return adduser(p);
-}
-
-User*
-uid2user(int id)
-{
-	User *u;
-	struct passwd *p;
-
-	for(u=utab[id%nelem(utab)]; u; u=u->next)
-		if(u->id == id)
-			return u;
-
-	if((p = getpwuid(id)) == nil)
-		return nil;
-	return adduser(p);
-}
-
-User*
-gname2user(char *name)
-{
-	int i;
-	User *u;
-	struct group *g;
-
-	for(i=0; i<nelem(gtab); i++)
-		for(u=gtab[i]; u; u=u->next)
-			if(strcmp(u->name, name) == 0)
-				return u;
-
-	if((g = getgrnam(name)) == nil)
-		return nil;
-	return addgroup(g);
-}
-
-User*
-gid2user(int id)
-{
-	User *u;
-	struct group *g;
-
-	for(u=gtab[id%nelem(gtab)]; u; u=u->next)
-		if(u->id == id)
-			return u;
-
-	if((g = getgrgid(id)) == nil)
-		return nil;
-	return addgroup(g);
-}
-
-void
-sysfatal(char *fmt, ...)
-{
-	char buf[1024];
-	va_list va, temp;
-
-	va_start(va, fmt);
-	va_copy(temp, va);
-	doprint(buf, buf+sizeof buf, fmt, &temp);
-	va_end(temp);
-	va_end(va);
-	fprint(2, "u9fs: %s\n", buf);
-	fprint(2, "last unix error: %s\n", strerror(errno));
-	exit(1);
-}
-
-void*
-emalloc(size_t n)
-{
-	void *p;
-
-	if(n == 0)
-		n = 1;
-	p = malloc(n);
-	if(p == 0)
-		sysfatal("malloc(%ld) fails", (long)n);
-	memset(p, 0, n);
-	return p;
-}
-
-void*
-erealloc(void *p, size_t n)
-{
-	if(p == 0)
-		p = malloc(n);
-	else
-		p = realloc(p, n);
-	if(p == 0)
-		sysfatal("realloc(..., %ld) fails", (long)n);
-	return p;
-}
-
-char*
-estrdup(char *p)
-{
-	p = strdup(p);
-	if(p == 0)
-		sysfatal("strdup(%.20s) fails", p);
-	return p;
-}
-
-char*
-estrpath(char *p, char *q, int frog)
-{
-	char *r, *s;
-
-	if(strcmp(q, "..") == 0){
-		r = estrdup(p);
-		if((s = strrchr(r, '/')) && s > r)
-			*s = '\0';
-		else if(s == r)
-			s[1] = '\0';
-		return r;
-	}
-
-	if(frog)
-		q = defrog(q);
-	else
-		q = strdup(q);
-	r = emalloc(strlen(p)+1+strlen(q)+1);
-	strcpy(r, p);
-	if(r[0]=='\0' || r[strlen(r)-1] != '/')
-		strcat(r, "/");
-	strcat(r, q);
-	free(q);
-	return r;
-}
-
-Fid *fidtab[1];
-
-Fid*
-lookupfid(int fid)
-{
-	Fid *f;
-
-	for(f=fidtab[fid%nelem(fidtab)]; f; f=f->next)
-		if(f->fid == fid)
-			return f;
-	return nil;
-}
-
-Fid*
-newfid(int fid, char **ep)
-{
-	Fid *f;
-
-	if(lookupfid(fid) != nil){
-		*ep = Efidactive;
-		return nil;
-	}
-
-	f = emalloc(sizeof(*f));
-	f->next = fidtab[fid%nelem(fidtab)];
-	if(f->next)
-		f->next->prev = f;
-	fidtab[fid%nelem(fidtab)] = f;
-	f->fid = fid;
-	f->fd = -1;
-	f->omode = -1;
-	return f;
-}
-
-Fid*
-newauthfid(int fid, void *magic, char **ep)
-{
-	Fid *af;
-	af = newfid(fid, ep);
-	if (af == nil)
-		return nil;
-	af->auth = 1;
-	af->authmagic = magic;
-	return af;
-}
-
-Fid*
-oldfidex(int fid, int auth, char **ep)
-{
-	Fid *f;
-
-	if((f = lookupfid(fid)) == nil){
-		*ep = Ebadfid;
-		return nil;
-	}
-
-	if (auth != -1 && f->auth != auth) {
-		*ep = Ebadfid;
-		return nil;
-	}
-
-	if (!f->auth) {
-		if(userchange(f->u, ep) < 0)
-			return nil;
-	}
-
-	return f;
-}
-
-Fid*
-oldfid(int fid, char **ep)
-{
-	return oldfidex(fid, 0, ep);
-}
-
-Fid*
-oldauthfid(int fid, void **magic, char **ep)
-{
-	Fid *af;
-	af = oldfidex(fid, 1, ep);
-	if (af == nil)
-		return nil;
-	*magic = af->authmagic;
-	return af;
-}
-
-void
-freefid(Fid *f)
-{
-	if(f->prev)
-		f->prev->next = f->next;
-	else
-		fidtab[f->fid%nelem(fidtab)] = f->next;
-	if(f->next)
-		f->next->prev = f->prev;
-	if(f->dir)
-		closedir(f->dir);
-	if(f->fd)
-		close(f->fd);
-	free(f->path);
-	free(f);
-}
-
-int
-fidstat(Fid *fid, char **ep)
-{
-	if(stat(fid->path, &fid->st) < 0){
-		fprint(2, "fidstat(%s) failed\n", fid->path);
-		if(ep)
-			*ep = strerror(errno);
-		return -1;
-	}
-	if(S_ISDIR(fid->st.st_mode))
-		fid->st.st_size = 0;
-	return 0;
-}
-
-int
-userchange(User *u, char **ep)
-{
-	if(defaultuser)
-		return 0;
-
-	if(setreuid(0, 0) < 0){
-		fprint(2, "setreuid(0, 0) failed\n");
-		*ep = "cannot setuid back to root";
-		return -1;
-	}
-
-	/*
-	 * Initgroups does not appear to be SUSV standard.
-	 * But it exists on SGI and on Linux, which makes me
-	 * think it's standard enough.  We have to do something
-	 * like this, and the closest other function I can find is
-	 * setgroups (which initgroups eventually calls).
-	 * Setgroups is the same as far as standardization though,
-	 * so we're stuck using a non-SUSV call.  Sigh.
-	 */
-	if(initgroups(u->name, u->defaultgid) < 0)
-		fprint(2, "initgroups(%s) failed: %s\n", u->name, strerror(errno));
-
-	if(setreuid(-1, u->id) < 0){
-		fprint(2, "setreuid(-1, %s) failed\n", u->name);
-		*ep = strerror(errno);
-		return -1;
-	}
-
-	return 0;
-}
-
-/*
- * We do our own checking here, then switch to root temporarily
- * to set our gid.  In a perfect world, you'd be allowed to set your
- * egid to any of the supplemental groups of your euid, but this
- * is not the case on Linux 2.2.14 (and perhaps others).
- *
- * This is a race, of course, but it's a race against processes
- * that can edit the group lists.  If you can do that, you can
- * change your own group without our help.
- */
-int
-groupchange(User *u, User *g, char **ep)
-{
-	if(g == nil)
-		return -1;
-	if(!useringroup(u, g)){
-		if(chatty9p)
-			fprint(2, "%s not in group %s\n", u->name, g->name);
-		*ep = Enotingroup;
-		return -1;
-	}
-
-	setreuid(0,0);
-	if(setregid(-1, g->id) < 0){
-		fprint(2, "setegid(%s/%d) failed in groupchange\n", g->name, g->id);
-		*ep = strerror(errno);
-		return -1;
-	}
-	if(userchange(u, ep) < 0)
-		return -1;
-
-	return 0;
-}
-
-
-/*
- * An attempt to enforce permissions by looking at the 
- * file system.  Separation of checking permission and
- * actually performing the action is a terrible idea, of 
- * course, so we use setreuid for most of the permission
- * enforcement.  This is here only so we can give errors
- * on open(ORCLOSE) in some cases.
- */
-int
-userperm(User *u, char *path, int type, int need)
-{
-	char *p, *q;
-	int i, have;
-	struct stat st;
-	User *g;
-
-	switch(type){
-	default:
-		fprint(2, "bad type %d in userperm\n", type);
-		return -1;
-	case Tdot:
-		if(stat(path, &st) < 0){
-			fprint(2, "userperm: stat(%s) failed\n", path);
-			return -1;
-		}
-		break;
-	case Tdotdot:
-		p = estrdup(path);
-		if((q = strrchr(p, '/'))==nil){
-			fprint(2, "userperm(%s, ..): bad path\n", p);
-			free(p);
-			return -1;
-		}
-		if(q > p)
-			*q = '\0';
-		else
-			*(q+1) = '\0';
-		if(stat(p, &st) < 0){
-			fprint(2, "userperm: stat(%s) (dotdot of %s) failed\n",
-				p, path);
-			free(p);
-			return -1;
-		}
-		free(p);
-		break;
-	}
-
-	if(u == none){
-		fprint(2, "userperm: none wants %d in 0%luo\n", need, st.st_mode);
-		have = st.st_mode&7;
-		if((have&need)==need)
-			return 0;
-		return -1;
-	}
-	have = st.st_mode&7;
-	if((uid_t)u->id == st.st_uid)
-		have |= (st.st_mode>>6)&7;
-	if((have&need)==need)
-		return 0;
-	if(((have|((st.st_mode>>3)&7))&need) != need)	/* group won't help */
-		return -1;
-	g = gid2user(st.st_gid);
-	for(i=0; i<g->nmem; i++){
-		if(strcmp(g->mem[i], u->name) == 0){
-			have |= (st.st_mode>>3)&7;
-			break;
-		}
-	}
-	if((have&need)==need)
-		return 0;
-	return -1;
-}
-
-int
-userwalk(User *u, char **path, char *elem, Qid *qid, char **ep)
-{
-	char *npath;
-	struct stat st;
-
-	npath = estrpath(*path, elem, 1);
-	if(stat(npath, &st) < 0){
-		free(npath);
-		*ep = strerror(errno);
-		return -1;
-	}
-	*qid = stat2qid(&st);
-	free(*path);
-	*path = npath;
-	return 0;
-}
-
-int
-useropen(Fid *fid, int omode, char **ep)
-{
-	int a, o;
-
-	/*
-	 * Check this anyway, to try to head off problems later.
-	 */
-	if((omode&ORCLOSE) && userperm(fid->u, fid->path, Tdotdot, W_OK) < 0){
-		*ep = Eperm;
-		return -1;
-	}
-
-	switch(omode&3){
-	default:
-		*ep = "programmer error";
-		return -1;
-	case OREAD:
-		a = R_OK;
-		o = O_RDONLY;
-		break;
-	case ORDWR:
-		a = R_OK|W_OK;
-		o = O_RDWR;
-		break;
-	case OWRITE:
-		a = W_OK;
-		o = O_WRONLY;
-		break;
-	case OEXEC:
-		a = X_OK;
-		o = O_RDONLY;
-		break;
-	}
-	if(omode & OTRUNC){
-		a |= W_OK;
-		o |= O_TRUNC;
-	}
-
-	if(S_ISDIR(fid->st.st_mode)){
-		if(a != R_OK){
-			fprint(2, "attempt by %s to open dir %d\n", fid->u->name, omode);
-			*ep = Eperm;
-			return -1;
-		}
-		if((fid->dir = opendir(fid->path)) == nil){
-			*ep = strerror(errno);
-			return -1;
-		}
-	}else{
-		/*
-		 * This is wrong because access used the real uid
-		 * and not the effective uid.  Let the open sort it out.
-		 *
-		if(access(fid->path, a) < 0){
-			*ep = strerror(errno);
-			return -1;
-		}
-		 *
-		 */
-		if((fid->fd = open(fid->path, o)) < 0){
-			*ep = strerror(errno);
-			return -1;
-		}
-	}
-	fid->omode = omode;
-	return 0;
-}
-
-int
-usercreate(Fid *fid, char *elem, int omode, long perm, char **ep)
-{
-	int o, m;
-	char *opath, *npath;
-	struct stat st, parent;
-
-	if(stat(fid->path, &parent) < 0){
-		*ep = strerror(errno);
-		return -1;
-	}
-
-	/*
-	 * Change group so that created file has expected group
-	 * by Plan 9 semantics.  If that fails, might as well go
-	 * with the user's default group.
-	 */
-	if(groupchange(fid->u, gid2user(parent.st_gid), ep) < 0
-	&& groupchange(fid->u, gid2user(fid->u->defaultgid), ep) < 0)
-		return -1;
-
-	m = (perm & DMDIR) ? 0777 : 0666;
-	perm = perm & (~m | (fid->st.st_mode & m));
-
-	npath = estrpath(fid->path, elem, 1);
-	if(perm & DMDIR){
-		if((omode&~ORCLOSE) != OREAD){
-			*ep = Eperm;
-			free(npath);
-			return -1;
-		}
-		if(stat(npath, &st) >= 0 || errno != ENOENT){
-			*ep = Eexist;
-			free(npath);
-			return -1;
-		}
-		/* race */
-		if(mkdir(npath, perm&0777) < 0){
-			*ep = strerror(errno);
-			free(npath);
-			return -1;
-		}
-		if((fid->dir = opendir(npath)) == nil){
-			*ep = strerror(errno);
-			remove(npath);		/* race */
-			free(npath);
-			return -1;
-		}
-	}else{
-		o = O_CREAT|O_EXCL;
-		switch(omode&3){
-		default:
-			*ep = "programmer error";
-			return -1;
-		case OREAD:
-		case OEXEC:
-			o |= O_RDONLY;
-			break;
-		case ORDWR:
-			o |= O_RDWR;
-			break;
-		case OWRITE:
-			o |= O_WRONLY;
-			break;
-		}
-		if(omode & OTRUNC)
-			o |= O_TRUNC;
-		if((fid->fd = open(npath, o, perm&0777)) < 0){
-			if(chatty9p)
-				fprint(2, "create(%s, 0x%x, 0%o) failed\n", npath, o, perm&0777);
-			*ep = strerror(errno);
-			free(npath);
-			return -1;
-		}
-	}
-
-	opath = fid->path;
-	fid->path = npath;
-	if(fidstat(fid, ep) < 0){
-		fprint(2, "stat after create on %s failed\n", npath);
-		remove(npath);	/* race */
-		free(npath);
-		fid->path = opath;
-		if(fid->fd >= 0){
-			close(fid->fd);
-			fid->fd = -1;
-		}else{
-			closedir(fid->dir);
-			fid->dir = nil;
-		}
-		return -1;
-	}
-	fid->omode = omode;
-	free(opath);
-	return 0;
-}
-
-int
-userremove(Fid *fid, char **ep)
-{
-	if(remove(fid->path) < 0){
-		*ep = strerror(errno);
-		return -1;
-	}
-	return 0;
-}
-
-void
-usage(void)
-{
-	fprint(2, "usage: u9fs [-Dnz] [-a authmethod] [-m msize] [-u user] [root]\n");
-	exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
-	char *authtype;
-	int i;
-	int fd;
-	int logflag;
-
-	auth = authmethods[0];
-	logflag = O_WRONLY|O_APPEND|O_CREAT;
-	ARGBEGIN{
-	case 'D':
-		chatty9p = 1;
-		break;
-	case 'a':
-		authtype = EARGF(usage());
-		auth = nil;
-		for(i=0; i<nelem(authmethods); i++)
-			if(strcmp(authmethods[i]->name, authtype)==0)
-				auth = authmethods[i];
-		if(auth == nil)
-			sysfatal("unknown auth type '%s'", authtype);
-		break;
-	case 'A':
-		autharg = EARGF(usage());
-		break;
-	case 'l':
-		logfile = EARGF(usage());
-		break;
-	case 'm':
-		msize = strtol(EARGF(usage()), 0, 0);
-		break;
-	case 'n':
-		network = 0;
-		break;
-	case 'u':
-		defaultuser = EARGF(usage());
-		break;
-	case 'z':
-		logflag |= O_TRUNC;
-	}ARGEND
-
-	if(argc > 1)
-		usage();
-
-	fd = open(logfile, logflag, 0666);
-	if(fd < 0)
-		sysfatal("cannot open log '%s'", logfile);
-
-	if(dup2(fd, 2) < 0)
-		sysfatal("cannot dup fd onto stderr");
-	fprint(2, "u9fs\nkill %d\n", (int)getpid());
-
-	fmtinstall('F', fcallconv);
-	fmtinstall('D', dirconv);
-	fmtinstall('M', dirmodeconv);
-
-	rxbuf = emalloc(msize);
-	txbuf = emalloc(msize);
-	databuf = emalloc(msize);
-
-	if(auth->init)
-		auth->init();
-
-	if(network)
-		getremotehostname(remotehostname, sizeof remotehostname);
-
-	if(gethostname(hostname, sizeof hostname) < 0)
-		strcpy(hostname, "gnot");
-
-	umask(0);
-
-	if(argc == 1)
-		if(chroot(argv[0]) < 0)
-			sysfatal("chroot '%s' failed", argv[0]);
-
-	none = uname2user("none");
-
-	serve(0, 1);
-	return 0;
-}
--- a/sys/src/cmd/unix/u9fs/u9fs.h
+++ /dev/null
@@ -1,30 +1,0 @@
-typedef struct Auth Auth;
-struct Auth {
-	char *name;
-
-	char* (*auth)(Fcall*, Fcall*);
-	char* (*attach)(Fcall*, Fcall*);
-	void (*init)(void);
-	char* (*read)(Fcall*, Fcall*);
-	char* (*write)(Fcall*, Fcall*);
-	char* (*clunk)(Fcall*, Fcall*);
-};
-
-extern char remotehostname[];
-extern char Eauth[];
-extern char *autharg;
-
-extern Auth authp9any;
-extern Auth authrhosts;
-extern Auth authnone;
-
-extern ulong truerand(void);
-extern void randombytes(uchar*, uint);
-
-extern ulong  msize;
-
-typedef struct Fid Fid;
-Fid *newauthfid(int fid, void *magic, char **ep);
-Fid *oldauthfid(int fid, void **magic, char **ep);
-
-void safecpy(char *to, char *from, int len);
--- a/sys/src/cmd/unix/u9fs/u9fsauth.h
+++ /dev/null
@@ -1,7 +1,0 @@
-typedef struct Auth Auth;
-struct Auth {
-	char *name;
-
-	char *(*session)(Fcall*, Fcall*);
-	char *(*attach)(Fcall*, Fcall*);
-};
--- a/sys/src/cmd/unix/u9fs/utflen.c
+++ /dev/null
@@ -1,22 +1,0 @@
-#include <plan9.h>
-
-int
-utflen(char *s)
-{
-	int c;
-	long n;
-	Rune rune;
-
-	n = 0;
-	for(;;) {
-		c = *(uchar*)s;
-		if(c < Runeself) {
-			if(c == 0)
-				return n;
-			s++;
-		} else
-			s += chartorune(&rune, s);
-		n++;
-	}
-	return 0;
-}
--- a/sys/src/cmd/unix/u9fs/utfrune.c
+++ /dev/null
@@ -1,29 +1,0 @@
-#include <plan9.h>
-
-char*
-utfrune(char *s, long c)
-{
-	long c1;
-	Rune r;
-	int n;
-
-	if(c < Runesync)		/* not part of utf sequence */
-		return strchr(s, c);
-
-	for(;;) {
-		c1 = *(uchar*)s;
-		if(c1 < Runeself) {	/* one byte rune */
-			if(c1 == 0)
-				return 0;
-			if(c1 == c)
-				return s;
-			s++;
-			continue;
-		}
-		n = chartorune(&r, s);
-		if(r == c)
-			return s;
-		s += n;
-	}
-	return 0;
-}
--- a/sys/src/cmd/unix/winplumb.c
+++ /dev/null
@@ -1,286 +1,0 @@
-#include <windows.h>
-#include <stdio.h>
-
-#pragma comment(lib, "wsock32.lib")
-#pragma comment(lib, "shell32.lib")
-
-char	*argv0 = "winplumb";
-char errbuf[256];
-unsigned long parseip(char*, char*);
-typedef unsigned long ulong;
-void oserror(void);
-
-void
-hnputl(void *p, unsigned long v)
-{
-	unsigned char *a;
-
-	a = p;
-	a[0] = v>>24;
-	a[1] = v>>16;
-	a[2] = v>>8;
-	a[3] = v;
-}
-
-void
-hnputs(void *p, unsigned short v)
-{
-	unsigned char *a;
-
-	a = p;
-	a[0] = v>>8;
-	a[1] = v;
-}
-
-unsigned long
-nhgetl(void *p)
-{
-	unsigned char *a;
-	a = p;
-	return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0);
-}
-
-unsigned short
-nhgets(void *p)
-{
-	unsigned char *a;
-	a = p;
-	return (a[0]<<8)|(a[1]<<0);
-}
-
-
-int
-main(int argc, char **argv)
-{
-	char *addr, *p, *q, to[4];
-	char buf[2048];
-	int port, fd, nfd, one, len, n, tot;
-	ulong ip;
-	struct sockaddr_in sin;
-	WSADATA wasdat;
-
-	if(argc != 1 && argc != 2){
-	usage:
-		fprintf(stderr, "usage: winplumb [tcp!ipaddr!port]\n");
-		ExitThread(1);
-	}
-
-	if(argc == 1)
-		addr = "tcp!*!17890";
-	else
-		addr = argv[1];
-
-	strcpy(buf, addr);
-	p = strchr(buf, '!');
-	if(p == 0)
-		goto usage;
-	q = strchr(p+1, '!');
-	if(q == 0)
-		goto usage;
-	*p++ = 0;
-	*q++ = 0;
-
-	if(strcmp(buf, "tcp") != 0)
-		goto usage;
-
-	port = atoi(q);
-	if(strcmp(p, "*") == 0)
-		ip = 0;
-	else
-		ip = parseip(to, p);
-
-	WSAStartup(MAKEWORD(1, 1), &wasdat);
-
-
-	fd = socket(AF_INET, SOCK_STREAM, 0);
-	if(fd < 0){
-		oserror();
-		fprintf(stderr, "socket: %s\n", errbuf);
-		ExitThread(1);
-	}
-
-	one = 1;
-	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof one) != 0){
-		oserror();
-		fprintf(stderr, "setsockopt nodelay: %s\n", errbuf);
-	}
-
-	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof one) != 0){
-		oserror();
-		fprintf(stderr, "setsockopt reuse: %s\n", errbuf);
-	}
-	memset(&sin, 0, sizeof sin);
-	sin.sin_family = AF_INET;
-	hnputs(&sin.sin_port, port);
-	hnputl(&sin.sin_addr, ip);
-	if(bind(fd, (struct sockaddr*)&sin, sizeof sin) < 0){
-		oserror();
-		fprintf(stderr, "bind: %s\n", errbuf);
-		ExitThread(1);
-	}
-
-	if(listen(fd, 5) < 0){
-		oserror();
-		fprintf(stderr, "listen: %s\n", errbuf);
-		ExitThread(1);
-	}
-
-	for(;;){
-		len = sizeof sin;
-		nfd = accept(fd, (struct sockaddr*)&sin, &len);
-		if(nfd < 0){
-			oserror();
-			fprintf(stderr, "accept: %s\n", errbuf);
-			continue;
-		}
-		tot = 0;
-		while(tot == 0 || buf[tot-1] != '\n'){
-			n = recv(nfd, buf+tot, sizeof buf-tot, 0);
-			if(n < 0)
-				break;
-			tot += n;
-		}
-		if(buf[tot-1] == '\n'){
-			buf[tot-1] = 0;
-			p = strchr(buf, ' ');
-			if(p)
-				*p++ = 0;
-			ShellExecute(0, 0, buf, p, 0, SW_SHOWNORMAL);
-		}
-		closesocket(nfd);
-	}
-}
-
-
-#define CLASS(p) ((*(unsigned char*)(p))>>6)
-
-
-unsigned long
-parseip(char *to, char *from)
-{
-	int i;
-	char *p;
-
-	p = from;
-	memset(to, 0, 4);
-	for(i = 0; i < 4 && *p; i++){
-		to[i] = strtoul(p, &p, 0);
-		if(*p == '.')
-			p++;
-	}
-	switch(CLASS(to)){
-	case 0:	/* class A - 1 byte net */
-	case 1:
-		if(i == 3){
-			to[3] = to[2];
-			to[2] = to[1];
-			to[1] = 0;
-		} else if (i == 2){
-			to[3] = to[1];
-			to[1] = 0;
-		}
-		break;
-	case 2:	/* class B - 2 byte net */
-		if(i == 3){
-			to[3] = to[2];
-			to[2] = 0;
-		}
-		break;
-	}
-	return nhgetl(to);
-}
-
-void
-oserror(void)
-{
-	int e, r, i;
-	char buf[200];
-
-	e = GetLastError();
-	
-	r = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
-		0, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		buf, sizeof(buf), 0);
-
-	if(r == 0)
-		sprintf(buf, "windows error %d", e);
-
-
-	for(i = strlen(buf)-1; i>=0 && buf[i] == '\n' || buf[i] == '\r'; i--)
-		buf[i] = 0;
-
-	strcpy(errbuf, buf);
-}
-
-extern int	main(int, char*[]);
-static int	args(char *argv[], int n, char *p);
-
-int PASCAL
-WinMain(HANDLE hInst, HANDLE hPrev, LPSTR arg, int nshow)
-{
-	int argc, n;
-	char *p, **argv;
-
-	/* conservative guess at the number of args */
-	for(argc=5,p=arg; *p; p++)
-		if(*p == ' ' || *p == '\t')
-			argc++;
-
-	argv = malloc(argc*sizeof(char*));
-	argc = args(argv+1, argc, arg);
-	argc++;
-	argv[0] = argv0;
-	main(argc, argv);
-	ExitThread(0);
-	return 0;
-}
-
-/*
- * Break the command line into arguments
- * The rules for this are not documented but appear to be the following
- * according to the source for the microsoft C library.
- * Words are seperated by space or tab
- * Words containing a space or tab can be quoted using "
- * 2N backslashes + " ==> N backslashes and end quote
- * 2N+1 backslashes + " ==> N backslashes + literal "
- * N backslashes not followed by " ==> N backslashes
- */
-static int
-args(char *argv[], int n, char *p)
-{
-	char *p2;
-	int i, j, quote, nbs;
-
-	for(i=0; *p && i<n-1; i++) {
-		while(*p == ' ' || *p == '\t')
-			p++;
-		quote = 0;
-		argv[i] = p2 = p;
-		for(;*p; p++) {
-			if(!quote && (*p == ' ' || *p == '\t'))
-				break;
-			for(nbs=0; *p == '\\'; p++,nbs++)
-				;
-			if(*p == '"') {
-				for(j=0; j<(nbs>>1); j++)
-					*p2++ = '\\';
-				if(nbs&1)
-					*p2++ = *p;
-				else
-					quote = !quote;
-			} else {
-				for(j=0; j<nbs; j++)
-					*p2++ = '\\';
-				*p2++ = *p;
-			}
-		}
-		/* move p up one to avoid pointing to null at end of p2 */
-		if(*p)
-			p++;
-		*p2 = 0;	
-	}
-	argv[i] = 0;
-
-	return i;
-}
-
binary files a/sys/src/cmd/unix/winplumb.exe /dev/null differ
--- a/sys/src/cmd/unix/winstart
+++ /dev/null
@@ -1,3 +1,0 @@
-#!/bin/rc
-
-echo $* | aux/trampoline tcp!192.168.233.1!17890