home *** CD-ROM | disk | FTP | other *** search
- Subject: RFS: remote file system (part 3 of 7)
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 3, Issue 79
- Submitted by: tektronix!tekcrl!toddb
-
- #!/bin/sh
- #
- # RFS, a kernel-resident remote file system. Shar 3 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/list.c
- # remote/make.base
- # remote/make.base.M68
- # remote/make.base.magnolia
- # remote/make.base.pyramid
- # remote/make.base.vax
- # remote/make.base.vaxnorfs
- # remote/new.c
- # remote/newinit.c
- # remote/rhost.c
- # remote/rmtmnt.c
- # remote/route.c
- # remote/server.h
- # remote/serverdata.c
- # remote/serverdir.c
- #
- # remote/list.c
- #
- if [ -f remote/list.c ]; then
- echo -n 'Hit <return> to overwrite remote/list.c or ^C to quit'
- read ans
- rm -f remote/list.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/list.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 * $Log: list.c,v $
- X * Revision 2.0 85/12/07 18:21:44 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: list.c,v 2.0 85/12/07 18:21:44 toddb Rel $";
- X#include "server.h"
- X#include <stdio.h>
- X
- X/*
- X * Stick a new item of any type on top of the list.
- X */
- Xl_list *addlist(list, item)
- X register l_list **list;
- X register l_list *item;
- X{
- X item->l_next = *list;
- X if (*list)
- X {
- X item->l_prev = (*list)->l_prev;
- X (*list)->l_prev = item;
- X }
- X else
- X item->l_prev = item;
- X *list = item;
- X return(item);
- X}
- X
- X/*
- X * delete an item from a list. The item itself is left intact. It is
- X * the responsibility of the caller to deal with the deleted item.
- X */
- Xl_list *deletelist(list, item)
- X register l_list **list;
- X register l_list *item;
- X{
- X if (item == *list)
- X {
- X if (item->l_next == NULL)
- X *list = NULL;
- X else
- X {
- X *list = item->l_next;
- X item->l_next->l_prev = item->l_next;
- X }
- X }
- X else
- X {
- X item->l_prev->l_next = item->l_next;
- X if (item->l_next != NULL)
- X item->l_next->l_prev = item->l_prev;
- X }
- X return (*list);
- X}
- X
- X/*
- X * stick 'item' at the top of the 'list' ( if it isn't there
- X * already.
- X */
- Xl_list *toplist(list, item)
- X register l_list **list;
- X register l_list *item;
- X{
- X if (item == *list)
- X return;
- X item->l_prev->l_next = item->l_next;
- X if (item->l_next)
- X item->l_next->l_prev = item->l_prev;
- X item->l_next = (*list);
- X /*
- X * if our target is the last on the list, then
- X * be careful that we don't make a cycle. Since
- X * we want the head of the list's l_prev pointer
- X * to point to the last in the list, we don't
- X * have to do anything.
- X */
- X if (item != (*list)->l_prev) /* NOT last on list */
- X item->l_prev = (*list)->l_prev;
- X (*list)->l_prev = item;
- X *list = item;
- X}
- SHAREOF
- chmod 444 remote/list.c
- #
- # remote/make.base
- #
- if [ -f remote/make.base ]; then
- echo -n 'Hit <return> to overwrite remote/make.base or ^C to quit'
- read ans
- rm -f remote/make.base
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base
- XSOBJS = change.$O file.$O fileserver.$O find.$O \
- X info.$O init.$O list.$O new.$O \
- X rhost.$O route.$O serverdata.$O serverdir.$O serverio.$O \
- X serversyscall.$O
- XCFILES = change.c file.c fileserver.c find.c \
- X info.c init.c list.c new.c \
- X rhost.c route.c serverdata.c serverdir.c serverio.c \
- X serversyscall.c
- X
- Xall: $(ALL)
- X
- X$(RFS_SERVER): $(SOBJS)
- X $(CC) -o $@ $(SOBJS) $(LDFLAGS)
- X $(XINU) $(RFS_SERVER)
- X$(RMTMNT): rmtmnt.$O
- X $(CC) -o $@ rmtmnt.$O $(LDFLAGS)
- X $(XINU) $(RMTMNT)
- X$(DEBUG): debug.$O
- X $(CC) -o $@ debug.$O $(LDFLAGS)
- X $(XINU) $(DEBUG)
- Xtags: $(CFILES)
- X ctags $(CFILES) $(INCLUDE)
- X$(SOBJS): $(INCLUDE)
- X
- Xinstall: all
- X $(INSTALL) -c -m 755 $(RFS_SERVER) $(DEST)/etc/rfs_server
- X $(INSTALL_RMTMNT) -c -m 0755 $(RMTMNT) $(DEST)/etc/rmtmnt
- SHAREOF
- chmod 664 remote/make.base
- #
- # remote/make.base.M68
- #
- if [ -f remote/make.base.M68 ]; then
- echo -n 'Hit <return> to overwrite remote/make.base.M68 or ^C to quit'
- read ans
- rm -f remote/make.base.M68
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base.M68
- XDEST = /usr3/mag
- XHOST =
- XINCLUDE = $(DEST)/usr/include/remote/remotefs.h server.h
- XCFLAGS = -G$(HOST) -O -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS -DMACHTYPE=magnolia
- XLDFLAGS = -z
- XCC = cc68
- XO = b
- XRFS_SERVER = rfs_server.x
- XRMTMNT = rmtmnt.x
- XDEBUG = debug.x
- XINSTALL_RMTMNT = install68
- XINSTALL = install68
- XALL = $(RFS_SERVER) $(RMTMNT)
- XXINU = xinu68
- X
- X.SUFFIXES:
- X.SUFFIXES: .b .c
- X
- X.c.b:
- X $(CC) $(CFLAGS) $< -c
- SHAREOF
- chmod 664 remote/make.base.M68
- #
- # remote/make.base.magnolia
- #
- if [ -f remote/make.base.magnolia ]; then
- echo -n 'Hit <return> to overwrite remote/make.base.magnolia or ^C to quit'
- read ans
- rm -f remote/make.base.magnolia
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base.magnolia
- XHOST = tekcrl
- XINCLUDE = /usr/include/remote/remotefs.h server.h
- XO = o
- XCFLAGS = -G$(HOST) -O -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS
- XLDFLAGS = -z
- XRFS_SERVER = rfs_server
- XRMTMNT = rmtmnt
- XDEBUG = debug
- XINSTALL = install68
- XINSTALL_RMTMNT = install68
- XDEST =
- XCC = cc
- XALL = $(RFS_SERVER) $(RMTMNT)
- XXINU = :
- SHAREOF
- chmod 664 remote/make.base.magnolia
- #
- # remote/make.base.pyramid
- #
- if [ -f remote/make.base.pyramid ]; then
- echo -n 'Hit <return> to overwrite remote/make.base.pyramid or ^C to quit'
- read ans
- rm -f remote/make.base.pyramid
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base.pyramid
- XINCLUDE = ../usr.include/remote/remotefs.h server.h
- XO = o
- XLDFLAGS = -z
- XRFS_SERVER = rfs_server
- XINS_RFS_SERVER = rfs_server
- XRMTMNT = rmtmnt
- XDEBUG = debug
- XINSTALL_RMTMNT = install
- XINSTALL = install
- XDEST =
- XCC = cc
- XALL = $(RFS_SERVER) $(RMTMNT)
- XXINU = :
- XDEFINES = -DRFSDEBUG -DCANREMOTE -DBYTEORDER=3,2,1,0 -DREMOTEFS -I/usr/include/sys
- XCFLAGS = -O ${DEFINES} -I../usr.include
- SHAREOF
- chmod 644 remote/make.base.pyramid
- #
- # remote/make.base.vax
- #
- if [ -f remote/make.base.vax ]; then
- echo -n 'Hit <return> to overwrite remote/make.base.vax or ^C to quit'
- read ans
- rm -f remote/make.base.vax
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base.vax
- XINCLUDE = ../usr.include/remote/remotefs.h server.h
- XO = o
- XLDFLAGS = -z
- XRFS_SERVER = rfs_server
- XINS_RFS_SERVER = rfs_server
- XRMTMNT = rmtmnt
- XDEBUG = debug
- XINSTALL_RMTMNT = install
- XINSTALL = install
- XDEST =
- XCC = cc
- XALL = $(RFS_SERVER) $(RMTMNT)
- XXINU = :
- XDEFINES = -DRFSDEBUG -DCANREMOTE -DBYTEORDER=0,1,2,3 -DREMOTEFS
- XCFLAGS = -O ${DEFINES} -I../usr.include
- SHAREOF
- chmod 664 remote/make.base.vax
- #
- # remote/make.base.vaxnorfs
- #
- if [ -f remote/make.base.vaxnorfs ]; then
- echo -n 'Hit <return> to overwrite remote/make.base.vaxnorfs or ^C to quit'
- read ans
- rm -f remote/make.base.vaxnorfs
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/make.base.vaxnorfs
- XINCLUDE = ../usr.include/remote/remotefs.h server.h
- XO = o
- XLDFLAGS = -z
- XRFS_SERVER = rfs_server
- XINS_RFS_SERVER = rfs_server
- XRMTMNT = rmtmnt
- XDEBUG = debug
- XINSTALL_RMTMNT = :
- XINSTALL = install
- XDEST =
- XCC = cc
- XALL = $(RFS_SERVER)
- XXINU = :
- XCFLAGS = -O -DRFSDEBUG -DBYTEORDER=0,1,2,3 -DNREMOTE=1 -I../usr.include
- SHAREOF
- chmod 664 remote/make.base.vaxnorfs
- #
- # remote/new.c
- #
- if [ -f remote/new.c ]; then
- echo -n 'Hit <return> to overwrite remote/new.c or ^C to quit'
- read ans
- rm -f remote/new.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/new.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 * $Log: new.c,v $
- X * Revision 2.0 85/12/07 18:21:48 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: new.c,v 2.0 85/12/07 18:21:48 toddb Rel $";
- X#include "server.h"
- X#include <stdio.h>
- X
- Xextern short current_pid;
- Xextern hosts *host;
- X
- Xusers *newuser()
- X{
- X register users *user;
- X
- X user = (users *)malloc(sizeof(users));
- X if (user == NULL)
- X log_fatal("cannot allocate space\n");
- X bzero(user, sizeof(users));
- X return(user);
- X}
- X
- Xhosts *newhost()
- X{
- X register hosts *h;
- X
- X h = (hosts *)malloc(sizeof(hosts));
- X if (h == NULL)
- X log_fatal("cannot allocate space\n");
- X bzero(h, sizeof(hosts));
- X h->h_cmdfd = -1;
- X return(h);
- X}
- X
- Xrusers *newruser()
- X{
- X register rusers *ruser;
- X
- X ruser = (rusers *)malloc(sizeof(rusers));
- X if (ruser == NULL)
- X log_fatal("cannot allocate space\n");
- X bzero(ruser, sizeof(rusers));
- X return(ruser);
- X}
- X
- Xprocess *newprocess()
- X{
- X register process *p;
- X
- X p = (process *)malloc(sizeof(process));
- X if (p == NULL)
- X log_fatal("cannot allocate space\n");
- X bzero(p, sizeof(process));
- X return(p);
- X}
- X
- Xfreeproc(p)
- X register process *p;
- X{
- X if (p->p_execfd >= 0)
- X close(p->p_execfd);
- X free(p);
- X}
- X
- Xchar **newname(namelist, name)
- X register char **namelist;
- X register char *name;
- X{
- X register long i = 0;
- X
- X if (namelist == NULL)
- X namelist = (char **)malloc(sizeof(char *) * 2);
- X else
- X {
- X /*
- X * count the elements in the list now.
- X */
- X for (i=0; namelist && namelist[i]; i++) ;
- X
- X namelist = (char **)realloc(namelist, sizeof(char *) * (i+2));
- X }
- X namelist[ i++ ] = copy(name);
- X namelist[ i ] = NULL;
- X return(namelist);
- X}
- X
- X/*
- X * Add a group to 'user' unless he has exceeded the limit or the group
- X * is already in his domain.
- X */
- Xaddgroup(user, gid)
- X register users *user;
- X register short gid;
- X{
- X register long i = 0,
- X *gr = user->u_local_groups;
- X
- X for (i=0; i < user->u_numgroups; i++)
- X if (gr[ i ] == gid)
- X return;
- X if (i >= NGROUPS)
- X return;
- X gr[ user->u_numgroups++ ] = gid;
- X}
- X
- Xprocess *add_new_process(uid, pid)
- X register short uid, pid;
- X{
- X register process *p;
- X register long i;
- X
- X debug0("allocate new proc: pid=%d uid=%d host=%s\n",
- X pid, uid, host->h_names[0]);
- X setup_proc(p = newprocess(), uid, pid);
- X addlist(&host->h_proclist, p);
- X
- X /*
- X * Initialize the file descriptors for this process.
- X */
- X for(i=0; i<NOFILE; i++)
- X p->p_fds[ i ] = 0x80; /* -128 */
- X
- X return(p);
- X}
- X
- Xsetup_proc(proc, uid, pid)
- X register process *proc;
- X register short uid, pid;
- X{
- X register rusers *ruser;
- X
- X proc->p_pid = pid;
- X proc->p_uid = uid;
- X proc->p_handler = current_pid;
- X proc->p_returnval = 0;
- X proc->p_execfd = -1;
- X if (ruser = findremuid(&host->h_rusers, uid))
- X proc->p_ruser = ruser;
- X else
- X proc->p_ruser = host->h_default_ruser;
- X}
- SHAREOF
- chmod 444 remote/new.c
- #
- # remote/newinit.c
- #
- if [ -f remote/newinit.c ]; then
- echo -n 'Hit <return> to overwrite remote/newinit.c or ^C to quit'
- read ans
- rm -f remote/newinit.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/newinit.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 * $Log: init.c,v $
- X * Revision 2.0 85/12/07 18:21:37 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: init.c,v 2.0 85/12/07 18:21:37 toddb Rel $";
- X#include "server.h"
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <grp.h>
- X#include <netdb.h>
- X#include <fcntl.h>
- X#include <sys/dir.h>
- X#include <sys/user.h>
- X#include <sys/signal.h>
- X#include <sys/ioctl.h>
- X
- Xextern hosts *hostlist;
- Xextern hosts *thishost;
- Xextern users *userlist;
- Xextern users *default_user;
- Xextern char hostname[];
- Xextern char *service;
- Xextern short current_uid;
- Xextern short current_pid;
- Xextern process *wildcard;
- Xextern struct sigvec sig_vec;
- Xextern struct sigvec sig_name;
- Xextern struct sigvec sig_alarm;
- Xextern struct sigvec sig_ignore;
- Xextern struct sigvec sig_continue;
- X#ifdef RFSDEBUG
- Xextern struct sigvec sig_debug;
- X#endif
- Xextern struct stat root;
- X
- X/*
- X * Initialize the host tables and user tables.
- X */
- Xinit()
- X{
- X long tt;
- X struct hostent *gethostent();
- X struct passwd *getpwent();
- X struct group *getgrent();
- X
- X /*
- X * catch signals.
- X */
- X sigvec(SIGHUP, &sig_ignore, (struct sigvec *)0);
- X sigvec(SIGINT, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGQUIT, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGILL, &sig_vec, (struct sigvec *)0);
- X#ifdef RFSDEBUG
- X sigvec(SIGTRAP, &sig_debug, (struct sigvec *)0);
- X#endif RFSDEBUG
- X /* SIGIOT */
- X /* SIGEMT */
- X /* SIGFPE */
- X /* SIGKILL */
- X sigvec(SIGBUS, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGSEGV, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGSYS, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGPIPE, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGALRM, &sig_alarm, (struct sigvec *)0);
- X sigvec(SIGTERM, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGURG, &sig_name, (struct sigvec *)0);
- X /* SIGSTOP */
- X /* SIGTSTP */
- X /* SIGCONT */
- X /* SIGCHLD */
- X sigvec(SIGTTIN, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGTTOU, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGIO, &sig_continue, (struct sigvec *)0);
- X sigvec(SIGXCPU, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGXFSZ, &sig_vec, (struct sigvec *)0);
- X sigvec(SIGVTALRM, &sig_vec, (struct sigvec *)0);
- X /* SIGPROF */
- X
- X /*
- X * set up some important global values, including uid, pid,
- X * the pipe file descriptors for messages to and from the gateway
- X * server. Register as the nameserver. Get host name. Get service.
- X * Get root stat info.
- X */
- X if (chdir("/") == -1)
- X log_fatal("cannot chdir(\"/\")\n");
- X wildcard = newprocess();
- X fcntl(2, F_SETFL, FAPPEND);
- X close(0);
- X close(1);
- X change_to_uid(0);
- X if (gethostname(hostname, HOSTNAMELEN) < 0 || *hostname == '\0')
- X log_fatal("host name not set!\n");
- X if (stat("/", &root) < 0)
- X log_fatal("cannot stat /\n");
- X#ifdef CANREMOTE
- X if (remotename(NM_SERVER, 0, 0, 0) < 0)
- X log("cannot register as nameserver\n");
- X /*
- X * Turn off remote access, if we have any.
- X */
- X remoteoff(NULL);
- X#endif
- X tt = open("/dev/tty", 2);
- X
- X if (tt >= 0)
- X {
- X ioctl(tt, TIOCNOTTY, 0);
- X close(tt);
- X }
- X setpgrp(0,0);
- X
- X initusers();
- X initgroups();
- X inithosts();
- X initrhosts();
- X}
- X
- X/*
- X * build the list of users on this host (where the server runs).
- X */
- Xinitusers()
- X{
- X register struct passwd *pw;
- X register users *user;
- X char buf[ BUFSIZ ];
- X register char *pbuf = buf;
- X
- X while(pw = getpwent())
- X {
- X if (*pw->pw_dir == '\0' || *pw->pw_name == '\0')
- X {
- X log("login \"%s\" has problems, dir=\"%s\"\n",
- X pw->pw_name, pw->pw_dir);
- X continue;
- X }
- X user = newuser();
- X user->u_local_uid = pw->pw_uid;
- X user->u_name = copy( pw->pw_name );
- X addgroup(user, pw->pw_gid);
- X user->u_dir = copy( pw->pw_dir );
- X sprintf(pbuf, "%s/.rhosts", pw->pw_dir);
- X user->u_rhosts = copy( pbuf );
- X addlist(&userlist, user);
- X }
- X endpwent();
- X if (user = findusername(DEFAULTUSER))
- X default_user = user;
- X else
- X log_fatal("The user \"%s\" must be in /etc/passwd (%s)\n",
- X DEFAULTUSER, "for default permissions");
- X}
- X
- X/*
- X * Build the list of groups that each user belongs to.
- X */
- Xinitgroups()
- X{
- X register struct group *gr;
- X register users *user;
- X register char **p;
- X
- X
- X while(gr = getgrent())
- X {
- X for (p = gr->gr_mem; *p; p++)
- X if (user = findusername(*p))
- X addgroup(user, gr->gr_gid);
- X else
- X log("group %s: bad user=%s\n",
- X gr->gr_name, *p);
- X }
- X endgrent();
- X}
- X
- X/*
- X * Then build the list of all hosts.
- X */
- Xinithosts()
- X{
- X register struct hostent *h;
- X register rusers *ruser;
- X register hosts *hst;
- X register users *user;
- X register long i;
- X boolean duplicate;
- X
- X while (h = gethostent())
- X {
- X /*
- X * One physical host may have more than one physical
- X * address each having a unique host name associated
- X * with it. If we find any entry having one of its aliases
- X * match a previous alias, then simply fold all aliases
- X * into it, and continue.
- X */
- X duplicate = FALSE;
- X for (i = -1; i < 0 || h->h_aliases[ i ]; i++)
- X {
- X if (i < 0)
- X hst = findhost(h->h_name);
- X else
- X hst = findhost(h->h_aliases[i]);
- X if (hst)
- X {
- X duplicate = TRUE;
- X break;
- X }
- X }
- X
- X /*
- X * If we have a redundant host... add all the names
- X * in; newname will remove redundant copies.
- X */
- X if (!duplicate)
- X hst = newhost();
- X hst->h_names = newname(hst->h_names, h->h_name);
- X for (i=0; h->h_aliases[ i ]; i++)
- X hst->h_names = newname(hst->h_names,
- X h->h_aliases[ i ]);
- X if (duplicate)
- X
- X hst->h_addr = *((struct in_addr *)(h->h_addr));
- X addlist(&hostlist, hst);
- X
- X /*
- X * now if there exists a user on this machine having
- X * the same name as the name of this host (NOT AN
- X * ALIAS!), then that will be our defaut local user
- X * to map to. Be sure that we don't allow a machine
- X * to be mapped onto a user if the uid is real small:
- X * e.g. a machine named root, where all its user ids
- X * become root using the remote fs!
- X */
- X user = findusername(hst->h_names[ 0 ]);
- X if (user && user->u_local_uid <= UID_TOO_LOW)
- X {
- X log("host/user %s: uid %d too low for alias\n",
- X hst->h_names[ 0 ], user->u_local_uid);
- X user = NULL;
- X }
- X else if (user)
- X {
- X hst->h_default_user = user;
- X debug2("default user for host %s (%s) is %s\n",
- X hst->h_names[ 0 ],
- X inet_ntoa(hst->h_addr), user->u_name);
- X }
- X ruser = hst->h_default_ruser = newruser();
- X if (user)
- X ruser->r_user = user;
- X else
- X ruser->r_user = default_user;
- X ruser->r_uid = -1;
- X ruser->r_name = copy(BOGUSUSER);
- X }
- X endhostent();
- X if ((thishost = findhostname(hostname)) == NULL)
- X log_fatal("this host (\"%s\") is not in host file\n",
- X hostname);
- X}
- X
- X/*
- X * Now for each user that has a .rhosts file, assemble the
- X * references and attach them to the appropriate host.
- X */
- Xinitrhosts()
- X{
- X register hosts *hst;
- X register rhost *rh;
- X register users *user;
- X char buf[ BUFSIZ ];
- X register char *pbuf = buf;
- X
- X for (user=userlist; user; user=user->u_next)
- X {
- X setrhost(user->u_rhosts);
- X while (rh = getrhostent(pbuf))
- X if (hst = findhostname(rh->rh_host))
- X addremoteuser(hst, user, rh->rh_user);
- X endrhost();
- X }
- X}
- X
- Xchar *copy(string)
- X register char *string;
- X{
- X register char *ret = malloc( strlen(string)+1 );
- X
- X if (ret == NULL)
- X log_fatal("cannot allocate space\n");
- X strcpy(ret, string);
- X return(ret);
- X}
- X
- X/*
- X * Add a remote user to those recognized on a certain host.
- X */
- Xaddremoteuser(h, user, remoteuser)
- X register hosts *h;
- X register users *user;
- X register char *remoteuser;
- X{
- X register rusers *ruser;
- X register long old = FALSE;
- X
- X debug2("\t%s!%s --> %s ", *h->h_names, remoteuser, user->u_name);
- X if ((ruser = findrusername(&h->h_rusers, remoteuser)) == NULL)
- X {
- X debug2("\n");
- X ruser = newruser();
- X }
- X else
- X {
- X old = TRUE;
- X if (strcmp(remoteuser, user->u_name) != 0)
- X {
- X debug2("(old, ignored)\n");
- X return;
- X }
- X else
- X debug2("(old)\n");
- X }
- X ruser->r_name = copy(remoteuser);
- X ruser->r_uid = -1;
- X ruser->r_user = user;
- X if (! old)
- X addlist(&h->h_rusers, ruser);
- X}
- SHAREOF
- chmod 664 remote/newinit.c
- #
- # remote/rhost.c
- #
- if [ -f remote/rhost.c ]; then
- echo -n 'Hit <return> to overwrite remote/rhost.c or ^C to quit'
- read ans
- rm -f remote/rhost.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/rhost.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 * $Log: rhost.c,v $
- X * Revision 2.0 85/12/07 18:21:52 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: rhost.c,v 2.0 85/12/07 18:21:52 toddb Rel $";
- X#include <stdio.h>
- X#include "server.h"
- X
- Xstatic char *rhostpath;
- Xstatic FILE *fd;
- Xstatic rhost rh;
- X
- Xsetrhost(path)
- X register char *path;
- X{
- X extern int errno;
- X
- X if ((fd = fopen(path, "r")) != 0)
- X debug2("rhost %s\n", path);
- X errno = 0;
- X}
- X
- Xrhost *getrhostent(buf)
- X register char *buf;
- X{
- X register char *p;
- X
- X while (1)
- X {
- X if (fd == NULL || fgets(buf, BUFSIZ, fd) == NULL)
- X return(NULL);
- X
- X /*
- X * assign the first token to rh_host and then look for the
- X * second token on the line. If there is none, then
- X * don't return this entry because we can never map
- X * a remote user id name of "" to anything meaningful.
- X */
- X rh.rh_host = buf;
- X for (p=buf; *p && *p != ' ' && *p != '\n'; p++) ;
- X if (*p == '\n' || *p == '\0')
- X continue;
- X
- X /*
- X * remove the newline on the end
- X */
- X rh.rh_user = p+1;
- X *p = '\0';
- X for (p++; *p && *p != ' ' && *p != '\n'; p++) ;
- X *p = '\0';
- X break;
- X }
- X return(&rh);
- X}
- X
- Xendrhost()
- X{
- X if (fd)
- X {
- X fclose(fd);
- X fd = NULL;
- X }
- X}
- SHAREOF
- chmod 444 remote/rhost.c
- #
- # remote/rmtmnt.c
- #
- if [ -f remote/rmtmnt.c ]; then
- echo -n 'Hit <return> to overwrite remote/rmtmnt.c or ^C to quit'
- read ans
- rm -f remote/rmtmnt.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/rmtmnt.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 * $Log: rmtmnt.c,v $
- X * Revision 2.0 85/12/07 18:21:56 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: rmtmnt.c,v 2.0 85/12/07 18:21:56 toddb Rel $";
- X#include "server.h"
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include <netdb.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <nlist.h>
- X
- Xextern int errno; /* for errors */
- Xchar *service; /* service name */
- Xchar byteorder[4] = { BYTEORDER };
- X
- X/*
- X * for slow or dead remote hosts, we catch alarms.
- X */
- Xint onalrm();
- Xstruct sigvec vec = { onalrm, 0, 0 };
- X
- X/*
- X * Displaying current mount points requires that we read kernel space.
- X */
- Xstruct nlist nl[] = {
- X#ifdef magnolia
- X { "remote_info" },
- X#else
- X { "_remote_info" },
- X#endif
- X { "" },
- X};
- X#ifdef magnolia
- Xchar *kernel = "/magix";
- X#else
- Xchar *kernel = "/vmunix";
- X#endif
- X
- Xmain(argc, argv)
- X int argc;
- X char **argv;
- X{
- X long generic = FALSE,
- X unmount = FALSE;
- X char *mntpt = NULL,
- X *host = NULL;
- X
- X /*
- X * Parse the args.
- X */
- X for (argv++, argc--; argc; argv++, argc--)
- X {
- X if (**argv != '-')
- X break;
- X switch(argv[0][1]) {
- X case 's': /* service name */
- X if (argv[0][2])
- X service = argv[0]+2;
- X else
- X argv++, argc--, service = argv[0];
- X break;
- X case 'g': /* Make this a generic mount point */
- X generic = TRUE;
- X break;
- X case 'u': /* unmount this mount point */
- X unmount = TRUE;
- X break;
- X default:
- X fprintf(stderr, "unknown option = %s\n", *argv);
- X usage();
- X exit(1);
- X }
- X }
- X
- X if (! generic && ! unmount && argc-- > 0)
- X host = *argv++;
- X if (argc-- > 0)
- X {
- X mntpt = *argv++;
- X if (*mntpt != '/')
- X {
- X fprintf(stderr, "mount point must begin with '/'\n");
- X mntpt = NULL;
- X }
- X }
- X else
- X {
- X show();
- X exit(0);
- X }
- X
- X if (argc > 0
- X || (generic && unmount)
- X || (mntpt == NULL))
- X usage();
- X
- X if (unmount)
- X turnoff(mntpt);
- X else
- X turnon(mntpt, host);
- X}
- X
- X/*
- X * Display the current mount points in the kernal.
- X */
- Xshow()
- X{
- X long index = 0,
- X diff,
- X now,
- X kfd;
- X char buf[BUFSIZ],
- X *p;
- X struct sockaddr_in hostaddr;
- X struct sockaddr_in *sys;
- X struct servent *servp;
- X struct hostent *hostent;
- X struct remoteinfo rinfo[ R_MAXSYS ],
- X *rp;
- X struct mbuf bufs[ R_MAXSYS ],
- X *m;
- X
- X servp = getservbyname(REMOTE_FS_SERVER, "tcp");
- X /*
- X * Get the address of the remote mount point information
- X * and read kernel memory.
- X */
- X nlist(kernel, nl);
- X if(nl[0].n_type == 0)
- X log_fatal("no %s for namelist\n", kernel);
- X kfd = open("/dev/kmem", 0);
- X if(kfd < 0)
- X log_fatal("cannot open /dev/kmem\n");
- X lseek(kfd, (long)nl[0].n_value, 0);
- X read(kfd, rinfo, sizeof(struct remoteinfo) * R_MAXSYS);
- X
- X /*
- X * Now get the mbufs on each mount point.
- X */
- X m = bufs;
- X time(&now);
- X for (index=0, rp = rinfo; rp < rinfo+R_MAXSYS; rp++, index++)
- X {
- X buf[0] = '\0';
- X if (rp->r_name || rp->r_mntpt)
- X printf("%d: ", index);
- X else
- X continue;
- X if (rp->r_name)
- X {
- X lseek(kfd, (long)rp->r_name, 0);
- X read(kfd, m, sizeof(struct mbuf));
- X rp->r_name = m++;
- X sys = mtod(rp->r_name, struct sockaddr_in *);
- X hostent = gethostbyaddr(&sys->sin_addr,
- X sizeof (struct in_addr), sys->sin_family);
- X if (hostent == NULL)
- X {
- X log("no host entry for %s\n",
- X inet_ntoa(sys->sin_addr));
- X continue;
- X }
- X bprintf(buf, "%s(%s) on ",
- X hostent->h_name, inet_ntoa(sys->sin_addr));
- X }
- X else
- X bprintf(buf, "generic mount point ");
- X bprintf(buf, "%s", rp->r_mntpath);
- X if (rp->r_mntpt == NULL)
- X bprintf(buf, ", implied");
- X if (rp->r_name && sys->sin_port != servp->s_port)
- X bprintf(buf, ", port %d", sys->sin_port);
- X if (rp->r_sock)
- X bprintf(buf, ", connected");
- X if (rp->r_close)
- X bprintf(buf, ", closing");
- X if (rp->r_users)
- X bprintf(buf, ", %d process%s",
- X rp->r_users, rp->r_users > 1 ? "es" : "");
- X if (rp->r_nfile)
- X bprintf(buf, ", %d open file%s",
- X rp->r_nfile, rp->r_nfile > 1 ? "s" : "");
- X if (rp->r_nchdir)
- X bprintf(buf, ", %d chdir%s",
- X rp->r_nchdir, rp->r_nchdir > 1 ? "'s" : "");
- X if (rp->r_opening)
- X bprintf(buf, ", opening");
- X if (rp->r_failed)
- X {
- X bprintf(buf, ", connect failed, retry ");
- X diff = rp->r_age - now;
- X if (diff <= 0)
- X bprintf(buf, "time reached");
- X else
- X {
- X bprintf(buf, "in ");
- X if (diff / 60)
- X bprintf(buf, "%d minute%s", diff/60,
- X (diff/60) > 1 ? "s" : "");
- X if (diff / 60 && diff % 60)
- X bprintf(buf, " and ");
- X if (diff % 60)
- X bprintf(buf, "%d second%s", diff%60,
- X (diff%60) > 1 ? "s" : "");
- X }
- X }
- X else if(rp->r_sock == NULL && rp->r_age)
- X {
- X bprintf(buf, ", last closed %s",
- X ctime(&rp->r_age));
- X buf[ strlen(buf)-1 ] = '\0'; /* remove newline */
- X }
- X printf("%s\n", buf);
- X }
- X}
- X
- X/*
- X * buffer printf. i.e. do a printf into a buffer, appending to whatever
- X * is there. Split long lines.
- X */
- Xbprintf(buf, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
- X char *buf;
- X{
- X char xbuf[ BUFSIZ ],
- X *pfrom, *pto, c;
- X long col;
- X
- X sprintf(xbuf, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
- X for (pto = buf; *pto; pto++) ;
- X for (pfrom = xbuf, col=0; *pfrom; pfrom++, col++)
- X {
- X c = *pfrom;
- X *pto++ = c;
- X if (c == '\n')
- X col = -1;
- X else if (c == ' ' && col > 50)
- X {
- X *pto++ = '\n';
- X *pto++ = '\t';
- X col = 7;
- X }
- X }
- X *pto = '\0';
- X}
- X
- X/*
- X * Do a mount.
- X */
- Xturnon(mntpt, host)
- X char *mntpt, *host;
- X{
- X int index, ret, fdout, fdin;
- X struct message msgbuf, *msg = &msgbuf;
- X struct sockaddr_in sys;
- X char buf[ BUFSIZ ];
- X
- X if (strlen(mntpt) >= R_MNTPATHLEN)
- X log_fatal("mount point must be < %d chars\n", R_MNTPATHLEN);
- X
- X /*
- X * Connect to the machine and send it our byte order and
- X * password file.
- X */
- X if (host)
- X {
- X if ((fdout = tcpname(&sys, host)) < 0)
- X log("system unreachable now...");
- X index = remoteon(mntpt, strlen(mntpt)+1,
- X &sys, sizeof(struct sockaddr_in));
- X }
- X else
- X index = remoteon(mntpt, strlen(mntpt), 0, 0);
- X if (index == -1)
- X log_fatal("cant mount remote fs\n");
- X else if (host && fdout < 0)
- X log(" system mounted anyway\n");
- X if (host == NULL)
- X return;
- X if ((fdin = open("/etc/passwd", O_RDONLY)) == -1)
- X log_fatal("can't open /etc/passwd\n");
- X msg->m_syscall = htons(RSYS_nosys);
- X msg->m_hdlen = htons(R_MINRMSG + sizeof(long));
- X msg->m_totlen = htonl(R_MINRMSG + sizeof(long));
- X msg->m_args[0] = htonl(CMD_MOUNT);
- X write(fdout, msg, R_MINRMSG + sizeof(long));
- X write(fdout, byteorder, 4);
- X while ((ret = read(fdin, buf, BUFSIZ)) > 0)
- X write(fdout, buf, ret);
- X close(fdout);
- X close(fdin);
- X return;
- X}
- X
- Xturnoff(mntpt)
- X char *mntpt;
- X{
- X int index, fd;
- X
- X index = remoteoff(mntpt);
- X if (index == -1)
- X log_fatal("can't unmount remote fs\n");
- X close(fd);
- X}
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n",
- X "rmtmnt [-sservicename] -g path",
- X "rmtmnt [-sservicename] host path",
- X "rmtmnt");
- X exit(1);
- X}
- X
- Xtcpname(sin, host)
- X struct sockaddr_in *sin;
- X char *host;
- X{
- X struct servent *servp;
- X struct hostent *hostp;
- X int s;
- X
- X servp = getservbyname(service ? service : REMOTE_FS_SERVER, "tcp");
- X
- X if (servp == NULL) {
- X fprintf(stderr, "%s: unknown service\n", REMOTE_FS_SERVER);
- X exit(1);
- X }
- X
- X hostp = gethostbyname(host);
- X if (hostp == NULL) {
- X fprintf(stderr, "%s: unknown host\en", host);
- X exit(1);
- X }
- X bzero((char *)sin, sizeof (struct sockaddr_in));
- X bcopy(hostp->h_addr, (char *)&sin->sin_addr, hostp->h_length);
- X sin->sin_family = hostp->h_addrtype;
- X sin->sin_port = servp->s_port;
- X
- X /*
- X * Ok, now make sure that the connection will work
- X */
- X if (sigvec(SIGALRM, &vec, (struct sigvec *)0) == -1) {
- X perror("signals");
- X return(-1);
- X }
- X s = socket(AF_INET, SOCK_STREAM, 0);
- X if (s < 0)
- X return(-1);
- X alarm(5);
- X if(connect(s, sin, sizeof(struct sockaddr_in)) < 0) {
- X alarm(0);
- X return(-1);
- X }
- X alarm(0);
- X return(s);
- X}
- X
- Xonalrm(sig)
- X{
- X fprintf(stderr, "timeout: ");
- X}
- X
- Xlog_fatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
- X{
- X log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
- X exit(1);
- X}
- X
- Xlog(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
- X{
- X if (errno)
- X perror("rmtmnt");
- X errno = 0;
- X fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
- X}
- SHAREOF
- chmod 444 remote/rmtmnt.c
- #
- # remote/route.c
- #
- if [ -f remote/route.c ]; then
- echo -n 'Hit <return> to overwrite remote/route.c or ^C to quit'
- read ans
- rm -f remote/route.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/route.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 * $Log: route.c,v $
- X * Revision 2.2 86/01/05 18:14:47 toddb
- X * Added a forgotten case to gateway_listen(): S_CORRUPTED.
- X *
- X * Revision 2.1 85/12/19 15:53:23 toddb
- X * Changed declaration of a local variable (sigmask) because it conflicts
- X * with a 4.3 define.
- X *
- X * Revision 2.0 85/12/07 18:22:04 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: route.c,v 2.2 86/01/05 18:14:47 toddb Exp $";
- X#include "server.h"
- X#include <sys/file.h>
- X#include <sys/time.h>
- X#include <setjmp.h>
- X#include <errno.h>
- X
- Xextern short current_pid;
- Xextern short current_ppid;
- Xextern short gateway_server;
- Xextern short current_server;
- Xextern long blocking_servers;
- Xextern long to_gateway;
- Xextern long from_servers;
- Xextern long errno;
- Xextern boolean i_am_gateway;
- Xextern boolean i_have_control;
- Xextern boolean gateway_needs_control;
- Xextern boolean route_to_gateway;
- Xextern boolean watch_for_lock;
- Xextern boolean i_am_asleep;
- Xextern hosts *host;
- X
- X/*
- X * Reroute to the server whose pid is 'pid'.
- X */
- Xreroute(pid, msg)
- X register short pid;
- X register struct message *msg;
- X{
- X if (route_to_gateway)
- X {
- X debug5("routing changed from server %d to gateway\n", pid);
- X route_to_gateway = FALSE;
- X pid = gateway_server;
- X }
- X watch_for_lock = gateway_needs_control = FALSE;
- X dont_gobble_msg(msg);
- X
- X if (pid == current_pid)
- X log_fatal("reroute myself???\n");
- X debug5("%d waking up %d\n", current_pid, pid);
- X
- X /*
- X * If we are the gateway, there may be some servers that are blocking
- X * on a request. If so, then we lock file descriptor 2 with an
- X * shared lock. This tells the server to always check to see if
- X * the lock goes up to an exclusive lock. If so, then the server
- X * must then return control to the gateway.
- X */
- X if (i_am_gateway)
- X {
- X set_label("reading messages");
- X i_have_control = FALSE;
- X if (blocking_servers)
- X if (flock(2, LOCK_NB | LOCK_SH) < 0)
- X log_fatal("cannot lock fd 2\n");
- X }
- X
- X i_am_asleep = TRUE;
- X if (pid == gateway_server)
- X say_something(S_THIS_IS_YOURS, gateway_server);
- X else
- X wake_up(pid);
- X slumber(FALSE);
- X if (! i_am_gateway)
- X {
- X /*
- X * Check for the lock on fd 2. But even if the gateway wants
- X * control, go ahead an serve this request.
- X */
- X if (flock(2, LOCK_NB | LOCK_EX) < 0)
- X if (flock(2, LOCK_NB | LOCK_SH) >= 0)
- X {
- X debug5("watch for lock on each request\n");
- X watch_for_lock = TRUE;
- X flock(2, LOCK_UN);
- X }
- X else
- X {
- X debug5("Gateway wants control\n");
- X gateway_needs_control = TRUE;
- X }
- X else
- X flock(2, LOCK_UN);
- X }
- X}
- X
- X
- X/*
- X * Tell the gateway something.
- X */
- Xsay_something(cmd, arg)
- X register long cmd, arg;
- X{
- X gtmsgs gmsg[2];
- X register gtmsgs *g = gmsg;
- X register long len = sizeof(gtmsgs);
- X
- X
- X if (cmd == S_NEWSERVER) /* actually 2 messages */
- X {
- X g->g_server = current_ppid;
- X g->g_cmd = cmd;
- X g->g_pid = current_pid;
- X cmd = S_NEWPROCESS;
- X g++;
- X len += sizeof(gtmsgs);
- X }
- X g->g_server = current_pid;
- X g->g_cmd = cmd;
- X g->g_pid = arg;
- X
- X debug5("say: cmd=%d, arg=%d\n", cmd, arg);
- X if (write(to_gateway, gmsg, len) != len)
- X log_fatal("pid %d: can't write to gateway!!\n",
- X current_pid);
- X}
- X
- X/*
- X * Read message from servers. We do the allocation of space and maintain it.
- X */
- Xgtmsgs *read_gtmsgs()
- X{
- X static gtmsgs *msgs;
- X static long current_len,
- X len_needed = 10;
- X register long red;
- X register gtmsgs *g;
- X
- X /*
- X * Allocate space for the current read.
- X */
- X if (current_len < len_needed)
- X {
- X if (msgs)
- X msgs = (gtmsgs *)realloc(msgs,
- X len_needed * sizeof(gtmsgs));
- X else
- X msgs = (gtmsgs *)malloc(len_needed * sizeof(gtmsgs));
- X current_len = len_needed;
- X }
- X
- X /*
- X * Now read the messages.
- X */
- X red = read(from_servers, msgs, (current_len-1) * sizeof(gtmsgs));
- X if (red % sizeof(gtmsgs) != 0)
- X log_fatal("partial message on read = %d\n", red);
- X red /= sizeof(gtmsgs);
- X if (red == current_len-1)
- X len_needed++;
- X msgs[ red ].g_server = 0;
- X#ifdef RFSDEBUG
- X for (g=msgs; g->g_server; g++)
- X debug14("red: server %d, cmd %d, pid=%d\n",
- X g->g_server, g->g_cmd, g->g_pid);
- X#endif RFSDEBUG
- X return(msgs);
- X}
- X
- X/*
- X * This process is called to gather incomming messages from servers out
- X * there with something interesting to say. We return TRUE if we have
- X * read a message from a process that is relinquishing control, FALSE
- X * otherwise.
- X */
- Xgateway_listen()
- X{
- X register process *proc;
- X register gtmsgs *msgs, *g;
- X short dequeue();
- X register short cmd, i, pid, server;
- X
- X msgs = read_gtmsgs();
- X
- X errno = 0;
- X for (g=msgs; g->g_server; g++)
- X {
- X pid = g->g_pid;
- X server = g->g_server;
- X cmd = g->g_cmd;
- X
- X switch(cmd) {
- X case S_NEWSERVER: /* a new server forked by another server */
- X debug5("hear: %d forks new server %d\n", server, pid);
- X break;
- X case S_NEWPROCESS: /* a new process is being served */
- X proc = add_new_process(0, pid);
- X proc->p_handler = server;
- X debug5("hear: pid %d serving pid %d\n", server, pid);
- X break;
- X case S_PROCEXIT: /* some server's client did an exit() call */
- X debug5("hear: proc exit from server %d: pid=%d\n",
- X server, pid);
- X if ((proc = findprocess(pid, -1)) == NULL)
- X log("can't find pid %d!\n", pid);
- X else
- X {
- X deletelist(&host->h_proclist, proc);
- X freeproc(proc);
- X }
- X break;
- X case S_I_WOULD_BLOCK: /* server will block on I/O */
- X debug5("hear: server %d blocks\n", server);
- X blocking_servers++;
- X goto gateway_control;
- X case S_ALLDONE: /* an existing server is ready to die */
- X case S_EOF: /* a server got eof on command socket */
- X mourne();
- X debug5("hear: server %d %s... ", server,
- X cmd == S_ALLDONE ? "dead" : "got eof");
- X for (proc=host->h_proclist; proc; proc=proc->p_next)
- X if (proc->p_handler == server)
- X {
- X debug5("free proc %d...", proc->p_pid);
- X deletelist(&host->h_proclist, proc);
- X freeproc(proc);
- X }
- X debug5("\n");
- X /* fall through */
- X case S_THIS_IS_YOURS: /* just relinquish control */
- X gateway_control:
- X /*
- X * Always unlock when we have control.
- X */
- X flock(2, LOCK_UN);
- X if (cmd == S_THIS_IS_YOURS)
- X debug5("hear: server %d gives us control\n",
- X server);
- X /*
- X * Now that we have control, see about dequeing
- X * a server that is ready to go. If there is one,
- X * Then change this message so that it looks like
- X * a message from ourself saying to reroute to
- X * 'server'.
- X */
- X server = dequeue();
- X if (server > 0)
- X {
- X debug5("server %d ready to go\n", server);
- X wake_up(server);
- X }
- X else
- X {
- X debug5("gateway pid %d continuing\n",
- X current_pid);
- X set_label("active");
- X i_have_control = TRUE;
- X }
- X break;
- X case S_I_AM_READY:
- X debug5("hear: server %d ready\n", server);
- X blocking_servers--;
- X if (flock(2, LOCK_EX) < 0)
- X log_fatal("cannot lock fd 2\n");
- X queue(server);
- X break;
- X case S_CORRUPTED:
- X log_fatal("corrupted input stream\n");
- X break;
- X default:
- X log("unknown message from %d = %d\n", server, cmd);
- X break;
- X }
- X }
- X
- X return(FALSE);
- X}
- X
- Xwake_up(pid)
- X long pid;
- X{
- X sendsig(pid, SIGIO);
- X}
- X
- Xsendsig(pid, sig)
- X long pid,
- X sig;
- X{
- X register func logger;
- X extern long log(), log_fatal();
- X
- X change_to_uid(0);
- X if (kill(pid, sig) < 0)
- X {
- X if (errno == ESRCH)
- X logger = log;
- X else
- X logger = log_fatal;
- X logger("couldn't signal %d w/ sig=%d\n", pid, sig);
- X return(FALSE);
- X }
- X return(TRUE);
- X}
- X
- Xstatic short *server_queue;
- Xstatic short server_len;
- Xstatic short last_server;
- X/*
- X * Put a server on a queue to be run again. Fifo queue.
- X */
- Xqueue(pid)
- X register short pid;
- X{
- X if (++last_server > server_len)
- X {
- X server_len++;
- X if (server_queue == NULL)
- X server_queue = (short *)malloc(sizeof(short));
- X else
- X server_queue = (short *)realloc(server_queue,
- X server_len*sizeof(short));
- X }
- X server_queue[ last_server - 1 ] = pid;
- X}
- X
- X/*
- X * Get the first server off the queue. Blech! We have to copy all the
- X * queue back one.
- X */
- Xshort dequeue()
- X{
- X register short retval, i;
- X
- X if (last_server == 0)
- X return(0);
- X retval = server_queue[ 0 ];
- X for (i=1; i<last_server; i++)
- X server_queue[ i-1 ] = server_queue[ i ];
- X last_server--;
- X return( retval );
- X}
- X
- X/*
- X * Go to sleep awaiting a wakup call. Do not return until we receive it.
- X * However, if we are the gateway, we, of course MUST return and go
- X * on reading messages.
- X *
- X * Since there is a window between testing the i_am_asleep flag and doing
- X * the pause, in which we could be awakened, we must always jump around
- X * this loop using longjmp() from the interrupt routine.
- X */
- Xslumber(forked)
- X boolean forked;
- X{
- X register long signalmask;
- X
- X if (i_am_gateway)
- X {
- X set_label("reading messages");
- X i_have_control = FALSE;
- X return;
- X }
- X set_label("asleep");
- X signalmask = sigblock(1<<(SIGIO-1));
- X while (i_am_asleep)
- X sigpause(signalmask);
- X sigsetmask(signalmask);
- X
- X debug5("pid %d continuing%s\n",
- X current_pid, forked ? "after fork" : "");
- X set_label("active");
- X mourne();
- X}
- SHAREOF
- chmod 444 remote/route.c
- #
- # remote/server.h
- #
- if [ -f remote/server.h ]; then
- echo -n 'Hit <return> to overwrite remote/server.h or ^C to quit'
- read ans
- rm -f remote/server.h
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/server.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: server.h,v 2.0 85/12/07 18:22:12 toddb Rel $
- X *
- X * $Log: server.h,v $
- X * Revision 2.0 85/12/07 18:22:12 toddb
- X * First public release.
- X *
- X */
- X#include <sys/param.h>
- X#include <sys/mbuf.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <remote/remotefs.h>
- X
- Xtypedef unsigned char boolean;
- X
- X/*
- X * The maximum number of longs in a message that we accept
- X */
- X#define MAXMSGS ((R_MAXMBUFS*MLEN)/sizeof(long))
- X/*
- X * The name of a host for which we have no record. And the name of the user
- X * to use if we don't recognize the user on the remote host.
- X */
- X#define BOGUSHOST "unknown host"
- X#define BOGUSUSER "unknown user"
- X#define DEFAULTUSER "guest"
- X
- X/*
- X * The uid number below which we reserve for privilaged users.
- X */
- X#define UID_TOO_LOW 20
- X
- X/*
- X * This is to make the debug? macro work for the server.
- X *
- X * The bits and what they turn on are as follows
- X * 0x00000001 process switching
- X * 0x00000002 system calls
- X * 0x00000004 setuid/setgid, umask
- X * 0x00000008 file descriptor allocation
- X * 0x00000010 connections
- X * 0x00000020 server switching
- X * 0x00000040 nameserver
- X * 0x00000080 directory nuxi
- X * 0x00000100 message in and out
- X * 0x00000200 don't fork child for gateway (good for adb)
- X * 0x00000400 local/remote file decisions
- X * 0x00000800 don't remove log file on exit (except exit on error)
- X * 0x00001000 exec information
- X * 0x00002000 auto debug for 0x20 (server switching)
- X * 0x00004000 parsing messages to gateway
- X */
- X#define rmt_debug log
- X#ifndef RFSDEBUG
- X#define dumphost()
- X#endif RFSDEBUG
- X
- X/*
- X * The size of the initial allocation for internal io buffers.
- X */
- X#define BIGBUF (8*1024)
- X
- X/*
- X * other Manifest constants...
- X */
- X#define HOSTNAMELEN 255
- X
- X/*
- X * Map a file descriptor from the user's fd to our own internal fd.
- X */
- X#define MAPFD(fd, proc) \
- X (((unsigned)fd > NOFILE) ? -1 : (proc)->p_fds[ fd ] )
- X/*
- X * requirements for different system calls.
- X */
- X#define NEED_ZIP 0x000 /* don't need anything special */
- X#define NEED_CWD 0x001 /* need the current working directory set */
- X#define NEED_PERM 0x002 /* need the user and group ids set */
- X#define NEED_FD 0x004 /* need a file descriptor allocated */
- X#define NEED_2PATH 0x010 /* uses two paths */
- X#define NEED_MYSERVER 0x020 /* must be run by the assigned server */
- X#define NEED_2REMOTE 0x040 /* both paths must be remote */
- X
- X/*
- X * Commands to the server sent by external programs (like rmtmnt, to mount
- X * a remote system.
- X */
- X#define CMD_SERVICE 1
- X#define CMD_MOUNT 2 /* here is mount information */
- X#define CMD_NEEDMOUNT 3 /* give me mount information */
- X#define CMD_WHOAMI 4 /* what uid am I on your host */
- X
- X/*
- X * Finally, some commands that are sent to the gateway server by other
- X * servers.
- X */
- X#define S_NEWSERVER 0
- X#define S_NEWPROCESS 1
- X#define S_ALLDONE 2
- X#define S_THIS_IS_YOURS 3
- X#define S_PROCEXIT 4
- X#define S_EOF 5
- X#define S_I_WOULD_BLOCK 6
- X#define S_I_AM_READY 7
- X#define S_CORRUPTED 8
- X
- X/*
- X * Macros for getting the address of the paths out of the incomming message.
- X * Note that path1addr is for system calls that deal with only one path,
- X * and twopath1addr() and twopath2addr() are for system calls that have
- X * two paths (in the latter cases, path2 appears in the same position
- X * as path1 does for single path system calls).
- X */
- X#define path1addr(msg) ((char *)&(msg)->m_args[R_PATHSTART])
- X#define twopath1addr(msg) ((char *)(msg) + (msg)->m_args[R_PATHOFF])
- X#define twopath2addr(msg) ((char *)&(msg)->m_args[R_PATHSTART])
- X
- X/*
- X * Macro for preventing getmsg(), and thereby gobble_last_msg() from
- X * reading the last message. This is used when control is being passed
- X * from one server to another.
- X */
- X#define dont_gobble_msg(msg) (msg)->m_totlen = 0
- X
- X/*
- X * Macro for determining whether a stat structure reflects the root inode
- X * of our machine or not.
- X */
- X#define isroot(p) (p->st_ino == root.st_ino && p->st_dev == root.st_dev)
- X
- X/*
- X * This structure is one-to-one with each local user where the server runs.
- X * Note that the u_next and u_prev pointers must be located
- X * in the first and second spots of the structure, respectively so that
- X * they can be modified by the linked-list routines.
- X */
- Xtypedef struct users_type users;
- Xstruct users_type {
- X users *u_next; /* pointers for linked list, both forward... */
- X users *u_prev; /* ... and back. */
- X char *u_name; /* The ascii name of same. */
- X char *u_dir; /* login directory for same */
- X char *u_rhosts; /* path of the user's rhost file */
- X short u_local_uid; /* A user id number on the local host */
- X long u_local_groups[NGROUPS];/* The groups this user belongs to */
- X char u_numgroups; /* The number of groups in u_local_groups */
- X};
- X
- X/*
- X * Remote user specification.
- X */
- Xtypedef struct ruser_type rusers;
- Xstruct ruser_type {
- X rusers *r_next;
- X rusers *r_prev;
- X short r_uid; /* Uid number on remote host ... */
- X char *r_name; /* Uid name on remote host ... */
- X users *r_user; /* corresponding local user */
- X};
- X
- X/*
- X * This is the important stuff. There is one of these structures for
- X * each pid that we are providing service to.
- X */
- Xtypedef struct process_type process;
- Xstruct process_type {
- X process *p_next;
- X process *p_prev;
- X long p_returnval; /* return value from last syscall */
- X rusers *p_ruser; /* info about the owner of this pid */
- X short p_pid; /* process id number on remote host */
- X short p_uid; /* remote uid that was last known */
- X short p_handler; /* the handler for this process */
- X short p_errno; /* errno for the system call */
- X char p_execfd; /* file descriptor of exec file */
- X boolean p_execstarted; /* whether we have done first read */
- X char p_fds[ NOFILE ];/* fd's assoc. with this pid */
- X};
- X
- X/*
- X * This structure keeps track of the possible hosts that may make a connection
- X * the the remote fs server. Note that the h_next and hprev pointers must be
- X * located in the first and second spots of the structure, respectively,
- X * so that they can be modified by the linked-list routines.
- X */
- Xtypedef struct hosts_type hosts;
- Xstruct hosts_type {
- X hosts *h_next;
- X hosts *h_prev;
- X char **h_names; /* name (and aliases) of a host */
- X rusers *h_rusers; /* the user list for this host */
- X users *h_default_user;/* default local user (if defined */
- X rusers *h_default_ruser;/* default when the remote user is unknown */
- X long h_portnum; /* port number that we connected on */
- X char *h_mntpt; /* mount point for this machine */
- X process *h_proclist; /* processes we know about on this host */
- X struct in_addr h_addr; /* network address */
- X union h_bytes {
- X long hu_mounted; /* non-zero if host has been mounted */
- X u_char hu_byteorder[4]; /* byte order for this host */
- X } h_bytes;
- X#define h_mounted h_bytes.hu_mounted
- X#define h_byteorder h_bytes.hu_byteorder
- X char h_cmdfd; /* file descriptor for commands */
- X boolean h_byteorderok; /* true if byte order same as ours */
- X short h_serverpid; /* gateway server for this host */
- X};
- X
- X/*
- X * This structure is the mask structure that the linked list routines use
- X * to modify any linked-list type of structure. Note that l_next and l_prev
- X * must be in the first and second spots.
- X */
- Xtypedef struct l_list_type l_list;
- Xstruct l_list_type {
- X l_list *l_next;
- X l_list *l_prev;
- X long l_data; /* never used */
- X};
- X
- X/*
- X * This structure is for convenience: it simply defines an easy way of
- X * storing the host/user line found in a .rhost file.
- X */
- Xtypedef struct rhost_type rhost;
- Xstruct rhost_type {
- X char *rh_host;
- X char *rh_user;
- X};
- X
- X/*
- X * Each message from the servers to the gateway, is placed into this
- X * structure, the "gateway message".
- X */
- Xtypedef struct gtmsg_type gtmsgs;
- Xstruct gtmsg_type {
- X short g_server; /* server that sent the message. */
- X short g_pid; /* pid of whom this message is about */
- X short g_cmd; /* what this message is about */
- X};
- X
- X/*
- X * Finally, this is the way we keep database info on the system calls
- X * themselves.
- X */
- Xtypedef struct syscallmap syscallmap;
- Xstruct syscallmap {
- X func s_server;
- X func s_syscall;
- X char s_type;
- X};
- X
- Xrhost *getrhostent();
- Xhosts *tcpaccept();
- Xhosts *findhostaddr();
- Xhosts *findhostname();
- Xhosts *newhost();
- Xl_list *toplist();
- Xl_list *bottomlist();
- Xl_list *addlist();
- Xl_list *deletelist();
- Xprocess *newprocess();
- Xprocess *findprocess();
- Xprocess *change_to_proc();
- Xprocess *add_new_process();
- Xusers *finduid();
- Xusers *findusername();
- Xusers *newuser();
- Xrusers *findremuid();
- Xrusers *findrusername();
- Xrusers *newruser();
- Xchar **newname();
- Xchar *copy();
- Xchar *malloc();
- Xchar *realloc();
- Xchar *get_data_buf();
- Xshort *newshortlist();
- SHAREOF
- chmod 444 remote/server.h
- #
- # remote/serverdata.c
- #
- if [ -f remote/serverdata.c ]; then
- echo -n 'Hit <return> to overwrite remote/serverdata.c or ^C to quit'
- read ans
- rm -f remote/serverdata.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/serverdata.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 * $Log: serverdata.c,v $
- X * Revision 2.0 85/12/07 18:22:20 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: serverdata.c,v 2.0 85/12/07 18:22:20 toddb Rel $";
- X#include "server.h"
- X#include <nlist.h>
- X#include <signal.h>
- X#include <netdb.h>
- X#include <sys/stat.h>
- X
- X/*
- X * system calls.
- X */
- Xlong access(), chdir(), chmod(), chown(), close(), dup(), execve(),
- X fchmod(), fchown(), fcntl(), flock(), fork(), fstat(), fsync(),
- X ftruncate(), ioctl(), link(), lseek(), lstat(), mkdir(),
- X mknod(), open(), read(), readlink(), rename(), rmdir(),
- X stat(), symlink(), truncate(), unlink(), utimes(),
- X write(),
- X/*
- X * ...and our own routines to set up for the system calls.
- X */
- X noop(), s_access(), s_dup(), s_execinfo(), s_execread(), s_exit(),
- X s_fcntl(), s_fd1(), s_fd1_plus(), s_fork(), s_ioctl(), s_lseek(),
- X s_open(), s_path1(), s_path1_plus(), s_path2(), s_read(),
- X s_readlink(), s_stat(), s_utimes(), s_write();
- X
- Xsyscallmap smap[] = {
- X s_fork, noop, NEED_ZIP, /* RSYS_fork */
- X s_read, read, NEED_ZIP, /* RSYS_read */
- X s_write, write, NEED_ZIP, /* RSYS_write */
- X s_open, open, NEED_CWD
- X |NEED_MYSERVER
- X |NEED_PERM
- X |NEED_FD, /* RSYS_open */
- X s_fd1, close, NEED_ZIP, /* RSYS_close */
- X noop, noop, NEED_CWD
- X |NEED_PERM
- X |NEED_FD, /* RSYS_creat */
- X s_path2, link, NEED_CWD
- X |NEED_MYSERVER
- X |NEED_2PATH
- X |NEED_2REMOTE
- X |NEED_PERM, /* RSYS_link */
- X s_path1, unlink, NEED_CWD|NEED_PERM, /* RSYS_unlink */
- X s_path1, chdir, NEED_MYSERVER
- X |NEED_CWD
- X |NEED_PERM
- X |NEED_MYSERVER, /* RSYS_chdir */
- X s_path1_plus, mknod, NEED_CWD|NEED_PERM, /* RSYS_mknod */
- X s_path1_plus, chmod, NEED_CWD|NEED_PERM, /* RSYS_chmod */
- X s_path1_plus, chown, NEED_CWD|NEED_PERM, /* RSYS_chown */
- X s_stat, stat, NEED_CWD|NEED_PERM, /* RSYS_stat */
- X s_lseek, lseek, NEED_ZIP, /* RSYS_lseek */
- X s_access, access, NEED_CWD|NEED_PERM, /* RSYS_access */
- X s_stat, lstat, NEED_CWD|NEED_PERM, /* RSYS_lstat */
- X s_dup, dup, NEED_FD, /* RSYS_dup */
- X s_ioctl, ioctl, NEED_ZIP, /* RSYS_ioctl */
- X s_path2, symlink, NEED_CWD
- X |NEED_2PATH
- X |NEED_PERM, /* RSYS_symlink */
- X s_readlink, readlink, NEED_CWD|NEED_PERM, /* RSYS_readlink */
- X s_stat, fstat, NEED_ZIP, /* RSYS_fstat */
- X s_dup, dup, NEED_FD, /* RSYS_dup2 */
- X s_fd1_plus, fcntl, NEED_ZIP, /* RSYS_fcntl */
- X s_fd1, fsync, NEED_ZIP, /* RSYS_fsync */
- X noop, noop, NEED_ZIP, /* RSYS_readv */
- X noop, noop, NEED_ZIP, /* RSYS_writev */
- X s_fd1_plus, fchown, NEED_PERM, /* RSYS_fchown */
- X s_fd1_plus, fchmod, NEED_PERM, /* RSYS_fchmod */
- X s_path2, rename, NEED_MYSERVER
- X |NEED_2REMOTE
- X |NEED_CWD
- X |NEED_2PATH
- X |NEED_PERM, /* RSYS_rename */
- X s_path1_plus, truncate, NEED_CWD|NEED_PERM, /* RSYS_truncate */
- X s_fd1_plus, ftruncate,NEED_ZIP, /* RSYS_ftruncate */
- X s_fd1_plus, flock, NEED_ZIP, /* RSYS_flock */
- X s_path1_plus, mkdir, NEED_CWD|NEED_PERM, /* RSYS_mkdir */
- X s_path1, rmdir, NEED_CWD|NEED_PERM, /* RSYS_rmdir */
- X s_utimes, utimes, NEED_CWD|NEED_PERM, /* RSYS_utimes */
- X s_exit, noop, NEED_ZIP, /* RSYS_exit */
- X s_fork, noop, NEED_ZIP, /* RSYS_Vfork */
- X s_execinfo, noop, NEED_MYSERVER
- X |NEED_CWD
- X |NEED_PERM, /* RSYS_execinfo */
- X s_execread, noop, NEED_PERM, /* RSYS_execread */
- X noop, noop, NEED_ZIP, /* RSYS_execve */
- X noop, noop, NEED_ZIP, /* RSYS_nosys */
- X s_lseek, lseek, NEED_ZIP, /* RSYS_qlseek */
- X};
- X
- Xchar *syscallnames[] = {
- X "fork",
- X "read",
- X "write",
- X "open",
- X "close",
- X "creat",
- X "link",
- X "unlink",
- X "chdir",
- X "mknod",
- X "chmod",
- X "chown",
- X "stat",
- X "lseek",
- X "access",
- X "lstat",
- X "dup",
- X "ioctl",
- X "symlink",
- X "readlink",
- X "fstat",
- X "dup2",
- X "fcntl",
- X "fsync",
- X "readv",
- X "writev",
- X "fchown",
- X "fchmod",
- X "rename",
- X "truncate",
- X "ftruncate",
- X "flock",
- X "mkdir",
- X "rmdir",
- X "utimes",
- X "exit",
- X "vfork",
- X "execinfo",
- X "execread",
- X "execve",
- X "nosys",
- X "quick lseek"
- X};
- X
- Xchar hostname[ HOSTNAMELEN ];/* our host name */
- Xchar mntpt[ MAXPATHLEN ]; /* mount point for client */
- Xchar *program; /* name of this program */
- Xchar *last_argaddr; /* last address that we can scribble on */
- Xchar *service = REMOTE_FS_SERVER; /* name of alternate internet service */
- Xchar *stdlogfile = "/usr/tmp/rfs_log"; /* log file for server */
- Xchar *logfile;
- Xlong serviceport; /* port number for service */
- Xlong remote_debug; /* level of debug output */
- Xshort current_uid; /* whatever uid we are, right now */
- Xshort current_pid; /* whatever pid we are, right now */
- Xshort current_ppid; /* our parent server */
- Xshort current_umask; /* whatever umask we have, right now */
- Xshort current_server; /* server that has control right now */
- Xshort gateway_server; /* pid of our gateway */
- Xshort last_sentry; /* previous sentry server (if non-zero) */
- Xlong fds_in_use; /* number of total file descriptors open */
- Xlong to_gateway; /* file descriptor for messages to gateway */
- Xlong so_listen; /* socket for listening for connections */
- Xlong from_servers; /* file descriptor for messages from servers */
- Xlong blocking_servers; /* number of servers waiting for I/O */
- Xhosts *hostlist; /* all the hosts we know of */
- Xhosts *host; /* the current host that we talk to */
- Xhosts *thishost; /* host pointer for this machine */
- Xusers *userlist; /* all the users on this host we know of */
- Xusers *default_user; /* default user to map unknown clients to */
- Xprocess *wildcard; /* wildcard process for easy requests */
- Xboolean i_am_gateway = TRUE; /* whether we are the gateway server */
- Xboolean i_have_control = TRUE; /* whether the gateway server has control of */
- X /* the command socket */
- Xboolean i_am_asleep; /* whether we are sleeping or not */
- Xboolean gateway_needs_control; /* True if gateway wants control back */
- Xboolean watch_for_lock; /* True if we need to watch for lock on fd 2 */
- Xboolean route_to_gateway; /* True if we should route to gateway */
- Xboolean in_root_directory = TRUE;/* whether we are at root directory or not */
- Xstruct stat filetypes[ NOFILE ]; /* file types for open files */
- X
- Xchar byteorder[4] = { BYTEORDER };
- Xlong catch(),
- X nameserver(),
- X wakeup_call(),
- X alarmsig();
- X
- Xstruct sigvec sig_continue = {
- X wakeup_call,
- X 1<<(SIGIO -1),
- X 0
- X};
- X
- Xstruct sigvec sig_ignore = {
- X (int (*)())SIG_IGN,
- X 1<<(SIGHUP -1),
- X 0
- X};
- X
- Xstruct sigvec sig_alarm = {
- X alarmsig,
- X 1<<(SIGALRM -1),
- X 0
- X};
- X
- Xstruct sigvec sig_name = {
- X nameserver,
- X 1<<(SIGURG -1),
- X 0
- X};
- X
- Xstruct sigvec sig_vec = {
- X catch,
- X (1<<(SIGINT -1))
- X |(1<<(SIGQUIT-1))
- X |(1<<(SIGBUS-1))
- X |(1<<(SIGILL-1))
- X |(1<<(SIGSEGV-1))
- X |(1<<(SIGPIPE-1))
- X |(1<<(SIGSYS-1))
- X |(1<<(SIGTERM-1))
- X |(1<<(SIGTTIN-1))
- X |(1<<(SIGTTOU-1))
- X |(1<<(SIGXCPU-1))
- X |(1<<(SIGXFSZ-1))
- X |(1<<(SIGVTALRM-1)),
- X 0
- X};
- X
- X#ifdef RFSDEBUG
- X
- Xlong newdebug();
- X
- Xstruct sigvec sig_debug = {
- X newdebug,
- X (1<<(SIGTRAP -1)),
- X 0
- X};
- X#endif RFSDEBUG
- X
- Xstruct stat root; /* stat info for root directory */
- SHAREOF
- chmod 444 remote/serverdata.c
- #
- # remote/serverdir.c
- #
- if [ -f remote/serverdir.c ]; then
- echo -n 'Hit <return> to overwrite remote/serverdir.c or ^C to quit'
- read ans
- rm -f remote/serverdir.c
- fi
-
- sed -e 's/^.//' << \SHAREOF > remote/serverdir.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 * $Log: serverdir.c,v $
- X * Revision 2.0 85/12/07 18:22:28 toddb
- X * First public release.
- X *
- X */
- Xstatic char *rcsid = "$Header: serverdir.c,v 2.0 85/12/07 18:22:28 toddb Rel $";
- X#include "server.h"
- X#include <sys/dir.h>
- X#include <sys/stat.h>
- X#include <errno.h>
- X
- Xextern hosts *host;
- Xextern long errno;
- Xextern char byteorder[];
- Xextern struct stat filetypes[];
- X
- X/*
- X * Check to see type open file type... we may have to massage input
- X * it if the user wants to read this file descriptor and it is a directory.
- X */
- Xcheckfiletype(fd)
- X register int fd;
- X{
- X struct stat statb, *statp = &statb;
- X
- X if (fd < 0)
- X return;
- X fstat(fd, statp);
- X filetypes[ fd ] = statb;
- X}
- X
- X/*
- X * If byte-ordering is different between this machine and our client,
- X * the directories must be massaged into the right byte order.
- X */
- Xfixdir(fd, buf, size)
- X register long size,
- X fd;
- X register char *buf;
- X{
- X register struct direct *dirp;
- X register char *next, *last;
- X register u_char *clientorder = host->h_byteorder;
- X short fixshort();
- X
- X if (size < 0)
- X return(errno);
- X if (fd >= NOFILE || (filetypes[fd].st_mode & S_IFDIR) == 0)
- X return(0);
- X
- X /*
- X * we don't know this client's byteorder... can't do it right
- X */
- X if (!host->h_mounted)
- X return(EIO);
- X dirp = (struct direct *)buf;
- X last = buf;
- X debug7("nuxi directory entry buf=0%x, size=%d, end @%x\n",
- X buf, size, buf+size);
- X while(last < buf + size && dirp->d_reclen)
- X {
- X dirp = (struct direct *)last;
- X next = last + dirp->d_reclen;
- X
- X debug7("dir @0x%x (next+%d @0x%x): %x %x %x %s -->",
- X last, dirp->d_reclen, next,
- X dirp->d_ino,
- X (unsigned)dirp->d_reclen,
- X (unsigned)dirp->d_namlen,
- X dirp->d_name);
- X dirp->d_ino = fixlong(clientorder, &dirp->d_ino);
- X dirp->d_reclen = fixshort(clientorder, &dirp->d_reclen);
- X dirp->d_namlen = fixshort(clientorder, &dirp->d_namlen);
- X debug7(" %x %x %x %s\n",
- X dirp->d_ino,
- X (unsigned)dirp->d_reclen,
- X (unsigned)dirp->d_namlen,
- X dirp->d_name);
- X last = next;
- X }
- X return(0);
- X}
- X
- Xfixlong(clto, from)
- X register char *clto, /* clients byte order */
- X *from; /* data to be fixed */
- X{
- X register char *srvo, /* server's byte order */
- X *to;
- X long result;
- X
- X to = (char *)&result;
- X srvo = byteorder;
- X to[ clto[0] ] = from[ srvo[0] ];
- X to[ clto[1] ] = from[ srvo[1] ];
- X to[ clto[2] ] = from[ srvo[2] ];
- X to[ clto[3] ] = from[ srvo[3] ];
- X return(result);
- X}
- X
- Xshort fixshort(clto, from)
- X register char *clto, /* clients byte order */
- X *from; /* data to be fixed */
- X{
- X register char *srvo, /* server's byte order */
- X *to;
- X short result;
- X
- X to = (char *)&result;
- X srvo = byteorder;
- X to[ clto[0]&0x1 ] = from[ srvo[0]&0x1 ];
- X to[ clto[1]&0x1 ] = from[ srvo[1]&0x1 ];
- X return(result);
- X}
- SHAREOF
- chmod 444 remote/serverdir.c
-
-