From 0fc761bc845bd9795f05206e24621c0f5e76423e Mon Sep 17 00:00:00 2001 From: ftrvxmtrx Date: Tue, 9 Jun 2015 00:15:59 +0200 Subject: [PATCH] unix is BUGGERED. remove it --- lib/namespace.ftp | 1 - sys/man/4/u9fs | 289 - sys/src/cmd/mkfile | 4 +- sys/src/cmd/unix/9pfreebsd/README | 134 - .../9pfreebsd/freebsd-3.2.il-kernel.patch | 7901 ----------------- sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h | 158 - sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h | 219 - sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h | 226 - sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile | 21 - sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c | 415 - .../unix/9pfreebsd/mount_9fs/mount_9fs.8.man | 319 - .../cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c | 1045 --- sys/src/cmd/unix/README | 51 - sys/src/cmd/unix/netkey.c | 587 -- sys/src/cmd/unix/u9fs/LICENSE | 16 - sys/src/cmd/unix/u9fs/authnone.c | 25 - sys/src/cmd/unix/u9fs/authp9any.c | 540 -- sys/src/cmd/unix/u9fs/authrhosts.c | 38 - sys/src/cmd/unix/u9fs/convD2M.c | 89 - sys/src/cmd/unix/u9fs/convM2D.c | 92 - sys/src/cmd/unix/u9fs/convM2S.c | 382 - sys/src/cmd/unix/u9fs/convS2M.c | 423 - sys/src/cmd/unix/u9fs/cygwin.c | 62 - sys/src/cmd/unix/u9fs/des.c | 355 - sys/src/cmd/unix/u9fs/dirmodeconv.c | 47 - sys/src/cmd/unix/u9fs/doprint.c | 610 -- sys/src/cmd/unix/u9fs/fcall.h | 123 - sys/src/cmd/unix/u9fs/fcallconv.c | 228 - sys/src/cmd/unix/u9fs/makefile | 64 - sys/src/cmd/unix/u9fs/oldfcall.c | 522 -- sys/src/cmd/unix/u9fs/oldfcall.h | 50 - sys/src/cmd/unix/u9fs/plan9.h | 199 - sys/src/cmd/unix/u9fs/print.c | 87 - sys/src/cmd/unix/u9fs/random.c | 58 - sys/src/cmd/unix/u9fs/readn.c | 21 - sys/src/cmd/unix/u9fs/remotehost.c | 32 - sys/src/cmd/unix/u9fs/rune.c | 205 - sys/src/cmd/unix/u9fs/safecpy.c | 12 - sys/src/cmd/unix/u9fs/strecpy.c | 14 - sys/src/cmd/unix/u9fs/sun-inttypes.h | 16 - sys/src/cmd/unix/u9fs/tokenize.c | 42 - sys/src/cmd/unix/u9fs/u9fs.c | 1769 ---- sys/src/cmd/unix/u9fs/u9fs.h | 30 - sys/src/cmd/unix/u9fs/u9fsauth.h | 7 - sys/src/cmd/unix/u9fs/utflen.c | 22 - sys/src/cmd/unix/u9fs/utfrune.c | 29 - sys/src/cmd/unix/winplumb.c | 286 - sys/src/cmd/unix/winplumb.exe | Bin 32768 -> 0 bytes sys/src/cmd/unix/winstart | 3 - 49 files changed, 1 insertion(+), 17867 deletions(-) delete mode 100644 sys/man/4/u9fs delete mode 100644 sys/src/cmd/unix/9pfreebsd/README delete mode 100644 sys/src/cmd/unix/9pfreebsd/freebsd-3.2.il-kernel.patch delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8.man delete mode 100644 sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c delete mode 100644 sys/src/cmd/unix/README delete mode 100644 sys/src/cmd/unix/netkey.c delete mode 100644 sys/src/cmd/unix/u9fs/LICENSE delete mode 100644 sys/src/cmd/unix/u9fs/authnone.c delete mode 100644 sys/src/cmd/unix/u9fs/authp9any.c delete mode 100644 sys/src/cmd/unix/u9fs/authrhosts.c delete mode 100644 sys/src/cmd/unix/u9fs/convD2M.c delete mode 100644 sys/src/cmd/unix/u9fs/convM2D.c delete mode 100644 sys/src/cmd/unix/u9fs/convM2S.c delete mode 100644 sys/src/cmd/unix/u9fs/convS2M.c delete mode 100644 sys/src/cmd/unix/u9fs/cygwin.c delete mode 100644 sys/src/cmd/unix/u9fs/des.c delete mode 100644 sys/src/cmd/unix/u9fs/dirmodeconv.c delete mode 100644 sys/src/cmd/unix/u9fs/doprint.c delete mode 100644 sys/src/cmd/unix/u9fs/fcall.h delete mode 100644 sys/src/cmd/unix/u9fs/fcallconv.c delete mode 100644 sys/src/cmd/unix/u9fs/makefile delete mode 100644 sys/src/cmd/unix/u9fs/oldfcall.c delete mode 100644 sys/src/cmd/unix/u9fs/oldfcall.h delete mode 100644 sys/src/cmd/unix/u9fs/plan9.h delete mode 100644 sys/src/cmd/unix/u9fs/print.c delete mode 100644 sys/src/cmd/unix/u9fs/random.c delete mode 100644 sys/src/cmd/unix/u9fs/readn.c delete mode 100644 sys/src/cmd/unix/u9fs/remotehost.c delete mode 100644 sys/src/cmd/unix/u9fs/rune.c delete mode 100644 sys/src/cmd/unix/u9fs/safecpy.c delete mode 100644 sys/src/cmd/unix/u9fs/strecpy.c delete mode 100644 sys/src/cmd/unix/u9fs/sun-inttypes.h delete mode 100644 sys/src/cmd/unix/u9fs/tokenize.c delete mode 100644 sys/src/cmd/unix/u9fs/u9fs.c delete mode 100644 sys/src/cmd/unix/u9fs/u9fs.h delete mode 100644 sys/src/cmd/unix/u9fs/u9fsauth.h delete mode 100644 sys/src/cmd/unix/u9fs/utflen.c delete mode 100644 sys/src/cmd/unix/u9fs/utfrune.c delete mode 100644 sys/src/cmd/unix/winplumb.c delete mode 100644 sys/src/cmd/unix/winplumb.exe delete mode 100644 sys/src/cmd/unix/winstart diff --git a/lib/namespace.ftp b/lib/namespace.ftp index e354910e3..d5c5e0d6a 100644 --- a/lib/namespace.ftp +++ b/lib/namespace.ftp @@ -3,7 +3,6 @@ mount -a #s/boot / # 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 diff --git a/sys/man/4/u9fs b/sys/man/4/u9fs deleted file mode 100644 index f253d8fee..000000000 --- a/sys/man/4/u9fs +++ /dev/null @@ -1,289 +0,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. diff --git a/sys/src/cmd/mkfile b/sys/src/cmd/mkfile index 4f9b1924b..f05cefe7f 100644 --- a/sys/src/cmd/mkfile +++ b/sys/src/cmd/mkfile @@ -8,10 +8,8 @@ LDFLAGS= 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')$'} diff --git a/sys/src/cmd/unix/9pfreebsd/README b/sys/src/cmd/unix/9pfreebsd/README deleted file mode 100644 index c4ce49842..000000000 --- a/sys/src/cmd/unix/9pfreebsd/README +++ /dev/null @@ -1,134 +0,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. - - - diff --git a/sys/src/cmd/unix/9pfreebsd/freebsd-3.2.il-kernel.patch b/sys/src/cmd/unix/9pfreebsd/freebsd-3.2.il-kernel.patch deleted file mode 100644 index d260c453e..000000000 --- a/sys/src/cmd/unix/9pfreebsd/freebsd-3.2.il-kernel.patch +++ /dev/null @@ -1,7901 +0,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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ -+ 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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ -+ #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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #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 -+ # -+ # -+ # 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 -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ #include -+ #include -+ -+ 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 - #include -*************** -*** 71,76 **** ---- 72,82 ---- - #include - #endif - -+ #ifdef IL -+ #include -+ #include -+ #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 - }; - - /* diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h b/sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h deleted file mode 100644 index 699f87246..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9auth.h +++ /dev/null @@ -1,158 +0,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**); diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h b/sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h deleted file mode 100644 index ef90b53e5..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9fs.h +++ /dev/null @@ -1,219 +0,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 diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h b/sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h deleted file mode 100644 index ad8fd10a1..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/9p.h +++ /dev/null @@ -1,226 +0,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 diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile b/sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile deleted file mode 100644 index 758c41d43..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/Makefile +++ /dev/null @@ -1,21 +0,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 diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c b/sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c deleted file mode 100644 index 01db16013..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/crypt.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Data Encryption Standard - * D.P.Mitchell 83/06/08. - * - * block_cipher(key, block, decrypting) - */ -#include -#include -#include -#include -#include -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; - } - } -} diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8.man b/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8.man deleted file mode 100644 index b0c4bab62..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.8.man +++ /dev/null @@ -1,319 +0,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= -Use specified port number for NFS requests. -The default is to query the portmapper for the NFS port. -.It acregmin= -.It acregmax= -.It acdirmin= -.It acdirmax= -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. diff --git a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c b/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c deleted file mode 100644 index fd08426ab..000000000 --- a/sys/src/cmd/unix/9pfreebsd/mount_9fs/mount_9fs.c +++ /dev/null @@ -1,1045 +0,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 -#include -#include -#include - -#include -#include -#include - -#ifdef ISO -#include -#endif - -#ifdef NFSKERB -#include -#include -#endif - -#include -#include "9p.h" -#include "9auth.h" -#include "9fs.h" -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 : or @ 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); -} - diff --git a/sys/src/cmd/unix/README b/sys/src/cmd/unix/README deleted file mode 100644 index 6e3afad13..000000000 --- a/sys/src/cmd/unix/README +++ /dev/null @@ -1,51 +0,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 - diff --git a/sys/src/cmd/unix/netkey.c b/sys/src/cmd/unix/netkey.c deleted file mode 100644 index bde26685a..000000000 --- a/sys/src/cmd/unix/netkey.c +++ /dev/null @@ -1,587 +0,0 @@ -#include -#include -#include - -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); - } -} diff --git a/sys/src/cmd/unix/u9fs/LICENSE b/sys/src/cmd/unix/u9fs/LICENSE deleted file mode 100644 index 13a5f81c3..000000000 --- a/sys/src/cmd/unix/u9fs/LICENSE +++ /dev/null @@ -1,16 +0,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. - diff --git a/sys/src/cmd/unix/u9fs/authnone.c b/sys/src/cmd/unix/u9fs/authnone.c deleted file mode 100644 index 7a8145cc5..000000000 --- a/sys/src/cmd/unix/u9fs/authnone.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -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, -}; diff --git a/sys/src/cmd/unix/u9fs/authp9any.c b/sys/src/cmd/unix/u9fs/authp9any.c deleted file mode 100644 index 2984e9796..000000000 --- a/sys/src/cmd/unix/u9fs/authp9any.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * 4th Edition p9any/p9sk1 authentication based on auth9p1.c - * Nigel Roles (nigel@9fs.org) 2003 - */ - -#include -#include -#include -#include /* 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, -}; diff --git a/sys/src/cmd/unix/u9fs/authrhosts.c b/sys/src/cmd/unix/u9fs/authrhosts.c deleted file mode 100644 index de150850e..000000000 --- a/sys/src/cmd/unix/u9fs/authrhosts.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -/* - * 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, -}; diff --git a/sys/src/cmd/unix/u9fs/convD2M.c b/sys/src/cmd/unix/u9fs/convD2M.c deleted file mode 100644 index c630b1b93..000000000 --- a/sys/src/cmd/unix/u9fs/convD2M.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/convM2D.c b/sys/src/cmd/unix/u9fs/convM2D.c deleted file mode 100644 index b83c957ef..000000000 --- a/sys/src/cmd/unix/u9fs/convM2D.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/convM2S.c b/sys/src/cmd/unix/u9fs/convM2S.c deleted file mode 100644 index 2fc6389f9..000000000 --- a/sys/src/cmd/unix/u9fs/convM2S.c +++ /dev/null @@ -1,382 +0,0 @@ -#include -#include - -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; inwname; 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; inwqid; 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; -} diff --git a/sys/src/cmd/unix/u9fs/convS2M.c b/sys/src/cmd/unix/u9fs/convS2M.c deleted file mode 100644 index 52cb486fb..000000000 --- a/sys/src/cmd/unix/u9fs/convS2M.c +++ /dev/null @@ -1,423 +0,0 @@ -#include -#include - -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; inwname; 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; inwname; 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; inwqid; 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; -} diff --git a/sys/src/cmd/unix/u9fs/cygwin.c b/sys/src/cmd/unix/u9fs/cygwin.c deleted file mode 100644 index 773d02cfb..000000000 --- a/sys/src/cmd/unix/u9fs/cygwin.c +++ /dev/null @@ -1,62 +0,0 @@ -/* compatability layer for u9fs support on CYGWIN */ - -#include -#include - -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); -} diff --git a/sys/src/cmd/unix/u9fs/des.c b/sys/src/cmd/unix/u9fs/des.c deleted file mode 100644 index 6152369cc..000000000 --- a/sys/src/cmd/unix/u9fs/des.c +++ /dev/null @@ -1,355 +0,0 @@ -#include - -/* - * 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; - } - } -} diff --git a/sys/src/cmd/unix/u9fs/dirmodeconv.c b/sys/src/cmd/unix/u9fs/dirmodeconv.c deleted file mode 100644 index 9941b165d..000000000 --- a/sys/src/cmd/unix/u9fs/dirmodeconv.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/doprint.c b/sys/src/cmd/unix/u9fs/doprint.c deleted file mode 100644 index b51c432bc..000000000 --- a/sys/src/cmd/unix/u9fs/doprint.c +++ /dev/null @@ -1,610 +0,0 @@ -#include - -#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 = ""; - 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. - * - */ - diff --git a/sys/src/cmd/unix/u9fs/fcall.h b/sys/src/cmd/unix/u9fs/fcall.h deleted file mode 100644 index 4a0d6f2cc..000000000 --- a/sys/src/cmd/unix/u9fs/fcall.h +++ /dev/null @@ -1,123 +0,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, -}; diff --git a/sys/src/cmd/unix/u9fs/fcallconv.c b/sys/src/cmd/unix/u9fs/fcallconv.c deleted file mode 100644 index ca422ebfc..000000000 --- a/sys/src/cmd/unix/u9fs/fcallconv.c +++ /dev/null @@ -1,228 +0,0 @@ -#include -#include -#include - -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; inwname; 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; inwqid; 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; i127) - printable = 0; - p = ans; - *p++ = '\''; - if(printable){ - memmove(p, buf, count); - p += count; - }else{ - for(i=0; i0 && i%4==0) - *p++ = ' '; - sprint(p, "%2.2ux", (uchar)buf[i]); - p += 2; - } - } - *p++ = '\''; - *p = 0; - return p - ans; -} diff --git a/sys/src/cmd/unix/u9fs/makefile b/sys/src/cmd/unix/u9fs/makefile deleted file mode 100644 index 9bfef0ba8..000000000 --- a/sys/src/cmd/unix/u9fs/makefile +++ /dev/null @@ -1,64 +0,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 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 diff --git a/sys/src/cmd/unix/u9fs/oldfcall.c b/sys/src/cmd/unix/u9fs/oldfcall.c deleted file mode 100644 index 4ed48fb31..000000000 --- a/sys/src/cmd/unix/u9fs/oldfcall.c +++ /dev/null @@ -1,522 +0,0 @@ -#include -#include -#include -#include - -/* - * 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; -} diff --git a/sys/src/cmd/unix/u9fs/oldfcall.h b/sys/src/cmd/unix/u9fs/oldfcall.h deleted file mode 100644 index 90c00d6ad..000000000 --- a/sys/src/cmd/unix/u9fs/oldfcall.h +++ /dev/null @@ -1,50 +0,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 -}; diff --git a/sys/src/cmd/unix/u9fs/plan9.h b/sys/src/cmd/unix/u9fs/plan9.h deleted file mode 100644 index 942afdc41..000000000 --- a/sys/src/cmd/unix/u9fs/plan9.h +++ /dev/null @@ -1,199 +0,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 -#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 /* for int64_t et al. */ -#include /* 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 -#include /* for memmove */ -#include /* 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 */ - 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); diff --git a/sys/src/cmd/unix/u9fs/print.c b/sys/src/cmd/unix/u9fs/print.c deleted file mode 100644 index 8011df6b9..000000000 --- a/sys/src/cmd/unix/u9fs/print.c +++ /dev/null @@ -1,87 +0,0 @@ -#include - -#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; -} diff --git a/sys/src/cmd/unix/u9fs/random.c b/sys/src/cmd/unix/u9fs/random.c deleted file mode 100644 index 6b4ab584b..000000000 --- a/sys/src/cmd/unix/u9fs/random.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#include -#include - -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>16; - case 2: - r[1] = l>>8; - case 1: - r[0] = l; - } - } -} diff --git a/sys/src/cmd/unix/u9fs/readn.c b/sys/src/cmd/unix/u9fs/readn.c deleted file mode 100644 index 89f060315..000000000 --- a/sys/src/cmd/unix/u9fs/readn.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/remotehost.c b/sys/src/cmd/unix/u9fs/remotehost.c deleted file mode 100644 index d1a369624..000000000 --- a/sys/src/cmd/unix/u9fs/remotehost.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include /* various networking crud */ -#include -#include -#include -#include - -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)); -} diff --git a/sys/src/cmd/unix/u9fs/rune.c b/sys/src/cmd/unix/u9fs/rune.c deleted file mode 100644 index b8f73ba94..000000000 --- a/sys/src/cmd/unix/u9fs/rune.c +++ /dev/null @@ -1,205 +0,0 @@ -#include - -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< 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; -} - diff --git a/sys/src/cmd/unix/u9fs/safecpy.c b/sys/src/cmd/unix/u9fs/safecpy.c deleted file mode 100644 index b7daeea5c..000000000 --- a/sys/src/cmd/unix/u9fs/safecpy.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -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); -} diff --git a/sys/src/cmd/unix/u9fs/strecpy.c b/sys/src/cmd/unix/u9fs/strecpy.c deleted file mode 100644 index 57cedf808..000000000 --- a/sys/src/cmd/unix/u9fs/strecpy.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/sun-inttypes.h b/sys/src/cmd/unix/u9fs/sun-inttypes.h deleted file mode 100644 index 4e147a1f3..000000000 --- a/sys/src/cmd/unix/u9fs/sun-inttypes.h +++ /dev/null @@ -1,16 +0,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 diff --git a/sys/src/cmd/unix/u9fs/tokenize.c b/sys/src/cmd/unix/u9fs/tokenize.c deleted file mode 100644 index 41ab050e3..000000000 --- a/sys/src/cmd/unix/u9fs/tokenize.c +++ /dev/null @@ -1,42 +0,0 @@ -#include - -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"); -} diff --git a/sys/src/cmd/unix/u9fs/u9fs.c b/sys/src/cmd/unix/u9fs/u9fs.c deleted file mode 100644 index b98ced8ba..000000000 --- a/sys/src/cmd/unix/u9fs/u9fs.c +++ /dev/null @@ -1,1769 +0,0 @@ -/* already in plan9.h #include *//* for struct passwd, struct group, struct stat ... */ -/* plan9.h is first to get the large file support definitions as early as possible */ -#include -#include /* for stat, umask */ -#include /* for malloc */ -#include /* for strcpy, memmove */ -#include /* for getpwnam, getpwuid */ -#include /* for getgrnam, getgrgid */ -#include /* for gethostname, pread, pwrite, read, write */ -#include /* for utime */ -#include /* for readdir */ -#include /* for errno */ -#include /* for remove [sic] */ -#include /* for O_RDONLY, etc. */ - -#include /* various networking crud */ -#include -#include - -#include -#include -#include - -/* #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; inwname; 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; inmem; 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; inext) - 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; inext) - 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; inmem; 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; iname, 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; -} diff --git a/sys/src/cmd/unix/u9fs/u9fs.h b/sys/src/cmd/unix/u9fs/u9fs.h deleted file mode 100644 index f553a3a43..000000000 --- a/sys/src/cmd/unix/u9fs/u9fs.h +++ /dev/null @@ -1,30 +0,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); diff --git a/sys/src/cmd/unix/u9fs/u9fsauth.h b/sys/src/cmd/unix/u9fs/u9fsauth.h deleted file mode 100644 index 6d101b121..000000000 --- a/sys/src/cmd/unix/u9fs/u9fsauth.h +++ /dev/null @@ -1,7 +0,0 @@ -typedef struct Auth Auth; -struct Auth { - char *name; - - char *(*session)(Fcall*, Fcall*); - char *(*attach)(Fcall*, Fcall*); -}; diff --git a/sys/src/cmd/unix/u9fs/utflen.c b/sys/src/cmd/unix/u9fs/utflen.c deleted file mode 100644 index 7eb5ff507..000000000 --- a/sys/src/cmd/unix/u9fs/utflen.c +++ /dev/null @@ -1,22 +0,0 @@ -#include - -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; -} diff --git a/sys/src/cmd/unix/u9fs/utfrune.c b/sys/src/cmd/unix/u9fs/utfrune.c deleted file mode 100644 index ea6772f06..000000000 --- a/sys/src/cmd/unix/u9fs/utfrune.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -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; -} diff --git a/sys/src/cmd/unix/winplumb.c b/sys/src/cmd/unix/winplumb.c deleted file mode 100644 index 7d0e5860c..000000000 --- a/sys/src/cmd/unix/winplumb.c +++ /dev/null @@ -1,286 +0,0 @@ -#include -#include - -#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>1); j++) - *p2++ = '\\'; - if(nbs&1) - *p2++ = *p; - else - quote = !quote; - } else { - for(j=0; jF>C2r>OU?D^LpeaN1A z`!A+)FDLwZ&LPXnU(Z=nv!%(^&{+ROW5tuM%@td>){Cykt6YuJR@auTuDnN!T~F3m zRxLr z&|~FP?*+NbqIfUVG=PH`?MJa02krJQF>YWn6)m~2TDykh`sH3r~|aPT0R)0bP>qKtIrXQ)tUsVXvQopWt>#o zIH^NSOm-AxM0~Y;4Y98Vscey!9V^=h{!KQXA1~V+E$gi1f+gB&?QS5;N9@(TUd_r? zt4v6~VBvd3+WKo~(h)&@j)b#1=pFQF4ii-C3>IodF;7)u#f_7Nj?&Frt4CeSmPe^Vp-3x3F1obW z8>V*Z3FhchFveQKe9MC{MUK~m_G4lOsX$~k-hJ9yQ#(=KRv7Mp(E^TD4lj@r&;T~@ zBKptN5+Spz)7l-5SG>b=%P`lx1y9Q^0Z*%#r>{c=Hfaus0JC$6wIkOSOItc}Vf}=j zTnok+(5%u7;J|Qp7Faq~*pTj763wz9%L@x7bQW1Vd^V(eJQ(oQvWr(pCHbgbYaKj; z_8F-QAsLKrjQ3iu<|shH_AI>kYRLJh1}UQmIpldWQZpFxLcq|4cyiLM>T`s$x~31h z5-qCrn|d1z5~U)ol)dt@W>MPj21IwL&rvMDXHm?=tMtk>&rn&uak6--0elMHcGlv|=z74l`bdb$jM1;?VKzVWnhH zf9N`8?-1i*NG%+47e+w0WVpw=o^=hxIIREv6Q~V@VE|&y7bi*tWx0VJluJDz^zyCL z0D8fK;J7jG1bWVxcbq+svgZ-@>|)PX*z*v3zKrMb8-D7Vbi2AToo_!SE`u@1OBej= zW%&xL$zhLX8$cg9;`5jyLfK`mY^aB))2hIxMp!miR zo_wgdq|~oAr>Dp{ZIXwx>~c5`PN@}qnitl%tW2j@HF-yqhwJ2X<$jvtZOimij)M;@ zlgI8+KM>>OvH22D@0n*~G%!P!YP?AxX`flRLGI^KI627wOK^Su2`Zq!DPOxs4N2C~ zzK!J@)`bi)o!9Cx9?L?g91?iM(WOjx2-r9At-xE@e(ZkSsPE6^vE&-8&TomXZJ!~b| zfojz%A12zT0DXgK9|P@fx!bDmp4b7wCC0i?@Wpf#;)0dw7=hFW#cCg<4PK*siZePB zmt_4;JlS?kEQ+%Jeo~)b4R!y)S(?n`SXWK4_e}WtUN(JZ~ zK=A;b(Z624(d2l^7|Ml$ORkwwgd%Deb-JL}Mq8vBq+9;cZW6ZW=(Oa5n%jJpE~=Ja z5ZAU7#Oh&4`Fo5(P0ft}Z7wRj<$JL4oH!K`XNXq)*TJ2Jo*djcrVGKH*K}KOX9N}4 zqx5g?oR-^mO04Xdxhz`62YQ?`Q|{$iJ*p*IlR9m@uJgcO*ft`5cJwf-X*$KMs$ONL zsm|4AqGy?v+Zc+zYz%cob73h<{e~oHGqDCxhk{v99I46VfD}5;W+u-+f}|j zunPcwNDdn!Mvr8Z6AZcAwWRg(CSW$7DGzCjrb9V$UfStFzr_vQk9ui?gT+a)TovXp zwp)bG+k@LJiWG?rPmJjh4e`f`B@A(Md;>T>#N#?|%hyi?uHJ)EQoLN4V%6gUSLaLd zfCB_04a2{CH%65lwm8~kmPmK(c?yYIX45bnWsi2=j%4mq-Bq3pBx7-?PBKT+t5@n z{}J;dI9~geJdmN^7i(*hzf^l_B5JkDH_YvYC0gNlE#%Ycrh$xlR33Q1UFdAOUzNgW zt>Bi18&f2Ej0g7{+eiq!p5XYAq%h_i!yD;L8>oc6QVUaz!U#5;Bi(}JBr|L7 zOsNO-!jW$N5RjghW{q@Pq=)45RxzO!TQKz7_JsCh(%qPtw|#cRn_}sWYd}BVfgBO_ zg$*6^TuR`)b>w%q9vl6g?I?C(ARdRh6)W(qBBtf=Xdlh@-ms1ph#l>+Dp{Fb8_U-n z3t`J6raNOn`y<;#IN9ijeZ_c>4#yO8xO-y5oz^_uUmx@LVa%tSV}8cWek^1xdIf?*O9hP#SXo&}ZcgX>x8K30lvx0gPTrIa zi!G8sc&!BePO#s@q?W2E=w9?9=D+PprP{nyGiz4+h-9m^l*>I1`Q4#XEWH+O!f-TF zvo?9Sa%x4bQPYQX&7jA_RqjJAoUc-uM==(U#if3wN;6VDz<|f#jFQ>`9@V4pH~>LO zZo^ymdBOIEk{qC<=G@SrjV| z%*Na;!2(O`We#I`yFF@ee#YnOtJR~W>LOYpzy;$tcyc7K)DkEcrv|FVxDL2+yw_^2 zdP1P;8rOl1mSt_QFp)NCwOkQYCE}~KXnAu;MP@-<)?*>Z&%B9qz4l|Yen4MC-<(ND z@w8)2j>XRCc`TWWN6)K$lsj6Po?#I1#Jsz>wfc8j!HUff=TSFYF}G*iE%Esx|X)+#aNpk>MwX+|(VrPiwC z3rhT2B|lBc=k;XuVWm7x*(E3sDdl{1>ngi-8fb4^S02jjDrXwZm5O&jIqf6)$xiXE zQf&|pp+I%=2Xb{9Cx3>Ms|BvCoYryn5f3n?__Q~G0T7h4b+Et+o@fTJXO48|GNR>`xp2{v6bnHF{c;Kq5c}C#sj;E)>M0N&fjVkv$ zbZcf8_EJ3;@Y)^bAsQW8;0&JFAU z1_;TTOLWVcO}t0e1o8HQ0&zOt9PMSumJ1`ofX__u18kRG7_kgI1W2GT5*S!yW?2Ww zYZAEnIcYA<-`ZdBM&kAMJA%_q6rRjs{{W9SmcWB@cE3{l(5V%?+x&l}0#OZ;n+a2xSBzWO9Vc;KF z*@$!CD`vtq&`wzo-!G*Ep0+HMrY>6sya41rP=^eqbxC;bs5S`%&4Xcj@Sq0AtsTApK$D%gG!Zg_#7X*Lw~i4lCLJSVjBHGkB|(vrzFHNO?T^pL)H=2_q14p?f{SR}Wz@xZhA( zunTm@csx0V4$e8F}q>eG(i##)cX0Nh^p^?Lh=yndIgJtp2K zYYF1N6*$^7zy<^~Q0t@BO$RI5>m4RklMZIffj>butf4;v5;RE6gc}u}nY%~4*938< z<8|(&hBl(6Xfp?XO46)4M=eM0z<#{$+e?ywOLO2WATHShSD%okpjA{AR!D|)T<(Ia z35g-KAgmM~QausH`wI1Nv_(PhA)k?YVw;CkvEVt9()w-yWyKV^Wr&leMv;uvb3iB~ z>eDeJT?e0GU?$dkq-1oYCHU&kAt*@Lugwl)8#NFCFS549(MCd+wKzxH3rIjrZ4`+` zGyvPKp-cf_|BK;ZL>@z_UhkRD;$2@nzx!l(;AKF}-e+xwN5JfMQ3zylqRpdUoZmgL zhZP&5)g4MtK{Vox1R#4DLr&b#={?iqeJ_JA!t4&|!JzAUK@@|^h;B5&sxM;waw~ce zd9E@sp;|2*tX2d)4zVIcdwpOo^#{}n3O$`NmEKlSv?W-Ps%rj7Q=r?7DteTyWm zUeS4VNWDV!VpaYpI6#KD7OZz!@9R8f>`}ERsaHbk0#xm1Y>hT#6b`j_JsnRuq8na@ ze_HMHV-eJ)lpN81g=LB%9Z~z_P=+COVcohM5cz60)w9cH+i(VpJOfU`H2tR_I3F+G zFzUBLOGR>@2eLCH+9V_c$%FSEO9ry!mOjqWJ`5SD8zLhikNBC9UW*uyuDC}}83~!m z`Fg@g$SNiQ>O%LRBcYM~^Q8;(rQwl~U78*>LZ!7XZ6GZ7Jv+^)1x~u!6y|r)<}K!NS2J z5N2?VE)Alz+WRQlc0x~$vSLWXh7{I*VdkQr;%F}ZX&?8WucfdaL+{hfSaxf{;7Xgd8+^|{{ zdq-w9<;sJ3DWD|uG!>)$!|_y0;B(LD2jDR9ytVmPU(zb4bNQq z?xEnU1mr(X#sWHV`xU$pb%RezRn=eq~CqgH_+%lor^8>II|66PKtuU`boM zS>+etB`_&9|5A@v8O=L7nqO;QBlcNFl;ymE+lk2U`y^Q_s}#eGI_VV_jkezqr{Zn|X@5`@*TY#8E9|9Ca_d2Dt6kPJ_Id|(yt(H$~;^NC0bI*(^yseIMe{4WM$+(<0| z5psUXNAg0&wEndF9Y2D?$YcHL@3$x4um#C90NwsM_iVOPNiNpD1iPt*%i0ZTerc^R zaeJbM0lY)bp=}W--dw6xMJKux{pZECoL~E&I@3q;bgaX2QxBK=Yi*fEc{cN3?8@6m z9txFz36lH#h{rCA$v*AZ*d##2WugVXzm(>g498gblGct4_EILNzr^Lc8I9&wh~v*UO9Sw9j_SUA$H;d8EDvo0bnNpZDQ>j*k=HLtz~0& z&LK2QnuZL)NL>#JqBqtef-c%Q8dE7s&dWgQm`#2WY4N@WlZQLhn@F(Q zlsrzihu7aPH*?UD38mUsi2@+nTqH>Gov9Zrh#w!mep^g#9Za9Vt?nlGpi%|}1)`i$R4WzV84WajRbrULyyK%AO>P06?G zQ{+{4m;5UO1!N3qC4QqCLZ@TzWF>Z>cK*zf%(IzBwC@Wi^nI3E0H=m5WIR|pDvkM;J7eA)d#$xt`@uz+t?QnjwQ@g>AtYW6 z>0eM&X)6h5YZ#l!qa%4Mu(HNpG7*anp<_dWxtC1fIyT@;9eYXaD4}3B+Di&JwSqW| zMZ}txLz;fX1@-tI99&Yo;~>s|lJUIeI9M2g$2X}P{uQ(Z9VFSQbIP3uo^iBY0^0{X zj&@psAFzlwk-QH$9c^c+Ije;9F=Z-x1o)I8SJ}Dr5AD|K@7XPYN_Uu>O;Lz$G?R+8 zmu4_Ek*1VtU!&QPcASF6FIGl7ADe1rs=6v|dAp&k;&(ayzGCeR#tzg#@!IuF`Klq_ zq=wXAebn&jafkj9tJe_^?-G-1t+iaS_K#3+lmq3?LZL&@Q)(>`%SIyEI!-dX#l8`~ zDJT@&hF*agJ6*85z&~m7I(SXHFytUO2Zji5oFFCVA#A8K{;TE41;b7R9nW@Q)K+5b zw0G?%zlxZuL4olmIbxP<6LL|Gir09c2sgT5P;NcSNtTd2Zw(ThJZ~*UwU+%p#JzC^ zc+%Q)ZD=251nq%+R3K>YaCbMQ&;i4IpS|@8eHzd>Mea(`HB^R9l?PMc%fkTpu!3#09YcZcN=Q$4U*>Bc zUcON&w7cKjX2Uj4T{(kyubd%B1z1$mj)5e;8b8;YWWvr}?G4u>@&8YMqm< zr_0^_(QIHxF8@3G*^(qKZarc#NR`rVeP4NqK z23W+qizaYS3$MWG_ZV-d=B&BS{WQjXG&{!qsX5Qyz~bFm;hCCv?-_s{)wRdatxEwKvO_r1+Nqdc)C{z(&o;UQ+U~Mbrd?rx;v0=nipts zU>EgE;!}O|v<{&q+&umk%zG&>Ax*!FAvuGO_Ol!ltBl8ctasWN-w9bNgz6nqZc*0H zh!}#S9cshvBekOy&)dXi@=Cm^IW|6?&$eZ{v29bAQ*=_`_*eIAOpC7`wfT}Hr%C}6Fe`B2ffIQpq zMCmxL>n9KU$Z3rnQ{M1Cs!8p0zpZQ#nr>Df;Z^tC!tmU&q&KA`Ih5kw5J5)cpAbts z)wkSzgqC^(S{%^ycinwb8IYQ$$ygvs0${+@-=}h)iIq!cc?|yp;7`@EFrd}G_On10 zQ;M~>@LHxm;#4f^Qm33{NK-Pq1{?q?vl*95ovKs50(VzLOi_35rEXK3_vXd;eLyuq z4S91*!gHlz^56yw@{;~Tm4>C6>Q~!#B~57C9$EX{^s4MMTgnLLDL%URVJxCSI0uUH|Q zlM|c3qNNG1=14B)F9D;-ED&7SY92SZdzE~r_&HoS<6LA@FlAxSQOBs!+93rC!0}3G z@MB3oQ(h$)@GbA+;jRX8HQ$N-l-h$uIjzFj{N`7`=u~rs%(LxX(5L>T(5F!C!&|y& zdV4I`mciyW95;Cc#lvG0wgTe0TFZC;$zj`RXY+Us8M!Dgn7ajx=z*_6+QEOIukGAd zwl5AYbIJu_L+%)KK{?u{d$GxsXuT3hiedZK+7gSL1N-w@E;KYX@lT$X9W~If5$G z|&m$1?zZ+(w_ zg*1vi`=YynlLMz=7mm8(=tTwry&-4s1W+r1HsoN(Fpfn=Ltl{t>5hZi3G_fta02KV z0;T8dnE?7Sfu`mBJ%JL<8an|p7$ev?o`x5I*eEO41!{T`AY|{Uz35LpflkU(MW_`P zcPCbB@l^&v}NUcR%DJ^%|-91fwwp02`(7wDpXb%z;Yc7C9oFasZGtXwv zu3@7^iqo#r6tsv=vNDa%_yWu;;F6Ar>tOlMZb#eS_2)Zon{6UBGal0NIsJ0z61^h zEr3Rr#qene@L%?o`q}arZ*UYBDC}f!WBGnM+B3HzYGIn{O(`yw=fHR8q*I?>#x**! z-4F%k0XR;u4h>}8A?0=YES|uXJH)$it74wx;Hi;ka$7tcFWL=D`-m9d>Fl^E-^0@X z&eHmC*b5){43|#?@;&-e28m2CNkrFq!Iwxo&4fgP4Rf<6m2g@<)4z6Cl0!}(Sky8xDUQddtuf`jy_ONo)5`1SdQ z}GjK+hM#{XWypwh*LeD>g+V> zvKjq(evg{d2689E#l@cDVqa--v67d*5UW(pt&8`SXy5NQhYUP@;@slm5+Am6>A*66 z3nM=jFHUU_IYE{6=}tIYoTWx;fY=M^#pL>0>Ap%PBgV0~IO}$`S4{L|rAb%mF*3i` zqiQAEQdGl+GmcnC^rRAay=P$0i{&V$lx8B>L+6gjp@auGrE2g3(+$`{NFg&~U+*PJ!2?I~D68oG5VQ>j22lH1 z%miwK9miqf0ykPL-WgoDO|}0-!A&%!z%DoAz(|_T?xL%CKM^z!N*il_BIu#YJ#j<| zoP!x`bt~0mdT-syQ$@IWT4YyO+q1ESietQmii>`k0VAp>MiZEil}7|+DX)CNUbgNq zkNbb6OYh5AyEG$%Ewr&4^<#m!0k@8YQ4edRqx~6F!HyQ_hAJ$EvNWPL+0`!z)Pjnj zeVg38hv!6ZX-V)4PGij;enUAZBz1|II~D`0So*N452gsMgD;|s zaWfTnsyvXR+bJetfs&g;$7#(MOVx|r@7mm7rz}VNETG0J!xMe zYBg`O2HV$zNoLS-(ZsaqC@>=m&!~jQQTt^djC7d^^813XQW5Pt=M2MxgMr1{?lNW#1WeNak7CsE2~MNP^ojr8O&22E+fGpo5;`F=A&^UTIAMWne;l zp5-{&$mv^aUAv!Xkda7Ny|X|mZXfyF46I?{S7lf7z!jAl_y!6vyY?&+*&EU%Vc#%N z6>l005kpqJF6NN$7d$>gN;6Xb5#<^b1|$h(AlFJydiplHDC-i13br6zrNpJP-(66~e;kOQwXwU#VXu}-JvE5f_kaYmyJYaO_4`)}{Q9H-iYbcoWKhdZjcl!_ru6EkkDY``rV<`0#o^$}{cI!2IHN7rsH zs)upy#K)?0qB=V;g^yHslrHCd6%S{$E<5U)in@et!hG<4>zecw!~$ab=vz3NeTy5v zz=L@=y;MsWgr>K5m5PZz?M_O=?|!3yB%WuLpZa?5*&UpR71G2cVRC`7l;ar!dL7+!)zpfyEKCKyqF%nZ>WW7f!wJ@qupgVoP2+L@8C03)hAiHiYB%MkNq5bS_Ugg@P1 zq`iQt5p7d#wjMZy1CF+CREf)kR0Mm!7Qyl5KLHYKAG``vRv4KNrzS2--i0LHflLTo zPL!q?-k}~Y+0!9-)T6=Y2y^}$xbOvjn~#(EV-PHYhhd1!H@{D{84EK^3xq~5#i6jp z8+P|L)3+4!y>_?P+1Qy$m+9TTj&>C+WVZ<7#@e{G*%Z<_BN(o^Jl^m1cIF(ZJ^f;HXrY1VX>X-&~9Iei$zQobMOTI-6LDSeIBd$_8c znr@D3L77cB`W=3Mv1w9~cPGnpwA}&R-Z;v)g179JlwD+_&}!`kVxm`iz*7#pM(RQ8!%3ZaF7b!;GIZYamM-r3+msL}OVN-Ox5gp$;ih zpL*?FfrhT*sT(j-8HYPKD^dn{(AEZD+xaxJk$@6+x zaGD>^DI5A3&(p_w#)l1Pgo@hV7GK7MCSCXlYhd_!@Z7flrmLhzA$5S%t>CV_AVA z_R<1gO2M}*_@V`Fm&Us;ecMQXF0BwP>HP&|$^(3(UGBHpj^aXM#!AeM>A^dZy%+Hh z@w(T8M;#>)=AP`t$1t7wmX2kX&U`D#b}X~XJvOgL?ZmX%@+bs6-XIN# zB8D3j?}g_#I}(+D`gQpyU%T|}22d?e+MaVLK3uM{c+jskNMOehrkOk2zl>O zq%{O5UOMw_b5C|Gv#kQ*M@e!ACy*t+qWRbR=mV?#A(Q^@37C5);DLLzF4|Wg*yInX zM;*^RhA}sx1ZY>H{yGE^p&6kKVK>6F2;W73oM%DKvk<2tPD7l67^|nRI1yu6^A$T{ zEMUGOAjW9^3Xhn-v0qI2bb;Pcgg%5pq8;m(d>dLnp&!^gT05Z+&^F+hup9afgGL^t zr8&)C9T+9FmtN#*_HYWWlD5?Xg2nnJM_VbSP8|wk=a8KtHp*QYOLDaBv{4FrH7sdU zXTcz_DIgt~wVuqbve!Lu3CS(^@{$p}^n>p!v-7Zmb$t0l=v<)X18kOliBz!g!_H}K zxB>dFcyS!eHQ)|$A9noR*9fbFxr99W2iHkn`ay8vYOKw>-{rp_d_e#c0XL`qO1v8% z)tl}pT(r94?%j?<*huH!4}oQ2FOl)Md$;{1H#d;YNoTO`kVE+VHNrP`Lw3D!i_vCq z&iVFJ>$M(Y>|g|CU(dk%x4&JspLqYaUIGF;4QvSupbfC_CWnG2hjy2Z7fZF>h)v|{ zMD=)OHdT<>#i;$@2S3o0vu8&zuZmN(ub_ZN6A@hQHZ0V}Hv#fI!hlrABxi3NrHMgf zUJ4WSwHtwH3>c9dY=?6lotgf7UW9oQ?~pZKoGEL`qP;+*t;Hc8tEFi0L+l3BI zqqM))QwCP4|IlkurkPy!Q!AJx(1wlCB_;e8xKme(qY4t;1XZ|+l%|WVM>^W#2C)qC zxO*ChJH3DIX{R?AKK^ z_m?c`Tw=807T?Bo_yoFr5MLD=i>P1Bs%c#avZZvb|4Cf(U^uv(YUY-XXP26Vw12?; zHHH)UI8O972NBomfhQkXk5xdBs;pM0jU2}1472N zWr4Q-hrl-}lk?=}LIAJp%cD|}!?}$&%i+hir^IL-4RpIYIvAzfakHgy25z-%pBf`~ zG%(=O`(wmF>NRY<d$#O}iVlmG#CEfOO^h?(O*T|J(U7YYlA8C(Mt&VrGvE zkWKUBalG!`gvV}#mk|D@`H_gjj*jC-ZSF_rN5cB#`7v7l^FWw|kb+=G;1MF=VHjZ$ z0e1C2VSZ$iFsQ*kg!Kpw2;+A6|J(d{q6D>=^J4(XPnjS4zzh0;koRgx3rJ)j#OAe+ z&5wlnx6O}?W{l4GEb`ap$0+SKRIwZ3S%l{iUPSmI!pjJ~2vpq{J+eP?5KwO677_wB{c`I9Wzqxu(aew7oSiUIgze;9$>%mAGl6Ln4+&{w+X1( zLGgYbK;u953yAhn8jJm#j1zQKK%Badpa8@b6NFaSu>iLhQ8RtPdYFB0XZPdi`Ki)k z^>?`EnKIf#YgXL(bxKpv7gD`Gr!zjEzTp<CLIFZK!VZMLM>v4ch42=_y9j?q zzzuiq7KFPI=%-bgaTBVViI9q5MZmNezBDFXLEMuy)v1@A6_z`~}QP59yeci*rBKLHrr6iyHj z3HYN|?oMtiCvkQ7yNil&cW#yH>X5`gc_40ivdUG}*jV4_;<)5Qj$5Rb5*p<*KQwXkcVG z!h3-5=$~7t+FCC?QR8ZAsMuWPsz%*)_1m{hC|DtGso#3N-2IxvHhDn~665-G{n5Rsr#~@Kfn;tlwI-V~hCt3jB)&TSS*gO&sUz-fSv& zz1{T2iq{qJI|w>?S8xJifKQ@kt0E_U~SZRgF(>*?Oa#Ggx~*v45(z zLW1>MpRC#{f*yFyVD0%t+=|90BtmS8$v5LZl2dhEJ*wOKgsY)`%T|%80U(uCm8Luk zw`^{#Z>p~rU8P%^sH>LFpYK{7RnV1N9&fB@+)28d2&IgHy`;Bu5)*yqKj!fuRG3?^ zU;(!{*2=9F&~9n#7q-@K-}(@hHh(nkmgjl6LInEJ`@b&ta6d+%^y4e=u_MB=Dsg2+ zlb8#Y*;eJNZ;%=|f|>9BEn6$=w{wM6O-&U~R4u9Bk;_RWJS zl`ErpyErdK;2JgWtHjc(#wOSTe00WWLyI<}Gr1?N#Z_VfQ0uCe)PLOQrYx zEp=6Eb~aRTJ~Ouh7N%kO*6R9P?gi_b=f14^m?zMn(+yKNydBRZU`J{Z8&* z*xOQ!b`d)9y0z4_S^14sRopjN9!qk+jOCb(D{rps)4K> zSjBk9oJgD&)>le(RmA-&j1EZd#~ji1ULWDbVk5?BQ!e+DPs#Cfr>y=hl~qe?DjL_+ z7m}4)vJ*_l6a9}9;)G9z`#J9O*41KN$=2-{OWfO5f8!RBamHP+j8k1xAFGNhHYH8m zk>tU9>5ULj{63doCpFbj`<6)6)#zf#(z0@CVMT-4E|lt;_>MC8($MTrADJeS)a$Ib zeAJ!X&nca|6qE41RNJH8LP|eGY3j(_%F0Gk8}6`WCG1($RH2qzxutdWO;u5)X{I_R z=+GnH)vLTQ<^H4rKM9+Zz@!8wB`_(0NeN6!U|a%^&+>4`R(rdjsX`o;Q#Ko zWotv7^yK3NlW2whpeqJ)trIsl%-PaVfthAEdVV%1jjtzt7R%FHw^ zd+N70ncF(oyvi8=-^A$${V1jbjPajyJT;zxZ-LwfpZcSG3X{J{3H+@Rc=sOjPQo)y z9*zQ>O&|Na6J90r@8fwNhZMlC_1FH|xR3wch~LUx|Fdv^+uuYA&v4iOtQZl0%U`U# z>u(j@e`7qdF$)kV_EmT|4+8m0IM_}yOJN&*&C7KqAx*#8NaKPM`+a>v8n+m`$R|lZ zT&EgO@0pO^J0bnm3F*I|kp9|)G^&Qr6TTq?y3^%~``XQj#(!l0UfGO$7KryErc1Jw zhzZ|=nD|dYJPq-M$35J1#9fGIAbu8c8shbciRePaw;+z7{kI}Mf_N6<=MnEfyc;n& zs+ti$g}4rJ1aS>wIz(TK_-+3u2V}FK#Y#84IF7D@ZF*+sGjmKZ_no)R#J+EvaqBnw zi8SZg6=3lJ;CJtTYro6P{@Am1%mjI&@lXFo{M;!1LEyjntqb3}h5O^Tv~R8Zbo#sY zu@Xg4h@!X3-*Ryq->QAHeb0@)FO9zY z5L21eQFw7QhD(9bFGEaq*G1t^B6cA(Adt>9A`q|C4&o<(Ks>ib<7W_4zKlTmZ3x5< z#su@^zYu-jhnV<%5rOLaE&}2G41xIj4Fcu=7J>59AQY0%