ref: 0fc761bc845bd9795f05206e24621c0f5e76423e
parent: 7a95bef00e41cbab2d97f6392b221e6192335343
author: ftrvxmtrx <ftrvxmtrx@gmail.com>
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 dong@research.bell-labs.com 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 (nigel@9fs.org) 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