home *** CD-ROM | disk | FTP | other *** search
- /*
- * UNIX PC Port programmed by Mike -=]Ford[=- Ditto (ditto@cbmvax.commodore.com)
- *
- * SCO XENIX/386 Port programmed by John F. Haugh II (jfh@rpp386.cactus.org)
- */
-
- #ifndef lint
- static char rcsid[]="$Header: ofiles.c,v 1.1 85/05/03 06:49:19 cspencer Exp $";
- #endif lint
- #include <sys/param.h>
- #include <sys/dir.h>
- #define KERNEL
- #include <sys/file.h>
- #undef KERNEL
- #include <sys/text.h>
- #include <sys/inode.h>
- #include <sys/user.h>
- #include <sys/proc.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include <pwd.h>
- #include <sys/var.h>
- #include <stdio.h>
- #include <fcntl.h>
-
-
- #define CDIR 01
- #define OFILE 02
- #define RDIR 04
- #define XFILE 010
-
-
- long eseek();
- long lseek();
-
- int nproc; /* number of entries in proc table */
- int mem; /* fd for /dev/mem */
- int kmem; /* fd for /dev/kmem */
- int swap; /* fd for /dev/swap */
-
- int pids_only = 0; /* if non-zero, only output process ids */
-
- char *progname;
- struct nlist unix_nl[] = {
- #define X_PROC 0
- {"_proc"},
- #define X_VAR 1
- {"_v"},
- {0}
- };
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int ruid = getuid ();
- int euid = geteuid ();
- struct inode *i,*getinode(), *gettext();
- struct stat s;
- struct user *u, *getuser();
- struct proc p;
- register int filen, flags, procn;
- register char *filename, *fsname;
-
- progname = argv[0];
-
- if(argc == 1) {
- fprintf(stderr,"usage: %s [-p] files\n", progname);
- exit(1);
- }
-
- /* check for -p flag */
- if(strcmp(argv[1],"-p") == 0) {
- pids_only++;
- --argc;
- ++argv;
- }
-
- setuid (euid); /* get any SUID privileges */
-
- if((mem = open("/dev/mem", O_RDONLY)) < 0)
- error("can't open /dev/mem. ");
- if((kmem = open("/dev/kmem", O_RDONLY)) < 0)
- error("can't open /dev/kmem. ");
- if((swap = open("/dev/swap", O_RDONLY)) < 0)
- error("can't open /dev/swap. ");
-
- setuid (ruid); /* give up any SUID privileges */
-
- getsyms();
-
- while(--argc) {
- filename = *++argv;
- fsname = "";
-
- if(stat(filename, &s)) {
- fprintf(stderr,"can't stat %s. ",filename);
- perror("");
- continue;
- }
- if(! pids_only) {
- printf("%s\t%s\n", filename,fsname);
- printf("%-8.8s\tPID\tType\tCommand\n", "User");
- }
- for(procn = 0; procn < nproc; procn++){
- procslot(procn, &p);
- flags = 0;
- if(p.p_stat == 0 || p.p_stat == SZOMB)
- continue;
- u = getuser(&p);
- if ( u == (struct user *)NULL)
- continue;
-
- if ((i = gettext (&p)) && check(&s,i))
- flags |= XFILE;
-
- i = getinode(u->u_rdir, "rdir");
- if(check(&s,i))
- flags |= RDIR;
-
- i = getinode(u->u_cdir, "cdir");
- if(check(&s,i))
- flags |= CDIR;
-
- for(filen = 0; filen < NOFILE; filen++) {
- struct file f;
-
- if(u->u_ofile[filen] == NULL)
- continue;
-
- eseek(kmem,(long)u->u_ofile[filen],0,"file");
- eread(kmem,(char *)&f, sizeof(f), "file");
-
- if(f.f_count > 0) {
- i = getinode((char *)f.f_inode, "file");
- if(check(&s,i))
- flags |= OFILE;
- }
- }
- if(flags) gotone(u,&p,flags);
- }
- if(! pids_only)
- printf("\n");
- }
- }
-
- /*
- * print the name of the user owning process "p" and the pid of that process
- */
- gotone(u,p,f)
- struct user *u;
- struct proc *p;
- int f;
- {
- register struct passwd *pw;
- struct passwd *getpwuid();
-
- /* only print pids and return */
- if(pids_only) {
- printf("%d ",p->p_pid);
- fflush(stdout);
- return;
- }
- pw = getpwuid(u->u_uid);
- if(pw)
- printf("%-8.8s\t", pw->pw_name );
- else
- printf("(%d)\t", u->u_uid);
- printf("%d\t", p->p_pid);
- if(f & OFILE) putchar('f'); /* proc has a file */
- if(f & CDIR) putchar('p'); /* proc's current dir is on device */
- if(f & RDIR) putchar('r'); /* proc's root dir is on device */
- if(f & XFILE) putchar('x'); /* proc's text proto is file */
- printf("\t");
- printf("%-14.14s", u->u_comm);
- printf("\n");
- }
-
- /*
- * is inode "i" on device "s"? returns TRUE or FALSE
- */
-
- check(s, i)
- struct stat *s;
- struct inode *i;
- {
- if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == brdev(i->i_dev))
- return 1;
- else if((s->st_dev == brdev(i->i_dev)) && (s->st_ino == i->i_number))
- return 1;
- else return 0;
- }
-
-
- /*
- * getinode - read an inode from from mem at address "addr"
- * return pointer to inode struct.
- */
- struct inode *getinode(ip,s)
- struct inode *ip;
- char *s;
- {
- static struct inode i;
-
- eseek(kmem, (long)ip, 0, "inode");
- eread(kmem, (char *)&i, sizeof(i), "inode");
- return &i;
- }
-
-
- /*
- * gettext - read the text table entry for process "p"
- * return pointer to inode
- */
-
- struct inode *gettext (p)
- struct proc *p;
- {
- struct text text;
-
- if (p->p_textp == 0)
- return 0;
-
- eseek (kmem, (long) p->p_textp, 0, "text");
- eread (kmem, (char *) &text, sizeof text, "text");
-
- return getinode (text.x_iptr);
- }
-
-
- /*
- * get user page for proc "p" from core or swap
- * return pointer to user struct
- */
- struct user *getuser(p)
- struct proc *p;
- {
- static char buf[NBPC];
- long upage;
-
- long swapaddr;
- int i;
-
- if ((p->p_flag & (SSWAP|SSPART)) || ! (p->p_flag & SLOAD)) {
- swapaddr = p->p_addr[0].te_frameno * NBPC;
- lseek (swap, swapaddr, 0);
- if (read (swap, buf, sizeof buf) < 0)
- return (0);
- } else {
- lseek (mem, p->p_addr[0].te_frameno * NBPC, 0);
- if (read (mem, buf, sizeof buf) < 0)
- return (0);
- }
- return (struct user *) buf;
- }
-
- /*
- * read with error checking
- */
- eread( fd, p, size, s)
- int fd;
- char *p;
- int size;
- char *s;
- {
- int n;
- char buf[100];
- if(( n = read(fd, p, size)) != size){
- sprintf(buf, "read error for %s. ", s);
- error(buf);
- }
- return n;
- }
-
- /*
- * seek with error checking
- */
- long eseek(fd, off, whence, s)
- int fd;
- long off;
- int whence;
- char *s;
- {
- long ret;
- char buf[100];
-
- if(( ret = lseek(fd, off, whence)) != off) {
- sprintf(buf, "seek for %s failed, wanted %o, got %o. ",
- s, off, ret);
- error(buf);
- }
- return ret;
- }
-
- /*
- * print mesg "s" followed by system erro msg. exit.
- */
- error(s)
- char *s;
- {
- if (s)
- fprintf(stderr,s);
- perror("");
- exit(1);
- }
-
- /*
- * get some symbols form the kernel
- */
- getsyms()
- {
- register i;
- struct var v;
-
- nlist("/xenix", unix_nl);
-
- for(i = 0; i < (sizeof(unix_nl)/sizeof(unix_nl[0]))-1; i++)
- if(unix_nl[i].n_value == 0) {
- fprintf(stderr,"%s: can't nlist for %s.\n",
- progname, unix_nl[i].n_name);
- exit(1);
- }
- eseek(kmem, (long)unix_nl[X_VAR].n_value, 0);
- eread(kmem, &v, sizeof(v), "var");
- nproc = v.v_proc;
- return;
- }
-
-
- /*
- * read proc table entry "n" into buffer "p"
- */
- procslot(n, p)
- int n;
- struct proc *p;
- {
- eseek(kmem, &((struct proc *) unix_nl[X_PROC].n_value)[n], 0);
- eread(kmem, (char *)p, sizeof(struct proc), "proc");
- return;
- }
-