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