kstuff 0.18 (part 3/6)
Dan Bernstein
brnstnd at kramden.acf.nyu.edu
Tue May 7 14:41:54 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 3 (of 6)."
# Contents: BLURB.authd FILES authuser.3 authuser.c avenrun.c
# filetable.c findinode/findinode.c findinode/updatefid.c
# getdevicename.c kmem.c netinp.c netstatuids.c nlistlist.c
# printpstat.c printucred.c proctable.c strerr.c testauthd.c
# Wrapped by brnstnd at kramden on Mon May 6 23:58:58 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'BLURB.authd' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'BLURB.authd'\"
else
echo shar: Extracting \"'BLURB.authd'\" \(2201 characters\)
sed "s/^X//" >'BLURB.authd' <<'END_OF_FILE'
XIf host X supports RFC 931, and if joe at X and sally at Y are connected
Xthrough TCP, then sally can find out the name of joe. This package
Xincludes authd, an RFC 931 server---the program that X runs to tell
Xsally who joe is. Once you've installed it, your users can't escape the
Xauthentication: if they telnet or rlogin or send mail or do whatever to
Xanother host, that host can find out the username.
X
XThis package also includes a library that acts as an RFC 931 client---
Xthe routines that sally uses to ask X's server who joe is. You don't
Xneed privileges to use the library, which should compile and run without
Xtrouble on any BSD-derived system. (authd is not so portable; although
Xit works without changes under SunOS and Ultrix, it might not work on
Xother systems. The package includes testauthd to make sure it works.)
X
XThe previous version of authd was reported to work on the following
Xsystems:
X
X Sun 2/170, SunOS 4.0
X Sun 4/280, SunOS 4.0.3
X Sun 3/80, SunOS 4.1
X Sun 3/160, SunOS 4.1
X Sun 3/180, SunOS 4.1
X Sun 4/60, SunOS 4.1
X Sun 4/330, SunOS 4.1
X DECsystem-5820, Ultrix 4.0
X DECsystem-5820, Ultrix 4.1
X DECStation-5400, Ultrix 4.1
X VAX 8650, Ultrix 4.1
X MicroVAX III, BSD 4.3+NFS
X HP9000 Series 300, HP-UX 7.0
X HP9000 Series 400, HP-UX 7.0
X HP9000 Series 800, HP-UX 7.0
X Convex C210, Convex UNIX 8.0
X
XI've placed this code into the public domain because I think that
Xeveryone should support at least this level of security. I'm sick of
Xseeing people forge mail and spoof NNTP and attack systems anonymously
Xthrough the network. Now they won't be able to, because every connection
Xwill be tagged with the username with at least as much security as the
XTCP host address in each packet. I hope that every site will do its part
Xto contribute to network security (and to help CERT trace intruders).
X
XIt should take approximately 10 minutes to read the instructions and
Xcompile, install, and test authd on a new machine. It should take
Xapproximately 2 minutes on each new machine once you're familiar with
Xthe instructions. Send comments on these estimates to brnstnd at nyu.edu,
Xcc the Office of Management and Budget, Paperwork Reduction Division.
X
X---Dan Bernstein, brnstnd at nyu.edu
END_OF_FILE
if test 2201 -ne `wc -c <'BLURB.authd'`; then
echo shar: \"'BLURB.authd'\" unpacked with wrong size!
fi
# end of 'BLURB.authd'
fi
if test -f 'FILES' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'FILES'\"
else
echo shar: Extracting \"'FILES'\" \(2483 characters\)
sed "s/^X//" >'FILES' <<'END_OF_FILE'
XBLURB
XREADME
XCHANGES
XFORMLETTER
XFILES
XMakefile
XINSTALL
XBLURB.authd
XREADME.authd
Xload.1
Xauthuser.3
Xauthd.8
Xtcpuid.8
Xtcpuname.8
Xpff.doc
XOFILES.hist
Xrfc931
Xauread.h
Xauthuser.h
Xavenrun.h
Xboottime.h
Xconfclonedev.h
Xconfconvexfilegarbage.h
Xconfconvexrpcnfs.h
Xconfconvexsysfile.h
Xconfdevt.h
Xconfdomain.h
Xconfetcconfhfileh.h
Xconffcredptr.h
Xconffree.h
Xconfgetuserconvex.h
Xconfgetuserdynix.h
Xconfgetusermips.h
Xconfgetusersupport.h
Xconfgnode.h
Xconfhavepflag.h
Xconfhaveppid.h
Xconfhavepsuid.h
Xconfhaveucred.h
Xconfhaveusigintr.h
Xconfhavevmseg.h
Xconfitype.h
Xconfkvm.h
Xconfloadavglong.h
Xconfmajorminor.h
Xconfmalloc.h
Xconfmntent.h
Xconfmntult.h
Xconfneedartospte.h
Xconfneedmachparam.h
Xconfneedmntinfo.h
Xconfnfs.h
Xconfnlistknlist.h
Xconfnlistmeaning.h
Xconfnlistunder.h
Xconfnlname.h
Xconfnonsfinet.h
Xconfnounpaddr.h
Xconfodofe.h
Xconfopalf.h
Xconfpcredinproc.h
Xconfpcredunderproc.h
Xconfpsess.h
Xconfregion.h
Xconfrtype.h
Xconfslowstat.h
Xconfsocketneedsxnode.h
Xconfsyncsema.h
Xconfsysucred.h
Xconftcpnlist.h
Xconftext.h
Xconftextneedsvmparam.h
Xconfttyvp.h
Xconfultrixrpcnfs.h
Xconfundefstdcbeforedir.h
Xconfuofile.h
Xconfusrptnlist.h
Xconfvmunix.h
Xconfvtype.h
Xfiletable.h
Xgetdevicename.h
Xgetfcred.h
Xgetnode.h
Xgetopt.h
Xgetpcred.h
Xgetsocket.h
Xgetuser.h
Xgetvmseg.h
Xgroupname.h
Xinpcblist.h
Xkmem.h
Xmallocfree.h
Xmmem.h
Xmntops.h
Xnetinp.h
Xnlistlist.h
Xnumeric.h
Xportname.h
Xprintfamily.h
Xprintfflag.h
Xprintftype.h
Xprintprotoinet.h
Xprintpstat.h
Xprintrlimits.h
Xprintrusage.h
Xprintsocktype.h
Xprintucred.h
Xproctable.h
Xrevnamei.h
Xrpcnfs.h
Xsmem.h
Xstattimeout.h
Xstrerr.h
Xstructfile.h
Xstructinpcb.h
Xstructmbuf.h
Xstructmtab.h
Xstructproc.h
Xstructprotosw.h
Xstructpte.h
Xstructsockaddrin.h
Xstructsocket.h
Xstructtcp.h
Xstructtext.h
Xstructucred.h
Xstructunpcb.h
Xstructuser.h
Xstructxnode.h
Xusername.h
Xvirtype.h
Xvmstuff.h
Xauread.c
Xauthd.c
Xauthuser.c
Xavenrun.c
Xboottime.c
Xfiletable.c
Xgetdevicename.c
Xgetfcred.c
Xgetnode.c
Xgetpcred.c
Xgetsocket.c
Xgetuser.c
Xgetvmseg.c
Xgroupname.c
Xinpcblist.c
Xkmem.c
Xload.c
Xmmem.c
Xmntops.c
Xnetinp.c
Xnetstatuids.c
Xnlistlist.c
Xnumeric.c
Xpff.c
Xportname.c
Xprintfamily.c
Xprintfflag.c
Xprintftype.c
Xprintprotoinet.c
Xprintpstat.c
Xprintrlimits.c
Xprintrusage.c
Xprintsocktype.c
Xprintucred.c
Xproctable.c
Xrevnamei.c
Xsmem.c
Xstattimeout.c
Xstrerr.c
Xtestauthd.c
Xusername.c
Xvirtype.c
Xfindinode
Xfindinode/README
Xfindinode/FILES
Xfindinode/Makefile
Xfindinode/FIDDIR
Xfindinode/INSTALL
Xfindinode/fsupdatefid
Xfindinode/fid.h
Xfindinode/fid.c
Xfindinode/updatefid.c
Xfindinode/findinode.c
Xfindinode/updatefid.8
Xfindinode/findinode.1
Xfindinode/getopt.h
END_OF_FILE
if test 2483 -ne `wc -c <'FILES'`; then
echo shar: \"'FILES'\" unpacked with wrong size!
fi
# end of 'FILES'
fi
if test -f 'authuser.3' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'authuser.3'\"
else
echo shar: Extracting \"'authuser.3'\" \(3350 characters\)
sed "s/^X//" >'authuser.3' <<'END_OF_FILE'
X.TH authuser 3
X.SH NAME
Xauthuser \- library to get information from a remote Authentication Server
X.SH SYNTAX
X.B #include <authuser.h>
X.PP
X.B unsigned short auth_tcpport;
X.PP
X.B char *auth_xline(user,fd,&in);
X.PP
X.B int auth_fd(fd,&in,&local,&remote);
X.PP
X.B char *auth_tcpuser(in,local,remote);
X.PP
X.B char *user;
X.br
X.B int fd;
X.br
X.B unsigned long in;
X.br
X.B unsigned short local;
X.br
X.B unsigned short remote;
X.SH DESCRIPTION
XThe
X.I authuser
Xlibrary provides a simple interface for
Xfinding out the remote identity
Xof a connection through the
XAuthentication Server
Xas specified by RFC 931.
XUse the -lauthuser loader option
Xto compile a program with this library.
X.PP
X.B auth_xline(user,fd,&in)
Xreturns a line of the form X-Auth-User: user or X-Forgery-By: username,
Xdepending upon what the host on the other side of
X.B fd
Xthinks of the user.
XThis is particularly appropriate for
Xmail and news headers.
X.PP
XIf the remote host reports that
X.B user
Xowns the connection on that side,
X.B auth_xline
Xwill return X-Auth-User: user.
XIf the remote host reports that a different
X.B username
Xowns the connection,
X.B auth_xline
Xwill return X-Forgery-By: username.
XIf user is NULL,
Xit returns X-Auth-User: username
Xwith the username reported by the remote host.
XIf
X.B fd
Xis not a TCP connection
Xor authentication is impossible,
X.B auth_xline
Xreturns NULL, setting errno appropriately.
X.PP
XThe line is not cr-lf terminated.
XIt is stored in a static area
Xwhich is overwritten on each call to
X.B auth_xline.
X.B auth_xline
Xplaces the Internet address of the other host into in.
X.PP
X.B auth_fd(fd,&in,&local,&remote)
Xretrieves address information from the connection in socket
X.B fd.
XIt places the
XInternet address of the host on other side into
X.B in
Xand the local and remote
XTCP ports into
X.B local
Xand
X.B remote.
X.B auth_fd
Xreturns -1 upon error, setting errno appropriately.
X.PP
X.B auth_tcpuser(in,local,remote)
Xreturns the name of the user on the other end of the TCP connection
Xbetween
X.B remote at in
Xand
X.B local.
XIf authentication is impossible,
X.B auth_tcpuser
Xreturns
XNULL, setting errno appropriately.
XThe user name is stored in a static area
Xwhich is overwritten on each call to
X.B auth_tcpuser
Xand
X.B auth_xline.
X.PP
XThe authentication routines check with the
Xremote Authentication Server on port
X.B auth_tcpport,
Xwhich defaults to 113
Xas specified by RFC 931.
XYou can set
X.B auth_tcpport
Xto other values
Xfor nonstandard implementations.
X.PP
X.SH RESTRICTIONS
X.I authuser
Xdoes no backslash interpretation
Xupon the remote user name.
XHopefully the next revision of RFC 931
Xwill make clear exactly what backslash
Xinterpretation should be going on.
X.PP
X.I authuser
Xdoes not use the operating system type
Xinformation provided by the Authentication Server.
X.SH VERSION
Xauthuser version 3.1, May 6, 1991.
X.SH AUTHOR
XPlaced into the public domain by Daniel J. Bernstein.
X.SH REFERENCES
XThe authentication server is more secure than passwords
Xin some ways, but less secure than passwords in many ways.
X(It's certainly better than no password at all---e.g., for
Xmail or news.)
XIt is not the final solution.
XFor an excellent discussion of security problems within
Xthe TCP/IP protocol suite, see
XSteve Bellovin's article
X``Security Problems in the TCP/IP Protocol Suite.''
X.SH "SEE ALSO"
Xauthtcp(1),
Xattachport(1),
Xgetpeername(3),
Xgetsockname(3),
Xtcp(4),
Xauthd(8)
END_OF_FILE
if test 3350 -ne `wc -c <'authuser.3'`; then
echo shar: \"'authuser.3'\" unpacked with wrong size!
fi
# end of 'authuser.3'
fi
if test -f 'authuser.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'authuser.c'\"
else
echo shar: Extracting \"'authuser.c'\" \(3622 characters\)
sed "s/^X//" >'authuser.c' <<'END_OF_FILE'
X/*
X5/6/91 DJB baseline authuser 3.1. Public domain.
X*/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X#include <netdb.h>
X#include <errno.h>
X#include <ctype.h>
Xextern int errno;
X#include "authuser.h"
X
Xunsigned short auth_tcpport = 113;
X
X#define SIZ 500 /* various buffers */
X
Xstatic int usercmp(u,v)
Xregister char *u;
Xregister char *v;
X{
X /* is it correct to consider Foo and fOo the same user? yes */
X /* but the function of this routine may change later */
X while (*u && *v)
X if (tolower(*u) != tolower(*v))
X return tolower(*u) - tolower(*v);
X else
X ++u,++v;
X return *u || *v;
X}
X
Xstatic char authline[SIZ];
X
Xchar *auth_xline(user,fd,in)
Xregister char *user; /* the supposed name of the user, NULL if unknown */
Xregister int fd; /* the file descriptor of the connection */
Xregister unsigned long *in;
X{
X unsigned short local;
X unsigned short remote;
X register char *ruser;
X
X if (auth_fd(fd,in,&local,&remote) == -1)
X return 0;
X ruser = auth_tcpuser(*in,local,remote);
X if (!ruser)
X return 0;
X if (!user)
X user = ruser; /* forces X-Auth-User */
X (void) sprintf(authline,
X (usercmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
X ruser);
X return authline;
X}
X
Xint auth_fd(fd,in,local,remote)
Xregister int fd;
Xregister unsigned long *in;
Xregister unsigned short *local;
Xregister unsigned short *remote;
X{
X struct sockaddr_in sa;
X int dummy;
X
X dummy = sizeof(sa);
X if (getsockname(fd,&sa,&dummy) == -1)
X return -1;
X if (sa.sin_family != AF_INET)
X {
X errno = EAFNOSUPPORT;
X return -1;
X }
X *local = ntohs(sa.sin_port);
X dummy = sizeof(sa);
X if (getpeername(fd,&sa,&dummy) == -1)
X return -1;
X *remote = ntohs(sa.sin_port);
X *in = sa.sin_addr.s_addr;
X return 0;
X}
X
Xstatic char ruser[SIZ];
Xstatic char realbuf[SIZ];
Xstatic char *buf;
X
Xchar *auth_tcpuser(in,local,remote)
Xregister unsigned long in;
Xregister unsigned short local;
Xregister unsigned short remote;
X{
X struct sockaddr_in sa;
X register int s;
X register int buflen;
X register int w;
X register int saveerrno;
X char ch;
X unsigned short rlocal;
X unsigned short rremote;
X
X if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
X return 0;
X sa.sin_family = AF_INET;
X sa.sin_port = htons(auth_tcpport);
X sa.sin_addr.s_addr = in;
X if (connect(s,&sa,sizeof(sa)) == -1)
X {
X saveerrno = errno;
X (void) close(s);
X errno = saveerrno;
X return 0;
X }
X
X buf = realbuf;
X (void) sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local);
X /* note the reversed order---the example in the RFC is misleading */
X buflen = strlen(buf);
X while ((w = write(s,buf,buflen)) < buflen)
X if (w == -1) /* should we worry about 0 as well? */
X {
X saveerrno = errno;
X (void) close(s);
X errno = saveerrno;
X return 0;
X }
X else
X {
X buf += w;
X buflen -= w;
X }
X buf = realbuf;
X while ((w = read(s,&ch,1)) == 1)
X {
X *buf = ch;
X if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
X ++buf;
X if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
X break;
X }
X if (w == -1)
X {
X saveerrno = errno;
X (void) close(s);
X errno = saveerrno;
X return 0;
X }
X *buf = '\0';
X
X if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s",&rremote,&rlocal,ruser) < 3)
X {
X (void) close(s);
X errno = EIO;
X /* makes sense, right? well, not when USERID failed to match ERROR */
X /* but there's no good error to return in that case */
X return 0;
X }
X if ((remote != rremote) || (local != rlocal))
X {
X (void) close(s);
X errno = EIO;
X return 0;
X }
X /* XXX: we're not going to do any backslash processing */
X (void) close(s);
X return ruser;
X}
END_OF_FILE
if test 3622 -ne `wc -c <'authuser.c'`; then
echo shar: \"'authuser.c'\" unpacked with wrong size!
fi
# end of 'authuser.c'
fi
if test -f 'avenrun.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'avenrun.c'\"
else
echo shar: Extracting \"'avenrun.c'\" \(2091 characters\)
sed "s/^X//" >'avenrun.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X/* getavenrun() returns a pointer into an array of 3 doubles giving the */
X/* current load average (i.e., AVErage Number of RUNning jobs). The first */
X/* is typically the 1-minute average, the second is the 5-minute average, */
X/* and the third is the 15-minute average. getavenrun returns 0 on error. */
X
X/* avenruninit() does optional initialization to cooperate with other */
X/* libraries that use nlistlist. avenruninit returns -1 on error. */
X
X/* avenrunstrerr is a strerrfun for use with the strerr library. */
X
X#include "avenrun.h"
X#include "kmem.h"
X#include "nlistlist.h"
X#include "strerr.h"
X#include "confloadavglong.h"
X
X#define AVENRUNNLIST "_avenrun"
X
Xstatic int avinit = 0;
X
Xstatic double av[3];
Xstatic short avtype;
Xstatic unsigned long avvalue;
Xstatic int avenrunerrno = 0;
X
Xstatic struct strerrtab e[] = {
X { 0, "avenrun error 0", 0 }
X#define AV_INIT 1
X, { AV_INIT, "cannot init avenrun: ", nliststrerr }
X#define AV_NLIST 2
X, { AV_NLIST, "cannot nlist: ", nliststrerr }
X#define AV_NLISTFOUND 3
X, { AV_NLISTFOUND, AVENRUNNLIST, nlistnotin }
X#define AV_KMEM 4
X, { AV_KMEM, "cannot read avenrun: ", kmemstrerr }
X};
X
Xchar *avenrunstrerr(ke)
Xstrerrfun *ke;
X{
X return strerrtaberr(ke,avenrunerrno,e,sizeof(e)/sizeof(*e),"unknown avenrun error");
X}
X
Xint avenruninit()
X{
X if (nlistadd(AVENRUNNLIST,&avtype,&avvalue) == -1)
X RETERN(-1,avenrunerrno,AV_INIT)
X avinit = 1;
X return 0;
X}
X
X#ifdef LOADAVGISLONG
Xstatic long avd[3];
X#endif
X
Xdouble *getavenrun()
X{
X if (!avinit)
X if (avenruninit() == -1)
X return 0;
X if (avtype == -1)
X if (nlistdo() == -1)
X RETERN(0,avenrunerrno,AV_NLIST)
X if (!avtype)
X RETERN(0,avenrunerrno,AV_NLISTFOUND)
X#ifdef LOADAVGISLONG
X if (kmemcpy((char *) &(avd[0]),(char *) avvalue,sizeof(avd)) == -1)
X RETERN(0,avenrunerrno,AV_KMEM)
X av[0] = ((double) avd[0]) / LOADAVGISLONG;
X av[1] = ((double) avd[1]) / LOADAVGISLONG;
X av[2] = ((double) avd[2]) / LOADAVGISLONG;
X#else
X if (kmemcpy((char *) &(av[0]),(char *) avvalue,sizeof(av)) == -1)
X RETERN(0,avenrunerrno,AV_KMEM)
X#endif
X return av;
X}
END_OF_FILE
if test 2091 -ne `wc -c <'avenrun.c'`; then
echo shar: \"'avenrun.c'\" unpacked with wrong size!
fi
# end of 'avenrun.c'
fi
if test -f 'filetable.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'filetable.c'\"
else
echo shar: Extracting \"'filetable.c'\" \(2666 characters\)
sed "s/^X//" >'filetable.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
Xstruct file *getfiletable() returns a pointer to a not necessarily
Xatomic copy of the file table. myfile is the base of the file table in
Xreal kernel memory, i.e., _file. mynfile is the number of entries in the
Xfile table, i.e., _nfile.
X
Xfiletableinit() does optional initialization to cooperate with other
Xlibraries.
X
Xfiletablestrerr is a strerrfun for filetableinit() and getfiletable().
X
X*/
X
X#include "mallocfree.h"
X#include "structfile.h"
X#include "filetable.h"
X#include "kmem.h"
X#include "nlistlist.h"
X#include "strerr.h"
X
X#define FILENLIST "_file"
X#define NFILENLIST "_nfile"
X
Xstatic int finit = 0;
Xstatic struct file *filetable = 0;
Xstatic short ftype;
Xstatic short nftype;
Xstatic unsigned long fvalue;
Xstatic unsigned long nfvalue;
Xstruct file *myfile;
Xint mynfile;
Xstatic int filetableerrno = 0;
X
Xstatic struct strerrtab e[] = {
X { 0, "filetable error 0", 0 }
X#define FT_INIT 1
X, { FT_INIT, "cannot init filetable: ", nliststrerr }
X#define FT_NLIST 2
X, { FT_NLIST, "cannot nlist: ", nliststrerr }
X#define FT_NLFFOUND 3
X, { FT_NLFFOUND, FILENLIST, nlistnotin }
X#define FT_NLNFFOUND 4
X, { FT_NLNFFOUND, NFILENLIST, nlistnotin }
X#define FT_NLFREAD 5
X, { FT_NLFREAD, "cannot read file table pointer: ", kmemstrerr }
X#define FT_NLNFREAD 6
X, { FT_NLNFREAD, "cannot read nfile: ", kmemstrerr }
X#define FT_FTREAD 7
X, { FT_FTREAD, "cannot read file table: ", kmemstrerr }
X#define FT_ALLOC 8
X, { FT_ALLOC, "out of memory", 0 }
X} ;
X
Xchar *filetablestrerr(ke)
Xstrerrfun *ke;
X{
X return strerrtaberr(ke,filetableerrno,e,sizeof(e)/sizeof(*e),"unknown filetable error");
X}
X
Xint filetableinit()
X{
X if (nlistadd(FILENLIST,&ftype,&fvalue) == -1)
X RETERN(-1,filetableerrno,FT_INIT)
X if (nlistadd(NFILENLIST,&nftype,&nfvalue) == -1)
X RETERN(-1,filetableerrno,FT_INIT)
X finit = 1;
X return 0;
X}
X
Xstruct file *getfiletable()
X{
X if (!finit)
X if (filetableinit() == -1)
X return 0;
X if (ftype == -1)
X if (nlistdo() == -1)
X RETERN(0,filetableerrno,FT_NLIST)
X if (!ftype)
X RETERN(0,filetableerrno,FT_NLFFOUND)
X if (!nftype)
X RETERN(0,filetableerrno,FT_NLNFFOUND)
X if (kmemcpy((char *) &mynfile,(char *) nfvalue,sizeof(mynfile)) == -1)
X RETERN(0,filetableerrno,FT_NLFREAD)
X if (kmemcpy((char *) &myfile,(char *) fvalue,sizeof(myfile)) == -1)
X RETERN(0,filetableerrno,FT_NLNFREAD)
X
X if (filetable)
X free((char *) filetable);
X filetable = (struct file *) malloc((unsigned) (sizeof(struct file) * mynfile));
X if (!filetable)
X RETERN(0,filetableerrno,FT_ALLOC)
X
X if (kmemcpy((char *) filetable,(char *) myfile,sizeof(struct file) * mynfile) == -1)
X RETERN(0,filetableerrno,FT_FTREAD)
X
X return filetable;
X}
END_OF_FILE
if test 2666 -ne `wc -c <'filetable.c'`; then
echo shar: \"'filetable.c'\" unpacked with wrong size!
fi
# end of 'filetable.c'
fi
if test -f 'findinode/findinode.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'findinode/findinode.c'\"
else
echo shar: Extracting \"'findinode/findinode.c'\" \(3687 characters\)
sed "s/^X//" >'findinode/findinode.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 "getopt.h"
X#include "fid.h"
X
X/* XXX: This has really shoddy error checking. */
X
Xint nonl(s)
Xchar *s;
X{
X while (*s)
X {
X if (*s == '\n')
X return 0;
X ++s;
X }
X return 1;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct node f;
X struct nodenum fn;
X struct dnodenum dn;
X struct stat st;
X int i;
X int j;
X static struct dnodenum dnarr[100];
X struct stat stroot;
X DIR *dirp;
X struct direct *dp;
X static char line[1000];
X int flagjustone;
X int opt;
X int uid;
X
X uid = getuid();
X
X if (fidinit() == -1)
X {
X fprintf(stderr,"findinode: fatal: cannot open fid database\n");
X exit(1);
X }
X
X if (lstat("/",&stroot) == -1)
X {
X fprintf(stderr,"findinode: fatal: cannot lstat /\n");
X exit(1);
X }
X
X flagjustone = 0;
X
X while ((opt = getopt(argc,argv,"aA")) != EOF)
X switch(opt)
X {
X case 'a': flagjustone = 0; break;
X case 'A': flagjustone = 1; break;
X case '?': ; /*XXX*/
X }
X
X while (fgets(line,sizeof(line),stdin)) /* XXX: truncation */
X {
X line[strlen(line) - 1] = 0;
X if (sscanf(line,"%lu %lx",&f.i,&f.d) < 2)
X if (lstat(line,&st) == -1)
X {
X printf("<nonexistent>: %s\n",line);
X fflush(stdout);
X continue;
X }
X else
X {
X f.i = st.st_ino;
X f.d = st.st_dev;
X }
X f.i = (unsigned long) (ino_t) f.i;
X f.d = (unsigned long) (dev_t) f.d;
X i = fidfilesget(f);
X /* XXX: put all this searching stuff into a function returning a string? */
X#ifdef notdef
X printf("file %s (%lu %lx) links %u\n",argv[1],f.i,f.d,i);
X#endif
X if (!i)
X if (f.i == stroot.st_ino && f.d == stroot.st_dev)
X printf("%lu %lx: /\n",f.i,f.d);
X else
X printf("%lu %lx: <unknown>\n",f.i,f.d);
X if (i > 1 && flagjustone)
X i = 1;
X for (;i;--i)
X {
X /* Get the directories. */
X fidlock();
X if (i > fidfilesget(f))
X {
X fidunlock();
X continue; /* just in case database changed */
X }
X fn.x = f; fn.n = i;
X dnarr[0].x.i = fn.x.i; dnarr[0].x.d = fn.x.d;
X dnarr[j = 1] = dn = fidf2dget(fn);
X printf("%lu %lx: ",f.i,f.d);
X while (fn.x.i = dn.x.i, fn.x.d = dn.x.d, fidfilesget(fn.x) > 0)
X {
X /* XXX: could report an error if fidfilesget() > 1 */
X fn.n = 1;
X dn = dnarr[++j] = fidf2dget(fn);
X if (j == 99)
X break; /*XXX*/
X }
X fidunlock();
X
X if (dnarr[j].x.i == stroot.st_ino && dnarr[j].x.d == stroot.st_dev)
X {
X chdir("/");
X do
X {
X printf("/");
X dirp = opendir(".");
X --j;
X while (dp = readdir(dirp))
X {
X if (dp->d_name[0] == 0)
X continue;
X if (dp->d_name[0] == '.' && dp->d_name[1] == 0)
X continue;
X if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0)
X continue;
X if (lstat(dp->d_name,&st) != -1)
X if (dnarr[j].x.i == st.st_ino && dnarr[j].x.d == st.st_dev)
X if (!j || (chdir(dp->d_name) != -1))
X {
X if (nonl(dp->d_name))
X printf("%s",dp->d_name);
X else
X printf("/<newline>"); /* XXX: should have -0 option */
X if (j)
X {
X /* XXX: maybe access(".",R_OK) would work ok here. */
X /* and X_OK---this is too blunt but easier than */
X /* doing it right */
X if (uid && (st.st_uid != uid) && !(st.st_mode & 0005))
X {
X j = 0;
X printf("//<protected>");
X }
X }
X break;
X }
X }
X closedir(dirp);
X if (!dp) /* XXX: gee, is this valid under ANSI? :-) */
X {
X printf("/<gone>");
X break;
X }
X }
X while (j);
X }
X else
X printf("<unknown>"); /*XXX*/
X putchar('\n');
X /*XXX: -0?*/
X }
X fflush(stdout);
X }
X}
END_OF_FILE
if test 3687 -ne `wc -c <'findinode/findinode.c'`; then
echo shar: \"'findinode/findinode.c'\" unpacked with wrong size!
fi
# end of 'findinode/findinode.c'
fi
if test -f 'findinode/updatefid.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'findinode/updatefid.c'\"
else
echo shar: Extracting \"'findinode/updatefid.c'\" \(2654 characters\)
sed "s/^X//" >'findinode/updatefid.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 "fid.h"
X
X/* XXX: error checks? */
X
X/* XXX: should we periodically seek out and destroy files/dirs with 0 links? */
X
Xremove(f,linknum,d,entnum)
Xstruct node f;
Xint linknum;
Xstruct dnode d;
Xint entnum;
X{
X int linkmax;
X int entmax;
X struct nodenum fn;
X struct dnodenum dn;
X
X fn.x = f; fn.n = linknum; fidf2ddel(fn);
X dn.x = d; dn.n = entnum; fidd2fdel(dn);
X linkmax = fidfilesget(f);
X if (linknum < linkmax)
X {
X fn.x = f; fn.n = linkmax;
X dn = fidf2dget(fn); fidf2ddel(fn); fidd2fdel(dn);
X fn.n = linknum; fidf2dput(fn,dn); fidd2fput(dn,fn);
X }
X entmax = fiddirsget(d);
X if (entnum < entmax)
X {
X dn.x = d; dn.n = entmax;
X fn = fidd2fget(dn); fidd2fdel(dn); fidf2ddel(fn);
X dn.n = entnum; fidd2fput(dn,fn); fidf2dput(fn,dn);
X }
X if (--linkmax) fidfilesput(f,linkmax); else fidfilesdel(f);
X if (--entmax) fiddirsput(d,entmax); else fiddirsdel(d);
X}
X
Xadd(f,d)
Xstruct node f;
Xstruct dnode d;
X{
X int linkmax;
X int entmax;
X struct nodenum fn;
X struct dnodenum dn;
X
X linkmax = fidfilesget(f); ++linkmax; fidfilesput(f,linkmax);
X entmax = fiddirsget(d); ++entmax; fiddirsput(d,entmax);
X fn.x = f; fn.n = linkmax;
X dn.x = d; dn.n = entmax;
X fidf2dput(fn,dn);
X fidd2fput(dn,fn);
X}
X
Xint dodir()
X{
X struct node f;
X struct dnode d;
X struct nodenum fn;
X struct dnodenum dn;
X DIR *dirp;
X struct direct *dp;
X struct stat st;
X int i;
X long t;
X long modt;
X
X if (lstat(".",&st) == -1)
X return -1;
X dirp = opendir(".");
X if (!dirp)
X return -1;
X fidlock();
X d.i = st.st_ino; d.d = st.st_dev;
X modt = st.st_mtime; if (modt < st.st_ctime) modt = st.st_ctime;
X t = fiddirtimesget(d); /* XXX: should have flag to skip this test */
X if (t == modt)
X {
X fidunlock();
X return 0;
X }
X fiddirtimesput(d,0); /* marking dir for update */
X i = fiddirsget(d);
X dn.x = d;
X while (i) /* wipe out old entries */
X {
X dn.n = i;
X fn = fidd2fget(dn);
X#ifdef notdef
X printf("[- %u %u %u %u] ",fn.x.i,fn.x.d,dn.x.i,dn.x.d);
X#endif
X remove(fn.x,fn.n,dn.x,dn.n);
X --i;
X }
X while (dp = readdir(dirp)) /* put in new entries */
X {
X if (dp->d_name[0] == 0)
X continue;
X if (dp->d_name[0] == '.' && dp->d_name[1] == 0)
X continue;
X if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0)
X continue;
X if (lstat(dp->d_name,&st) != -1)
X {
X f.i = st.st_ino; f.d = st.st_dev;
X#ifdef notdef
X printf("[+ %u %u %u %u] ",f.i,f.d,d.i,d.d);
X#endif
X add(f,d);
X }
X }
X fidunlock();
X fiddirtimesput(d,modt);
X return 0;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X fidinit();
X
X while (*++argv)
X if (chdir(*argv) == 0)
X dodir();
X}
END_OF_FILE
if test 2654 -ne `wc -c <'findinode/updatefid.c'`; then
echo shar: \"'findinode/updatefid.c'\" unpacked with wrong size!
fi
# end of 'findinode/updatefid.c'
fi
if test -f 'getdevicename.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'getdevicename.c'\"
else
echo shar: Extracting \"'getdevicename.c'\" \(3848 characters\)
sed "s/^X//" >'getdevicename.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline. todo: hash device names.
X3/15/91 DJB separated into library function
XOriginally stolen from printdevice() in Dupuy ofiles.
X*/
X
X/*
X
Xchar *getdevicename(node) struct Xnode *node; returns the name of a
Xdevice in /dev (e.g., /dev/kmem) with the same remote device as node, or
X0 if no such device exists.
X
Xchar *getttydevname(dev) dev_t dev; returns the name of a character
Xdevice with the given remote device, or 0 if no such device exists. XXX
Xfor the name and modularization: this is used to find the ctty of a
Xprocess given u_ttyd, but that doesn't make it logical.
X
X*/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "confnfs.h"
X#include "confundefstdcbeforedir.h"
X#ifdef UNDEFSTDCBEFOREDIR /* stupid features don't deserve short names */
X#undef __stdc__ /* dorks */
X#endif
X#include <sys/dir.h>
X#include <errno.h>
Xextern int errno;
X#include "mallocfree.h"
X#include "structxnode.h"
X#include "confgnode.h"
X#include "confclonedev.h"
X#include "confmajorminor.h"
X
Xstatic char dev[] = "/dev/";
X
Xstatic int scanned = 0;
X
Xstruct devname
X {
X struct devname *next;
X char *name;
X unsigned mode;
X dev_t rdev;
X#ifdef CLONEDEV
X short clonedev;
X#endif
X#ifndef NFS
X unsigned ino;
X#endif
X }
X;
X
Xstatic struct devname *devnamelist = 0;
X
Xstatic int scandev()
X{
X struct stat status;
X register struct direct *entry;
X register DIR *devdir;
X register struct devname *dvent;
X
X scanned = 1;
X
X errno = 0;
X if (!(devdir = opendir(dev)))
X return -1; /*XXX*/
X
X if (dvent = (struct devname *) malloc(sizeof(struct devname)))
X {
X while (entry = readdir(devdir))
X {
X if (!(dvent->name = malloc(sizeof(dev) + strlen(entry->d_name))))
X break;
X (void) strcpy(dvent->name,dev);
X (void) strcat(dvent->name,entry->d_name);
X if (stat(dvent->name, &status) < 0
X || ((status.st_mode & S_IFMT) != S_IFBLK
X && (status.st_mode & S_IFMT) != S_IFCHR))
X {
X free((char *) dvent->name);
X continue;
X }
X
X dvent->mode = status.st_mode & S_IFMT;
X dvent->rdev = status.st_rdev;
X#ifdef CLONEDEV
X if (dvent->mode == S_IFCHR && major(dvent->rdev) == CLONEDEV)
X dvent->clonedev = minor(dvent->rdev);
X else
X dvent->clonedev = -1;
X#endif
X#ifndef NFS
X dvent->ino = status.st_ino;
X#endif
X dvent->next = devnamelist;
X devnamelist = dvent;
X if (!(dvent = (struct devname *) malloc(sizeof(struct devname))))
X break;
X }
X free ((char *) dvent);
X }
X closedir(devdir);
X return 0;
X}
X
Xchar *getdevicename(node)
Xstruct Xnode *node;
X{
X register struct devname *dvent;
X
X if (!scanned)
X if (scandev() == -1)
X return 0; /*XXX*/
X
X for (dvent = devnamelist;dvent;dvent = dvent->next)
X {
X#ifdef NFS
X if (dvent->rdev == node->v_rdev
X && (dvent->mode == ((node->v_type == VBLK) ? S_IFBLK : S_IFCHR)))
X#else
X#ifdef GNODE
X if (dvent->rdev == node->g_rdev && dvent->ino == node->g_number
X && (dvent->mode == (((node->g_mode & GFMT) == GFBLK) ? S_IFBLK : S_IFCHR)))
X#else
X if (dvent->rdev == node->i_rdev && dvent->ino == node->i_number
X && (dvent->mode == (((node->i_mode & IFMT) == IFBLK) ? S_IFBLK : S_IFCHR)))
X#endif
X#endif
X return dvent->name;
X#ifdef CLONEDEV
X if (node->v_type == VCHR && dvent->clonedev > 0
X && major(node->v_rdev) == dvent->clonedev)
X return dvent->name;
X#endif
X }
X return 0; /*XXX*/
X}
X
Xchar *getttydevname(dev)
Xdev_t dev;
X{
X register struct devname *dvent;
X
X if (!scanned)
X if (scandev() == -1)
X return 0; /*XXX*/
X
X for (dvent = devnamelist;dvent;dvent = dvent->next)
X {
X /*XXX: is this right normally? */
X if (dvent->rdev == dev
X && (dvent->mode == S_IFCHR))
X return dvent->name;
X#ifdef notdef /* XXX: CLONEDEV */
X if (node->v_type == VCHR && dvent->clonedev > 0
X && major(node->v_rdev) == dvent->clonedev)
X return dvent->name;
X#endif
X }
X return 0; /*XXX*/
X}
END_OF_FILE
if test 3848 -ne `wc -c <'getdevicename.c'`; then
echo shar: \"'getdevicename.c'\" unpacked with wrong size!
fi
# end of 'getdevicename.c'
fi
if test -f 'kmem.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kmem.c'\"
else
echo shar: Extracting \"'kmem.c'\" \(1753 characters\)
sed "s/^X//" >'kmem.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
Xint kmemcpy(buf,pos,n) char *buf; char *pos; int n; copies n bytes from
Xposition pos in kernel memory into buffer buf (in user memory). It
Xreturns 0 on success, -1 on error.
X
Xkmeminit() is an optional initialization routine to cooperate with other
Xlibraries.
X
Xkmemstrerr is a strerrfun for kmeminit() and kmemcpy().
X
X*/
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include "kmem.h"
X#include "strerr.h"
X
X#define KMEM "/dev/kmem"
X
X#define LSEEKFROMSTART 0
X
Xstatic int kmemfd = -1;
Xstatic int kmemerrno = 0;
X
Xstatic char *kmemerrprk(ke) strerrfun *ke; { *ke = strerrsys; return KMEM; }
X
Xchar *kmemstrerr(ke)
Xstrerrfun *ke;
X{
X *ke = 0;
X switch(kmemerrno)
X {
X case 0:
X return "kmem error 0";
X#define KMEM_OPEN 1
X case KMEM_OPEN:
X *ke = kmemerrprk;
X return "cannot open ";
X#define KMEM_LSEEK 2
X case KMEM_LSEEK:
X *ke = strerrsys;
X return "cannot lseek kmem";
X#define KMEM_READ 3
X case KMEM_READ:
X *ke = strerrsys;
X return "cannot read kmem";
X#define KMEM_READZERO 4
X case KMEM_READZERO:
X return "kmem read 0 bytes";
X default:
X return "unknown kmem error";
X }
X}
X
Xint kmeminit()
X{
X kmemfd = open(KMEM,O_RDONLY);
X if (kmemfd == -1)
X RETERN(-1,kmemerrno,KMEM_OPEN)
X return 0;
X}
X
Xint kmemcpy(buf,pos,n)
Xchar *buf;
Xchar *pos;
Xint n;
X{
X int r;
X
X if (!n)
X return 0;
X if (kmemfd == -1)
X if (kmeminit() == -1)
X return -1;
X if (lseek(kmemfd,(long) pos,LSEEKFROMSTART) == -1)
X RETERN(-1,kmemerrno,KMEM_LSEEK)
X while ((r = read(kmemfd,buf,n)) < n)
X if (r == -1)
X RETERN(-1,kmemerrno,KMEM_READ)
X else if (r == 0) /* XXX: this can never happen */
X RETERN(-1,kmemerrno,KMEM_READZERO)
X else
X {
X buf += r;
X n -= r;
X }
X return 0;
X}
END_OF_FILE
if test 1753 -ne `wc -c <'kmem.c'`; then
echo shar: \"'kmem.c'\" unpacked with wrong size!
fi
# end of 'kmem.c'
fi
if test -f 'netinp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'netinp.c'\"
else
echo shar: Extracting \"'netinp.c'\" \(2170 characters\)
sed "s/^X//" >'netinp.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain. todo: eliminate this file.
XDerived from authd 3.01, DJB.
X*/
X
X#ifdef USENETSTAT
X
X#include "confnonsfinet.h"
X#ifdef NONSFINET
X#define NETSTAT "/usr/bin/netstat -n -A"
X#endif
X
X/* End of machine define-mod section. */
X
X#ifndef NETSTAT
X#define NETSTAT "/usr/ucb/netstat -n -A -f inet"
X#endif
X#ifndef NETSTATBUF
X#define NETSTATBUF 200 /* 80 would suffice */
X#endif
X#ifndef NETSTATREMOTE
X#define NETSTATREMOTE 49 /* has to be 53 for SunOS 4.1.1, I think */
X#endif
X#ifndef NETSTATWIDTH
X#define NETSTATWIDTH 17
X#endif
X#ifndef REMOTESIZE
X#define REMOTESIZE 100 /* guaranteed to be enough */
X#endif
X
X#endif
X
X#include <stdio.h>
XFILE *popen(); /* grrrr */
X#include "kmem.h"
X#include "structinpcb.h"
X#ifdef USENETSTAT
X#include "structtcp.h"
X#else
X#include "inpcblist.h"
X#endif
X#include "netinp.h"
X
X#ifdef USENETSTAT
Xstatic FILE *fi;
Xstatic char remote[REMOTESIZE];
Xstatic char s[NETSTATBUF];
Xstatic int header;
Xstatic int pcb;
Xstatic struct tcpcb tcp;
Xstatic struct inpcb inp;
X
Xchar *inploc;
X
Xint netinpinit(r1,r2,r3,r4,rp)
Xint r1;
Xint r2;
Xint r3;
Xint r4;
Xint rp;
X{
X fi = popen(NETSTAT,"r");
X if (!fi)
X return -1;
X (void) sprintf(remote,"%d.%d.%d.%d.%d ",r1,r2,r3,r4,rp);
X header = 0;
X return 0;
X}
X
Xstruct inpcb *nextnetinp()
X{
X if (!header)
X {
X header = 1;
X if (!fgets(s,sizeof(s),fi))
X return 0;
X if (!fgets(s,sizeof(s),fi))
X return 0;
X }
X do
X {
X if (!fgets(s,sizeof(s),fi))
X return 0; /* XXX: cannot distinguish from error */
X if (sscanf(s,"%8x",&pcb) != 1)
X return 0;
X }
X while (strncmp(s + NETSTATREMOTE,remote,NETSTATWIDTH));
X if (kmemcpy((char *) &tcp,(char *) pcb,sizeof(tcp)) == -1)
X return 0;
X if (!tcp.t_inpcb)
X return 0;
X if (kmemcpy((char *) &inp,(char *) tcp.t_inpcb,sizeof(inp)) == -1)
X return 0;
X if (inp.inp_ppcb != (char *) pcb)
X return 0;
X inploc = tcp.t_inpcb;
X return &inp;
X}
X
X#else
X
Xchar *inploc;
Xstatic struct inpcb *inp;
X
Xint netinpinit(r1,r2,r3,r4,rp)
Xint r1;
Xint r2;
Xint r3;
Xint r4;
Xint rp;
X{
X if (inpcblistinit() == -1)
X return -1;
X inp = 0;
X}
X
Xstruct inpcb *nextnetinp()
X{
X inp = nextinpcb(inp);
X inploc = (char *) inpcbloc;
X return inp;
X}
X
X#endif
END_OF_FILE
if test 2170 -ne `wc -c <'netinp.c'`; then
echo shar: \"'netinp.c'\" unpacked with wrong size!
fi
# end of 'netinp.c'
fi
if test -f 'netstatuids.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'netstatuids.c'\"
else
echo shar: Extracting \"'netstatuids.c'\" \(2453 characters\)
sed "s/^X//" >'netstatuids.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB modified to not compile without HAVE_UCRED
X5/1/91 DJB baseline public domain
X*/
X
X#include "confhaveucred.h"
X#ifndef HAVE_UCRED
Xerror! error! error! XXX
Xnetstatuids will not work on a system without struct ucred.
X#endif
X
X#include <stdio.h>
X#include "structfile.h"
X#include "structucred.h"
X#include "structinpcb.h"
X#include "inpcblist.h"
X#include "filetable.h"
X#include "getfcred.h"
X#include "strerr.h"
X#include "authuser.h"
X#include <pwd.h>
X#include "mallocfree.h"
X
Xchar *pw(u)
Xint u;
X{
X struct passwd *pw;
X char buf[20];
X
X pw = getpwuid(u);
X if (pw)
X return pw->pw_name;
X sprintf(buf,"%d",u);
X return buf;
X}
X
Xmain()
X{
X struct inpcb *inp;
X struct file *ft;
X struct file *fp;
X struct ucred *uc;
X int *sfs;
X int numsfs;
X int i;
X unsigned char *fa;
X unsigned char *la;
X char *user;
X
X if (filetableinit() == -1)
X {
X fprintf(stderr,"ns5: %s\n",strerr(filetablestrerr));
X exit(1);
X }
X if (inpcblistinit() == -1)
X {
X fprintf(stderr,"ns5: %s\n",strerr(inpcbliststrerr));
X exit(1);
X }
X
X ft = getfiletable();
X if (!ft)
X {
X fprintf(stderr,"ns5: %s\n",strerr(filetablestrerr));
X exit(1);
X }
X sfs = (int *) malloc((unsigned) (sizeof(int) * mynfile));
X if (!sfs)
X {
X fprintf(stderr,"ns5: out of memory\n");
X exit(1);
X }
X numsfs = 0;
X
X for (fp = ft;fp < ft + mynfile;++fp)
X if (fp->f_count && fp->f_type == DTYPE_SOCKET)
X sfs[numsfs++] = fp - ft;
X
X inp = 0;
X while (inp = nextinpcb(inp))
X for (i = 0;i < numsfs;++i)
X if ((fp = ft + sfs[i])->f_data == (char *) inp->inp_socket)
X {
X sfs[i] = sfs[--numsfs];
X uc = getfcred(fp);
X if (!uc)
X {
X fprintf(stderr,"ns5: warning: %s\n",strerr(getfcredstrerr));
X break;
X }
X fa = (unsigned char *) &(inp->inp_faddr);
X la = (unsigned char *) &(inp->inp_laddr);
X user = 0;
X if (inp->inp_fport)
X user = auth_tcpuser(inp->inp_faddr.s_addr
X ,ntohs(inp->inp_lport)
X ,ntohs(inp->inp_fport));
X else
X break; /*XXX: unconnected server*/
X if (!user)
X user = "?";
X printf("%s@%d.%d.%d.%d:%d\t%s@%d.%d.%d.%d:%d\n"
X ,user
X ,(unsigned) fa[0],(unsigned) fa[1],(unsigned) fa[2],(unsigned) fa[3]
X ,ntohs(inp->inp_fport)
X ,pw(uc->cr_ruid)
X ,(unsigned) la[0],(unsigned) la[1],(unsigned) la[2],(unsigned) la[3]
X ,ntohs(inp->inp_lport)
X );
X fflush(stdout); /*XXX*/
X break;
X }
X
X if (inperrno)
X {
X fprintf(stderr,"ns5: %s\n",strerr(inpcbliststrerr));
X exit(1);
X }
X exit(0);
X}
END_OF_FILE
if test 2453 -ne `wc -c <'netstatuids.c'`; then
echo shar: \"'netstatuids.c'\" unpacked with wrong size!
fi
# end of 'netstatuids.c'
fi
if test -f 'nlistlist.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nlistlist.c'\"
else
echo shar: Extracting \"'nlistlist.c'\" \(3961 characters\)
sed "s/^X//" >'nlistlist.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
XThe problem: Independent libraries want to access a shared resource,
Xthe kernel name list. Normally, if those libraries were written
Xindependently, they would each do a separate nlist(). This is
Xunacceptably inefficient.
X
XThe solution: nlistlist. Other libraries can call nlistadd() in their
Xinitialization routines, then nlistdo() before they need the data.
Xnlistlist buffers all nlistadd()ed names and only looks them up on an
Xnlistdo(). So independent libraries can cooperate merely by providing
Xinitialization routines.
X
Xint nlistadd(name,type,value) char *name; short *type; unsigned long *value;
Xsets *type to -1 and returns 0. Upon the next call to nlistdo(), name
X(which should always begin with an underscore) will be looked up in the
Xkernel's name list (typically /vmunix). The type of the returned address
Xwill be stored in *type, and the value will be stored in *value. If
Xthere is some problem, nlistadd returns -1, and the above operations
Xwill not occur. The meaning of *type on a successful lookup varies from
Xsystem to system, but a zero *type indicates that name is not in the
Xname list.
X
Xnlistdo() handles all previous nlistadd()s as mentioned above. It
Xreturns 0 on success, -1 on error.
X
Xnliststrerr is a strerrfun for nlistadd() and nlistdo().
X
Xnlistnotin is a strerrfun for use by libraries using nlistlist. It
Xprints a message like " not in nlist", and is appropriate after a type
Xis returned as 0.
X
X*/
X
X#include <nlist.h>
X#include "mallocfree.h"
X#include "nlistlist.h"
X#include "strerr.h"
X#include "confnlistknlist.h"
X#include "confnlistunder.h"
X#include "confnlistmeaning.h"
X#include "confvmunix.h"
X#include "confnlname.h"
X
Xchar *nlistnotin(ke)
Xstrerrfun *ke;
X{
X return strerrstr(ke," not in nlist");
X}
X
Xstatic int nlisterrno = 0;
X
Xstatic struct strerrtab e[] = {
X { 0, "nlist error 0", 0 }
X#define NLIST_ALLOC 1
X, { NLIST_ALLOC, "cannot malloc for nlist", 0 }
X#define NLIST_NLIST 2
X, { NLIST_NLIST, "nlist() failed", 0 }
X} ;
X
Xchar *nliststrerr(ke)
Xstrerrfun *ke;
X{
X return strerrtaberr(ke,nlisterrno,e,sizeof(e)/sizeof(*e),"unknown nlist error");
X}
X
Xstatic struct nlistlist
X {
X char *name;
X short *type;
X unsigned long *value;
X struct nlistlist *next;
X }
Xhead = { 0 , 0 };
X
Xstatic int nlistnum = 0;
X
Xint nlistadd(name,type,value)
Xchar *name;
Xshort *type;
Xunsigned long *value;
X{
X struct nlistlist *t;
X
X t = head.next;
X head.next = (struct nlistlist *) malloc(sizeof(struct nlistlist));
X if (!head.next)
X {
X head.next = t;
X nlisterrno = NLIST_ALLOC;
X return -1;
X }
X head.next->next = t;
X head.next->name = name;
X head.next->type = type;
X head.next->value = value;
X *type = -1;
X ++nlistnum;
X return 0;
X}
X
Xint nlistdo()
X{
X struct nlist *nl;
X struct nlistlist *t;
X struct nlistlist *tnext;
X int i;
X
X if (!nlistnum)
X return 0;
X nl = (struct nlist *) malloc((unsigned) (sizeof(struct nlist) * (nlistnum + 1)));
X if (!nl)
X RETERN(-1,nlisterrno,NLIST_ALLOC)
X i = 0;
X for (t = head.next;t;t = t->next)
X {
X#ifdef FORGET_UNDERSCORES
X NLNAME(nl[i]) = t->name + 1;
X#else
X NLNAME(nl[i]) = t->name;
X#endif
X ++i;
X }
X NLNAME(nl[i]) = "";
X#ifdef KNLIST
X knlist(nl);
X /* XXX: This appears to fail in some cases. So... */
X for (i = 0;i < nlistnum;++i)
X if (!nl[i].n_value)
X {
X nlist(VMUNIX,nl); /*XXX*/
X break;
X }
X#else
X#ifdef MEANINGLESS_NLIST
X nlist(VMUNIX,nl);
X#else
X if (nlist(VMUNIX,nl) == -1)
X {
X free((char *) nl);
X nlisterrno = NLIST_NLIST;
X return -1;
X }
X#endif
X#endif
X#ifdef notdef /*XXX: debugging */
X printf("[nlist");
X while (i) { --i; printf(" %s:%x",NLNAME(nl[i]),nl[i].n_value); }
X printf("]");
X#endif
X i = 0;
X for (t = head.next;t;t = tnext)
X {
X *(t->type) = nl[i].n_type;
X /* XXX: force some uniformity on the types? */
X *(t->value) = nl[i].n_value;
X /* XXX: let user give us a function to free t->name? */
X tnext = t->next;
X free((char *) t);
X ++i;
X }
X nlistnum = 0;
X free((char *) nl);
X head.next = 0;
X return 0;
X}
END_OF_FILE
if test 3961 -ne `wc -c <'nlistlist.c'`; then
echo shar: \"'nlistlist.c'\" unpacked with wrong size!
fi
# end of 'nlistlist.c'
fi
if test -f 'printpstat.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'printpstat.c'\"
else
echo shar: Extracting \"'printpstat.c'\" \(1996 characters\)
sed "s/^X//" >'printpstat.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
Xchar *printpstat(p) struct proc *p; returns a string representing
Xvarious basic information about p's status (with p in user memory).
XNot well defined.
X
X*/
X
X#include <stdio.h>
X#include <strings.h>
X#include "printpstat.h"
X#include "structproc.h"
X#include "confhavepflag.h"
X
Xstatic char result[300];
X/* XXX: 300 is guaranteed safe for the current code, but if you add */
X/* more printing flags, you may have to bring the number up. */
X
Xchar *printpstat(p)
Xstruct proc *p;
X{
X int pstat;
X int pflag;
X char *t;
X
X pstat = p->p_stat;
X#ifndef HAVE_PFLAG
X pflag = p->p_select | p->p_sched | p->p_vm; /*XXX: annoying*/
X#else
X pflag = p->p_flag;
X#endif
X
X switch(pstat)
X {
X#ifdef SSLEEP
X case SSLEEP: strcpy(result,"S "); break;
X#endif
X#ifdef SWAIT
X case SWAIT: strcpy(result,"D "); break;
X#endif
X#ifdef SRUN
X case SRUN: strcpy(result,"R "); break;
X#endif
X#ifdef SIDL
X case SIDL: strcpy(result,"X "); break;
X#endif
X#ifdef SZOMB
X case SZOMB: strcpy(result,"Z "); break;
X#endif
X#ifdef SSTOP
X case SSTOP: strcpy(result,"T "); break;
X#endif
X default: strcpy(result,"? ");
X }
X t = result + 2;
X
X#define PFLAG(S,X) if (pflag & S) { strcpy(t,X); t += strlen(t); pflag &= ~S; }
X
X#ifdef SLOAD
X PFLAG(SLOAD,"load ")
X#endif
X#ifdef SSYS
X PFLAG(SSYS,"sys ")
X#endif
X#ifdef SLOCK
X PFLAG(SLOCK,"lock ")
X#endif
X#ifdef SSWAP
X PFLAG(SSWAP,"swap ")
X#endif
X#ifdef SOMASK
X PFLAG(SOMASK,"omask ")
X#endif
X#ifdef SWEXIT
X PFLAG(SWEXIT,"wexit ")
X#endif
X#ifdef SWTED
X PFLAG(SWTED,"wted ")
X#endif
X#ifdef SULOCK
X PFLAG(SULOCK,"ulock ")
X#endif
X#ifdef STRC
X PFLAG(STRC,"traced ")
X#endif
X#ifdef SPAGI
X PFLAG(SPAGI,"ipage ")
X#endif
X#ifdef SSEL
X PFLAG(SSEL,"sel! ")
X#endif
X#ifdef SPTECHG
X PFLAG(SPTECHG,"ptechg ")
X#endif
X#ifdef SEXECDN
X PFLAG(SEXECDN,"execdn ")
X#endif
X#ifdef SVFORK
X PFLAG(SVFORK,"vfork ")
X#endif
X#ifdef SVFDONE
X PFLAG(SVFDONE,"vfdone ")
X#endif
X#ifdef SNOVM
X PFLAG(SNOVM,"novm ")
X#endif
X if (pflag)
X {
X sprintf(t,"flag %x ",pflag);
X }
X return result;
X}
END_OF_FILE
if test 1996 -ne `wc -c <'printpstat.c'`; then
echo shar: \"'printpstat.c'\" unpacked with wrong size!
fi
# end of 'printpstat.c'
fi
if test -f 'printucred.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'printucred.c'\"
else
echo shar: Extracting \"'printucred.c'\" \(3161 characters\)
sed "s/^X//" >'printucred.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB modified to print something sensible under !HAVE_UCRED
X5/1/91 DJB baseline public domain
X*/
X
X/*
X
Xchar *printucred(uc,style,ruids,tags,uns) struct ucred *uc; int style;
Xint ruids; int tags; int uns; prints uc in a variety of styles.
X
Xstyle is not yet officially defined. XXX this whole interface
X
XIf ruids is 0, the effective uid is printed, and the real uid is printed
Xif different. If ruids is 1, only the effective uid is printed. If ruids
Xis 2, only the real uid is printed.
X
XIf tags is 1, information is tagged with inline labels. If tags is 0, it
Xis assumed that labels are placed at the top of columns.
X
XIf uns is 1, uids are printed as usernames if possible. If uns is 0,
Xuids are always printed as uids.
X
X*/
X
X#include <stdio.h>
X#include <strings.h>
X#include "structucred.h"
X#include "printucred.h"
X#include "username.h"
X#include "groupname.h"
X#include "confhaveucred.h"
X/* XXX: should provide for string group names! */
X
Xstatic char result[50 + NGROUPS * 8];
X/* XXX: assumes uids and gids are at most 8 (really 5) characters */
X/* XXX: assumes uids and gids are short */
X/* XXX: string representation? */
X/* XXX: under newer Suns, auid? audit? label? */
X
Xchar *printucred(uc,style,ruids,tags,uns)
Xstruct ucred *uc;
Xint style;
Xint ruids;
Xint tags;
Xint uns;
X{
X int i;
X char *t;
X unsigned gid;
X unsigned rgid;
X unsigned uid;
X unsigned ruid;
X unsigned puid;
X
X#ifdef HAVE_UCRED
X uid = uc->cr_uid;
X ruid = uc->cr_ruid;
X#else
X uid = uc->uid;
X ruid = uc->uid;
X#endif
X puid = (ruids == 2) ? ruid : uid;
X if (uns)
X {
X char *pun;
X uid2username(puid,&pun); /* XXX: care about return value? */
X if (style == 1)
X sprintf(result,"%s%8s",tags ? "uid " : "",pun);
X else
X sprintf(result,"%s%s",tags ? "uid " : "",pun);
X }
X else
X if (style == 1)
X sprintf(result,"%s%5u",tags ? "uid " : "",puid);
X else
X sprintf(result,"%s%u",tags ? "uid " : "",puid);
X t = result + strlen(result);
X if (!ruids && (uid != ruid))
X {
X if (uns)
X {
X char *pun;
X uid2username(ruid,&pun); /* XXX: care about return value? */
X if (style == 1)
X sprintf(t,"/%8u",ruid);
X else
X sprintf(t,"/%u",ruid);
X }
X else
X if (style == 1)
X sprintf(t,"/%5u",ruid);
X else
X sprintf(t,"/%u",ruid);
X t += strlen(t);
X }
X if (style == 1 && !ruids && (uid == ruid))
X {
X if (uns) { sprintf(t," "); t += 9; }
X else { sprintf(t," "); t += 6; }
X }
X if (style == 2)
X {
X sprintf(t," ");
X t = result + (tags ? 4 : 0) + (!ruids ? 6 : 0) + 5 + (uns ? 6 : 0);
X *t = 0;
X }
X#ifdef HAVE_UCRED /*XXX*/
X if (style == 3)
X {
X gid = (unsigned short) uc->cr_gid;
X rgid = (unsigned short) uc->cr_rgid;
X sprintf(t," %s%u",tags ? "gid " : "",gid); t += strlen(t);
X if (gid != rgid)
X {
X sprintf(t,"/%u",rgid); t += strlen(t);
X }
X for (i = 0;i < NGROUPS;++i)
X {
X register short g;
X g = uc->cr_groups[i];
X if (g == -1)
X break; /* XXX: is this right? */
X if (g != gid && g != rgid)
X sprintf(t," %u",(unsigned) (unsigned short) g);
X t += strlen(t);
X if (!g)
X break; /* XXX: is this right? */
X }
X }
X#endif
X return result;
X}
END_OF_FILE
if test 3161 -ne `wc -c <'printucred.c'`; then
echo shar: \"'printucred.c'\" unpacked with wrong size!
fi
# end of 'printucred.c'
fi
if test -f 'proctable.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'proctable.c'\"
else
echo shar: Extracting \"'proctable.c'\" \(2453 characters\)
sed "s/^X//" >'proctable.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X#include "mallocfree.h"
X#include "proctable.h"
X#include "structproc.h"
X#include "kmem.h"
X#include "nlistlist.h"
X#include "strerr.h"
X
X#define PROCNLIST "_proc"
X#define NPROCNLIST "_nproc"
X
Xstatic int pinit = 0;
Xstatic struct proc *proctable = 0;
Xstatic short ptype;
Xstatic short nptype;
Xstatic unsigned long pvalue;
Xstatic unsigned long npvalue;
Xstruct proc *myproc;
Xint mynproc;
Xstatic int proctableerrno = 0;
X
Xchar *proctablestrerr(ke)
Xstrerrfun *ke;
X{
X *ke = 0;
X switch(proctableerrno)
X {
X case 0:
X return "proctable error 0";
X#define PT_INIT 1
X case PT_INIT:
X *ke = nliststrerr;
X return "cannot init proctable: ";
X#define PT_NLIST 2
X case PT_NLIST:
X *ke = nliststrerr;
X return "cannot nlist: ";
X#define PT_NLPFOUND 3
X case PT_NLPFOUND:
X *ke = nlistnotin;
X return PROCNLIST;
X#define PT_NLNPFOUND 4
X case PT_NLNPFOUND:
X *ke = nlistnotin;
X return NPROCNLIST;
X#define PT_NLPREAD 5
X case PT_NLPREAD:
X *ke = kmemstrerr;
X return "cannot read proc table pointer: ";
X#define PT_NLNPREAD 6
X case PT_NLNPREAD:
X *ke = kmemstrerr;
X return "cannot read nproc: ";
X#define PT_FTREAD 7
X case PT_FTREAD:
X *ke = kmemstrerr;
X return "cannot read proc table: ";
X#define PT_ALLOC 8
X case PT_ALLOC:
X *ke = 0;
X return "out of memory";
X default:
X return "unknown proctable error";
X }
X}
X
Xint proctableinit()
X{
X if (nlistadd(PROCNLIST,&ptype,&pvalue) == -1)
X RETERN(-1,proctableerrno,PT_INIT)
X if (nlistadd(NPROCNLIST,&nptype,&npvalue) == -1)
X RETERN(-1,proctableerrno,PT_INIT)
X pinit = 1;
X return 0;
X}
X
Xstruct proc *getproctable()
X{
X if (!pinit)
X if (proctableinit() == -1)
X return 0;
X if (ptype == -1)
X if (nlistdo() == -1)
X RETERN(0,proctableerrno,PT_NLIST)
X if (!ptype)
X RETERN(0,proctableerrno,PT_NLPFOUND)
X if (!nptype)
X RETERN(0,proctableerrno,PT_NLNPFOUND)
X if (kmemcpy((char *) &mynproc,(char *) npvalue,sizeof(mynproc)) == -1)
X RETERN(0,proctableerrno,PT_NLPREAD)
X if (kmemcpy((char *) &myproc,(char *) pvalue,sizeof(myproc)) == -1)
X RETERN(0,proctableerrno,PT_NLNPREAD)
X
X if (proctable)
X free((char *) proctable);
X proctable = (struct proc *) malloc((unsigned) (sizeof(struct proc) * mynproc));
X if (!proctable)
X RETERN(0,proctableerrno,PT_ALLOC)
X
X if (kmemcpy((char *) proctable,(char *) myproc,sizeof(struct proc) * mynproc) == -1)
X RETERN(0,proctableerrno,PT_FTREAD)
X
X return proctable;
X}
END_OF_FILE
if test 2453 -ne `wc -c <'proctable.c'`; then
echo shar: \"'proctable.c'\" unpacked with wrong size!
fi
# end of 'proctable.c'
fi
if test -f 'strerr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'strerr.c'\"
else
echo shar: Extracting \"'strerr.c'\" \(2183 characters\)
sed "s/^X//" >'strerr.c' <<'END_OF_FILE'
X/* History:
X5/1/91 DJB baseline public domain
X*/
X
X#include <stdio.h>
X#include <errno.h>
Xextern int errno;
Xextern int sys_nerr;
Xextern char *sys_errlist[];
X#include <strings.h>
X#include "mallocfree.h"
X#include "strerr.h"
X
Xchar *strerrtaberr(ke,err,tab,n,dfl)
Xstrerrfun *ke;
Xint err; /* error number */
Xstruct strerrtab *tab; /* error table */
Xint n; /* size of tab */
Xchar *dfl; /* what to say if err isn't in tab */
X{
X int i;
X if ((err < 0) || (err >= n))
X {
X *ke = 0;
X return dfl;
X }
X if (tab[err].err != err)
X {
X for (i = 0;i < n;++i)
X if (tab[i].err == err)
X break;
X if (i == n)
X {
X *ke = 0;
X return dfl;
X }
X }
X else
X i = err; /* fastest this way */
X /* So now tab[i].err == err. */
X *ke = tab[i].next;
X return tab[i].s;
X}
X
Xchar *strerrstr(ke,s)
Xstrerrfun *ke;
Xchar *s;
X{
X *ke = 0;
X return s;
X}
X
Xchar *strerrsys(ke)
Xstrerrfun *ke;
X{
X *ke = strerrno;
X return ": ";
X}
X
Xstatic char unk[30];
X
Xchar *strerrno(ke)
Xstrerrfun *ke;
X{
X *ke = 0;
X if ((errno < 0) || (errno > sys_nerr))
X {
X (void) sprintf(unk,"unknown error %d",errno);
X return unk;
X }
X return sys_errlist[errno];
X}
X
Xstruct sel { struct sel *next; char *s; unsigned len; } ;
X
Xchar *strerr(ke)
Xstrerrfun ke;
X{
X char *s;
X char *t;
X struct sel head;
X struct sel *sel;
X struct sel *temp;
X int saveerrno; /*XXX: what if malloc messes up other errors? */
X unsigned len;
X
X head.next = 0;
X sel = &head;
X
X /* Note that *sel is always allocated. We do this so that we can */
X /* better handle malloc errors. */
X
X while (ke)
X {
X s = ke(&ke);
X saveerrno = errno;
X temp = (struct sel *) malloc(sizeof(struct sel));
X if (!temp)
X {
X sel->s = "aack! malloc error";
X sel->len = strlen(sel->s);
X break;
X }
X errno = saveerrno;
X sel->next = temp;
X temp->next = 0;
X sel->s = s;
X sel->len = strlen(s);
X sel = temp;
X }
X
X len = 1;
X for (sel = &head;temp = sel->next;sel = temp)
X len += sel->len;
X
X s = malloc(len);
X if (!s)
X return "aack! malloc error"; /*XXX*/
X
X t = s;
X for (sel = &head;temp = sel->next;sel = temp)
X {
X (void) strcpy(t,sel->s);
X t += sel->len;
X if (sel != &head) /*XXX*/
X free((char *) sel);
X }
X free((char *) sel);
X
X return s;
X}
END_OF_FILE
if test 2183 -ne `wc -c <'strerr.c'`; then
echo shar: \"'strerr.c'\" unpacked with wrong size!
fi
# end of 'strerr.c'
fi
if test -f 'testauthd.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'testauthd.c'\"
else
echo shar: Extracting \"'testauthd.c'\" \(2704 characters\)
sed "s/^X//" >'testauthd.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#ifdef sun
X#include <sys/fcntl.h>
X#endif
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X#include <pwd.h>
X#include <errno.h>
Xextern int errno;
X#include "authuser.h"
X
Xmain()
X{
X int s;
X int t;
X int u;
X struct sockaddr_in sa;
X int salen;
X int localport;
X unsigned long in;
X unsigned short local;
X unsigned short remote;
X char *user;
X struct passwd *pw;
X int ok;
X
X ok = 1;
X
X#define ZOT(x) { fprintf(stderr,"test: fatal: %s\n",x); exit(37); }
X
X printf("connecting to myself through loopback (127.1)...\n");
X
X s = socket(AF_INET,SOCK_STREAM,0);
X if (s == -1)
X ZOT("cannot create server socket")
X
X localport = 0; /* meaning pick a port, we don't care which */
X
X sa.sin_family = AF_INET;
X sa.sin_port = htons(localport);
X sa.sin_addr.s_addr = INADDR_ANY;
X
X if (bind(s,&sa,sizeof(sa)) == -1)
X ZOT("cannot bind server socket")
X
X salen = sizeof(sa);
X if (getsockname(s,&sa,&salen) == -1)
X ZOT("cannot get name of server socket")
X
X if (listen(s,5) == -1)
X ZOT("cannot listen for connections") /* XXX: impossible */
X
X u = socket(AF_INET,SOCK_STREAM,0);
X if (u == -1)
X ZOT("cannot create client socket")
X
X /* we could bind now if we wanted to pick a local port, or to know */
X /* our local port before connection */
X
X /* if connect() blocked then we'd never get a chance to accept() */
X if (fcntl(u,F_SETFL,O_NDELAY) == -1) /* XXX: FNDELAY? */
X ZOT("cannot set client socket to non-blocking mode")
X
X /* sa is already initialized above to the address we want to connect to */
X if (connect(u,&sa,sizeof(sa)) != -1)
X ; /* XXX: this is slightly screwy, though common, behavior */
X else
X if (errno != EINPROGRESS)
X ZOT("connect failed") /* XXX: should retry if EINTR */
X
X salen = sizeof(sa);
X if ((t = accept(s,&sa,&salen)) == -1)
X ZOT("cannot accept connection")
X
X printf("system says host is %s\n",inet_ntoa(sa.sin_addr));
X
X /* now let's see what the server can figure out about the client */
X
X if (auth_fd(t,&in,&local,&remote) == -1)
X ZOT("authuser cannot figure out connection information")
X
X if (sa.sin_addr.s_addr != in)
X {
X ok = 0;
X sa.sin_addr.s_addr = in;
X }
X printf("authuser says host is %s\n",inet_ntoa(sa.sin_addr));
X
X pw = getpwuid(getuid());
X if (pw)
X printf("system says username is %s\n",pw->pw_name);
X else
X {
X ok = 0;
X printf("system cannot figure out your username\n");
X }
X
X user = auth_tcpuser(in,local,remote);
X if (user)
X printf("authd says username is %s\n",user);
X else
X {
X ok = 0;
X printf("authd cannot figure out your username\n");
X }
X
X if (ok)
X if (!strcmp(user,pw->pw_name))
X printf("Everything looks okay to me.\n");
X else
X ok = 1;
X
X exit(!ok);
X}
END_OF_FILE
if test 2704 -ne `wc -c <'testauthd.c'`; then
echo shar: \"'testauthd.c'\" unpacked with wrong size!
fi
# end of 'testauthd.c'
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
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