kstuff 0.18 (part 6/6)

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Tue May 7 15:05:06 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 6 (of 6)."
# Contents:  pff.c
# Wrapped by brnstnd at kramden on Mon May  6 23:59:04 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'pff.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pff.c'\"
else
echo shar: Extracting \"'pff.c'\" \(27865 characters\)
sed "s/^X//" >'pff.c' <<'END_OF_FILE'
X/* History:
X5/3/91 DJB various changes
X5/1/91 DJB baseline public domain
X*/
X/* XXX: Should allow for process gids... */
X
X#include <stdio.h>
X#include "structfile.h"
X#include "structtext.h"
X#include "structucred.h"
X#include "structuser.h"
X#include "structproc.h" /*XXX: must be after structuser for BSD-Tahoe dorks*/
X#include "structxnode.h"
X#include "printfflag.h"
X#include "printftype.h"
X#include "printpstat.h"
X#include "printrlimits.h"
X#include "printrusage.h"
X#include "printucred.h"
X#include "getdevicename.h"
X#include "getfcred.h"
X#include "getnode.h"
X#include "getopt.h"
X#include "getpcred.h"
X#include "getsocket.h"
X#include "getuser.h"
X#include "getvmseg.h"
X#include "confhaveppid.h"
X#include "confhaveusigintr.h"
X#include "confmajorminor.h"
X#include "confnfs.h"
X#include "confodofe.h"
X#include "confopalf.h"
X#include "confpsess.h"
X#include "confregion.h"
X#include "conftext.h"
X#include "confttyvp.h"
X#include "confuofile.h"
X#include "filetable.h"
X#include "proctable.h"
X#include "revnamei.h"
X#include "portname.h"
X#include "username.h"
X#include "mallocfree.h"
X#include "numeric.h"
X#include "mntops.h"
X#include "strerr.h"
X#include "kmem.h"
X#include <signal.h>
X#ifndef ITIMER_REAL
X#include <sys/time.h>
X#endif
X#ifndef RLIM_NLIMITS
X#include <sys/resource.h>
X#endif
X#include <sys/stat.h>
X
X#define STYLE_BRIEF 0
X#define STYLE_DEFAULT 1
X#define STYLE_LONG 2
X#define STYLE_UIDLONG 3
X#define STYLE_FULL 4
X#define STYLE_TINY 5
X#define STYLE_PIDS 6
X#define STYLE_NAME 7
X
X#define two(i) (1 << i) /* table if necessary */
X
Xchar progname[] = "pff";
X
Xstatic int flagall = 0;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct proc *pt;
X struct file *ft;
X struct nodebuf buf;
X struct socketbuf sbuf;
X int i;
X int style;
X int opt;
X struct stat st;
X struct mounted *mt;
X struct statlist *fsstats;
X int security;
X int uid;
X int ppflags;
X int offlags;
X int pnflags;
X
X#ifdef SECURITY
X security = 1;
X#else
X security = 0;
X#endif
X uid = getuid();
X if (!uid)
X   security = 0;
X if (getgid() == getegid())
X   security = 0;
X
X getnodeinit();
X seginit();
X get_mntlist();
X proctableinit();
X filetableinit();
X pt = getproctable();
X if (!pt)
X  { fprintf(stderr,"%s: cannot get process table: %s\n",
X      progname,strerr(proctablestrerr)); exit(1); }
X ft = getfiletable();
X if (!ft)
X  { fprintf(stderr,"%s: cannot get file table: %s\n",
X      progname,strerr(filetablestrerr)); exit(1); }
X
X style = STYLE_DEFAULT;
X while ((opt = getopt(argc,argv,"as:f:d:i:u:p:xX")) != EOF)
X   switch(opt)
X    {
X     case 'a': flagall = 1; break; /*XXX: inverse?*/
X     case 's': switch(*optarg)
X		{
X		 case 'd': style = STYLE_DEFAULT; break;
X		 case 'f': style = STYLE_FULL; break;
X		 case 'b': style = STYLE_BRIEF; break;
X		 case 'p': style = STYLE_PIDS; break;
X		 case 'u': style = STYLE_UIDLONG; break;
X		 case 'l': style = STYLE_LONG; break;
X		 case 't': style = STYLE_TINY; break;
X		 case 'n': style = STYLE_NAME; break;
X		 case 'A': style = STYLE_BRIEF; break; /* <censored>: deprecated */
X		 case 'D': style = STYLE_TINY; break; /* Dupuy: deprecated */
X		 case 'F': style = STYLE_LONG; break; /* Fstat: deprecated */
X		 case 'h': fprintf(stderr,
X"full\nuidlong\nlong\nname\ndefault\nbrief\ntiny\npids\n"); exit(1);
X		 case 'H': fprintf(stderr,"\
Xfull: all information available, in a relatively unstructured format\n\
Xuidlong: like long, but prints users by name where possible\n\
Xlong: like default, but includes file reference count, offset, credentials\n\
Xname: like default, but prints filenames instead of device/inode\n\
Xdefault: like short, but includes file descriptor type and flags\n\
Xbrief: one open file per line, basic information\n\
Xtiny: all open files for one process per line\n\
Xpids: process ids only\n\
X"
X			   ); exit(1);
X		 default: ; /*XXX*/
X		}
X	       break;
X     case 'p': if (!numeric(optarg))
X		{
X		 fprintf(stderr,"%s: fatal: pid %s not numeric\n"
X		   ,progname,optarg);
X		 exit(1);
X		}
X	       procaddpid(atoi(optarg)); flagall = 1;
X	       break;
X     case 'u': if (username2uid(optarg,&i) == -1)
X		{
X		 fprintf(stderr,"%s: fatal: username %s not found\n"
X		   ,progname,optarg);
X		 exit(1);
X		}
X	       procadduid(i); flagall = 1;
X	       break;
X     case 'f': if (stat(optarg,&st) == -1)
X		{
X		 fprintf(stderr,"%s: fatal: cannot stat %s: %s\n"
X		   ,progname,optarg,strerr(strerrno));
X		 exit(1);
X		}
X	       /* XXX: keep track of filename? */
X	       /* XXX: print filename? */
X	       if (((st.st_mode & S_IFMT) == S_IFBLK)
X		 ||((st.st_mode & S_IFMT) == S_IFCHR))
X		{
X		 buf.flagdev = NODE_ID_DEV;
X		 buf.id.dev.maj = major(st.st_rdev);
X		 buf.id.dev.min = minor(st.st_rdev);
X		}
X	       else
X		{
X	         buf.flagdev = NODE_ID_INO;
X	         buf.id.ino.inum = st.st_ino;
X	         buf.id.ino.dev = st.st_dev;
X		}
X	       validadd(&buf);
X	       break;
X     case 'd': mt = getmntname(optarg);
X	       if (!mt)
X		{
X		 fprintf(stderr,"%s: fatal: cannot find mount of %s\n"
X		   ,progname,optarg);
X		 exit(1);
X		}
X	       for (fsstats = stats;fsstats;fsstats = fsstats->next)
X		 if (!strncmp(mt->filesystem,fsstats->fsname,MNTMAXSTR))
X		  {
X	           buf.flagdev = NODE_ID_INO;
X	           buf.id.ino.inum = 0;
X	           buf.id.ino.dev = fsstats->device;
X	           validadd(&buf);
X		   break;
X		  }
X	       break;
X     case 'i': sbuf.fsw = FSW_INET;
X	       if (portname2port(optarg,&sbuf.fu.inet.lp) == -1)
X		{
X		 fprintf(stderr,"%s: fatal: port %s not found\n"
X		   ,progname,optarg);
X		 exit(1);
X		}
X	       validsadd(&sbuf);
X	       break;
X     case 'x': if (!uid) security = 1; break;
X     case 'X': if (!uid) security = 0; break;
X     case '?': exit(1); /*XXX*/
X    }
X argc -= optind; argv += optind;
X
X for (;*argv;++argv)
X  {
X   int guess;
X   /* ambiguity time */
X   guess = 1;
X   if (((*argv)[0] == '/') || ((*argv)[0] == '.'))
X     guess = 1;
X   else if (argv[0][0] == '#')
X    {
X     guess = 2;
X     ++*argv;
X    }
X   else if (numeric(*argv))
X     guess = 2;
X   /* XXX: any other choices? */
X
X   if (guess == 1)
X    {
X     i = 0; /* becomes 1 if we shouldn't warn about failing getmntname */
X     if (stat(*argv,&st) == -1)
X       fprintf(stderr,"%s: warning: cannot stat %s: %s\n"
X	   ,progname,*argv,strerr(strerrno));
X     else
X      {
X       i = 1;
X       if (((st.st_mode & S_IFMT) == S_IFBLK)
X         ||((st.st_mode & S_IFMT) == S_IFCHR))
X        {
X         buf.flagdev = NODE_ID_DEV;
X         buf.id.dev.maj = major(st.st_rdev);
X         buf.id.dev.min = minor(st.st_rdev);
X        }
X       else
X        {
X         buf.flagdev = NODE_ID_INO;
X         buf.id.ino.inum = st.st_ino;
X         buf.id.ino.dev = st.st_dev;
X        }
X       validadd(&buf);
X      }
X     mt = getmntname(*argv);
X     if (!mt)
X      {
X       if (!i)
X         fprintf(stderr,"%s: warning: cannot find mount of %s\n"
X	   ,progname,*argv);
X      }
X     else
X      {
X       for (fsstats = stats;fsstats;fsstats = fsstats->next)
X         if (!strncmp(mt->filesystem,fsstats->fsname,MNTMAXSTR))
X          {
X           buf.flagdev = NODE_ID_INO;
X           buf.id.ino.inum = 0;
X           buf.id.ino.dev = fsstats->device;
X           validadd(&buf);
X           break;
X          }
X      }
X    }
X   else if (guess == 2)
X    {
X     flagall = 1;
X     if (!numeric(*argv))
X      {
X       /* this can never happen with the current guess structure */
X       fprintf(stderr,"%s: fatal: pid %s not numeric\n",progname,*argv);
X       exit(1);
X      }
X     procaddpid(atoi(*argv));
X    }
X  }
X
X ppflags = 8064;
X offlags = 64;
X pnflags = 0;
X
X /* XXX: use 128 for fd creds by name? */
X
X switch(style)
X  {
X   case STYLE_BRIEF:
X     puts("         CMD   PID   UID   FD TYPE      INODE    FS");
X     ppflags += 1;
X     offlags += 0;
X     pnflags += 0;
X     break;
X   case STYLE_DEFAULT:
X     puts("         CMD   PID   UID   FD D FLAGS     TYPE      INODE    FS");
X     ppflags += 1;
X     offlags += 16 + 4;
X     pnflags += 0;
X     break;
X   case STYLE_LONG:
X     puts("              CMD   PID   UID   FD   REF D     OFFSET FLAGS     CRED        TYPE      INODE    FS");
X     ppflags += 16384 + 1;
X     offlags += 16 + 4 + 2 + 8 + 32;
X     pnflags += 0;
X     break;
X   case STYLE_UIDLONG:
X     puts("              CMD   PID USERNAME   FD   REF D     OFFSET FLAGS     CRED        TYPE      INODE    FS");
X     ppflags += 32768 + 1;
X     offlags += 16 + 4 + 2 + 8 + 32;
X     pnflags += 0;
X     break;
X   case STYLE_FULL:
X     ppflags += 8192 + 126;
X     offlags += 16 + 4 + 2 + 8 + 32;
X     pnflags += 0;
X     break;
X   case STYLE_TINY:
X     puts("              CMD   PID USERNAME OFILES");
X     ppflags += 8192 + 32768 + 65536 + 131072 + 262144 + 1048576 + 1;
X     offlags += 16 + 4 + 2 + 8 + 32;
X     pnflags += 0;
X     break;
X   case STYLE_NAME:
X     puts("         CMD   PID   UID   FD D FLAGS     TYP FILENAME");
X     ppflags += 1;
X     offlags += 16 + 4;
X     pnflags += 6;
X     break;
X   case STYLE_PIDS:
X   default: /* default should never happen */
X     style = STYLE_PIDS;
X     ppflags += 524288;
X     offlags += 16 + 4 + 2 + 8 + 32;
X     pnflags += 2;
X     break;
X  }
X
X for (i = 0;i < mynproc;++i)
X   if (pt[i].p_pid) /*XXX*/
X     if (!security || (uid == pt[i].p_uid))
X       if (procmatch(&(pt[i])))
X         printproc(&(pt[i]),&(myproc[i]),ft,ppflags,offlags,pnflags);
X if (style == STYLE_PIDS)
X   putchar('\n');
X exit(0);
X}
X
X/* flags:
X1 put process identification before each fd line
X    16384 allow 17 chars rather than 12 for command name
X2 print basic process information
X4 print process status
X8 print process resource usage
X16 print process limits
X32 print process credentials
X64 print process signal handling
X128 show text segment as fd, when it exists
X256 show controlling tty as fd, when it exists
X512 show cwd as fd
X1024 show root dir as fd, when it exists
X2048 show all open file descriptors
X4096 show all mmap segments
X8192 print extra newline
X32768 show uids as usernames wherever possible
X65536 don't space-fill fd labels (like cwd, 0, 1, 2, etc.)
X131072 don't actually print fd descriptions with newline
X262144 print preliminary prefd at most once before all fds
X524288 print just pid, return as fast as possible XXX: how interact w/others?
X1048576 under 1 + 8192 + 262144, don't print newline unless prefd has been used
X*/
X
Xprintproc(p,preal,ft,flags,offlags,pnflags)
Xstruct proc *p;
Xstruct proc *preal;
Xstruct file *ft;
Xint flags;
Xint offlags;
Xint pnflags;
X{
X#ifdef OPALF
X static struct file *(fof[NOFILE]);
X#endif
X#ifdef ODOFE
X static struct ofile_ext oe;
X#endif
X static struct nodebuf buf;
X static struct socketbuf sbuf;
X static char prefd[80];
X struct user *u;
X struct ucred *uc;
X int i;
X
X /* printf("xstat %d ",p->p_xstat); */
X /* printf("pri %d %d ",p->p_usrpri,p->p_pri); */
X /* printf("time %d %d %d",p->p_slptime,p->p_time,(int) p->p_pctcpu); */
X /* XXX: handle pctcpu? */
X /* char *p_wchan */
X /* XXX: u_timer[] */
X /* XXX: u_start, on machines that have it */
X /*XXX:p_tsize,p_dsize,p_ssize,p_rssize, p_maxrss===u.u_limit[MAXRSS],p_swrss*/
X
X if (p->p_stat == 0)
X   return;
X if (p->p_stat == SZOMB)
X   return;
X#ifdef SIDL
X if (p->p_stat == SIDL)
X   return;
X#endif
X
X u = getuser(p);
X if (!u)
X  {
X#ifdef notdef /* sigh */
X   fprintf(stderr,"%s: warning: getuser failed on proc %d: %s\n"
X     ,progname
X     ,p->p_pid
X     ,strerr(getuserstrerr)
X     );
X#endif
X   return;
X  }
X if (u->u_procp != preal)
X  {
X   /* XXX: warn? */
X   return;
X  }
X
X uc = getpcred(p,u);
X if (!uc)
X   return;
X
X if (flags & 1)
X  {
X   sprintf(prefd
X     ,((flags & 16384) ? "%17.17s %5d %s " : "%12.12s %5d %s ")
X     ,u->u_comm
X     ,p->p_pid
X     ,printucred(uc,1,2,0,(flags & 32768) ? 1 : 0) /* XXX: should use names here */
X    );
X  }
X
X if (flags & 2)
X  {
X   printf("proc %8x ",preal);
X   printf("pid %d ",p->p_pid);
X#ifdef HAVE_PPID
X   printf("ppid %d ",p->p_ppid);
X#endif
X   printf("pgrp %d ",p->p_pgrp); /* XXX: p_sgid under POSIX */
X   printf("uid %d",p->p_suid);
X   if (p->p_uid != p->p_suid) printf("/%d",p->p_uid);
X   printf(" nice %d ",p->p_nice);
X   printf("umask %o ",u->u_cmask);
X   puts(u->u_comm);
X  }
X
X if (flags & 4)
X   printf("status: %s\n",printpstat(p));
X
X if (flags & 8)
X  {
X   printf("self: %s\n",printrusage(&(u->u_ru)));
X   printf("kids: %s\n",printrusage(&(u->u_cru)));
X  }
X if (flags & 16)
X   printf("rlimits: %s\n",printrlimits(u->u_rlimit));
X
X if (flags & 32)
X  {
X   if (uc) printf("cred: %s\n",printucred(uc,0,0,1,(flags & 32768) ? 1 : 0));
X  }
X
X if (flags & 64)
X  {
X   printf("signals:");
X   for (i = 0;i < NSIG;++i)
X    {
X     if (!(i % 8)) putchar(' ');
X     if (u->u_signal[i] == SIG_DFL) putchar('d');
X     else if (u->u_signal[i] == SIG_IGN) putchar('i');
X     else putchar('C');
X#ifdef HAVE_USIGINTR
X     if (u->u_sigintr & two(i))
X       if (p->p_sigmask & two(i)) putchar(';'); else putchar(',');
X     else
X#endif
X       if (p->p_sigmask & two(i)) putchar(':'); else putchar('.');
X     /* any other flags to include? */
X    }
X   putchar('\n');
X  }
X
X#ifdef REGION
X if (flags & 128)
X  {
X   /* XXX: This is totally, absolutely undocumented to work. */
X   struct vm_vspace vs;
X   struct vm_object vo;
X   int i;
X   for (i = 0;i < sizeof(vs.vs_regiontab) / sizeof(vs.vs_regiontab[0]);++i)
X    {
X     kmemcpy(&vs,p->p_vspace,sizeof(vs));
X     kmemcpy(&vo,vs.vs_regiontab[i].re_object,sizeof(vo));
X     if (vo.ob_vp && validnode(vo.ob_vp,&buf,0))
X      {
X       if (flags & 524288)
X	{
X	 printf("%d ",p->p_pid);
X	 return;
X	}
X       if (flags & 1)
X         fputs(prefd,stdout);
X       if (flags & 262144)
X	 prefd[0] = 0;
X       printf("text ");
X       if (!(flags & 131072))
X	{
X         spacenode(offlags);
X         printbuf(&buf,pnflags);
X	}
X       break;
X      }
X    }
X  }
X#else
X#ifdef TEXT
X if (flags & 128)
X  {
X   struct text text;
X   kmemcpy(&text,p->p_textp,sizeof(text));
X   if (validnode(text.x_Xptr,&buf,0))
X    {
X     if (flags & 524288)
X      {
X       printf("%d ",p->p_pid);
X       return;
X      }
X     if (flags & 1)
X       fputs(prefd,stdout);
X     if (flags & 262144)
X       prefd[0] = 0;
X     printf("text ");
X     if (!(flags & 131072))
X      {
X       spacenode(offlags);
X       printbuf(&buf,pnflags);
X      }
X    }
X  }
X#endif
X#endif
X
X if (flags & 256)
X  {
X#ifdef TTYVP
X#ifdef PSESS
X   static struct sess pse;
X   kmemcpy(&pse,p->p_sessp,sizeof(pse));
X   if (pse.s_vp && validnode(pse.s_vp,&buf,0))
X#else
X   if (u->u_ttyvp && validnode(u->u_ttyvp,&buf,0))
X#endif
X    {
X     if (flags & 524288)
X      {
X       printf("%d ",p->p_pid);
X       return;
X      }
X     if (flags & 1)
X       fputs(prefd,stdout);
X     if (flags & 262144)
X       prefd[0] = 0;
X     printf("ctty ");
X     if (!(flags & 131072))
X      {
X       spacenode(offlags);
X       printbuf(&buf,pnflags);
X      }
X    }
X#else
X   if (u->u_ttyd)
X    {
X     char *s;
X     s = getttydevname(u->u_ttyd);
X     if (s)
X      {
X       buf.type = "chr"; /*XXX: breaks virtype encapsulation */
X       buf.flagdev = NODE_ID_DEV;
X       buf.id.dev.maj = 0; /*XXX*/
X       buf.id.dev.min = 0; /*XXX*/
X       buf.id.dev.name = s;
X       if (validnode(0,&buf,1)) /* XXX: does this work? */
X	{
X         if (flags & 524288)
X          {
X           printf("%d ",p->p_pid);
X           return;
X          }
X         if (flags & 1)
X           fputs(prefd,stdout);
X	 if (flags & 262144)
X	   prefd[0] = 0;
X         printf("ctty ");
X	 if (!(flags & 131072))
X	  {
X           spacenode(offlags);
X           printbuf(&buf,pnflags);
X	  }
X	}
X      }
X    }
X#endif
X  }
X
X if (flags & 512)
X   if (u->u_cdir && validnode(u->u_cdir,&buf,0))
X    {
X     if (flags & 524288)
X      {
X       printf("%d ",p->p_pid);
X       return;
X      }
X     if (flags & 1)
X       fputs(prefd,stdout);
X     if (flags & 262144)
X       prefd[0] = 0;
X     if (flags & 65536)
X       printf("cwd ");
X     else
X       printf(" cwd ");
X     if (!(flags & 131072))
X      {
X       spacenode(offlags);
X       printbuf(&buf,pnflags);
X      }
X    }
X if (flags & 1024)
X   if (u->u_rdir && validnode(u->u_rdir,&buf,0))
X    {
X     if (flags & 524288)
X      {
X       printf("%d ",p->p_pid);
X       return;
X      }
X     if (flags & 1)
X       fputs(prefd,stdout);
X     if (flags & 262144)
X       prefd[0] = 0;
X     printf("rdir ");
X     if (!(flags & 131072))
X      {
X       spacenode(offlags);
X       printbuf(&buf,pnflags);
X      }
X    }
X
X if (flags & 2048)
X  {
X#ifdef OPALF
X   if (u->u_lastfile >= NOFILE) /* XXX: ever? */
X     kmemcpy(fof,u->u_ofile,sizeof(struct file *) * NOFILE);
X   else
X     kmemcpy(fof,u->u_ofile,sizeof(struct file *) * (u->u_lastfile + 1));
X   u->u_ofile = fof; /* ensures that we're dealing with a pointer */
X#endif
X#ifdef ODOFE
X   if (u->u_ofile_ext)
X    {
X     kmemcpy(&oe,u->u_ofile_ext,sizeof(oe));
X     u->u_nofile = oe.oe_nofile;
X    }
X#endif
X   for (i = 0;i < NUOFILE(u);++i)
X    {
X#ifdef ODOFE
X     if (u->u_ofile_ext)
X       kmemcpy(u->u_lofile,oe.oe_ofile + i,sizeof(struct ofile));
X       /* XXX: this is slow as molasses */
X     else
X       u->u_lofile[0] = u->u_lofile[i]; /* XXX: structure copying */
X#endif
X     if (UOFILE(u,i))
X       if (ft[UOFILE(u,i) - myfile].f_data)
X	{
X	 switch(ft[UOFILE(u,i) - myfile].f_type)
X	  {
X	   case DTYPE_INODE:
X	     if (!validnode(ft[UOFILE(u,i) - myfile].f_data,&buf,0))
X	       continue;
X	     break;
X	   case DTYPE_SOCKET:
X	     if (!validsocket(ft[UOFILE(u,i) - myfile].f_data,&sbuf))
X	       continue;
X	     break;
X	   default: /* including SPU, PROCESS */
X	     if (!validother(ft[UOFILE(u,i) - myfile].f_data))
X	       continue;
X	  }
X         if (flags & 524288)
X          {
X           printf("%d ",p->p_pid);
X           return;
X          }
X	 if (flags & 1)
X	   fputs(prefd,stdout);
X	 if (flags & 262144)
X	   prefd[0] = 0;
X	 if (flags & 65536)
X           printf("%d ",i);
X	 else
X           printf("%4d ",i);
X	 if (!(flags & 131072))
X           printfile(ft + (UOFILE(u,i) - myfile),offlags,pnflags,&buf,&sbuf);
X        }
X    }
X  }
X
X if (flags & 4096)
X  {
X   struct vnode **segvns;
X   segvns = getvmseg(p);
X   for (i = 0;segvns[i] && (i < vmsegmax);++i)
X    {
X     if (validnode(segvns[i],&buf,0))
X      {
X       if (flags & 524288)
X        {
X         printf("%d ",p->p_pid);
X         return;
X        }
X       if (flags & 1)
X         fputs(prefd,stdout);
X       if (flags & 262144)
X	 prefd[0] = 0;
X       printf("mmap ");
X       if (!(flags & 131072))
X	{
X         spacenode(offlags);
X         printbuf(&buf,pnflags);
X	}
X      }
X    }
X  }
X
X if (flags & 8192)
X   if (!prefd[0] || !(flags & 1) || !(flags & 1048576) || !(flags & 262144))
X     putchar('\n');
X}
X
X/* offlags:
X1 print file data location, 9 chars
X2 print reference count, 6 chars
X4 print file type, 2 chars
X8 print file offset, 11 chars
X16 print file flags, 9 chars
X32 print file credentials as uids, 12 chars (or 18 chars with usernames)
X64 print extended file information, free format
X128 use usernames rather than uids
X*/
X
Xint printfile(f,offlags,pnflags,buf,sbuf)
Xstruct file *f;
Xint offlags;
Xint pnflags;
Xstruct nodebuf *buf;
Xstruct socketbuf *sbuf; /*XXX*/
X{
X struct ucred *uc;
X /* XXX: f_ops? f_msgcount? */
X if (offlags & 1)
X   printf("%8x ",f->f_data);
X if (offlags & 2)
X   printf("%5d ",(int) f->f_count);
X if (offlags & 4)
X   printf("%s ",printftype(f)); /* could also do numeric */
X if (offlags & 8)
X   printf("%10lu ",(unsigned long) f->f_offset);
X if (offlags & 16)
X   printf("%s ",printfflag(f,4)); /* XXX: could also use 1,2,3 */
X if (offlags & 32)
X  {
X   uc = getfcred(f);
X   if (uc) printf("%s ",printucred(uc,1,0,0,(offlags & 128) ? 1 : 0));
X  }
X if (offlags & 64)
X   if (f->f_type == DTYPE_SOCKET)
X     printsbuf(sbuf);
X   else if (f->f_type == DTYPE_INODE)
X     printbuf(buf,pnflags);
X#ifdef DTYPE_SPU
X   else if (f->f_type == DTYPE_SPU)
X     printf("(spu io)");
X#endif
X#ifdef DTYPE_PROCESS
X   else if (f->f_type == DTYPE_PROCESS)
X    {
X     static struct proc p;
X     kmemcpy(&p,f->f_data,sizeof(p));
X     printf("(process %d)",p.p_pid);
X    }
X#endif
X   /* XXX: other types? */
X   else
X     printf("unk type %d %8x\n",f->f_type,f->f_data);
X else
X   putchar('\n');
X}
X
Xint spacenode(offlags) /*XXX this whole routine */
Xint offlags;
X{
X if (offlags & 1)
X   printf("%8s ","");
X if (offlags & 2)
X   printf("%5s ","");
X if (offlags & 4)
X   printf("I "); /*XXX*/
X if (offlags & 8)
X   printf("%10s ","");
X if (offlags & 16)
X   printf("%s ","---------"); /*XXX*/
X if (offlags & 32)
X   printf("%s ",(offlags & 128) ? "                 " : "           "); /*XXX*/
X}
X
Xprintbuf(buf,pnflags)
Xstruct nodebuf *buf;
Xint pnflags;
X{
X printf("%s",buf->type);
X switch(buf->flagdev)
X  {
X   case NODE_ID_FIFO:
X     printf(" (named pipe)\n");
X     break;
X   case NODE_ID_FIFOINO:
X     printf(" (named pipe)");
X   case NODE_ID_INO:
X     if (!(pnflags & 4))
X      {
X       printf((pnflags & 1) ? " inode %d" : " ino %7d",buf->id.ino.inum);
X       if (buf->id.ino.name)
X         if ((pnflags & 1))
X           printf(" %s fs %x (%s)",buf->id.ino.flagnfs ? "nfs" : "local"
X	     ,buf->id.ino.dev,buf->id.ino.name);
X         else
X	   printf(" %5x (%s)",buf->id.ino.dev,buf->id.ino.name);
X       else
X         if ((pnflags & 1))
X	   printf(" block dev %x",buf->id.ino.dev);
X         else
X	   printf(" %5x",buf->id.ino.dev);
X      }
X     if (pnflags & 2)
X      {
X       putchar(' '); if (!(pnflags & 4)) putchar('(');
X       revnamei((unsigned long) buf->id.ino.inum,(unsigned long) buf->id.ino.dev);
X       if (!(pnflags & 4)) putchar(')');
X       /* XXX: should do the printing right here */
X      }
X     putchar('\n');
X     break;
X   case NODE_ID_DEV:
X     if (pnflags & 4)
X      {
X       if (buf->id.dev.name)
X         printf(" %s\n",buf->id.dev.name);
X       else
X         printf(" dev (%d,%d)\n",buf->id.dev.maj,buf->id.dev.min);
X      }
X     else
X      {
X       if (buf->id.dev.name)
X         printf(" dev (%s)\n",buf->id.dev.name);
X       else
X         printf(" dev (%d,%d)\n",buf->id.dev.maj,buf->id.dev.min);
X      }
X     break;
X   default:
X     printf(" \n"); /*XXX*/
X  }
X return;
X}
X
Xprintsbuf(sbuf)
Xstruct socketbuf *sbuf;
X{
X printf("(");
X
X if (sbuf->strsockt) printf("%s ",sbuf->strsockt);
X else printf("unknown socket type %d ",sbuf->socktype);
X
X if (sbuf->flagaccept) printf("accept ");
X if (sbuf->flagreuse) printf("reuse ");
X if (sbuf->flaghead) printf("head ");
X
X if (sbuf->famname) printf("%s",sbuf->famname);
X else printf("unknown family %d",sbuf->family);
X
X switch(sbuf->fsw)
X  {
X   case FSW_UNK:
X     break;
X   case FSW_INET:
X     if (sbuf->fu.inet.strpro) printf(" %s ",sbuf->fu.inet.strpro);
X     else printf(" protocol %d ",sbuf->fu.inet.proto);
X     if (sbuf->fu.inet.r0 || sbuf->fu.inet.r1 || sbuf->fu.inet.r2 || sbuf->fu.inet.r3)
X       printf("%u.%u.%u.%u",sbuf->fu.inet.r0,sbuf->fu.inet.r1,sbuf->fu.inet.r2,sbuf->fu.inet.r3);
X     else printf("*");
X     if (sbuf->fu.inet.rp) printf(":%d",sbuf->fu.inet.rp);
X     else printf(":*");
X     if (sbuf->fu.inet.l0 || sbuf->fu.inet.l1 || sbuf->fu.inet.l2 || sbuf->fu.inet.l3)
X       printf(" %u.%u.%u.%u",sbuf->fu.inet.l0,sbuf->fu.inet.l1,sbuf->fu.inet.l2,sbuf->fu.inet.l3);
X       /* XXX: always print local host as uname? */
X     else printf(" *");
X     if (sbuf->fu.inet.lp) printf(":%d",sbuf->fu.inet.lp);
X     else printf(":*");
X     break;
X   case FSW_UNIX:
X     printf(" unpcb %x inode %x conn %x",sbuf->fu.un.unpcb,sbuf->fu.un.node,sbuf->fu.un.conn);
X     /* XXX: print that vnode? print that unpcb? */
X     printf("%s",sbuf->fu.un.path);
X     break;
X   default:
X     break; /*XXX*/
X  }
X
X printf(")\n");
X}
X
Xstruct validlist
X {
X  struct validlist *next;
X  int type; /* 1 for node, 2 for socket */
X  union
X   {
X    struct nodebuf n;
X    struct socketbuf s;
X   }
X  v;
X }
X;
X
Xstatic struct validlist *validhead = 0;
X
Xint validsmatch(v,sbuf)
Xstruct socketbuf *v;
Xstruct socketbuf *sbuf;
X{
X /* XXX: many more match types are possible */
X /* socktype, family, fsw */
X
X if (v->fsw == FSW_UNK) /* no sockets at all */
X   return 0;
X if (sbuf->fsw != v->fsw) /* must match nonzero fsw */
X   return 0;
X if (v->fsw == FSW_INET)
X   if (v->fu.inet.lp && (v->fu.inet.lp != sbuf->fu.inet.lp))
X     return 0;
X return 1;
X}
X
Xint validmatch(v,buf)
Xstruct nodebuf *v;
Xstruct nodebuf *buf;
X{
X if (v->flagdev == NODE_ID_DEV)
X   if (buf->flagdev == NODE_ID_DEV)
X     return (v->id.dev.maj == buf->id.dev.maj) && (v->id.dev.min == buf->id.dev.min);
X   else
X     return 0;
X if ((buf->flagdev == NODE_ID_INO) || (buf->flagdev == NODE_ID_FIFOINO))
X  {
X   /* It would be wrong to check NFS here: stat doesn't indicate NFS. */
X   if (v->id.ino.inum)
X     if (v->id.ino.inum != buf->id.ino.inum)
X       return 0;
X   if (v->id.ino.dev != buf->id.ino.dev)
X     return 0;
X   return 1;
X  }
X return 0;
X}
X
Xstatic struct socketbuf sockcache[256];
Xstatic int sockcacheok[256]; /* had better be initialized to 0 */
Xstatic char *sockcachepos[256];
X
Xint cachegetsocket(sock,buf)
Xchar *sock;
Xstruct socketbuf *buf;
X{
X int hash;
X hash = ((char *) &sock)[0] + ((char *) &sock)[3];
X   /* XXX: major XXX: we had better have 4-byte addresses here */
X hash = hash & 255; /* okay, at least this is in the right range */
X if (sockcacheok[hash])
X   if (sockcachepos[hash] == sock)
X    {
X     *buf = sockcache[hash]; /* XXX: structure copying */
X     return 0;
X    }
X if (getsocket(sock,buf) == -1)
X   return -1;
X sockcache[hash] = *buf; /* XXX: structure copying */
X sockcacheok[hash] = 1;
X sockcachepos[hash] = sock;
X return 0;
X}
X
Xint validsocket(sock,sbuf)
Xchar *sock;
Xstruct socketbuf *sbuf;
X{
X struct validlist *v;
X if (getsocket(sock,sbuf) == -1)
X   return 0;
X if (!validhead)
X   return flagall;
X for (v = validhead;v;v = v->next)
X   if (v->type == 2)
X     if (validsmatch(&(v->v.s),sbuf))
X       return 1;
X return 0;
X}
X
Xstatic struct nodebuf nodecache[256];
Xstatic int nodecacheok[256]; /* had better be initialized to 0 */
Xstatic char *nodecachepos[256];
X
Xint cachegetnode(node,buf)
Xchar *node;
Xstruct nodebuf *buf;
X{
X int hash;
X hash = ((char *) &node)[0] + ((char *) &node)[3];
X   /* XXX: major XXX: we had better have 4-byte addresses here */
X hash = hash & 255; /* okay, at least this is in the right range */
X if (nodecacheok[hash])
X   if (nodecachepos[hash] == node)
X    {
X     *buf = nodecache[hash]; /* XXX: structure copying */
X     return 0;
X    }
X if (getnode(node,buf) == -1)
X   return -1;
X nodecache[hash] = *buf; /* XXX: structure copying */
X nodecacheok[hash] = 1;
X nodecachepos[hash] = node;
X return 0;
X}
X
Xint validnode(node,buf,gndone)
Xchar *node;
Xstruct nodebuf *buf;
Xint gndone;
X{
X struct validlist *v;
X if (!gndone)
X   if (cachegetnode(node,buf) == -1)
X     return 0;
X if (!validhead)
X   return flagall;
X for (v = validhead;v;v = v->next)
X   if (v->type == 1)
X     if (validmatch(&(v->v.n),buf))
X       return 1;
X return 0;
X}
X
Xint validsadd(sbuf)
Xstruct socketbuf *sbuf;
X{
X struct validlist *v;
X v = (struct validlist *) malloc(sizeof(struct validlist));
X if (!v)
X   return -1;
X v->next = validhead;
X v->type = 2;
X v->v.s = *sbuf; /* XXX: requires struct copying */
X validhead = v;
X return 0;
X}
X
Xint validadd(buf)
Xstruct nodebuf *buf;
X{
X struct validlist *v;
X v = (struct validlist *) malloc(sizeof(struct validlist));
X if (!v)
X   return -1;
X v->next = validhead;
X v->type = 1;
X v->v.n = *buf; /* XXX: requires struct copying */
X validhead = v;
X return 0;
X}
X
Xint validother(node)
Xchar *node;
X{
X if (validhead)
X   return 0;
X return flagall;
X}
X
Xstruct proclist
X {
X  struct proclist *next;
X  int type; /* 1 for pid, 2 for uid */
X  union
X   {
X    int pid;
X    int uid;
X   }
X  u;
X }
X;
X
Xstatic struct proclist *prochead = 0;
X
Xint procmatch(proc)
Xstruct proc *proc;
X{
X struct proclist *p;
X if (!prochead)
X   return 1;
X for (p = prochead;p;p = p->next)
X  {
X   if (p->type == 1)
X     if (proc->p_pid == p->u.pid)
X       return 1;
X   if (p->type == 2)
X     if (proc->p_uid == p->u.uid)
X       return 1;
X   /*XXX: more types? */
X  }
X return 0;
X}
X
Xint procaddpid(pid)
Xint pid;
X{
X struct proclist *p;
X p = (struct proclist *) malloc(sizeof(struct proclist));
X if (!p)
X   return -1;
X p->next = prochead;
X p->type = 1;
X p->u.pid = pid;
X prochead = p;
X return 0;
X}
X
Xint procadduid(uid)
Xint uid;
X{
X struct proclist *p;
X p = (struct proclist *) malloc(sizeof(struct proclist));
X if (!p)
X   return -1;
X p->next = prochead;
X p->type = 2;
X p->u.uid = uid;
X prochead = p;
X return 0;
X}
END_OF_FILE
if test 27865 -ne `wc -c <'pff.c'`; then
    echo shar: \"'pff.c'\" unpacked with wrong size!
fi
# end of 'pff.c'
fi
echo shar: End of archive 6 \(of 6\).
cp /dev/null ark6isdone
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