Path: utzoo!utgpu!cs.utexas.edu!asuvax!noao!rutgers!cmcl2!kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: alt.sources Subject: kstuff 0.18 (part 4/6) Message-ID: <6075:May704:50:5991@kramden.acf.nyu.edu> Date: 7 May 91 04:50:59 GMT Followup-To: alt.sources.d Organization: IR Lines: 1765 #! /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 '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 was the original author of ofiles. X XVic Abell XDan Bernstein XWill Crowder XTom Christiansen XMichael Ditto XViktor Dukhovni XTom Dunigan XAlexander Dupuy XVik Lall XCraig Leres XRay Moody XGary Nebbett XTim Rosmus XMike Spitzer XRichard Tobin 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 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 wrote the original ofiles for BSD 4.2, around XMay 1985. This is the ``original ofiles'' node above. X XAlexander Dupuy maintained ofiles in September Xand October 1988. He integrated a vnode version with DYNIX support from XTom Dunigan , 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 , 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---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 and socket-searching enhancements Xby Viktor Dukhovni . 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 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 . 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 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 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 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 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 X#ifdef USE_SYSLOG X#include 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: (no guarantees, but chances are that X findinode's never seen that inode-device) X 2065 300: /etc// (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// 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 is probably true here) X 2065 300: /tmp/joe// 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 to something like . 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 X#include X#include X#include X#include X#include 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 X#include X#include 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 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 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 X#endif X#include X#include "confgetuserdynix.h" X#include "confgetusermips.h" X#include "confgetuserconvex.h" X#include "confkvm.h" X#ifdef KVM X#include X#include /* 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 */ 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 X#include X#include 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