release #2, shar 6 of 7
Todd Brunhoff
toddb at tekcrl.UUCP
Wed Mar 12 05:41:24 AEST 1986
#!/bin/sh
#
# RFS, a kernel-resident remote file system. Shar 6 of 7
#
#
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# remote/usr.sys.VAX4.3/h/user.h.diff
# remote/usr.sys.VAX4.3/machine/trap.c.diff
# remote/usr.sys.VAX4.3/sys/init_sysent.c.diff
# remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
# remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
# remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
# remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
# remote/usr.sys.remote/remote_mkdata
# remote/usr.sys.remote/remotefs.h
# remote/usr.sys.remote/rmt_data_template
# remote/usr.sys.remote/rmt_exec.c
# remote/usr.sys.remote/rmt_final.c
# remote/usr.sys.remote/rmt_syscall3.c
#
# remote/usr.sys.VAX4.3/h/user.h.diff
#
if [ -f remote/usr.sys.VAX4.3/h/user.h.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/h/user.h.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/h/user.h.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/h/user.h.diff
XThese changes keep track of the per-process RFS information.
X***************
X*** 121,126
X } u_ncache;
X struct nameidata u_nd;
X
X int u_stack[1];
X };
X
X
X--- 121,137 -----
X } u_ncache;
X struct nameidata u_nd;
X
X+ #ifdef REMOTEFS
X+ short u_rmtoffset[2]; /* path offset for local segment */
X+ short u_rmtcdir; /* system # of remote current dir */
X+ long u_rmtsys; /* room for 32 systems */
X+ /* one bit for each remote system */
X+ #ifdef pyr /* Pyramid */
X+ int *u.u_ap;
X+ #define u_arg u_ap
X+ #endif pyr
X+ #endif REMOTEFS
X+
X int u_stack[1];
X };
X
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/h/user.h.diff
#
# remote/usr.sys.VAX4.3/machine/trap.c.diff
#
if [ -f remote/usr.sys.VAX4.3/machine/trap.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/machine/trap.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/machine/trap.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/machine/trap.c.diff
XThese changes enable syscall() to start up a remote version of a system
Xcall if the normal system call fails with error == EISREMOTE.
X***************
X*** 23,28
X #ifdef SYSCALLTRACE
X #include "../sys/syscalls.c"
X #endif
X
X #include "mtpr.h"
X
X
X--- 23,35 -----
X #ifdef SYSCALLTRACE
X #include "../sys/syscalls.c"
X #endif
X+ #ifdef REMOTEFS
X+ #include "../remote/remotefs.h"
X+ /*
X+ * needed only if EISREMOTE isn't in /usr/include/errno.h
X+ */
X+ #include "../h/errno.h"
X+ #endif REMOTEFS
X
X #include "mtpr.h"
X
X***************
X*** 191,196
X register struct proc *p;
X int opc;
X struct timeval syst;
X
X syst = u.u_ru.ru_stime;
X if (!USERMODE(locr0[PS]))
X
X--- 198,212 -----
X register struct proc *p;
X int opc;
X struct timeval syst;
X+ #ifdef REMOTEFS
X+ /*
X+ * It is imperative that these declarations come after other register
X+ * declarations, because the (standard) code below depends upon the
X+ * order of allocation.
X+ */
X+ extern u_char remote_sysmap[];
X+ register long rmt_syscall, runremote, rmt_called, rmt_cnt;
X+ #endif REMOTEFS
X
X syst = u.u_ru.ru_stime;
X if (!USERMODE(locr0[PS]))
X***************
X*** 223,228
X if (u.u_error == 0 && u.u_eosys != RESTARTSYS)
X u.u_error = EINTR;
X } else {
X u.u_eosys = NORMALRETURN;
X #ifdef SYSCALLTRACE
X if (syscalltrace) {
X
X--- 239,248 -----
X if (u.u_error == 0 && u.u_eosys != RESTARTSYS)
X u.u_error = EINTR;
X } else {
X+ #ifdef REMOTEFS
X+ rmt_syscall = remote_sysmap[ code ];
X+ rmt_called = FALSE;
X+ rmt_cnt = 0;
X u.u_eosys = NORMALRETURN;
X while (! rmt_called) {
X runremote = (rmt_syscall != RSYS_nosys
X***************
X*** 224,229
X u.u_error = EINTR;
X } else {
X u.u_eosys = NORMALRETURN;
X #ifdef SYSCALLTRACE
X if (syscalltrace) {
X register int i;
X
X--- 244,265 -----
X rmt_called = FALSE;
X rmt_cnt = 0;
X u.u_eosys = NORMALRETURN;
X+ while (! rmt_called) {
X+ runremote = (rmt_syscall != RSYS_nosys
X+ && u.u_procp->p_flag & SREMOTE);
X+ if (runremote)
X+ rmt_called = remote_startup(rmt_cnt,
X+ rmt_syscall);
X+ if (! rmt_called) {
X+ (*callp->sy_call)();
X+ if (u.u_error != EISREMOTE)
X+ rmt_called = TRUE;
X+ else
X+ rmt_cnt++;
X+ }
X+ }
X+ #else REMOTEFS
X+ u.u_eosys = NORMALRETURN;
X #ifdef SYSCALLTRACE
X if (syscalltrace) {
X register int i;
X***************
X*** 244,249
X }
X #endif
X (*(callp->sy_call))();
X }
X if (u.u_eosys == NORMALRETURN) {
X if (u.u_error) {
X
X--- 280,286 -----
X }
X #endif
X (*(callp->sy_call))();
X+ #endif REMOTEFS
X }
X if (u.u_eosys == NORMALRETURN) {
X if (u.u_error) {
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/machine/trap.c.diff
#
# remote/usr.sys.VAX4.3/sys/init_sysent.c.diff
#
if [ -f remote/usr.sys.VAX4.3/sys/init_sysent.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/init_sysent.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/sys/init_sysent.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/init_sysent.c.diff
XThese two changes add in the new RFS systems calls, remoteon(), remoteoff()
Xand remotename(). If the second hunk fails, then you have some system
Xcall numbers that are not in standard 4.2BSD.
X***************
X*** 95,100
X #define compat(n, name) 0, nosys
X #endif
X
X /* BEGIN JUNK */
X #ifdef vax
X int resuba();
X
X--- 95,108 -----
X #define compat(n, name) 0, nosys
X #endif
X
X+ #ifdef REMOTEFS
X+ /*
X+ * remote file sys stuff (toddb at du)
X+ */
X+ int remoteon(), /* remote file sys stuff */
X+ remoteoff(),
X+ remotename();
X+ #endif REMOTEFS
X /* BEGIN JUNK */
X #ifdef vax
X int resuba();
X***************
X*** 269,274
X 2, setquota, /* 148 = quota */
X 4, qquota, /* 149 = qquota */
X 3, getsockname, /* 150 = getsockname */
X 0, nosys, /* 151 = nosys */
X 0, nosys, /* 152 = nosys */
X 0, nosys, /* 153 = nosys */
X
X--- 277,287 -----
X 2, setquota, /* 148 = quota */
X 4, qquota, /* 149 = qquota */
X 3, getsockname, /* 150 = getsockname */
X+ #ifdef REMOTEFS
X+ 4, remoteon, /* 151 = remoteon */
X+ 1, remoteoff, /* 152 = remoteoff */
X+ 4, remotename, /* 153 = remotename */
X+ #else REMOTEFS
X 0, nosys, /* 151 = nosys */
X 0, nosys, /* 152 = nosys */
X 0, nosys, /* 153 = nosys */
X***************
X*** 272,277
X 0, nosys, /* 151 = nosys */
X 0, nosys, /* 152 = nosys */
X 0, nosys, /* 153 = nosys */
X 0, nosys, /* 154 = nosys */
X };
X int nsysent = sizeof (sysent) / sizeof (sysent[0]);
X
X--- 285,291 -----
X 0, nosys, /* 151 = nosys */
X 0, nosys, /* 152 = nosys */
X 0, nosys, /* 153 = nosys */
X+ #endif REMOTEFS
X 0, nosys, /* 154 = nosys */
X };
X int nsysent = sizeof (sysent) / sizeof (sysent[0]);
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/sys/init_sysent.c.diff
#
# remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
#
if [ -f remote/usr.sys.VAX4.3/sys/kern_exec.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/kern_exec.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
XThe following changes implement local execution of an object file that
Xlives on another host.
X***************
X*** 27,32
X #include "acct.h"
X #include "exec.h"
X
X #ifdef vax
X #include "../vax/mtpr.h"
X #endif
X
X--- 27,36 -----
X #include "acct.h"
X #include "exec.h"
X
X+ #ifdef REMOTEFS
X+ #include "../h/errno.h"
X+ #endif REMOTEFS
X+
X #ifdef vax
X #include "../vax/mtpr.h"
X #endif
X***************
X*** 55,61
X int na, ne, ucp, ap, len, cc;
X int indir, uid, gid;
X char *sharg;
X! struct inode *ip;
X swblk_t bno;
X char cfname[MAXCOMLEN + 1];
X #define SHSIZE 32
X
X--- 59,70 -----
X int na, ne, ucp, ap, len, cc;
X int indir, uid, gid;
X char *sharg;
X! #ifdef REMOTEFS
X! struct inode *ip; /* have to take address */
X! int remote = -1;
X! #else REMOTEFS
X! register struct inode *ip;
X! #endif REMOTEFS
X swblk_t bno;
X char cfname[MAXCOMLEN + 1];
X #define SHSIZE 32
X***************
X*** 71,76
X ndp->ni_segflg = UIO_USERSPACE;
X ndp->ni_dirp = ((struct execa *)u.u_ap)->fname;
X if ((ip = namei(ndp)) == NULL)
X return;
X bno = 0;
X bp = 0;
X
X--- 80,91 -----
X ndp->ni_segflg = UIO_USERSPACE;
X ndp->ni_dirp = ((struct execa *)u.u_ap)->fname;
X if ((ip = namei(ndp)) == NULL)
X+ #ifdef REMOTEFS
X+ if (u.u_error == EISREMOTE)
X+ remote = remote_execinfo(&ip, &uid, &gid,
X+ &exdata, ((struct execa *)u.u_ap)->fname);
X+ if (u.u_error)
X+ #endif REMOTEFS
X return;
X bno = 0;
X bp = 0;
X***************
X*** 75,80
X bno = 0;
X bp = 0;
X indir = 0;
X uid = u.u_uid;
X gid = u.u_gid;
X if (ip->i_mode & ISUID)
X
X--- 90,99 -----
X bno = 0;
X bp = 0;
X indir = 0;
X+
X+ #ifdef REMOTEFS
X+ if (remote < 0) {
X+ #endif REMOTEFS
X uid = u.u_uid;
X gid = u.u_gid;
X if (ip->i_mode & ISUID)
X***************
X*** 112,117
X 0, 1, &resid);
X if (u.u_error)
X goto bad;
X #ifndef lint
X if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
X exdata.ex_shell[0] != '#') {
X
X--- 131,145 -----
X 0, 1, &resid);
X if (u.u_error)
X goto bad;
X+ #ifdef REMOTEFS
X+ }
X+ else
X+ resid = 0;
X+
X+ remote_again:
X+
X+ #endif REMOTEFS
X+
X #ifndef lint
X if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
X exdata.ex_shell[0] != '#') {
X***************
X*** 170,176
X bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
X }
X indir = 1;
X! iput(ip);
X ndp->ni_nameiop = LOOKUP | FOLLOW;
X ndp->ni_segflg = UIO_SYSSPACE;
X ip = namei(ndp);
X
X--- 198,207 -----
X bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE);
X }
X indir = 1;
X! #ifdef REMOTEFS
X! if (remote < 0)
X! #endif REMOTEFS
X! iput(ip);
X ndp->ni_nameiop = LOOKUP | FOLLOW;
X ndp->ni_segflg = UIO_SYSSPACE;
X ip = namei(ndp);
X***************
X*** 174,179
X ndp->ni_nameiop = LOOKUP | FOLLOW;
X ndp->ni_segflg = UIO_SYSSPACE;
X ip = namei(ndp);
X if (ip == NULL)
X return;
X bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
X
X--- 205,222 -----
X ndp->ni_nameiop = LOOKUP | FOLLOW;
X ndp->ni_segflg = UIO_SYSSPACE;
X ip = namei(ndp);
X+ #ifdef REMOTEFS
X+ if (ip == NULL) {
X+ if (u.u_error == EISREMOTE)
X+ remote = remote_execinfo(&ip, 0, 0, 0);
X+ if (u.u_error)
X+ return;
X+ if (ip == NULL)
X+ goto remote_again;
X+ }
X+ else
X+ remote = -1;
X+ #else REMOTEFS
X if (ip == NULL)
X return;
X #endif REMOTEFS
X***************
X*** 176,181
X ip = namei(ndp);
X if (ip == NULL)
X return;
X bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
X MAXCOMLEN);
X cfname[MAXCOMLEN] = '\0';
X
X--- 219,225 -----
X #else REMOTEFS
X if (ip == NULL)
X return;
X+ #endif REMOTEFS
X bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
X MAXCOMLEN);
X cfname[MAXCOMLEN] = '\0';
X***************
X*** 268,274
X bdwrite(bp);
X bp = 0;
X nc = (nc + NBPW-1) & ~(NBPW-1);
X! getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid);
X if (u.u_error) {
X badarg:
X for (cc = 0; cc < nc; cc += CLSIZE*NBPG) {
X
X--- 312,324 -----
X bdwrite(bp);
X bp = 0;
X nc = (nc + NBPW-1) & ~(NBPW-1);
X!
X! #ifdef REMOTEFS
X! getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid, remote);
X! #else REMOTEFS
X! getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid);
X! #endif REMOTEFS
X!
X if (u.u_error) {
X badarg:
X for (cc = 0; cc < nc; cc += CLSIZE*NBPG) {
X***************
X*** 376,381
X /*
X * Read in and set up memory for executed file.
X */
X getxfile(ip, ep, nargc, uid, gid)
X register struct inode *ip;
X register struct exec *ep;
X
X--- 426,434 -----
X /*
X * Read in and set up memory for executed file.
X */
X+ #ifdef REMOTEFS
X+ getxfile(ip, ep, nargc, uid, gid, remote)
X+ #else REMOTEFS
X getxfile(ip, ep, nargc, uid, gid)
X #endif REMOTEFS
X register struct inode *ip;
X***************
X*** 377,382
X * Read in and set up memory for executed file.
X */
X getxfile(ip, ep, nargc, uid, gid)
X register struct inode *ip;
X register struct exec *ep;
X int nargc, uid, gid;
X
X--- 430,436 -----
X getxfile(ip, ep, nargc, uid, gid, remote)
X #else REMOTEFS
X getxfile(ip, ep, nargc, uid, gid)
X+ #endif REMOTEFS
X register struct inode *ip;
X register struct exec *ep;
X int nargc, uid, gid;
X***************
X*** 383,388
X {
X size_t ts, ds, ids, uds, ss;
X int pagi;
X
X if (ep->a_magic == 0413)
X pagi = SPAGI;
X
X--- 437,445 -----
X {
X size_t ts, ds, ids, uds, ss;
X int pagi;
X+ #ifdef REMOTEFS
X+ int oldtextsize;
X+ #endif REMOTEFS
X
X if (ep->a_magic == 0413)
X pagi = SPAGI;
X***************
X*** 388,393
X pagi = SPAGI;
X else
X pagi = 0;
X if (ip->i_flag & IXMOD) { /* XXX */
X u.u_error = ETXTBSY;
X goto bad;
X
X--- 445,461 -----
X pagi = SPAGI;
X else
X pagi = 0;
X+ #ifdef REMOTEFS
X+ if (remote >= 0) {
X+ /*
X+ * Prevent xalloc() from making a shared or paged text.
X+ */
X+ pagi = 0;
X+ oldtextsize = ep->a_text;
X+ ep->a_data += ep->a_text;
X+ ep->a_text = 0;
X+ }
X+ #endif REMOTEFS
X if (ip->i_flag & IXMOD) { /* XXX */
X u.u_error = ETXTBSY;
X goto bad;
X***************
X*** 452,457
X u.u_smap = u.u_csmap;
X vgetvm(ts, ds, ss);
X
X if (pagi == 0)
X u.u_error =
X rdwri(UIO_READ, ip,
X
X--- 520,530 -----
X u.u_smap = u.u_csmap;
X vgetvm(ts, ds, ss);
X
X+ #ifdef REMOTEFS
X+ if (remote >= 0)
X+ u.u_error = remote_execread(remote, oldtextsize, ep);
X+ else
X+ #endif REMOTEFS
X if (pagi == 0)
X u.u_error =
X rdwri(UIO_READ, ip,
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/sys/kern_exec.c.diff
#
# remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
#
if [ -f remote/usr.sys.VAX4.3/sys/kern_exit.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/kern_exit.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
XThe following changes ensure that upon exit, a process notifies any remote
Xservers that may know about him, that he is indeed dead.
X***************
X*** 23,28
X #include "mbuf.h"
X #include "inode.h"
X #include "syslog.h"
X
X /*
X * Exit system call: pass back caller's arg
X
X--- 23,31 -----
X #include "mbuf.h"
X #include "inode.h"
X #include "syslog.h"
X+ #ifdef REMOTEFS
X+ #include "../remote/remotefs.h"
X+ #endif REMOTEFS
X
X /*
X * Exit system call: pass back caller's arg
X***************
X*** 56,61
X vmsizmon();
X #endif
X p = u.u_procp;
X p->p_flag &= ~(STRC|SULOCK);
X p->p_flag |= SWEXIT;
X p->p_sigignore = ~0;
X
X--- 59,71 -----
X vmsizmon();
X #endif
X p = u.u_procp;
X+ #ifdef REMOTEFS
X+ /*
X+ * First, release our server.
X+ */
X+ if (p->p_flag & SREMOTE)
X+ remote_exit();
X+ #endif REMOTEFS
X p->p_flag &= ~(STRC|SULOCK);
X p->p_flag |= SWEXIT;
X p->p_sigignore = ~0;
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/sys/kern_exit.c.diff
#
# remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
#
if [ -f remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
XThese changes are the primary hook into the operating system for detecting
Xa "remote" file.
X***************
X*** 149,154
X int isdotdot; /* != 0 if current name is ".." */
X int flag; /* op ie, LOOKUP, CREATE, or DELETE */
X off_t enduseful; /* pointer past last used dir slot */
X
X lockparent = ndp->ni_nameiop & LOCKPARENT;
X docache = (ndp->ni_nameiop & NOCACHE) ^ NOCACHE;
X
X--- 149,157 -----
X int isdotdot; /* != 0 if current name is ".." */
X int flag; /* op ie, LOOKUP, CREATE, or DELETE */
X off_t enduseful; /* pointer past last used dir slot */
X+ #ifdef REMOTEFS
X+ int remote;
X+ #endif
X
X lockparent = ndp->ni_nameiop & LOCKPARENT;
X docache = (ndp->ni_nameiop & NOCACHE) ^ NOCACHE;
X***************
X*** 202,207
X * Check accessiblity of directory.
X */
X if ((dp->i_mode&IFMT) != IFDIR) {
X u.u_error = ENOTDIR;
X goto bad;
X }
X
X--- 205,226 -----
X * Check accessiblity of directory.
X */
X if ((dp->i_mode&IFMT) != IFDIR) {
X+ #ifdef REMOTEFS
X+ remote = isremote(dp, cp, nbp->b_un.b_addr);
X+ /*
X+ * If it is really local, then start again at the root.
X+ */
X+ if (remote < 0) {
X+ iput(dp);
X+ dp = rootdir;
X+ ILOCK(dp);
X+ dp->i_count++;
X+ fs = dp->i_fs;
X+ cp = nbp->b_un.b_addr;
X+ goto dirloop2;
X+ }
X+ else if (! remote)
X+ #endif REMOTEFS
X u.u_error = ENOTDIR;
X goto bad;
X }
X***************
X*** 642,647
X u.u_error = EPERM;
X goto bad;
X }
X }
X }
X nbp->av_forw = freenamebuf;
X
X--- 661,677 -----
X u.u_error = EPERM;
X goto bad;
X }
X+ #ifdef REMOTEFS
X+ /*
X+ * don't allow anyone to remove a remote mount
X+ * point.
X+ */
X+ if (rmt_host(dp, &i)) {
X+ iput(ndp->ni_pdir);
X+ u.u_error = EBUSY;
X+ goto bad;
X+ }
X+ #endif REMOTEFS
X }
X }
X nbp->av_forw = freenamebuf;
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/sys/ufs_namei.c.diff
#
# remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
#
if [ -f remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff or ^C to quit'
read ans
rm -f remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
XThese changes modify chdirec(), which is called by chroot() and chdir(),
Xso that you can be allowed to do a chdir() to a remote mount point.
XIn addition, the changes ensure that we adjust internal pointers when doing
Xa chdir() OUT of a remote mount point.
X
X***************
X*** 51,56
X chdirec(ipp)
X register struct inode **ipp;
X {
X register struct inode *ip;
X struct a {
X char *fname;
X
X--- 51,59 -----
X chdirec(ipp)
X register struct inode **ipp;
X {
X+ #ifdef REMOTEFS
X+ int i;
X+ #endif REMOTEFS
X register struct inode *ip;
X struct a {
X char *fname;
X***************
X*** 64,69
X if (ip == NULL)
X return;
X if ((ip->i_mode&IFMT) != IFDIR) {
X u.u_error = ENOTDIR;
X goto bad;
X }
X
X--- 67,77 -----
X if (ip == NULL)
X return;
X if ((ip->i_mode&IFMT) != IFDIR) {
X+ #ifdef REMOTEFS
X+ if (rmt_hostdir(ip, &i) != NULL)
X+ u.u_error = remotechdir(i);
X+ else
X+ #endif REMOTEFS
X u.u_error = ENOTDIR;
X goto bad;
X }
X***************
X*** 69,74
X }
X if (access(ip, IEXEC))
X goto bad;
X IUNLOCK(ip);
X if (*ipp)
X irele(*ipp);
X
X--- 77,85 -----
X }
X if (access(ip, IEXEC))
X goto bad;
X+ #ifdef REMOTEFS
X+ remotechdir(-1);
X+ #endif REMOTEFS
X IUNLOCK(ip);
X if (*ipp)
X irele(*ipp);
SHAREOF
chmod 664 remote/usr.sys.VAX4.3/sys/ufs_syscalls.c.diff
#
# remote/usr.sys.remote/remote_mkdata
#
if [ -f remote/usr.sys.remote/remote_mkdata ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/remote_mkdata or ^C to quit'
read ans
rm -f remote/usr.sys.remote/remote_mkdata
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/remote_mkdata
X#!/bin/sh
X#
X# Copyright 1985, Todd Brunhoff.
X#
X# This software was written at Tektronix Computer Research Laboratories
X# as partial fulfillment of a Master's degree at the University of Denver.
X# This software is not Tektronix proprietary software and should not be
X# confused with any software product sold by Tektronix. No warranty is
X# expressed or implied on the reliability of this software; the author,
X# the University of Denver, and Tektronix, inc. accept no liability for
X# any damage done directly or indirectly by this software. This software
X# may be copied, modified or used in any way, without fee, provided this
X# comment remains an unaltered part of the software.
X#
X
Xif [ ! -f "$1" ]
Xthen
X echo "Usage:"
X echo " /lib/cpp -DKERNEL ... ..../init_sysent.c | $0 ..../remotefs.h"
X exit 1
Xfi
X
XREMOTE=$1
X
X#
X# First, get the complete list of remote system calls and put them
X# into memory for awk.
X#
XMEM=`sed -e '/^#define[ ]*RSYS_/!d' \
X -e 's/.*RSYS_\([^ ]*\) \([0-9]*\)$/mem[\2]="\1";last=\2;/' \
X < $REMOTE`
X#
X# Then, compile a list of all system calls from a cpp expanded listing
X# of sys/init_sysent.c which should be on standard input.
X# The only kludge here is that we must change internal names for system
X# calls:
X# internal changed
X# name to
X# ---------- ----------
X# rexit exit
X# saccess access
X#
Xsed -e '1,/^struct[ ]*sysent[ ]*sysent[ ]*\[\]/d' \
X -e '/^};/,$d' \
X -e '/^#/d' \
X -e 's/ *[0-9], *//' \
X -e 's/,.*//' \
X -e 's/^rexit$/exit/' \
X -e 's/^saccess$/access/' \
X -e '/^[ ]*$/d' \
X| tail +2 \
X| cat -n \
X| awk '
XBEGIN {
X '"$MEM"'
X syscall = 0;
X column = 0;
X printf "u_char\tremote_sysmap[] = {\n"
X}
X{
X while (syscall < $1) {
X if (column % 2 == 0)
X printf "\t"
X printf "%-31s", "RSYS_nosys,"
X if (column % 2 == 1)
X printf "\n"
X syscall++
X column++
X }
X
X if (column % 2 == 0)
X printf "\t"
X len = length($2);
X found = 0;
X for (i=0; i <= last; i++) {
X if (mem[ i ] == $2) {
X found = 1;
X break;
X }
X }
X if (found) {
X printf "RSYS_%s,", $2
X len = 25-len;
X }
X else {
X printf "RSYS_nosys, /* %s */", $2
X len = 12 - len;
X }
X if (column % 2 == 1)
X printf "\n"
X else
X while (len-- > 0)
X printf " "
X column++;
X syscall++
X} END {
X if (column % 2 == 0)
X printf "\n"
X printf "};\n"
X}'
SHAREOF
chmod 664 remote/usr.sys.remote/remote_mkdata
#
# remote/usr.sys.remote/remotefs.h
#
if [ -f remote/usr.sys.remote/remotefs.h ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/remotefs.h or ^C to quit'
read ans
rm -f remote/usr.sys.remote/remotefs.h
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/remotefs.h
X/*
X * Copyright 1985, Todd Brunhoff.
X *
X * This software was written at Tektronix Computer Research Laboratories
X * as partial fulfillment of a Master's degree at the University of Denver.
X * This is not Tektronix proprietary software and should not be
X * confused with any software product sold by Tektronix. No warranty is
X * expressed or implied on the reliability of this software; the author,
X * the University of Denver, and Tektronix, inc. accept no liability for
X * any damage done directly or indirectly by this software. This software
X * may be copied, modified or used in any way, without fee, provided this
X * notice remains an unaltered part of the software.
X *
X * $Header: remotefs.h,v 2.2 86/01/25 20:46:02 toddb Exp $
X *
X * $Log: remotefs.h,v $
X * Revision 2.2 86/01/25 20:46:02 toddb
X * Changed constant for FREMOTE from 08000 (octal???!!!) to 010000.
X * Luckily pcc interpreted it as 010000.
X *
X * Revision 2.1 86/01/05 18:17:01 toddb
X * Added ifdef'ed constants for pyramids: FREMOTE, SREMOTE and SNOREMOTE.
X *
X * Revision 2.0 85/12/07 18:17:35 toddb
X * First public release.
X *
X */
X#ifndef RFSDEBUG
X#define debug0()
X#define debug1()
X#define debug2()
X#define debug3()
X#define debug4()
X#define debug5()
X#define debug6()
X#define debug7()
X#define debug8()
X#define debug9()
X#define debug10()
X#define debug11()
X#define debug12()
X#define debug13()
X#define debug14()
X#define rmt_showmsg()
X#else RFSDEBUG
X/*
X * Each of the debugging macros are defined here. With this scheme we
X * are able to turn on any portion of the debugging with very little overhead
X * This appears to be better than similar schemes that test if
X * remote_debug <= some-level, because they force the software into having
X * more and more debug software run as the number gets higher.
X */
Xextern long remote_debug;
X
X#define debug0 (!(remote_debug&0x00001)) ? 0:rmt_debug /* exec info */
X#define debug1 (!(remote_debug&0x00002)) ? 0:rmt_debug /* startup activity */
X#define debug2 (!(remote_debug&0x00004)) ? 0:rmt_debug /* rmt_copypath() */
X#define debug3 (!(remote_debug&0x00008)) ? 0:rmt_debug /* unused */
X#define debug4 (!(remote_debug&0x00010)) ? 0:rmt_debug /* remote_fork */
X#define debug5 (!(remote_debug&0x00020)) ? 0:rmt_debug /* remote[on|off] */
X#define debug6 (!(remote_debug&0x00040)) ? 0:rmt_debug /* file descriptors */
X#define debug7 (!(remote_debug&0x00080)) ? 0:rmt_debug /* isremote() */
X#define debug8 (!(remote_debug&0x00100)) ? 0:rmt_debug /* file remoteness */
X#define debug9 (!(remote_debug&0x00200)) ? 0:rmt_debug /* connection startup */
X#define debug10 (!(remote_debug&0x00400)) ? 0:rmt_debug /* msg setup */
X#define debug11 (!(remote_debug&0x00800)) ? 0:rmt_debug /* msg exceptions */
X#define debug12 (!(remote_debug&0x01000)) ? 0:rmt_debug /* shutdowns */
X#define debug13 (!(remote_debug&0x02000)) ? 0:rmt_debug /* path translation */
X#define debug14 (!(remote_debug&0x04000)) ? 0:rmt_debug /* chdir() activity */
X#define debug15 (!(remote_debug&0x08000)) ? 0:rmt_debug /* msg content */
X#define debug16 (!(remote_debug&0x10000)) ? 0:rmt_debug /* msg data content */
X#define debug17 (!(remote_debug&0x20000)) ? 0:rmt_debug /* unused */
X#define debug18 (!(remote_debug&0x40000)) ? 0:rmt_debug /* unused */
X#define debug19 (!(remote_debug&0x80000)) ? 0:rmt_debug /* unused */
X
X#endif RFSDEBUG
X
X/*
X * Flags for file structures and proc structures. These should really be
X * in file.h and proc.h, but are here for now. Note that you must have
X * the fix in ino_close() if DTYPE_REMOTE is defined as 3.
X */
X#define DTYPE_REMOTE 3 /* file.h: remote file descriptor */
X#ifdef pyr
X#define SREMOTE 0x00080000 /* proc.h: activity has occured */
X#define SNOREMOTE 0x80000000 /* proc.h: disallow remote access */
X#define FREMOTE 04000 /* file.h: this is a remote file */
X#endif pyr
X#if vax || magnolia || P4400
X#define SREMOTE 0x08000000 /* proc.h: activity has occured */
X#define SNOREMOTE 0x10000000 /* proc.h: disallow remote access */
X#define FREMOTE 010000 /* file.h: this is a remote file */
X#endif vax || magnolia || P4400
X
X/*
X * Defines for the name server.
X */
X#define server_alive(p) \
X ((p) \
X && (p)->p_stat != NULL \
X && remote_ns.rn_pid == (p)->p_pid)
X
X#define NM_SERVER 0 /* register as name server */
X#define NM_WHATNAME 1 /* what name does the kernel need? */
X#define NM_NAMEIS 2 /* the name is... */
X#define NM_DEBUG 3 /* turn on debugging */
X
X/*
X * Some manifest constants.
X */
X#define TRUE 1
X#define FALSE 0
X#define REMOTE_FS_SERVER "remotefs"
X#define R_MAXSYS NREMOTE /* defined in param.h */
X#define R_MNTPATHLEN 30
X#define R_MAXMSG ((MAXPATHLEN * 2) + MLEN)
X#define R_RETRY (60*5) /* retry time for connections */
X
X/*
X * State of the data being sent.
X */
X#define R_NOTHINGSENT 1
X#define R_DATANOTSENT 2
X#define R_MSGNOTRED 3
X#define R_DATANOTRED 4
X
X/*
X * internal flags passed to rmt_msgfin() and rmt_datafin().
X */
X#define RFLG_DATAV 0x1 /* data to remotemsg() is a vector */
X#define RFLG_RD 0x2 /* data to remotemsg() to be read */
X#define RFLG_WR 0x4 /* data to remotemsg() to be written */
X#define RFLG_INFO 0x8 /* send message only (don't receive */
X
X/*
X * known indices of data in the message.
X */
X#define R_PATHOFF 3 /* to server (Offset to 2nd path) */
X#define R_PATHSTART 4 /* to server start of actual path */
X#define R_DATA 2 /* to server */
X#define R_RETVAL 0 /* from server */
X#define R_EXECUID 1 /* from server (exec setuid) */
X#define R_EXECGID 2 /* from server (exec setgid) */
X#define R_EXECREADONLY 3 /* from server (exec text read-only) */
X#define R_EXECDATA 4 /* from server (start of exec info) */
X
X/*
X * Maximum size for the message arg data in long words. NOT LONGWORDS!! This
X * should be the largest of the following three sizes among all machines
X * that will use the remote file system:
X *
X * sizeof(struct exec) * sizeof(long) + R_EXECDATA * sizeof(long)
X * (# of stat struct members + 1) * sizeof(long)
X */
X#define R_MAXARGS 18
X
X/*
X * Maximum and minimum message length in bytes that we will ever need on a
X * receive (big enough for a stat(), lstat() or fstat(), and small enough for
X * a return with no other values.
X */
X#define R_MINRMSG (sizeof(struct message)-R_MAXARGS*sizeof(long))
X#define R_MAXRMSG (sizeof(struct message))
X
X/*
X * The maximum number of mbufs that we need to send a message with
X * two paths, each 1024 characters long. This is used only in the user
X * level implementation.
X */
X#define R_MAXMBUFS (R_MINRMSG+(MAXPATHLEN*2))/MLEN
X
X/*
X * Here, we describe incomming and outgoing messages. Note that the number
X * of cells in m_args is only for incomming messages. An outgoing message
X * may consume much more.
X */
Xstruct message {
X long m_totlen; /* length of total message (including data) */
X short m_uid; /* uid of client */
X short m_pid; /* pid of client */
X short m_hdlen; /* length of header (excluding data) */
X short m_syscall; /* syscall number */
X#define m_errno m_syscall /* errno (for server) */
X long m_args[R_MAXARGS];/* remaining arguments or return values */
X};
X
X/*
X * This structure describes the kernel information kept for each
X * connection to a remote server.
X */
Xstruct remoteinfo {
X char r_mntpath[ R_MNTPATHLEN ]; /* path of mount point */
X u_char r_close:1; /* True if connection to be closed */
X u_char r_received:1; /* True if an incomming msg in r_msg */
X u_char r_failed:1; /* connection failed */
X u_char r_opening:1; /* connection in process of opening */
X u_char r_refcnt; /* a reference count of active use */
X short r_sender; /* owner of outgoing data */
X short r_recver; /* owner of incomming data */
X u_short r_users; /* count of users using this */
X u_short r_nfile; /* count of open files */
X u_short r_nchdir; /* count of chdir() to this host */
X struct mbuf *r_name; /* socket address of remote host */
X struct inode *r_mntpt; /* inode of mount point */
X /* if null, then global */
X struct socket *r_sock; /* socket with active connection */
X#define r_age r_msg.m_totlen /* used for cacheing name lookups */
X#define r_openerr r_msg.m_errno /* used to relay connection errors */
X struct message r_msg; /* incomming message */
X};
X
Xtypedef int (*func)();
X
X/*
X * This describes all info associated with each syscall. Note that while
X * the flag information is available, most syscalls don't reference it
X * because they have the flag hard coded in-line. It exists for the
X * sake of routines like read and write which cannot hard code the flags
X * very easily. The follow flag is useful only for system calls that involve
X * pathnames. The before entry is to tell syscall whether to try to
X * call the remote syscall routine before calling the real system call.
X * The size here make each table entry a
X * power of 2 in size (16 bytes) which the compiler can make faster code for.
X */
Xstruct syscalls {
X func sys_gen;
X func sys_spec;
X long sys_flag;
X short sys_follow;
X short sys_before;
X};
Xtypedef struct syscalls syscalls;
X
X/*
X * This structure simply describes the process willing to act as a
X * name server for the remote file system, and the information passing
X * to and from it.
X */
Xstruct nameserver {
X struct proc *rn_proc; /* process registered as nameserver */
X struct mbuf *rn_name; /* input from name server */
X char *rn_path; /* path to translate */
X short rn_pathlen; /* length of path to translate */
X short rn_pid; /* pid of process (for uniqueness) */
X};
X
X/*
X * System calls
X * Note that these have nothing to do with either the vax or magnolia idea
X * of the system calls. They are simply an index into the systems calls
X * that we are concerned with.
X */
X#define RSYS_fork 0
X#define RSYS_read 1
X#define RSYS_write 2
X#define RSYS_open 3
X#define RSYS_close 4
X#define RSYS_creat 5
X#define RSYS_link 6
X#define RSYS_unlink 7
X#define RSYS_chdir 8
X#define RSYS_mknod 9
X#define RSYS_chmod 10
X#define RSYS_chown 11
X#define RSYS_stat 12
X#define RSYS_lseek 13
X#define RSYS_access 14
X#define RSYS_lstat 15
X#define RSYS_dup 16
X#define RSYS_ioctl 17
X#define RSYS_symlink 18
X#define RSYS_readlink 19
X#define RSYS_fstat 20
X#define RSYS_dup2 21
X#define RSYS_fcntl 22
X#define RSYS_fsync 23
X#define RSYS_readv 24
X#define RSYS_writev 25
X#define RSYS_fchown 26
X#define RSYS_fchmod 27
X#define RSYS_rename 28
X#define RSYS_truncate 29
X#define RSYS_ftruncate 30
X#define RSYS_flock 31
X#define RSYS_mkdir 32
X#define RSYS_rmdir 33
X#define RSYS_utimes 34
X#define RSYS_exit 35
X#define RSYS_vfork 36
X#define RSYS_execinfo 37
X#define RSYS_execread 38
X#define RSYS_execve 39
X#define RSYS_nosys 40
X#define RSYS_qlseek 41
X
X/*
X * This macro fills in some of the information needed on every transfer
X * and returns the byte (not longword) offset of the next free byte.
X */
X#define introduce(buf, sysnum) \
X ((buf)->m_pid = htons(u.u_procp->p_pid),\
X (buf)->m_uid = htons(u.u_uid), \
X (buf)->m_syscall = htons(sysnum), \
X (R_MINRMSG))
X#define introduce_1extra(buf, sysnum, x1) \
X ((buf)->m_pid = htons(u.u_procp->p_pid),\
X (buf)->m_uid = htons(u.u_uid), \
X (buf)->m_syscall = htons(sysnum), \
X (buf)->m_args[0] = htonl(x1), \
X (R_MINRMSG + sizeof(long)))
X#define introduce_2extra(buf, sysnum, x1, x2) \
X ((buf)->m_pid = htons(u.u_procp->p_pid),\
X (buf)->m_uid = htons(u.u_uid), \
X (buf)->m_syscall = htons(sysnum), \
X (buf)->m_args[0] = htonl(x1), \
X (buf)->m_args[1] = htonl(x2), \
X (R_MINRMSG + 2*sizeof(long)))
X/*
X * This macro defines whether a host is being used or not.
X * The rmtclearhosts() and rmtcopyhosts() are for expansion if someone
X * wants to use more than 32 hosts.
X */
X#define rmthostused(rsys) (u.u_rmtsys & (1<<rsys))
X#define rmtusehost(rsys) (u.u_rmtsys |= (1<<rsys))
X#define rmtunusehost(rsys) (u.u_rmtsys &= ~(1<<rsys))
X#define rmtclearhosts() (u.u_rmtsys = 0)
X#define rmtcopyhosts(dest,hosts) (dest = hosts)
X
X#ifdef pyr
X/*
X * Pyramid changed the name on ctob and btoc
X **/
X#define ctob(x) ptob(x)
X#define btoc(x) btop(x)
X#endif
SHAREOF
chmod 444 remote/usr.sys.remote/remotefs.h
#
# remote/usr.sys.remote/rmt_data_template
#
if [ -f remote/usr.sys.remote/rmt_data_template ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_data_template or ^C to quit'
read ans
rm -f remote/usr.sys.remote/rmt_data_template
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_data_template
X/*
X * Copyright 1985, Todd Brunhoff.
X *
X * This software was written at Tektronix Computer Research Laboratories
X * as partial fulfillment of a Master's degree at the University of Denver.
X * This is not Tektronix proprietary software and should not be
X * confused with any software product sold by Tektronix. No warranty is
X * expressed or implied on the reliability of this software; the author,
X * the University of Denver, and Tektronix, inc. accept no liability for
X * any damage done directly or indirectly by this software. This software
X * may be copied, modified or used in any way, without fee, provided this
X * notice remains an unaltered part of the software.
X *
X * $Header: rmt_data_template,v 2.0 85/12/07 18:19:42 toddb Rel $
X *
X * $Log: rmt_data_template,v $
X * Revision 2.0 85/12/07 18:19:42 toddb
X * First public release.
X *
X */
X#include "../h/errno.h"
X#include "../h/param.h"
X#include "../h/mbuf.h"
X#include "../h/socket.h"
X#include "../remote/remotefs.h"
X
X
Xextern int
X rmt_access(),
X rmt_chdir(),
X rmt_chmod(),
X rmt_chown(),
X rmt_dup(),
X rmt_dup2(),
X rmt_error(),
X remote_exit(),
X rmt_fcntl(),
X rmt_flock(),
X remote_fork(),
X rmt_fsync(),
X rmt_ioctl(),
X rmt_lseek(),
X rmt_mknod(),
X rmt_noop(),
X rmt_onearg(),
X rmt_open(),
X rmt_readlink(),
X rmt_stat(),
X rmt_truncate(),
X rmt_utimes(),
X rmt_execinfo(),
X rmt_execread(),
X rmt_execve(),
X remote_fd(),
X remote_path1(),
X remote_path2(),
X rmt_datafin();
X
X/*
X * This table depends on the order of system calls as defined in
X * sys/sys/init_sysent.c, and our local map in remote_sysmap, which
X * is generated (and appended to this file) by the program mkdata.
X * The latter is a table of indices into remote_syscall[].
X * Remote_syscall[] is a table containing general and specific actions
X * for each system call, whether to follow symbolic links in namei and
X * flags that are passed to rmt_msgfin() and rmt_datafin().
X */
X
Xsyscalls remote_syscall[] = {
X/*
X * general specific flags to follow call before
X * rmt_fin() symlinks real syscall
X */
X{ remote_fork, rmt_noop, RFLG_INFO, FALSE, TRUE }, /* RSYS_fork */
X{ remote_fd, rmt_datafin, RFLG_RD, FALSE, TRUE }, /* RSYS_read */
X{ remote_fd, rmt_datafin, RFLG_WR, FALSE, TRUE }, /* RSYS_write */
X{ remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_open */
X{ remote_fd, rmt_onearg, RFLG_INFO, FALSE, TRUE }, /* RSYS_close */
X{ remote_path1, rmt_open, 0, TRUE, FALSE }, /* RSYS_creat */
X{ remote_path2, rmt_noop, 0, FALSE, FALSE }, /* RSYS_link */
X{ remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_unlink */
X{ remote_path1, rmt_chdir, 0, TRUE, FALSE }, /* RSYS_chdir */
X{ remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mknod */
X{ remote_path1, rmt_chmod, 0, TRUE, FALSE }, /* RSYS_chmod */
X{ remote_path1, rmt_chown, 0, FALSE, FALSE }, /* RSYS_chown */
X{ remote_path1, rmt_stat, 0, TRUE, FALSE }, /* RSYS_stat */
X{ remote_fd, rmt_lseek, 0, FALSE, TRUE }, /* RSYS_lseek */
X{ remote_path1, rmt_access, 0, FALSE, FALSE }, /* RSYS_lstat */
X{ remote_path1, rmt_stat, 0, TRUE, FALSE }, /* RSYS_access */
X{ remote_fd, rmt_dup, 0, FALSE, TRUE }, /* RSYS_dup */
X{ remote_fd, rmt_ioctl, 0, FALSE, TRUE }, /* RSYS_ioctl */
X{ remote_path2, rmt_noop, 0, TRUE, FALSE }, /* RSYS_symlink */
X{ remote_path1, rmt_readlink, RFLG_RD, FALSE, FALSE }, /* RSYS_readlink */
X{ remote_fd, rmt_stat, 0, FALSE, TRUE }, /* RSYS_fstat */
X{ remote_fd, rmt_dup2, 0, FALSE, TRUE }, /* RSYS_dup2 */
X{ remote_fd, rmt_fcntl, 0, FALSE, TRUE }, /* RSYS_fcntl */
X{ remote_fd, rmt_onearg, RFLG_INFO, FALSE, TRUE }, /* RSYS_fsync */
X{ remote_fd, rmt_datafin, RFLG_RD|RFLG_DATAV,
X FALSE, TRUE },/* RSYS_readv */
X{ remote_fd, rmt_datafin, RFLG_WR|RFLG_DATAV,
X FALSE, TRUE },/* RSYS_writev */
X{ remote_fd, rmt_chown, 0, FALSE, TRUE }, /* RSYS_fchown */
X{ remote_fd, rmt_chmod, 0, FALSE, TRUE }, /* RSYS_fchmod */
X{ remote_path2, rmt_noop, 0, TRUE, FALSE }, /* RSYS_rename */
X{ remote_path1, rmt_truncate, 0, TRUE, FALSE }, /* RSYS_truncate */
X{ remote_fd, rmt_truncate, 0, FALSE, TRUE }, /* RSYS_ftruncate */
X{ remote_fd, rmt_flock, 0, FALSE, TRUE }, /* RSYS_flock */
X{ remote_path1, rmt_mknod, 0, FALSE, FALSE }, /* RSYS_mkdir */
X{ remote_path1, rmt_onearg, 0, FALSE, FALSE }, /* RSYS_rmdir */
X{ remote_path1, rmt_noop, 0, TRUE, FALSE }, /* RSYS_utimes */
X{ remote_exit, rmt_noop, RFLG_INFO,FALSE, TRUE }, /* RSYS_exit */
X{ remote_fork, rmt_noop, RFLG_INFO, FALSE, TRUE }, /* RSYS_vfork */
X{ remote_path1, rmt_execinfo, 0, TRUE, FALSE }, /* RSYS_execinfo */
X{ rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_execread */
X{ remote_path1, rmt_error, 0, TRUE, FALSE }, /* RSYS_execve */
X{ rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_nosys */
X{ rmt_error, rmt_noop, 0, FALSE, FALSE }, /* RSYS_qlseek */
X};
X
Xstruct remoteinfo remote_info[ R_MAXSYS ];
Xstruct remoteinfo *remote_generic;
Xlong remote_debug;
Xlong remote_sysindex;
Xlong remote_maxchunk = (1024*10);
Xstruct mbuf *remote_path;
Xstruct nameserver remote_ns;
X
X/*
X * The following list maps all of the actual system call numbers into our
X * idea of the system call numbers. THIS IS GENERATED AUTOMATICALLY...
X * DO NOT MODIFY!
X */
SHAREOF
chmod 444 remote/usr.sys.remote/rmt_data_template
#
# remote/usr.sys.remote/rmt_exec.c
#
if [ -f remote/usr.sys.remote/rmt_exec.c ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_exec.c or ^C to quit'
read ans
rm -f remote/usr.sys.remote/rmt_exec.c
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_exec.c
X/*
X * Copyright 1985, Todd Brunhoff.
X *
X * This software was written at Tektronix Computer Research Laboratories
X * as partial fulfillment of a Master's degree at the University of Denver.
X * This is not Tektronix proprietary software and should not be
X * confused with any software product sold by Tektronix. No warranty is
X * expressed or implied on the reliability of this software; the author,
X * the University of Denver, and Tektronix, inc. accept no liability for
X * any damage done directly or indirectly by this software. This software
X * may be copied, modified or used in any way, without fee, provided this
X * notice remains an unaltered part of the software.
X *
X * $Header: rmt_exec.c,v 2.2 86/03/10 12:23:39 toddb Exp $
X *
X * $Log: rmt_exec.c,v $
X * Revision 2.2 86/03/10 12:23:39 toddb
X * In rmt_exec.c, execinfo gets the file size out of R_RETVAL. The problem
X * is that it does one too many ntohl() calls; rmt_getmsg already has done
X * a byteswap of the message header, including R_RETVAL. The test for
X * filesize larger than datasize+textsize+headersize may then fail if the
X * extra swap operation constructs a negative number. (Dave Johnson at Brown)
X *
X * Revision 2.1 85/12/30 16:45:30 toddb
X * fixed syntax error for 4.3.
X *
X * Revision 2.0 85/12/07 18:17:54 toddb
X * First public release.
X *
X */
X#ifndef pyr /* Pyramid */
X#include "../machine/reg.h"
X#include "../machine/pte.h"
X#include "../machine/psl.h"
X#endif
X
X#include "../h/param.h"
X#include "../h/systm.h"
X#include "../h/map.h"
X#include "../h/dir.h"
X#include "../h/user.h"
X#include "../h/kernel.h"
X#include "../h/proc.h"
X#include "../h/file.h"
X#include "../h/uio.h"
X#include "../remote/remotefs.h"
X#include "../h/mbuf.h"
X#include "../netinet/in.h"
X#include "../h/vm.h"
X#include "../h/errno.h"
X#ifdef BSD4_3
X#include "../h/namei.h"
X#include "../h/exec.h"
X#else BSD4_3
X#include "../h/nami.h"
X#endif BSD4_3
X
X#ifdef vax
X#include "../vax/mtpr.h"
X#endif
X
Xextern struct remoteinfo remote_info[];
Xextern long remote_sysindex;
Xextern long remote_maxchunk;
X
X#ifdef magnolia
X#define DEMAND_PAGED 0513
X#define SHARED_TEXT 0510
X#else magnolia
X#define DEMAND_PAGED 0413
X#define SHARED_TEXT 0410
X#endif magnolia
X
X/*
X * Get execution info for a file that is on a remote system. At this point
X * we know that the file is remote. We must send one request to get the
X * header and then if all is ok, we will be asked for the file to be sent over
X * en-masse.
X */
X#ifdef BSD4_3
Xremote_execinfo(ip, auid, agid, pexdata, fname)
X struct exec *pexdata;
X#else BSD4_3
Xremote_execinfo(ip, auid, agid, fname)
X#endif BSD4_3
X register struct inode **ip;
X long *auid, *agid;
X register char *fname;
X{
X long error,
X sysindex = remote_sysindex,
X uid, gid,
X hdrsize,
X execsize;
X struct inode *namei();
X struct remoteinfo *rp = remote_info + remote_sysindex;
X struct message *msg;
X
X u.u_error = 0;
X error = remote_path1(RSYS_execinfo);
X if (error) {
X /*
X * Try again if its a local file.
X */
X if (error < 0 && fname) {
X#ifdef BSD4_3
X struct nameidata *ndp = &u.u_nd;
X
X ndp->ni_dirp = (caddr_t) fname;
X if ((*ip = namei(ndp)) == NULL)
X#else BSD4_3
X u.u_dirp = (caddr_t) fname;
X if ((*ip = namei(uchar, LOOKUP, 1)) == NULL)
X#endif BSD4_3
X if (u.u_error == 0 || u.u_error == EISREMOTE)
X u.u_error = ELOOP;
X return(remote_sysindex);
X }
X else if (error < 0)
X error = ENOENT;
X u.u_error = error;
X return(-1);
X }
X /*
X * The R_RETVAL cell contains the total size of the file. So that
X * had better be >= the size of the header + size of text + size
X * of data.
X */
X msg = &rp->r_msg;
X#ifdef BSD4_3
X bcopy(msg->m_args+R_EXECDATA,
X (caddr_t)pexdata, sizeof(struct exec));
X if (pexdata->a_magic == DEMAND_PAGED)
X hdrsize = CLBYTES;
X else
X hdrsize = sizeof(sizeof(struct exec));
X#else BSD4_3
X bcopy(msg->m_args+R_EXECDATA,
X (caddr_t)&u.u_exdata, sizeof (u.u_exdata));
X if (u.u_exdata.ux_mag == DEMAND_PAGED)
X hdrsize = CLBYTES;
X else
X hdrsize = sizeof(u.u_exdata.Ux_A);
X#endif BSD4_3
X
X execsize = msg->m_args[ R_RETVAL ];
X debug0("obj=%d,hrd=%d,error=%d,tx=%d,dat=%d\n",
X execsize, hdrsize, u.u_error,
X#ifdef BSD4_3
X pexdata->a_text, pexdata->a_text
X#else BSD4_3
X u.u_exdata.ux_tsize, u.u_exdata.ux_dsize
X#endif BSD4_3
X );
X
X#ifdef BSD4_3
X if (pexdata->a_text + pexdata->a_data + hdrsize > execsize
X && *((char *)pexdata) != '#') {
X error = ENOEXEC;
X goto bad;
X }
X#else BSD4_3
X if (u.u_exdata.ux_tsize + u.u_exdata.ux_dsize + hdrsize > execsize
X && u.u_exdata.ux_shell[0] != '#') {
X error = ENOEXEC;
X goto bad;
X }
X#endif BSD4_3
X
X if ((u.u_procp->p_flag&STRC) && msg->m_args[ R_EXECREADONLY ]) {
X error = EACCES;
X goto bad;
X }
X if (auid) { /* first time thru for this exec... set uid/gid stuff */
X uid = ntohl(msg->m_args[ R_EXECUID ]);
X if (uid < 0)
X uid = u.u_uid;
X gid = ntohl(msg->m_args[ R_EXECGID ]);
X if (gid < 0)
X gid = u.u_gid;
X *auid = uid;
X *agid = gid;
X }
X return(sysindex);
X
Xbad:
X u.u_error = error;
X return(-1);
X}
X
X/*
X * This is the simple routine that is called by remote_path1 as the
X * specific routine for handling RSYS_execinfo. remote_execinfo() is
X * called from exec, and remote_execinfo() calls remote_path1() who in
X * turn calls rmt_execinfo().
X */
Xrmt_execinfo(sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X struct message *msg = mtod(m, struct message *);
X#ifdef BSD4_3
X msg->m_args[0] = htonl(sizeof (struct exec));
X#else BSD4_3
X msg->m_args[0] = htonl(sizeof (u.u_exdata));
X#endif BSD4_3
X return (rmt_msgfin(sysindex, m, 0));
X}
X
X/*
X * Read into memory an executable file from a remote system.
X */
X#ifdef BSD4_3
Xremote_execread(sysindex, oldtextsize, ep)
X register struct exec *ep;
X register int sysindex, oldtextsize;
X#else BSD4_3
Xremote_execread(sysindex, oldtextsize)
X register int sysindex, oldtextsize;
X#endif BSD4_3
X{
X struct remoteinfo *rp = remote_info + sysindex;
X struct uio auio;
X struct iovec aiov[2];
X struct mbuf *m;
X struct message *msg;
X register long hdrsize, datasize, textsize, error, len, magic;
X register struct proc *p = u.u_procp;
X long iovlen;
X
X#ifdef BSD4_3
X datasize = (int)ep->a_data;
X magic = ep->a_magic;
X#define HEADERSIZE sizeof(struct exec);
X#else BSD4_3
X datasize = (int)u.u_exdata.ux_dsize;
X magic = u.u_exdata.ux_mag;
X#define HEADERSIZE sizeof(u.u_exdata.Ux_A);
X#endif BSD4_3
X if (datasize <= 0) {
X u.u_error = ENOEXEC;
X return(-1);
X }
X
X /*
X * We are guarenteed that at this point the text size is zero.
X * But we know what the old text size was passed along for the sake of
X * shared-text programs: the binaries for these do not
X * necessarily have the data page-aligned in the file (as we
X * assume that demand-paged programs do), but instead,
X * it is aligned when it is read in. We must do the same here.
X */
X if (oldtextsize && magic == SHARED_TEXT) {
X aiov[0].iov_len = oldtextsize;
X aiov[1].iov_len = datasize - oldtextsize;
X iovlen = 2;
X aiov[0].iov_base = (char *)ctob(tptov(p, 0));
X aiov[1].iov_base = (char *)ctob(btoc(oldtextsize));
X debug0("execrd: %d @ %x, %d @ %x ",
X aiov[0].iov_len, aiov[0].iov_base,
X aiov[1].iov_len, aiov[1].iov_base);
X }
X else {
X iovlen = 1;
X aiov[0].iov_base = (char *)ctob(dptov(p, 0)),
X aiov[0].iov_len = datasize;
X debug0("execrd: %d @ %x ", aiov[0].iov_len, aiov[0].iov_base);
X }
X auio.uio_offset = 0;
X auio.uio_segflg = 0;
X if (magic == DEMAND_PAGED)
X hdrsize = CLBYTES;
X else
X hdrsize = HEADERSIZE;
X
X /*
X * Now ask for it in remote_maxchunk size chunks.
X */
X debug0("hdsz=%d, datasz=%d, rd ", hdrsize, datasize);
X error = 0;
X while (datasize >= 0) {
X auio.uio_resid = MIN(datasize, remote_maxchunk);
X if (auio.uio_resid == 0)
X datasize = -1;
X else {
X if (aiov[0].iov_len <= 0 && iovlen == 2) {
X aiov[0] = aiov[1];
X iovlen = 1;
X }
X auio.uio_iov = aiov;
X auio.uio_iovcnt = iovlen;
X datasize -= auio.uio_resid;
X }
X MGET(m, M_WAIT, MT_DATA);
X if (m == NULL)
X return(ENOBUFS);
X msg = mtod(m, struct message *);
X len = introduce_2extra(msg, RSYS_execread, hdrsize,
X auio.uio_resid);
X m->m_len = len;
X msg->m_hdlen = htons(len);
X msg->m_totlen = htonl(len);
X#ifdef RFSDEBUG
X if (auio.uio_resid) {
X debug0("\n %d: %d@%d", auio.uio_resid,
X aiov[0].iov_len, aiov[0].iov_base);
X if (iovlen == 2)
X debug0(",%d@%d.",
X aiov[1].iov_len, aiov[1].iov_base);
X }
X rmt_showmsg(msg, FALSE);
X#endif RFSDEBUG
X if (datasize >= 0)
X error = remoteio(sysindex, &m, &auio, RFLG_RD);
X else
X remoteio(sysindex, &m, 0, RFLG_INFO);
X#ifdef RFSDEBUG
X msg = &rp->r_msg;
X rmt_showmsg(msg, TRUE);
X#endif RFSDEBUG
X /*
X * If there are any errors, simply send the last
X * message: we're all done.
X */
X if (error && datasize >= 0)
X datasize = 0;
X else if (error)
X return(error);
X }
X
X debug0("\n");
X return ( error );
X}
SHAREOF
chmod 444 remote/usr.sys.remote/rmt_exec.c
#
# remote/usr.sys.remote/rmt_final.c
#
if [ -f remote/usr.sys.remote/rmt_final.c ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_final.c or ^C to quit'
read ans
rm -f remote/usr.sys.remote/rmt_final.c
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_final.c
X/*
X * Copyright 1985, Todd Brunhoff.
X *
X * This software was written at Tektronix Computer Research Laboratories
X * as partial fulfillment of a Master's degree at the University of Denver.
X * This is not Tektronix proprietary software and should not be
X * confused with any software product sold by Tektronix. No warranty is
X * expressed or implied on the reliability of this software; the author,
X * the University of Denver, and Tektronix, inc. accept no liability for
X * any damage done directly or indirectly by this software. This software
X * may be copied, modified or used in any way, without fee, provided this
X * notice remains an unaltered part of the software.
X *
X * $Header: rmt_final.c,v 2.1 85/12/30 16:51:01 toddb Exp $
X *
X * $Log: rmt_final.c,v $
X * Revision 2.1 85/12/30 16:51:01 toddb
X * Made rmt_copypath() compatible between 4.2 and 4.3 by adding a c-version
X * of copystr() and copyinstr() for 4.2 versions (copystr() and copyinstr()
X * are assembler routines in 4.3).
X *
X * Revision 2.0 85/12/07 18:20:12 toddb
X * First public release.
X *
X */
X#include "../h/param.h"
X#ifndef pyr /* Pyramid */
X#include "../machine/pte.h"
X#endif
X#include "../h/systm.h"
X#include "../h/map.h"
X#include "../h/dir.h"
X#include "../h/user.h"
X#include "../h/kernel.h"
X#include "../h/proc.h"
X#include "../h/mbuf.h"
X#include "../h/socket.h"
X#include "../h/file.h"
X#include "../remote/remotefs.h"
X#include "../h/errno.h"
X#include "../netinet/in.h"
X#include "../h/uio.h"
X
Xextern struct remoteinfo remote_info[];
X
X/*
X * rmt_msgfin() finalizes the message by adding in the header and total
X * lengths and sending the message. It returns the return value found in the
X * reply.
X */
Xrmt_msgfin(sysindex, m, flags)
X long sysindex, flags;
X struct mbuf *m;
X{
X long error, len;
X struct message *msg = mtod(m, struct message *);
X struct remoteinfo *rp = remote_info + sysindex;
X
X /*
X * If the length has been set (by remote_path[12]), then don't
X * meddle, otherwise assign it.
X */
X if (msg->m_hdlen == 0)
X len = m->m_len;
X else
X len = msg->m_hdlen;
X msg->m_hdlen = htons(len);
X msg->m_totlen = htonl(len);
X
X rmt_showmsg(msg, FALSE);
X error = remoteio(sysindex, &m, 0, flags);
X
X if (! error) {
X if ((flags & RFLG_INFO) == 0) {
X msg = &rp->r_msg;
X rmt_showmsg(msg, TRUE);
X if ((error = msg->m_errno) == 0)
X u.u_r.r_val1 = msg->m_args[R_RETVAL];
X }
X else
X u.u_r.r_val1 = 0;
X }
X return ( error );
X}
X
X/*
X * rmt_datafin() finalizes a message and fixes up the header and total
X * lengths (like rmt_msgfin()) and sends a message plus data. It returns
X * the return value found in the reply.
X */
Xrmt_datafin(sysindex, m, flags)
X long sysindex, flags;
X struct mbuf *m;
X{
X register long i, error, len;
X struct message *msg = mtod(m, struct message *);
X short syscall = ntohs(msg->m_syscall);
X struct remoteinfo *rp = remote_info + sysindex;
X struct uio auio, *uio;
X struct iovec aiov[16], *iov = aiov;
X struct a {
X long fd;
X char *databuf;
X long datalen;
X } *uap = (struct a *)u.u_ap;
X
X /*
X * Package up the data.
X * If the length has been set (by remote_path1 for readlink),
X * then don't meddle, otherwise assign it the length of the first
X * (and only) mbuf.
X */
X if (msg->m_hdlen == 0)
X msg->m_hdlen = htons(len = m->m_len);
X else
X msg->m_hdlen = htons(len = msg->m_hdlen);
X if (flags & (RFLG_RD | RFLG_WR)) {
X uio = &auio;
X uio->uio_iov = iov;
X uio->uio_segflg = 0;
X uio->uio_offset = 0;
X if (flags & RFLG_DATAV) {
X uio->uio_iovcnt = uap->datalen;
X error = copyin((caddr_t)uap->databuf, (caddr_t)iov,
X (unsigned)(uap->datalen * sizeof (struct iovec)));
X if (error)
X goto done;
X uio->uio_resid = 0;
X for (i = 0; i < uio->uio_iovcnt; i++) {
X if (iov->iov_len < 0) {
X error = EINVAL;
X goto done;
X }
X uio->uio_resid += iov->iov_len;
X iov++;
X }
X }
X else {
X iov->iov_base = uap->databuf;
X iov->iov_len = uio->uio_resid = uap->datalen;
X uio->uio_iovcnt = 1;
X }
X if (uio->uio_resid < 0) {
X error = EINVAL;
X goto done;
X }
X if (flags & RFLG_WR)
X msg->m_totlen = htonl(len + uio->uio_resid);
X else
X msg->m_totlen = htonl(len);
X }
X else {
X uio = NULL;
X msg->m_totlen = htonl(len);
X }
X rmt_showmsg(msg, FALSE);
X error = remoteio(sysindex, &m, uio, flags);
X m = NULL;
X if (error)
X goto done;
X
X msg = &rp->r_msg;
X rmt_showmsg(msg, TRUE);
X if ((error = msg->m_errno) == 0)
X u.u_r.r_val1 = msg->m_args[R_RETVAL];
Xdone:
X if (m)
X m_free(m);
X return ( error );
X}
X
X/*
X * Copy a path into a string of mbufs. The source pointer may be in user
X * space, in which case we must use uchar() to copy. Note that this routine
X * expects 'm' to point to the first mbuf in the current chain: it will
X * append to the end of the chain, and update the length of the message
X * in msg->m_hdlen.
X */
Xrmt_copypath(psrc, m, copy_from_user)
X register char *psrc;
X register struct mbuf *m;
X{
X register char *pdest;
X register int error,
X totlen,
X room;
X register struct mbuf *m2;
X struct message *msg = mtod(m, struct message *);
X int copystr(),
X copyinstr(),
X got;
X func copier = copy_from_user ? copyinstr : copystr;
X
X /*
X * find the end of the mbuf chain.
X */
X while (m->m_next)
X m = m->m_next;
X m2 = m;
X pdest = mtod(m, char *) + m->m_len;
X totlen = msg->m_hdlen;
X
X debug2("copy %s path @%x-->%x, len=%d\n",
X copy_from_user ? "user" : "kernel", psrc, pdest, totlen);
X
X room = MLEN - m->m_len;
X for(;;) {
X got = 0; /* copy*str adds copied bytes to 'got' */
X error = (*copier)(psrc, pdest, room, (u_int *)&got);
X if (error && error != ENOENT)
X return(error);
X m2->m_len += got;
X totlen += got;
X if (got < room)
X break;
X MGET(m, M_WAIT, MT_DATA);
X if (m == NULL)
X return(ENOBUFS);
X m2 = m2->m_next = m;
X m2->m_len = 0;
X room = MLEN;
X pdest = mtod(m2, char *);
X psrc += got;
X }
X msg->m_hdlen = totlen;
X debug2("len now=%d\n", totlen);
X
X return(0);
X}
X
X#ifdef BSD4_3
X#else BSD4_3
X/*
X * C version of copyinstr() from 4.3.
X */
Xcopyinstr(src, dest, maxlength, lencopied)
X register char *src, *dest;
X register int maxlength;
X register int *lencopied;
X{
X register int c;
X int dummy;
X
X if (!maxlength)
X return(EFAULT);
X if (lencopied == NULL)
X lencopied = &dummy;
X for(;;) {
X c = *dest++ = fubyte(src++);
X if (c == -1) {
X *(dest-1) = 0;
X return(EFAULT);
X }
X if (--maxlength < 0)
X return(ENOENT);
X (*lencopied)++;
X if (c == 0)
X return(0);
X }
X}
X
X/*
X * C version of copystr() from 4.3.
X */
Xcopystr(src, dest, maxlength, lencopied)
X register char *src, *dest;
X register int maxlength;
X register int *lencopied;
X{
X int dummy;
X
X if (!maxlength)
X return(EFAULT);
X if (lencopied == NULL)
X lencopied = &dummy;
X for(;;) {
X if (--maxlength < 0)
X return(ENOENT);
X (*lencopied)++;
X if ((*dest++ = *src++) == 0)
X return(0);
X }
X}
X#endif BSD4_3
X
X#ifdef RFSDEBUG
X
Xrmt_debug(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
X{
X printf(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
X}
X
Xrmt_showmsg(msg, fromserver)
X struct message *msg;
X int fromserver;
X{
X long end, len, pid, uid, totlen;
X
X if ((remote_debug & 0x18000) == 0)
X return;
X if (fromserver)
X len = msg->m_hdlen,
X totlen = msg->m_totlen,
X pid = msg->m_pid,
X uid = msg->m_uid;
X else
X len = ntohs(msg->m_hdlen),
X totlen = ntohl(msg->m_totlen),
X pid = ntohs(msg->m_pid),
X uid = ntohs(msg->m_uid);
X debug15("%s srvr: len=%d,tot=%d,pid=%d,uid=%d",
X fromserver ? "from" : "to", len, totlen, pid, uid);
X
X /* round up into long words */
X len = (len - R_MINRMSG + 3) >> 2;
X if (fromserver)
X {
X debug15(",err=%d,ret=%d",
X msg->m_errno,
X msg->m_args[ R_RETVAL ]);
X end = R_RETVAL+1;
X }
X else
X {
X debug15(",syscall=%d", htons(msg->m_syscall));
X end = 0;
X }
X for (; end<len; end++)
X debug16(",0x%x", ntohl(msg->m_args[ end ]));
X rmt_debug("\n");
X}
X#endif RFSDEBUG
SHAREOF
chmod 444 remote/usr.sys.remote/rmt_final.c
#
# remote/usr.sys.remote/rmt_syscall3.c
#
if [ -f remote/usr.sys.remote/rmt_syscall3.c ]; then
echo -n 'Hit <return> to overwrite remote/usr.sys.remote/rmt_syscall3.c or ^C to quit'
read ans
rm -f remote/usr.sys.remote/rmt_syscall3.c
fi
sed -e 's/^.//' << \SHAREOF > remote/usr.sys.remote/rmt_syscall3.c
X/*
X * Copyright 1985, Todd Brunhoff.
X *
X * This software was written at Tektronix Computer Research Laboratories
X * as partial fulfillment of a Master's degree at the University of Denver.
X * This is not Tektronix proprietary software and should not be
X * confused with any software product sold by Tektronix. No warranty is
X * expressed or implied on the reliability of this software; the author,
X * the University of Denver, and Tektronix, inc. accept no liability for
X * any damage done directly or indirectly by this software. This software
X * may be copied, modified or used in any way, without fee, provided this
X * notice remains an unaltered part of the software.
X *
X * $Header: rmt_syscall3.c,v 2.0 85/12/07 18:19:35 toddb Rel $
X *
X * $Log: rmt_syscall3.c,v $
X * Revision 2.0 85/12/07 18:19:35 toddb
X * First public release.
X *
X */
X#include "../h/param.h"
X#ifndef pyr /* Pyramid */
X#include "../machine/pte.h"
X#endif
X#include "../h/systm.h"
X#include "../h/map.h"
X#include "../h/dir.h"
X#include "../h/user.h"
X#include "../h/kernel.h"
X#include "../h/proc.h"
X#include "../h/inode.h"
X#include "../h/mbuf.h"
X#include "../h/socket.h"
X#include "../remote/remotefs.h"
X#include "../h/file.h"
X#include "../h/stat.h"
X#include "../h/errno.h"
X#include "../netinet/in.h"
X
Xextern long rmtrw(), rmtioctl(), rmtselect(), rmtclose();
Xstruct fileops remoteops =
X { rmtrw, rmtioctl, rmtselect, rmtclose };
Xrmtrw() { return(0); }
Xrmtioctl() { return(0); }
Xrmtselect() { return(0); }
Xrmtclose() { return(0); }
X
Xextern struct remoteinfo remote_info[];
Xextern struct remoteinfo *remote_generic;
X
X/*
X * Remote open()
X */
Xrmt_open (sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X register long fd, error;
X register struct message *msg = mtod(m, struct message *);
X register struct file *fp;
X struct file *falloc();
X register struct a {
X char *path;
X long flags,
X mode;
X } *uap = (struct a *)u.u_ap;
X
X /*
X * Initialize the file structure.
X */
X if ((fp = falloc()) == NULL)
X return(-1);
X fp->f_type = DTYPE_REMOTE;
X fp->f_ops = &remoteops;
X fd = u.u_r.r_val1;
X fp->f_data = (caddr_t)sysindex;
X fp->f_flag = (uap->mode&FMASK) | FREMOTE;
X remote_info[ sysindex ].r_nfile++;
X
X if (ntohs(msg->m_syscall) == RSYS_creat) {
X uap->mode = uap->flags;
X uap->flags = FWRITE|FCREAT|FTRUNC;
X msg->m_syscall = htons(RSYS_open);
X }
X msg->m_args[ 0 ] = htonl(uap->flags);
X msg->m_args[ 1 ] = htonl(uap->mode);
X msg->m_args[ 2 ] = htonl(fd);
X msg->m_args[ 3 ] = htonl(u.u_cmask);
X
X /*
X * Now send it.
X */
X error = rmt_msgfin(sysindex, m, 0);
X if (error)
X rmt_deallocfd(fd);
X else {
X msg = &remote_info[ sysindex ].r_msg;
X fp->f_offset = msg->m_args[1];
X }
X return(error);
X}
X
X/*
X * Remote readlink()
X */
Xrmt_readlink (sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X struct message *msg = mtod(m, struct message *);
X struct a {
X char *path;
X char *buf;
X long len;
X } *uap = (struct a *)u.u_ap;
X
X
X msg->m_args[ 0 ] = htonl(uap->len);
X /*
X * Now send it.
X */
X return( rmt_datafin(sysindex, m, RFLG_RD) );
X}
X
X/*
X * Remote stat() and lstat() and fstat()
X */
Xrmt_stat (sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X long error, i;
X struct message *msg = mtod(m, struct message *);
X struct remoteinfo *rp = remote_info + sysindex;
X struct a {
X long fd_or_path;
X struct stat *statp;
X } *uap = (struct a *)u.u_ap;
X struct stat st;
X
X if (ntohl(msg->m_syscall) == RSYS_fstat)
X m->m_len = R_MINRMSG + sizeof(long);
X if (error = rmt_msgfin(sysindex, m, 0))
X return( error );
X msg = &rp->r_msg;
X i = R_RETVAL + 1;
X st.st_dev = ntohl(msg->m_args[ i++ ]);
X st.st_ino = ntohl(msg->m_args[ i++ ]);
X st.st_mode = ntohl(msg->m_args[ i++ ]);
X st.st_nlink = ntohl(msg->m_args[ i++ ]);
X st.st_uid = ntohl(msg->m_args[ i++ ]);
X st.st_gid = ntohl(msg->m_args[ i++ ]);
X st.st_rdev = ntohl(msg->m_args[ i++ ]);
X st.st_size = ntohl(msg->m_args[ i++ ]);
X st.st_atime = ntohl(msg->m_args[ i++ ]);
X st.st_mtime = ntohl(msg->m_args[ i++ ]);
X st.st_ctime = ntohl(msg->m_args[ i++ ]);
X st.st_blksize = ntohl(msg->m_args[ i++ ]);
X st.st_blocks = ntohl(msg->m_args[ i++ ]);
X st.st_spare1 = sysindex+1;
X st.st_spare2 = 0;
X st.st_spare3 = 0;
X st.st_spare4[0] = st.st_spare4[1] = 0;
X if (msg->m_args[ i ]) { /* this is the remote root */
X if (rp->r_mntpt == NULL)
X rp = remote_generic;
X if (rp && rp->r_mntpt != NULL) {
X st.st_dev = rp->r_mntpt->i_dev;
X st.st_ino = rp->r_mntpt->i_number;
X }
X }
X (void)copyout((caddr_t)&st, (caddr_t)uap->statp, sizeof(struct stat));
X return(0);
X}
X
X/*
X * Remote truncate() and ftrucate()
X */
Xrmt_truncate (sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X long i = 0;
X struct message *msg = mtod(m, struct message *);
X struct a {
X long fd_or_path;
X long len;
X } *uap = (struct a *)u.u_ap;
X
X if (htons(msg->m_syscall) == RSYS_ftruncate)
X i++;
X msg->m_args[ i ] = htonl(uap->len);
X /*
X * Now send it.
X */
X return( rmt_msgfin(sysindex, m, 0) );
X}
X
X/*
X * Remote utimes()
X */
Xrmt_utimes (sysindex, m)
X long sysindex;
X struct mbuf *m;
X{
X struct message *msg = mtod(m, struct message *);
X struct a {
X char *path;
X struct timeval *timevalp;
X } *uap = (struct a *)u.u_ap;
X struct timeval *tv = uap->timevalp;
X
X msg->m_args[ 0 ] = htonl(tv[0].tv_sec);
X msg->m_args[ 1 ] = htonl(tv[0].tv_usec);
X msg->m_args[ 2 ] = htonl(tv[1].tv_sec);
X msg->m_args[ 3 ] = htonl(tv[1].tv_usec);
X
X /*
X * Now send it.
X */
X return( rmt_msgfin(sysindex, m, 0) );
X}
SHAREOF
chmod 444 remote/usr.sys.remote/rmt_syscall3.c
More information about the Comp.sources.unix
mailing list