kstuff 0.18 (part 4/6)

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Tue May 7 14:50:59 AEST 1991


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 6)."
# Contents:  INSTALL OFILES.hist authd.c findinode/README
#   findinode/fid.c getnode.c getsocket.c getuser.c mntops.c
# Wrapped by brnstnd at kramden on Mon May  6 23:59:01 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'INSTALL'\"
else
echo shar: Extracting \"'INSTALL'\" \(5717 characters\)
sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
X#!/bin/sh
X
X# Actions.
X# Change kmem to anything and mode to 0755 if you don't have a kmem group,
X# or change kmem to anything and mode to 0700 if you don't want normal
X# users to be able to use these utilities.
XMODE=02755  # load, pff
XSYSMODE=02755  # authd, tcpuid, tcpuname, netstatuids
XGROUP=kmem
XINSTALL="install -c"
XPROGINSTALL="$INSTALL -g $GROUP -m $MODE"
XSYSINSTALL="$INSTALL -g $GROUP -m $SYSMODE"
XLIBINSTALL="$INSTALL -m 0444"   # really ends up 0644
XMANINSTALL="$INSTALL -m 0444"
X
X# Directories.
XBIN=/usr/local/bin
XETC=/etc
XLIB=/usr/lib
XINCLUDE=/usr/include
XMAN=/usr/man
X
X# Programs.
XPFF="$BIN"/pff
XLOAD="$BIN"/load
XAUTHD="$ETC"/authd
XTCPUID="$ETC"/tcpuid # must be on same filesystem as authd
XTCPUNAME="$ETC"/tcpuname # ditto
XNETSTATUIDS="$ETC"/netstatuids
XAUTHUSER="$LIB"/libauthuser.a
XAUTHUSERH="$INCLUDE"/authuser.h
X
X# Man pages.
XMPFF="$MAN"/man1/pff.1  # XXX: not used
XMLOAD="$MAN"/man1/load.1
XMAUTHUSER="$MAN"/man3/authuser.3
XMAUTHD="$MAN"/man8/authd.8
XMTCPUID="$MAN"/man8/tcpuid.8
XMTCPUNAME="$MAN"/man8/tcpuname.8
XMNETSTATUIDS="$MAN"/man8/netstatuids.8  # XXX: not used
X
X# Name of port 113 in /etc/services.
XPORTNAME=auth
X
Xecho "Each action will be printed before it is run. Press return to proceed."
Xecho "Type skip (or anything starting with an s) to skip a step."
Xecho "(To see all actions, do something like % yes skip | sh INSTALL.)"
X
Xecho "1. Install load and pff."
Xecho "! $PROGINSTALL pff $PFF: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$PROGINSTALL" pff "$PFF" ;;
Xesac
X
Xecho "! $PROGINSTALL load $LOAD: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$PROGINSTALL" load "$LOAD" ;;
Xesac
X
Xecho "2. Install authd, tcpuid, tcpuname, and netstatuids."
Xecho "! $SYSINSTALL authd $AUTHD: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$SYSINSTALL" authd "$AUTHD" ;;
Xesac
X
Xecho "! rm -f $TCPUID; ln $AUTHD $TCPUID: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) rm -f "$TCPUID"; ln "$AUTHD" "$TCPUID" ;;
Xesac
X
Xecho "! rm -f $TCPUNAME; ln $AUTHD $TCPUNAME: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) rm -f "$TCPUNAME"; ln "$AUTHD" "$TCPUNAME" ;;
Xesac
X
Xecho "! $SYSINSTALL netstatuids $NETSTATUIDS: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$SYSINSTALL" netstatuids "$NETSTATUIDS" ;;
Xesac
X
Xecho "3. Install the authuser library."
Xecho "! $LIBINSTALL authuser.h $AUTHUSERH: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$LIBINSTALL" authuser.h "$AUTHUSERH" ;;
Xesac
X
Xecho "! ar rv $AUTHUSER authuser.o: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) ar rv "$AUTHUSER" authuser.o ;;
Xesac
X
Xecho "! ranlib $AUTHUSER: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) ranlib "$AUTHUSER" ;;
Xesac
X
Xecho "! chmod 644 $AUTHUSER: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) chmod 644 "$AUTHUSER" ;;
Xesac
X
Xecho "4. Make the man pages available."
Xecho "! $MANINSTALL authuser.3 $MAUTHUSER: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$MANINSTALL" authuser.3 "$MAUTHUSER" ;;
Xesac
X
Xecho "! $MANINSTALL load.1 $MLOAD: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$MANINSTALL" load.1 "$MLOAD" ;;
Xesac
X
Xecho "! $MANINSTALL authd.8 $MAUTHD: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$MANINSTALL" authd.8 "$MAUTHD" ;;
Xesac
X
Xecho "! $MANINSTALL tcpuid.8 $MTCPUID: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$MANINSTALL" tcpuid.8 "$MTCPUID" ;;
Xesac
X
Xecho "! $MANINSTALL tcpuname.8 $MTCPUNAME: " | tr -d '\012'
Xread line; case "$line" in
Xs*) echo "[skipped]" ;;
X*) eval "$MANINSTALL" tcpuname.8 "$MTCPUNAME" ;;
Xesac
X
Xecho "5. Make sure an auth port is in /etc/services."
Xecho "Let me glance at /etc/services for you..."
Xif grep '^'$PORTNAME'[ 	]*113/tcp' /etc/services >/dev/null 2>&1
Xthen echo "Okay, you have it already. Let's continue."
Xelse echo "Nope, it's not there."
X     echo "Let me check that you don't have a different auth port..."
X     if grep '^'$PORTNAME'[ 	][ 	]*' /etc/services >/dev/null 2>&1
X     then echo "Aaack! $PORTNAME is already used in /etc/services. Exiting."
X	  exit 1
X     fi
X     echo "! echo $PORTNAME'	113/tcp' >> /etc/services: " | tr -d '\012'
X     read line; case "$line" in
X     s*) echo "[skipped]" ;;
X     *) echo "$PORTNAME"'		113/tcp' >> /etc/services ;;
X     esac
Xfi
X
Xecho "6. Enable auth in /etc/inetd.conf."
Xecho "Let me glance at /etc/inetd.conf for you..."
Xif grep '^'"$PORTNAME"'[ 	]' /etc/inetd.conf >/dev/null 2>&1
Xthen echo "Okay, it's already there. That's it!"
X     exit 0
Xfi
Xif grep 'telnet.*root' /etc/inetd.conf >/dev/null 2>&1
Xthen echo "It's not there yet. Hmmm, looks like you have a Sun-style inetd."
X     echo "! echo $PORTNAME' stream tcp nowait root '$AUTHD' authd' >> /etc/inetd.conf: " | tr -d '\012'
X     read line; case "$line" in
X     s*) echo "[skipped]" ;;
X     *) echo "$PORTNAME"'	stream	tcp	nowait	root	'"$AUTHD"'	authd' >> /etc/inetd.conf ;;
X     esac
Xelse echo "It's not there yet."
X     echo "! echo $PORTNAME' stream tcp nowait '$AUTHD' authd' >> /etc/inetd.conf: " | tr -d '\012'
X     read line; case "$line" in
X     s*) echo "[skipped]" ;;
X     *) echo "$PORTNAME"'	stream	tcp	nowait	'"$AUTHD"'	authd' >> /etc/inetd.conf ;;
X     esac
Xfi
X
Xecho "7. Let inetd know about the new service."
Xecho "On most machines you have to % kill -HUP nn"
Xecho "where nn is the number of the inetd process."
Xecho "Here's what ps acugx shows about inetd:"
Xps acugx | sed -n -e 1p -e /inetd/p
Xecho "I'll leave this step to you. That's it!"
X
Xexit 0
END_OF_FILE
if test 5717 -ne `wc -c <'INSTALL'`; then
    echo shar: \"'INSTALL'\" unpacked with wrong size!
fi
chmod +x 'INSTALL'
# end of 'INSTALL'
fi
if test -f 'OFILES.hist' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'OFILES.hist'\"
else
echo shar: Extracting \"'OFILES.hist'\" \(6101 characters\)
sed "s/^X//" >'OFILES.hist' <<'END_OF_FILE'
XA history of ofiles
XDan Bernstein
X4/6/91
X
X
X1. Contributors to ofiles/fstat/pff
X
XC. Spencer <??? at BBN> was the original author of ofiles.
X
XVic Abell <abe at mace.cc.purdue.edu>
XDan Bernstein <brnstnd at nyu.edu>
XWill Crowder <willcr at ism.isc.com>
XTom Christiansen <tchrist at convex.com>
XMichael Ditto <???>
XViktor Dukhovni <viktor at shearson.com>
XTom Dunigan <dunigan at msr.epm.ornl.gov>
XAlexander Dupuy <dupuy at cs.columbia.edu>
XVik Lall <???>
XCraig Leres <leres at helios.ee.lbl.gov>
XRay Moody <Ray.Moody at timbuk.cray.com>
XGary Nebbett <grn at stl.stc.co.uk last known address>
XTim Rosmus <tim at pilchuck.data-io.com>
XMike Spitzer <???>
XRichard Tobin <richard at aiai.ed.ac.uk>
X
XParticular thanks to Vic Abell, Alexander Dupuy, and Craig Leres for a
Xlot of the information contained here. Thanks also to Eduardo Krell
X<ekrell at ulysses.att.com> for bringing the Dupuy version of ofiles to my
Xattention.
X
X
X2. The ofiles/fstat/pff tree
X
X  original ofiles
X	 |
X  modified original ofiles  find-fs   BSD 4.3-Tahoe fstat
X	 |             \     |                 |
X  Abell ofiles      Dupuy ofiles        Abell fstat
X	 |                   |                 |
X  modified Abell ofiles      |        Christiansen fstat
X		  \          |         /
X		   ---------pff--------
X
XThe lines here trace ideas, not just code. pff does not use any fstat
Xcode, but it borrows heavily from the fstat output format, for example.
X
X
X3. Who, what, when
X
XC. Spencer <??? at BBN> wrote the original ofiles for BSD 4.2, around
XMay 1985. This is the ``original ofiles'' node above.
X
XAlexander Dupuy <dupuy at cs.columbia.edu> maintained ofiles in September
Xand October 1988. He integrated a vnode version with DYNIX support from
XTom Dunigan <dunigan at msr.epm.ornl.gov>, modified it to work with remote
Xfiles and filesystems, added support for examining the descriptor tables
Xof selected processes, added text segment support, merged enhancements
Xto the vnode version with the inode version, added socket-printing
Xoptions done in August 1988 by Craig Leres <leres at helios.ee.lbl.gov>,
Xand ported ofiles to Ultrix 2.0.
X
XAt some point (viz., ``modified original ofiles''), another version of
Xofiles---the ``Abell ofiles'', maintained by Vic Abell
X<abe at mace.cc.purdue.edu>---split off the above branch. See below for
Xfurther details.
X
XIn July 1990 Dupuy eliminated the DYNIX support but integrated several
Xfurther versions, including an initial SunOS 4.0 port by Gary Nebbett
X<last known address grn at stl.stc.co.uk> and socket-searching enhancements
Xby Viktor Dukhovni <viktor at shearson.com>. He then ported ofiles to a VAX
Xrunning 4.3+NFS and finished integrating Dukhovni's May 1990 SunOS 4.1
Xport. This version was distributed. In late June 1990 Dupuy integrated a
Xpatch from Tim Rosmus <tim at pilchuck.data-io.com> to distinguish between
XNFS4 vnodes and SunOS 4's NFS, to handle Mt. XINU systems. That version
Xis the ``Dupuy ofiles'' node in the tree.
X
XThe Abell ofiles gives credit to Dunigan, Dupuy, Nebbett, Michael Ditto
X<???>, and Richard Tobin <richard at aiai.ed.ac.uk>.  It is not clear when
Xthis version split off; it may have been directly from the original
Xofiles, as it does not support NFS. Abell tracked down the above names;
Xthey did not (necessarily) contribute to that version. (In fact, Tobin
Xapparently did not work on ofiles; Dupuy took the text segment search
Xcode from Tobin's find-fs, which he posted to Sun-Spots at some point.)
X
XAt the Purdue University Computer Center, Mike Spitzer <???> ported
Xofiles to BSD 4.3 and DYNIX 3.0.1[24], Ray Moody <ray at mace.cc.purdue.edu>
Xadded code to report on shared and exclusive locks, Vik Lall <???>
Xapparently did some ports, somebody ported it to SunOS 4.0 and Ultrix
X2.2, and Abell added an option to look up network connections by
Xprotocol control block address. This became the Abell ofiles, which
Xappeared on comp.sources.unix in volume 18. Will Crowder
X<willcr at ism.isc.com> patched the Abell ofiles for SunOS 4.1; this, and
Xany other modifications to that version after the comp.sources.unix
Xrelease, appear at the ``modified Abell ofiles'' node.
X
XIn the meantime, an independent fstat program appeared in BSD 4.3-Tahoe
X(when?). fstat performs much of the same function as ofiles in a
Xsomewhat different way. The 4.3-Tahoe version does not support NFS.
XAbell ported fstat to various systems and sent it to comp.sources.unix
Xvolume 18. Tom Christiansen <tchrist at convex.com> ported it to the Convex
Xand added partial NFS support (his version didn't decode the filesystem
Xfrom /etc/mtab as the Dupuy ofiles does); note that source to this
Xversion is not available because Convex is, well, um, stingy.
X
XIn March and April 1991, Dan Bernstein <brnstnd at nyu.edu---that's me>
Xintegrated the various versions of ofiles, stole some ideas (though not
Xcode) from fstat, and rewrote most of the program (the easy parts) from
Xscratch. ``pff'' (process-file-file) has getuser() and various other
Xpieces of the Abell ofiles, mmap and text segment support from the Dupuy
Xofiles, Convex support as in the Christiansen fstat, offset reporting as
Xin fstat, controlling ttys, open file flags (like rwa for read, write,
Xappend), vnode and device printing mostly from the Dupuy ofiles, NFS
Xsupport as in the Dupuy ofiles and the Christiansen fstat, socket
Xsearching similar to the Dupuy ofiles, and several output formats
Ximitating the output formats of the older programs. pff can also report
Xprocess status, including resource usage and signal handling.
X
Xpff does *not* support the DYNIX core file reading from the Abell ofiles,
Xany sort of debugging output, file size reporting as in fstat, various
Xname lookups (e.g., hostnames, services), and socket searches by
Xprotocol. It's also rather shoddy on error-checking. Other than this, pff
Xappears to provide all the features of its ancestors. It works so far
Xunder Ultrix 4.1, SunOS 4.0.3, SunOS 4.1, and Convex UNIX 9.0.
X
XI do not know what interest Spencer, Ditto, Dunigan, Lall, Nebbett,
XRosmus, or Spitzer currently have in the code, so as noted in README
Xcertain parts of pff might not be freely distributable. The code I wrote
Xfor this package is all public-domain.
END_OF_FILE
if test 6101 -ne `wc -c <'OFILES.hist'`; then
    echo shar: \"'OFILES.hist'\" unpacked with wrong size!
fi
# end of 'OFILES.hist'
fi
if test -f 'authd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'authd.c'\"
else
echo shar: Extracting \"'authd.c'\" \(4355 characters\)
sed "s/^X//" >'authd.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB authd version 3.5 alpha.
X5/3/91 DJB modified to not compile without HAVE_UCRED
X5/1/91 DJB baseline public domain
XDerived from authd 3.01, DJB.
X*/
X
X#include "confhaveucred.h"
X#ifndef HAVE_UCRED
Xerror! error! error! XXX
Xauthd will not work on a system without struct ucred.
X#endif
X
X#include <stdio.h>
X#ifdef USE_SYSLOG
X#include <syslog.h>
X#endif
X#include "structfile.h"
X#include "structucred.h"
X#include "structinpcb.h"
X#include "getfcred.h"
X#include "filetable.h"
X#include "netinp.h"
X#include "auread.h"
X#include "username.h"
X
Xint flagpwnam = 0;
Xint flagauthd = 0;
Xchar localport[10];
Xchar remoteport[10];
X
Xzap(err,argv0)
Xchar *err;
Xchar *argv0;
X{
X if (flagauthd)
X   /* Reporting errors honestly to a remote host could damage security. */
X   printf("%s, %s: ERROR: UNKNOWN-ERROR\r\n",localport,remoteport);
X else
X   fprintf(stderr,"%s: fatal: %s\n",argv0,err);
X exit(37); /*XXX*/
X}
X
X#define ZAP(err) zap(err,argv[0])
X
Xint loc4[4];
Xint rem4[4];
X#define l1 loc4[0]
X#define l2 loc4[1]
X#define l3 loc4[2]
X#define l4 loc4[3]
X#define r1 rem4[0]
X#define r2 rem4[1]
X#define r3 rem4[2]
X#define r4 rem4[3]
X
Xint doit(fp)
Xregister struct file *fp;
X{
X register struct ucred *uc;
X register int uid;
X char *un;
X
X uc = getfcred(fp);
X if (!uc)
X   return -1;
X uid = (int) uc->cr_ruid;
X if (flagpwnam)
X  {
X   if (uid2username(uid,&un) == 1)
X     /* XXX: We don't give out userids that don't have usernames. */
X     return -1;
X   if (flagauthd)
X   /* UNIX is a trademark of AT&T. :-) */
X   /* XXX: We could try to report UNIX variants here. */
X     printf("%s, %s: USERID: %s: %s\r\n",localport,remoteport,"UNIX",un);
X   else
X     printf("%s\n",un);
X  }
X else
X   printf("%d\n",uid);
X return 0;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X register struct file *xfile;
X register struct file *fp;
X register struct inpcb *inp;
X int lp;
X int rp;
X 
X if ((!strcmp(argv[0],"authd"))
X  || ((strlen(argv[0]) >= 6)
X   && (!strcmp(argv[0] + strlen(argv[0]) - 6,"/authd"))))
X   flagauthd = flagpwnam = 1;
X else
X   if ((!strcmp(argv[0],"tcpuname"))
X    || ((strlen(argv[0]) >= 9)
X     && (!strcmp(argv[0] + strlen(argv[0]) - 9,"/tcpuname"))))
X     flagpwnam = 1;
X
X if (flagauthd)
X  {
X   if (readlr(localport,remoteport,loc4,rem4,&lp,&rp) == -1)
X     exit(1); /*XXX*/
X#ifdef USE_SYSLOG
X /* This isn't worth the time for the procedure call, but if you want... */
X   syslog(LOG_DEBUG,"authd: checking up on %d.%d.%d.%d %d %d.%d.%d.%d %d\n",
X     r1,r2,r3,r4,rp,l1,l2,l3,l4,lp);
X#endif
X  }
X else
X  {
X   if (argc < 4)
X     ZAP("need four arguments");
X   if (sscanf(argv[1],"%d.%d.%d.%d",&r1,&r2,&r3,&r4) < 4)
X     ZAP("arg 1 must be a.b.c.d");
X   if (sscanf(argv[2],"%d",&rp) < 1)
X     ZAP("arg 2 must be integer");
X   if (sscanf(argv[3],"%d.%d.%d.%d",&l1,&l2,&l3,&l4) < 4)
X     ZAP("arg 3 must be a.b.c.d");
X   if (sscanf(argv[4],"%d",&lp) < 1)
X     ZAP("arg 4 must be integer");
X  }
X
X if (netinpinit(r1,r2,r3,r4,rp) == -1)
X   ZAP("cannot init netstat");
X if (filetableinit() == -1)
X   ZAP("cannot init space for file table");
X
X xfile = getfiletable();
X if (!xfile)
X   ZAP("cannot get file table");
X
X while (inp = nextnetinp())
X  {
X/* Cursed be Convex and the other manufacturers who make this code */
X/* nearly impossible to write with any pretense of portability. */
X   if((((char *) &inp->inp_faddr)[3] == (char) r4)
X    &&(((char *) &inp->inp_laddr)[3] == (char) l4)
X    &&(((char *) &inp->inp_faddr)[2] == (char) r3)
X    &&(((char *) &inp->inp_laddr)[2] == (char) l3)
X    &&(((char *) &inp->inp_faddr)[1] == (char) r2)
X    &&(((char *) &inp->inp_laddr)[1] == (char) l2)
X    &&(((char *) &inp->inp_faddr)[0] == (char) r1)
X    &&(((char *) &inp->inp_laddr)[0] == (char) l1)
X    &&(inp->inp_fport == htons((unsigned short) rp))
X    &&(inp->inp_lport == htons((unsigned short) lp))
X   )
X   /* Is it worth snarfing the socket and checking that it points back */
X   /* to inp? No, because then we have to worry about sys/socketvar.h, */
X   /* including sys/mbuf.h on a Convex and maybe other machines, etc. */
X   /* Sometimes portability gets in the way of everything else. */
X     for (fp = xfile;fp < xfile + mynfile;++fp)
X       if (fp->f_count && (fp->f_type == DTYPE_SOCKET))
X         if ((char *) fp->f_data == (char *) inp->inp_socket)
X	  {
X	   if (doit(fp) == -1)
X	     ZAP("cannot get userid");
X	   exit(0);
X	  }
X  }
X ZAP("no such TCP connection");
X exit(1);
X}
END_OF_FILE
if test 4355 -ne `wc -c <'authd.c'`; then
    echo shar: \"'authd.c'\" unpacked with wrong size!
fi
# end of 'authd.c'
fi
if test -f 'findinode/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'findinode/README'\"
else
echo shar: Extracting \"'findinode/README'\" \(4270 characters\)
sed "s/^X//" >'findinode/README' <<'END_OF_FILE'
Xfindinode - find all filenames with a given (dev,inode) pair
X
XThe entire purpose of this package is to give you a fast mapping from
Xdevice and inode number to filename(s), i.e., a reverse namei. It works
Xby keeping a database showing all directories containing each inode. A
Xdaemon runs continuously to maintain this database. The accuracy of
Xfindinode's answers depends on how much CPU time you give the daemon.
XNote that findinode will always detect when it cannot provide an
Xaccurate answer. It also refuses to divulge filenames inside protected
Xdirectories to anyone except the owner (or root, of course).
X
XExample: One system here has about 1.8GB disk space with 1.4GB used (and
X0.2GB reserved for the system as usual), spread over 49000 inodes in
X2400 directories. The findinode database takes a mere 6.1MB, or under
Xhalf a percent of the total disk space. find / -type d takes 90 seconds;
Xthe initial fsupdatefid sweep used just 200 user seconds and 600 system
Xseconds. A typical update sweep takes only a few minutes, automatically
Xspread out by fsupdatefid over a few hours so that the CPU and disks do
Xnot carry a significant extra load. Since the entire database is
Xrecycled several times a day, findinode almost never misses a file.
X
XMore precise documentation: Run findinode and give it a line of the form
X
X    2065 300
Xor
X    /usr/ucb/w
X
XThe first form means ``find pathnames referring to inode 2065 (decimal)
Xon device 300 (hexadecimal).'' The second means ``find pathnames
Xreferring to the same file as /usr/ucb/w''; such a pathname may be
Xtruncated to 1000 characters. The second form is redundant but useful.
X
Xfindinode will print (and flush, before waiting for further input) one
Xor more lines in the following form:
X
X    2065 300: /etc/hosts.equiv
X
XThe first two numbers will always be the inode and device numbers of the
Xfile, no matter what the input line format was. The rest of the line is
Xa filename. A printed pathname of /foo/bar/blah guarantees the following:
XSometime after findinode read the input line, / contained directory foo,
Xwhich sometime after that contained directory bar, which sometime after
Xthat contained file blah, which had the stated (inode,device) pair
Xsometime before the filename was printed.
X
XNote that findinode does not guarantee that it will find all links, or
Xthat it will find as many or as few links as the file has, or that it
Xwill print distinct pathnames. In particular, if a file has a dozen
Xlinks in one directory, findinode will typically print a dozen lines
Xreferring to the first link.
X
XNone of the path components printed by findinode will be empty or
Xcontain a newline. If findinode cannot make these guarantees, it will
Xprint a line in one of the following formats:
X
X    2065 300: <unknown>       (no guarantees, but chances are that
X			       findinode's never seen that inode-device)
X    2065 300: /etc//<gone>    (no guarantees, but chances are that at
X                               some time in the past, the inode was
X			       contained in some sub[sub...]directory of
X			       a directory with the same inode-device
X			       numbers as what /etc had sometime while
X			       findinode was running)
X    2065 300: /home/shmoe//<protected>
X			      (no guarantees, but your real uid probably
X			       does not have permission to read the
X			       /home/shmoe directory, and whatever's
X			       true about <gone> is probably true here)
X    2065 300: /tmp/joe//<newline>
X			      (findinode detected that it was about to
X			       print a path component containing a
X			       newline)
X
XAdditional error formats may be defined in future versions of findinode;
Xthey will always begin with a character other than a slash, or contain a
Xdouble slash in the printed pathname.
X
Xfindinode -A suppresses the multiple-line output; it will print exactly
Xone line for each line of input. -a turns multiple-line output back on.
X
XCompiling: You may have to change direct to dirent throughout, or change
X<sys/dir.h> to something like <dirent.h>.
X
XTODO:
Xclean out directories and files with 0 links
Xkeep statistics on findinode success rate
Xafter a failure, have updatefid check some directory again?
Xdo something better with multiple links in one directory?
Xwrite some real documentation! get this into beta!
END_OF_FILE
if test 4270 -ne `wc -c <'findinode/README'`; then
    echo shar: \"'findinode/README'\" unpacked with wrong size!
fi
# end of 'findinode/README'
fi
if test -f 'findinode/fid.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'findinode/fid.c'\"
else
echo shar: Extracting \"'findinode/fid.c'\" \(5425 characters\)
sed "s/^X//" >'findinode/fid.c' <<'END_OF_FILE'
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/stat.h>
X#include <sys/dir.h>
X#include <stdio.h>
X#include <ndbm.h>
X#include "fid.h"
X
Xstatic int fdlock;
Xstatic DBM *dbfiles;
Xstatic DBM *dbdirs;
Xstatic DBM *dbdirtimes;
Xstatic DBM *dbf2d;
Xstatic DBM *dbd2f;
X
Xint fidinit()
X{
X fdlock = open(DBLOCK,O_RDWR | O_CREAT,0600);
X if (fdlock == -1) return -1;
X dbfiles = dbm_open(DBFILES,O_RDWR | O_CREAT,0600);
X if (!dbfiles) return -1;
X dbdirs = dbm_open(DBDIRS,O_RDWR | O_CREAT,0600);
X if (!dbdirs) return -1;
X dbdirtimes = dbm_open(DBDIRTIMES,O_RDWR | O_CREAT,0600);
X if (!dbdirtimes) return -1;
X dbf2d = dbm_open(DBF2D,O_RDWR | O_CREAT,0600);
X if (!dbf2d) return -1;
X dbd2f = dbm_open(DBD2F,O_RDWR | O_CREAT,0600);
X if (!dbd2f) return -1;
X return 0;
X}
X
Xint fidlock()
X{
X return flock(fdlock,LOCK_EX);
X}
X
Xint fidunlock()
X{
X return flock(fdlock,LOCK_UN);
X}
X
X/*XXX these routines*/
Xstatic datum f2key(f) struct node f; { datum key;
X static char buf[8]; unsigned long fi = f.i; unsigned long fd = f.d;
X buf[0] = fi & 255; fi /= 256; buf[1] = fi & 255; fi /= 256;
X buf[2] = fi & 255; fi /= 256; buf[3] = fi & 255;
X buf[4] = fd & 255; fd /= 256; buf[5] = fd & 255; fd /= 256;
X buf[6] = fd & 255; fd /= 256; buf[7] = fd & 255;
X key.dptr = buf; key.dsize = 8; return key; }
X
Xstatic datum d2key(d) struct dnode d; { datum key;
X static char buf[8]; unsigned long di = d.i; unsigned long dd = d.d;
X buf[0] = di & 255; di /= 256; buf[1] = di & 255; di /= 256;
X buf[2] = di & 255; di /= 256; buf[3] = di & 255;
X buf[4] = dd & 255; dd /= 256; buf[5] = dd & 255; dd /= 256;
X buf[6] = dd & 255; dd /= 256; buf[7] = dd & 255;
X key.dptr = buf; key.dsize = 8; return key; }
X
Xstatic datum fn2key(fn) struct nodenum fn; { datum key;
X static char buf[12];
X unsigned long fni = fn.x.i; unsigned long fnd = fn.x.d;
X unsigned long fnn = fn.n;
X buf[0] = fni & 255; fni /= 256; buf[1] = fni & 255; fni /= 256;
X buf[2] = fni & 255; fni /= 256; buf[3] = fni & 255;
X buf[4] = fnd & 255; fnd /= 256; buf[5] = fnd & 255; fnd /= 256;
X buf[6] = fnd & 255; fnd /= 256; buf[7] = fnd & 255;
X buf[8] = fnn & 255; fnn /= 256; buf[9] = fnn & 255; fnn /= 256;
X buf[10] = fnn & 255; fnn /= 256; buf[11] = fnn & 255;
X key.dptr = buf; key.dsize = 12; return key; }
X
Xstatic struct nodenum key2fn(d) datum d; { struct nodenum fn;
X unsigned char *buf = (unsigned char *) d.dptr;
X fn.x.i = ((buf[3] * 256 + buf[2]) * 256 + buf[1]) * 256 + buf[0];
X fn.x.d = ((buf[7] * 256 + buf[6]) * 256 + buf[5]) * 256 + buf[4];
X fn.n = ((buf[11] * 256 + buf[10]) * 256 + buf[9]) * 256 + buf[8];
X return fn;
X}
X
Xstatic datum dn2key(dn) struct dnodenum dn; { datum key;
X static char buf[12];
X unsigned long dni = dn.x.i; unsigned long dnd = dn.x.d;
X unsigned long dnn = dn.n;
X buf[0] = dni & 255; dni /= 256; buf[1] = dni & 255; dni /= 256;
X buf[2] = dni & 255; dni /= 256; buf[3] = dni & 255;
X buf[4] = dnd & 255; dnd /= 256; buf[5] = dnd & 255; dnd /= 256;
X buf[6] = dnd & 255; dnd /= 256; buf[7] = dnd & 255;
X buf[8] = dnn & 255; dnn /= 256; buf[9] = dnn & 255; dnn /= 256;
X buf[10] = dnn & 255; dnn /= 256; buf[11] = dnn & 255;
X key.dptr = buf; key.dsize = 12; return key; }
X
Xstatic struct dnodenum key2dn(d) datum d; { struct dnodenum dn;
X unsigned char *buf = (unsigned char *) d.dptr;
X dn.x.i = ((buf[3] * 256 + buf[2]) * 256 + buf[1]) * 256 + buf[0];
X dn.x.d = ((buf[7] * 256 + buf[6]) * 256 + buf[5]) * 256 + buf[4];
X dn.n = ((buf[11] * 256 + buf[10]) * 256 + buf[9]) * 256 + buf[8];
X return dn;
X}
X
Xint fidfilesput(f,n) struct node f; int n; { datum content;
X content.dptr = (char *)&n; content.dsize = sizeof(n);
X return dbm_store(dbfiles,f2key(f),content,DBM_REPLACE); }
X
Xint fidfilesdel(f) struct node f; {
X return dbm_delete(dbfiles,f2key(f)); }
X
Xint fidfilesget(f) struct node f; { datum content;
X content = dbm_fetch(dbfiles,f2key(f));
X if (!content.dptr) return 0;
X return *((int *) content.dptr); }
X
Xint fiddirsput(d,n) struct dnode d; int n; { datum content;
X content.dptr = (char *)&n; content.dsize = sizeof(n);
X return dbm_store(dbdirs,d2key(d),content,DBM_REPLACE); }
X
Xint fiddirsdel(d) struct dnode d; {
X return dbm_delete(dbdirs,d2key(d)); }
X
Xint fiddirsget(d) struct dnode d; { datum content;
X content = dbm_fetch(dbdirs,d2key(d));
X if (!content.dptr) return 0;
X return *((int *) content.dptr); }
X
Xint fiddirtimesput(d,n) struct dnode d; long n; { datum content;
X content.dptr = (char *)&n; content.dsize = sizeof(n);
X return dbm_store(dbdirtimes,d2key(d),content,DBM_REPLACE); }
X
Xint fiddirtimesdel(d) struct dnode d; {
X return dbm_delete(dbdirtimes,d2key(d)); }
X
Xlong fiddirtimesget(d) struct dnode d; { datum content;
X content = dbm_fetch(dbdirtimes,d2key(d));
X if (!content.dptr) return 0;
X return *((long *) content.dptr); }
X
Xint fidf2dput(f,d) struct nodenum f; struct dnodenum d; {
X return dbm_store(dbf2d,fn2key(f),dn2key(d),DBM_REPLACE); }
X
Xint fidf2ddel(f) struct nodenum f; {
X return dbm_delete(dbf2d,fn2key(f)); }
X
Xstruct dnodenum fidf2dget(f) struct nodenum f; { datum content;
X content = dbm_fetch(dbf2d,fn2key(f));
X /* XXX: what if content.dptr is 0? */
X return key2dn(content); }
X
Xint fidd2fput(d,f) struct dnodenum d; struct nodenum f; {
X return dbm_store(dbd2f,dn2key(d),fn2key(f),DBM_REPLACE); }
X
Xint fidd2fdel(d) struct dnodenum d; {
X return dbm_delete(dbd2f,dn2key(d)); }
X
Xstruct nodenum fidd2fget(d) struct dnodenum d; { datum content;
X content = dbm_fetch(dbd2f,dn2key(d));
X /* XXX: what if content.dptr is 0? */
X return key2fn(content); }
END_OF_FILE
if test 5425 -ne `wc -c <'findinode/fid.c'`; then
    echo shar: \"'findinode/fid.c'\" unpacked with wrong size!
fi
# end of 'findinode/fid.c'
fi
if test -f 'getnode.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getnode.c'\"
else
echo shar: Extracting \"'getnode.c'\" \(5893 characters\)
sed "s/^X//" >'getnode.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB various modifications
X5/1/91 DJB baseline
XRewritten by DJB to store rather than print information.
XOriginally stolen from Dupuy ofiles.
X*/
X
X/* XXX: error checks! support strerr! */
X
X/*
X
Xint getnode(node,buf) struct Xnode *node; struct nodebuf *buf; looks up
Xthe filesystem node (in kernel memory) and places its vital statistics
Xinto buf. buf->type is a three-character file type as defined by the
Xvirtype library. buf->flagdev is NODE_ID_INO if node is a regular inode,
XNODE_ID_DEV if it is a device, NODE_ID_FIFO if it is a fifo, and
XNODE_ID_FIFOINO if it is a fifo but the regular inode information is
Xalso filled in. (Some systems do not support type NODE_ID_FIFOINO.)
X
XIf buf->flagdev is NODE_ID_INO, buf->id.ino has the following elements:
Xinum is the file serial number; dev is the file device number; name is
Xthe filename of the device, or 0 if it is unknown; flagnfs is 0 for a
Xlocal file and 1 for a remote file.
X
XIf buf->flagdev is NODE_ID_DEV, buf->id.dev has the following elements:
Xmaj is the major number of the remote device; min is the minor number;
Xand name is the filename, or 0 if it is unknown.
X
Xgetnode() returns 0 on success, -1 on error. XXX: need getnodestrerr.
X
Xgetnodeinit() does optional initialization to cooperate with other
Xlibraries.
X
X*/
X
X#ifdef NFS
X#define NL_NFS "_nfs_vnodeops"
Xstatic unsigned long nlnfsv;
Xstatic short nlnfst;
X#define NL_UFS "_ufs_vnodeops"
Xstatic unsigned long nlufsv;
Xstatic short nlufst;
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "confnfs.h"
X#include "structxnode.h"
X#include "nlistlist.h"
X#include "stattimeout.h"
X#include "rpcnfs.h"
X#include "virtype.h"
X#include "mntops.h"
X#include "getdevicename.h"
X#include "getnode.h"
X#include "confneedmntinfo.h"
X#include "confgnode.h"
X#include "confmajorminor.h"
X
X#define istype(mode,type) (((mode) & S_IFMT) == (type))
X#define ispecial(mode) (istype((mode),S_IFBLK) || istype((mode),S_IFCHR))
X#ifdef NFS
X#define vspecial(vtype) ((vtype) == VCHR || (vtype) == VBLK)
X#endif
X
Xstatic int init = 0;
X
X#ifdef GNODE
X
Xint getnode(node,buf)
Xstruct gnode *node;
Xstruct nodebuf *buf;
X{
X struct gnode g;
X struct statlist *fsstats;
X
X if (!node)
X   return -1;
X kmemcpy(&g,node,sizeof(g));
X buf->type = itype(g.g_mode);
X if (ispecial(g.g_mode))
X  {
X   buf->flagdev = NODE_ID_DEV;
X   buf->id.dev.maj = major(g.g_rdev);
X   buf->id.dev.min = minor(g.g_rdev);
X   buf->id.dev.name = getdevicename(&g);
X   return 0;
X  }
X if (!init)
X   pervn();
X fsstats = stats;
X
X buf->flagdev = NODE_ID_INO;
X buf->id.ino.inum = g.g_number;
X buf->id.ino.dev = g.g_dev;
X
X while (fsstats) /* XXX: hash! */
X  {
X   if (fsstats->device == g.g_dev)
X    {
X     buf->id.ino.name = fsstats->filename;
X     /* another iffy test for nfs */
X     if (itype(g.g_mode) == vtype(((struct vnode *) &g)->v_type))
X       buf->id.ino.flagnfs = 1;
X     else
X       buf->id.ino.flagnfs = 0;
X     return 0;
X    }
X   fsstats = fsstats->next;
X  }
X
X buf->id.ino.name = 0;
X return 0;
X}
X
X#else
X
Xint getnode(node,buf)
Xstruct Xnode *node;
Xstruct nodebuf *buf;
X{
X#ifdef NFS
X struct vnode v;
X#endif
X static union xnode
X  {
X   struct inode i;
X#ifdef NFS
X   struct rnode r;
X#endif
X  }
X x;
X struct statlist *fsstats;
X
X if (!init)
X   pervn();
X fsstats = stats;
X
X if (!node)
X   return -1;
X
X#ifdef NFS
X kmemcpy(&v,node,sizeof(v));
X
X buf->type = vtype(v.v_type);
X
X if (vspecial(v.v_type))
X  {
X   buf->flagdev = NODE_ID_DEV;
X   buf->id.dev.maj = major(v.v_rdev);
X   buf->id.dev.min = minor(v.v_rdev);
X   buf->id.dev.name = getdevicename(&v);
X   return 0;
X  }
X
X buf->flagdev = NODE_ID_INO;
X#ifdef S_IFIFO
X if (v.v_type == VFIFO)
X  {
X#ifdef GET_FIFOS
X   struct snode sn;
X   buf->flagdev = NODE_ID_FIFOINO;
X   kmemcpy(&sn,v.v_data,sizeof(sn));
X   kmemcpy(&v,sn.s_realvp,sizeof(v));
X#else
X   buf->flagdev = NODE_ID_FIFO;
X   return 0;
X#endif
X  }
X#endif
X
X kmemcpy(&x,v.v_data,sizeof(x));
X
X if ((unsigned long) v.v_op == nlnfsv)
X  {
X#ifndef NEED_MNTINFO
X   buf->id.ino.flagnfs = 1;
X   buf->id.ino.inum = x.r.r_attr.va_nodeid;
X   buf->id.ino.dev = x.r.r_attr.va_fsid;
X
X   while (fsstats)
X    {
X     if (fsstats->device == (dev_t) x.r.r_attr.va_fsid)
X      {
X       buf->id.ino.name = fsstats->filename;
X       return 0;
X      }
X     fsstats = fsstats->next;
X    }
X   buf->id.ino.name = 0;
X   return 0;
X#else
X   struct vfs vf;
X   struct mntinfo mi;
X   dev_t fsdev;
X
X   kmemcpy(&vf,v.v_vfsp,sizeof(vf));
X   kmemcpy(&mi,vf.vfs_data,sizeof(mi));
X   fsdev = makedev(0xff,mi.mi_mntno);
X
X   buf->id.ino.flagnfs = 1;
X   buf->id.ino.inum = x.r.r_nfsattr.na_nodeid;
X
X   while (fsstats)
X    {
X     if (fsstats->device == fsdev)
X      {
X       buf->id.ino.dev = mi.mi_mntno;
X       buf->id.ino.name = fsstats->filename;
X       return 0;
X      }
X     fsstats = fsstats->next;
X    }
X
X   buf->id.ino.dev = x.r.r_nfsattr.na_fsid; /* XXX: is this right? */
X   buf->id.ino.name = 0;
X   return 0;
X#endif
X  }
X else if ((unsigned long) v.v_op == nlufsv)
X  {
X   /* XXX: Yes, this *is* a confusing interaction between {} and #ifdef. */
X#else
X kmemcpy(&x.i,node,sizeof(x.i));
X buf->type = itype(x.i.i_mode);
X
X if (ispecial(x.i.i_mode))
X  {
X   buf->flagdev = NODE_ID_DEV;
X   buf->id.dev.maj = major(x.i.i_rdev);
X   buf->id.dev.min = minor(x.i.i_rdev);
X   buf->id.dev.name = getdevicename(&x.i);
X   return 0;
X  }
X#endif
X
X buf->flagdev = NODE_ID_INO;
X buf->id.ino.inum = x.i.i_number;
X buf->id.ino.dev = x.i.i_dev;
X buf->id.ino.flagnfs = 0;
X while (fsstats)
X  {
X   if (fsstats->device == x.i.i_dev)
X    {
X     buf->id.ino.name = fsstats->filename;
X     return 0;
X    }
X   fsstats = fsstats->next;
X  }
X buf->id.ino.name = 0;
X#ifdef NFS
X  }
X else
X   return -1; /* XXX: inode unrecognized fs type */
X#endif
X return 0;
X}
X
X#endif
X
Xstatic pervn()
X{
X if (!init)
X   getnodeinit();
X#ifdef NFS
X if (!nlnfst)
X   nlistdo();
X#endif
X}
X
Xgetnodeinit()
X{
X#ifdef NFS
X nlistadd(NL_NFS,&nlnfst,&nlnfsv); /*XXX*/
X nlistadd(NL_UFS,&nlufst,&nlufsv);
X#endif
X init = 1;
X}
END_OF_FILE
if test 5893 -ne `wc -c <'getnode.c'`; then
    echo shar: \"'getnode.c'\" unpacked with wrong size!
fi
# end of 'getnode.c'
fi
if test -f 'getsocket.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getsocket.c'\"
else
echo shar: Extracting \"'getsocket.c'\" \(4398 characters\)
sed "s/^X//" >'getsocket.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB various modifications
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
Xint getsocket(f,sbuf) struct socket *f; struct socketbuf *sbuf; looks up
Xsocket f (in kernel memory) and places its vital statistics into sbuf.
Xsbuf->socktype is the general socket type, such as SOCK_STREAM.
Xsbuf->strsockt is the name of the socket type, or 0 if the type is
Xunknown. sbuf->flag{accept,reuse,head} are the accept, reuse, and head
Xflags on the socket respectively. sbuf->family is the socket's address
Xfamily, such as AF_INET; sbuf->famname is the name of the family, or 0
Xif the family is unknown. sbuf->famname may be truncated to 30
Xcharacters.
X
Xsbuf->fsw is a family switch to control sbuf->fu: FSW_INET for AF_INET,
XFSW_UNIX for AF_UNIX, and FSW_UNK for other types.
X
XIf sbuf->fsw is FSW_INET: sbuf->fu.inet has several members. proto is
Xthe Internet protocol, such as IPPROTO_TCP. strpro is the name for
Xproto, or 0 if it is unknown. r0, r1, r2, r3 are the bytes (from network
Xdown to host) of the IP address of the remote host; rp is the remote
Xport, for protocols where that is meaningful. l0, l1, l2, l3 and lp form
Xthe local address.
X
XIf sbuf->fsw is FSW_UNIX: sbuf->fu.un has several members. node is the
Xaddress of the filesystem node associated with the socket, if any. conn
Xis the address of the connected node, if any. path is the bound pathname
Xof the socket, if applicable; it may be either a character array or a
Xpointer in future releases of this library. unpcb is the address of the
Xsocket's protocol control block.
X
Xgetsocket() returns 0 upon success, -1 upon error.
X
X*/
X
X#include <stdio.h>
X#include "structinpcb.h"
X#include "structmbuf.h"
X#include "structprotosw.h"
X#include "structsocket.h"
X#include "structunpcb.h"
X#include "structxnode.h"
X#include "printfamily.h"
X#include "printprotoinet.h"
X#include "printsocktype.h"
X#include "kmem.h"
X#include <sys/un.h>
X#include "getsocket.h"
X#include "confdomain.h"
X
Xgetsocket(f,sbuf)
Xstruct socket *f;
Xstruct socketbuf *sbuf;
X{
X struct socket s;
X struct protosw psw;
X#ifdef DOMAIN
X struct domain dom;
X#endif
X int family;
X
X kmemcpy(&s,f,sizeof(s));
X
X /* XXX: state, follow head, error, pgrp */
X kmemcpy(&psw,s.so_proto,sizeof(psw));
X#ifdef DOMAIN
X kmemcpy(&dom,psw.pr_domain,sizeof(dom));
X family = dom.dom_family;
X#else
X family = psw.pr_family;
X#endif
X
X sbuf->socktype = s.so_type;
X sbuf->strsockt = printsocktype(s.so_type);
X sbuf->flagaccept = !!(s.so_options & SO_ACCEPTCONN);
X sbuf->flagreuse = !!(s.so_options & SO_REUSEADDR);
X sbuf->flaghead = !!(s.so_head);
X /* N.B. psw.pr_type always equals s.so_type */
X sbuf->family = family;
X#ifdef DOMAIN
X if (dom.dom_name && (family >= 0) && (family < 50))
X  {
X   char domname[50][30]; /* XXX: so I'm scum. so sue me. */
X   kmemcpy(domname[family],dom.dom_name,sizeof(domname[family]));
X   domname[family][29] = 0;
X   sbuf->famname = domname[family];
X  }
X else
X#endif
X sbuf->famname = printfamily(family);
X sbuf->fsw = FSW_UNK;
X
X if (family == AF_INET)
X  {
X   struct inpcb inp;
X   unsigned char *a;
X
X   sbuf->fsw = FSW_INET;
X   sbuf->fu.inet.proto = psw.pr_protocol;
X   sbuf->fu.inet.strpro = printprotoinet(psw.pr_protocol);
X
X   /*XXX: do port lookups? */
X   /*XXX: do host lookups? */
X   kmemcpy(&inp,s.so_pcb,sizeof(inp));
X   a = (unsigned char *) &inp.inp_faddr;
X   sbuf->fu.inet.r0 = a[0]; sbuf->fu.inet.r1 = a[1];
X   sbuf->fu.inet.r2 = a[2]; sbuf->fu.inet.r3 = a[3];
X   a = (unsigned char *) &inp.inp_fport;
X   sbuf->fu.inet.rp = a[0] * 256 + a[1];
X   a = (unsigned char *) &inp.inp_laddr;
X   sbuf->fu.inet.l0 = a[0]; sbuf->fu.inet.l1 = a[1];
X   sbuf->fu.inet.l2 = a[2]; sbuf->fu.inet.l3 = a[3];
X   a = (unsigned char *) &inp.inp_lport;
X   sbuf->fu.inet.lp = a[0] * 256 + a[1];
X  }
X else if (family == AF_UNIX)
X  {
X   struct unpcb unp;
X
X   sbuf->fsw = FSW_UNIX;
X   kmemcpy(&unp,s.so_pcb,sizeof(unp));
X   sbuf->fu.un.unpcb = (char *) s.so_pcb;
X   sbuf->fu.un.node = (char *) unp.unp_Xnode;
X   sbuf->fu.un.conn = (char *) unp.unp_conn;
X   sbuf->fu.un.path[0] = 0;
X   if (unp.unp_addr)
X    {
X     struct sockaddr_un *sa;
X     struct mbuf mb;
X     kmemcpy((char *) &mb,(char *) unp.unp_addr,sizeof(mb));
X     sa = (struct sockaddr_un *) (((char *) &mb) + mb.m_off);
X     /* XXX: check that length is less than 108 */
X     sprintf(sbuf->fu.un.path,
X       " %.*s",mb.m_len - sizeof(sa->sun_family),sa->sun_path); /*XXX*/
X    }
X  }
X else
X   ; /* XXX: other s.so_pcb's? */
X return 0;
X}
END_OF_FILE
if test 4398 -ne `wc -c <'getsocket.c'`; then
    echo shar: \"'getsocket.c'\" unpacked with wrong size!
fi
# end of 'getsocket.c'
fi
if test -f 'getuser.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getuser.c'\"
else
echo shar: Extracting \"'getuser.c'\" \(6695 characters\)
sed "s/^X//" >'getuser.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline
XConvex support added by Dan Bernstein.
XTranslated to independent library with strerr support by Dan Bernstein.
XCode for this library derived from Abell version of ofiles.
XContributors and possible contributors: C. Spencer, Michael Ditto,
XTom Dunigan, Alexander Dupuy, Greg Nebbett, Richart Tobin, Mike Spitzer,
XRay Moody, Vik Lall, Vic Abell.
X*/
X
X/*
X
Xstruct user *getuser(p) struct proc *p; returns a pointer to a (not
Xnecessarily atomic) copy in user memory of the u area for process p.
XUpon errors it returns 0.
X
XThis is one of the nastiest, most machine-dependent pieces of code I've
Xever had the pleasure of working with to achieve an essentially
Xmachine-independent result.
X
Xint getuserinit() does optional initialization to cooperate with other
Xlibraries.
X
Xgetuserstrerr is a strerrfun for getuser() and getuserinit().
X
X*/
X
X#include "getuser.h"
X#include "confgetusersupport.h"
X#include "confusrptnlist.h"
X#include "structuser.h"
X#include "structpte.h"
X#include "structproc.h"
X#include "confneedmachparam.h"
X#ifdef NEED_MACHPARAM
X#include <machine/machparam.h>
X#endif
X#include <sys/vmmac.h>
X#include "confgetuserdynix.h"
X#include "confgetusermips.h"
X#include "confgetuserconvex.h"
X#include "confkvm.h"
X#ifdef KVM
X#include <kvm.h>
X#include <fcntl.h> /* XXX: really under KVM? */
X#endif
X#include "nlistlist.h"
X#include "kmem.h"
X#include "mmem.h"
X#include "smem.h"
X#include "strerr.h"
X#include "confhavepflag.h"
X
Xstatic int getusererrno = 0;
X
Xstatic struct strerrtab e[] = {
X  { 0, "getuser error 0", 0 }
X#define GU_INIT 1
X, { GU_INIT, "cannot init getuser: ", nliststrerr }
X#define GU_NLIST 2
X, { GU_NLIST, "cannot nlist: ", nliststrerr }
X#ifndef GETUSERSUPPORT
X#define GU_NLPFOUND 3
X, { GU_NLPFOUND, NLISTPAGES, nlistnotin }
X#define GU_NLBFOUND 4
X, { GU_NLBFOUND, NLISTBASE, nlistnotin }
X#endif
X#define GU_KVM 5 /* stupid kvm library, no error reporting */
X, { GU_KVM, "vendor kvm library failed", 0 } /* credit where due :-) */
X#define GU_ALLOC 6
X, { GU_ALLOC, "out of memory", 0 }
X#define GU_SLOAD 7
X, { GU_SLOAD, "cannot swap in u area: ", smemstrerr }
X#define GU_UAREA 8
X, { GU_UAREA, "cannot read u area: ", kmemstrerr }
X#define GU_DMAP 9
X, { GU_DMAP, "cannot read dmap: ", kmemstrerr }
X#define GU_BLKNO 10
X, { GU_BLKNO, "cannot read blkno: ", kmemstrerr }
X#define GU_PTE 11
X, { GU_PTE, "cannot read pte: ", kmemstrerr }
X#define GU_UPGTBL 12
X, { GU_UPGTBL, "cannot read upgtbl: ", mmemstrerr }
X#define GU_UPAGE 13
X, { GU_UPAGE, "cannot read upage: ", mmemstrerr }
X};
X
Xchar *getuserstrerr(ke) strerrfun *ke;
X{
X return strerrtaberr(ke,getusererrno,e,sizeof(e)/sizeof(*e),"unknown getuser error");
X}
X
X#ifndef GETUSERSUPPORT
Xstatic short nlpagest;
Xstatic unsigned long nlpagesv;
Xstatic short nlbaset;
Xstatic unsigned long nlbasev;
Xstruct pte *usrpt, *Usrptma;
X#endif
X
Xstatic int init = 0;
X
Xint getuserinit()
X{
X#ifndef GETUSERSUPPORT
X if (nlistadd(NLISTPAGES,&nlpagest,&nlpagesv) == -1)
X   RETERN(-1,getusererrno,GU_INIT)
X if (nlistadd(NLISTBASE,&nlbaset,&nlbasev) == -1)
X   RETERN(-1,getusererrno,GU_INIT)
X#endif
X init = 1;
X return 0;
X}
X
Xstatic int pergu()
X{
X if (!init)
X   if (getuserinit() == -1)
X     return -1;
X#ifndef GETUSERSUPPORT
X if (nlpagest == -1)
X  {
X   if (nlistdo() == -1)
X     RETERN(-1,getusererrno,GU_NLIST)
X   if (!nlpagest)
X     RETERN(-1,getusererrno,GU_NLPFOUND)
X   if (!nlbaset)
X     RETERN(-1,getusererrno,GU_NLBFOUND)
X  }
X Usrptma = (struct pte *) nlpagesv;
X usrpt = (struct pte *) nlbasev; /* used by <vmmac.h> */
X#endif
X return 0;
X}
X
X#ifdef KVM
Xstatic kvm_t *kd = 0;
X
Xstruct user *getuser(p)
Xstruct proc *p;
X{
X if (pergu() == -1)
X   return 0;
X if (!kd)
X   if (!(kd = kvm_open((char *)0,(char *)0,(char *)0,O_RDONLY)))
X     RETERN(0,getusererrno,GU_KVM)
X return kvm_getu(kd,p);
X}
X#else
X#ifdef GETUSER_CONVEX
Xstruct user *getuser(p)
Xstruct proc *p;
X{
X static struct user u;
X if (pergu() == -1)
X   return 0;
X Getprocu(p,&u,sizeof(struct user)); /*XXX*/
X return &u;
X}
X#else
X#ifdef GETUSER_DYNIX
Xstruct user *getuser(p)
Xstruct proc *p;
X{
X int btr;
X static struct user *u;
X char *valloc();
X
X u = 0;
X if (pergu() == -1)
X   return 0;
X if (!u)
X   if (!(u = (struct user *) valloc(ctob(UPAGES))))
X     RETERN(0,getusererrno,GU_ALLOC)
X btr = ctob(UPAGES);
X if ((p->p_flag & SLOAD) == 0)
X  {
X   if (smemcpy((char *)u,(char *) dtob(p->p_swaddr),btr) == -1)
X    {
X     free((char *) u);
X     getusererrno = GU_SLOAD;
X     return 0;
X    }
X  }
X else
X   if (kmemcpy((char *)u,(char *)p->p_uarea,btr) == -1)
X    {
X     free((char *) u);
X     getusererrno = GU_UAREA;
X     return 0;
X    }
X return u;
X}
X#else
Xstruct user *getuser(p)
Xstruct proc *p;
X{
X struct pte *ptep, apte;
X#ifdef GETUSER_MIPS
X struct pte wpte[UPAGES];
X int ncl;
X#endif
X struct pte mypgtbl[NBPG/sizeof(struct pte)];
X int upage;
X char *up;
X static struct user user;
X
X if (pergu() == -1)
X   return 0;
X /* easy way */
X#ifndef HAVE_PFLAG
X if ((p->p_sched & SLOAD) == 0)
X  {
X   struct dmap l_dmap;
X   int ublkno;
X   /* code adapted from ps.c (or so says ofiles.c) */
X   if (kmemcpy(&l_dmap,(char *)(p->p_smap),sizeof(struct dmap)) == -1)
X     RETERN(0,getusererrno,GU_DMAP)
X   if (kmemcpy(&ublkno,(char *)(l_dmap.dm_ptdaddr),sizeof(int)) == -1)
X     RETERN(0,getusererrno,GU_BLKNO)
X   if (kmemcpy((char *)&user,(char *)dtob(ublkno),sizeof(struct user)) == -1)
X     RETERN(0,getusererrno,GU_UAREA)
X   /* that's it? wow ---DJB */
X  }
X#else
X if ((p->p_flag & SLOAD) == 0)
X  {
X   if (kmemcpy((char *)&user,(char *)dtob(p->p_swaddr),sizeof(struct user)) == -1)
X     RETERN(0,getusererrno,GU_UAREA)
X  }
X#endif
X else
X  {   /* boo */
X#ifdef GETUSER_MIPS
X   if (kmemcpy((char *)wpte,(char *)p->p_addr,sizeof(wpte)) == -1)
X     RETERN(0,getusererrno,GU_PTE)
X   
X   /* now collect various pages of u area */
X   ncl = (sizeof(struct user) + NBPG*CLSIZE - 1)/(NBPG*CLSIZE);
X   up = (char *) &user;
X   for (upage = 0; upage < ncl; upage += CLSIZE)
X    {
X     if (mmemcpy(up,(char *)ctob(wpte[upage].pg_pfnum),NBPG*CLSIZE) == -1)
X       RETERN(0,getusererrno,GU_UPAGE)
X     up += (NBPG*CLSIZE);
X    }
X#else
X   ptep = &Usrptma[btokmx(p->p_p0br) + p->p_szpt - 1];
X
X   /* get the page table for the user page */
X   if (kmemcpy((char *)&apte,(char *)ptep,sizeof(apte)) == -1)
X     RETERN(0,getusererrno,GU_PTE)
X
X   /* now get this user's page table */
X   if (mmemcpy((char *)mypgtbl,(char *)ctob(apte.pg_pfnum),sizeof(mypgtbl)) == -1)
X     RETERN(0,getusererrno,GU_UPGTBL)
X   /* now collect various pages of u area */
X   up = (char *) &user;
X   for (upage = 0; upage < sizeof(struct user)/NBPG; upage++)
X    {
X     if (mmemcpy(up,(char *)ctob(mypgtbl[NPTEPG-UPAGES+upage].pg_pfnum),NBPG) == -1)
X       RETERN(0,getusererrno,GU_UPAGE)
X     up += NBPG;
X    }
X#endif
X  }
X return &user;
X}
X#endif
X
X#endif
X#endif
END_OF_FILE
if test 6695 -ne `wc -c <'getuser.c'`; then
    echo shar: \"'getuser.c'\" unpacked with wrong size!
fi
# end of 'getuser.c'
fi
if test -f 'mntops.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mntops.c'\"
else
echo shar: Extracting \"'mntops.c'\" \(4124 characters\)
sed "s/^X//" >'mntops.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline
XOriginally stolen from Dupuy ofiles.
X*/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "rpcnfs.h" /* XXX: see structmtab.h */
X#include "structmtab.h"
X#include "stattimeout.h"
X#include "mallocfree.h"
X#include "mntops.h"
X#include "confslowstat.h"
X#include "confmntent.h"
X#include "confmntult.h"
X
X#ifdef SLOWSTAT
X#define STAT_TIMEOUT 5 /* time out stat() calls after 5 sec */
X#endif
X#ifndef STAT_TIMEOUT
X#define STAT_TIMEOUT 0
X#endif
X
X#ifdef MNTULT
Xstatic struct fs_data mntdata;
X#else
Xstatic FILE *mnttab;
X#endif
X
Xstruct statlist *stats = 0;
X
X#ifdef MNTULT
X
Xint get_mntlist()
X{
X register struct statlist *statp;
X int mnt = 0;
X int result;
X
X#ifdef NOSTAT_MANY
X while (result = getmnt(&mnt,&mntdata,sizeof(mntdata),NOSTAT_MANY,0))
X#else
X while (result = getmnt(&mnt,&mntdata,sizeof(mntdata),mnt))
X#endif
X  {
X   if (!(statp = (struct statlist *) malloc(sizeof(struct statlist))))
X      break;
X   statp->next = stats;
X   stats = statp;
X
X   (void) strcpy(statp->filename,mntdata.fd_path);
X   (void) strcpy(statp->fsname,mntdata.fd_devname);
X   statp->device = mntdata.fd_dev;
X  }
X
X if (result < 0)
X   return -1;
X return 0;
X}
X
Xstruct mounted *getmntname(name)
Xchar *name;
X{
X static struct mounted mounted;
X int result;
X
X#ifdef NOSTAT_ONE
X if (!(result = getmnt(0,&mntdata,0,NOSTAT_ONE,name)))
X   return 0;
X#else
X int mnt = 0;
X
X while (result = getmnt(&mnt,&mntdata,sizeof(mntdata),mnt))
X  {
X   if (strcmp(name,mntdata.fd_devname) == 0)
X     break;
X   if (strcmp(name,mntdata.fd_path) == 0)
X     break;
X  }
X
X if (mnt == 0)
X   return 0;
X#endif
X
X if (result < 0)
X   return 0;
X
X mounted.mountpoint = mntdata.fd_path;
X mounted.filesystem = mntdata.fd_devname;
X return &mounted;
X}
X
Xstruct mounted *getmntfile(filestats)
Xstruct stat *filestats;
X{
X static struct mounted mounted;
X int context;
X
X while (getmnt(&context,&mntdata,sizeof(mntdata)),context)
X   if (filestats->st_dev == mntdata.fd_dev)
X      break;
X
X if (!context)
X   return 0;
X
X mounted.mountpoint = mntdata.fd_path;
X mounted.filesystem = mntdata.fd_devname;
X return &mounted;
X}
X
X#else
X
X#ifndef MNTENT
X
Xstruct mtab *getmntent(mntfile)
XFILE *mntfile;
X{
X static struct mtab mtab;
X char devname[MNTMAXSTR];
X
X if (fread((char *) &mtab,sizeof(mtab),1,mntfile) != 1)
X   return 0;
X strncpy(devname,mtab.m_dname,MNTMAXSTR);
X strcpy(mtab.m_dname,"/dev/");
X strncat(mtab.m_dname,devname,MNTMAXSTR - 5);
X return &mtab;
X}
X
X#endif
X
Xint get_mntlist()
X{
X register struct statlist *statp;
X struct stat status;
X struct mntent *mnt;
X
X#ifdef MNTENT
X mnttab = setmntent(MOUNTED,"r");
X#else
X mnttab = fopen("/etc/mtab","r");
X#endif
X
X if (!mnttab)
X   return -1;
X
X while (mnt = getmntent(mnttab))
X  {
X   if (!(statp = (struct statlist *) malloc(sizeof(struct statlist))))
X     break;
X   statp->next = stats;
X   stats = statp;
X
X   (void) strncpy(statp->filename,mnt->mnt_dir,MNTMAXSTR);
X   (void) strncpy(statp->fsname,mnt->mnt_fsname,MNTMAXSTR);
X   statp->filename[MNTMAXSTR - 1] = '\0';
X   statp->fsname[MNTMAXSTR - 1] = '\0';
X
X   if (stattimeout(statp->filename,&status,STAT_TIMEOUT))
X    {        /* find out what it is */
X     /*XXX: report error on statp->filename */
X     stats = statp->next;
X     free((char *) statp);
X     continue;
X    }
X   statp->device = status.st_dev;
X  }
X}
X
Xstruct mounted *getmntname(name)
Xchar *name;
X{
X static struct mounted mounted;
X register struct mntent *mnt;
X
X rewind(mnttab);
X while ((mnt = getmntent(mnttab)))
X  {
X   if (strncmp(name,mnt->mnt_fsname,MNTMAXSTR) == 0)
X     break;
X   if (strncmp(name,mnt->mnt_dir,MNTMAXSTR) == 0)
X     break;
X  }
X
X if (!mnt)
X   return 0;
X
X mounted.mountpoint = mnt->mnt_dir;
X mounted.filesystem = mnt->mnt_fsname;
X return &mounted;
X}
X
Xstruct mounted *getmntfile(filestats)
Xstruct stat *filestats;
X{
X static struct mounted mounted;
X register struct mntent *mnt;
X struct stat dirstats;
X
X rewind(mnttab);
X while (mnt = getmntent(mnttab))
X   if ((stat(mnt->mnt_dir,&dirstats) >= 0) &&
X       (filestats->st_dev == dirstats.st_dev))
X     break;
X
X if (!mnt)
X   return 0;
X
X mounted.mountpoint = mnt->mnt_dir;
X mounted.filesystem = mnt->mnt_fsname;
X return &mounted;
X}
X
X#endif
END_OF_FILE
if test 4124 -ne `wc -c <'mntops.c'`; then
    echo shar: \"'mntops.c'\" unpacked with wrong size!
fi
# end of 'mntops.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Alt.sources mailing list