home *** CD-ROM | disk | FTP | other *** search
- /************************************************************
- *
- * This program was written by me, Mike "Ford" Ditto, and
- * I hereby release it into the public domain in the interest
- * of promoting the development of free, quality software
- * for the hackers and users of the world.
- *
- * Feel free to use, copy, modify, improve, and redistribute
- * this program, but keep in mind the spirit of this
- * contribution; always provide source, and always allow
- * free redistribution (shareware is fine with me). If
- * you use a significant part of this code in a program of
- * yours, I would appreciate being given the appropriate
- * amount of credit.
- * -=] Ford [=-
- *
- ************************************************************/
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <pwd.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/sysmacros.h>
- #include <sys/stat.h>
- #include <sys/inode.h>
- #include <sys/file.h>
- #include <sys/seg.h>
- #include <sys/page.h>
- #include <sys/text.h>
- #include <sys/proc.h>
- #include <sys/signal.h>
- #include <sys/dir.h>
- #include <sys/user.h>
- #include <sys/var.h>
-
- extern char *sbrk();
- extern long lseek();
- extern void perror(), exit();
- extern struct passwd *getpwuid();
- extern char *malloc();
-
-
- char *progname;
-
- #define inodeaddr (mysyms[0].xl_value)
- #define fileaddr (mysyms[1].xl_value)
- #define procaddr (mysyms[2].xl_value)
- #define varaddr (mysyms[3].xl_value)
-
- struct xlist mysyms[] =
- {
- { 0,0,0,"_inode" },
- { 0,0,0,"_file" },
- { 0,0,0,"_proc" },
- { 0,0,0,"_v" },
- { 0,0,0,(char *)0 }
- };
-
- char buf[BUFSIZ];
-
- int kmem, mem, swap, kflag, uflag;
- int NINODE, NFILE, NPROC;
-
- struct inode *inodep;
- struct file *filep;
- struct proc *procp;
- struct var *var;
-
-
- /* main program for fuser(1M), a program which lists */
- /* processes that are using the given file(s) */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int status=0;
-
- progname = *argv;
-
- setup();
-
- while (++argv,--argc)
- if ((*argv)[0]=='-')
- {
- register char c, *i;
-
- kflag=uflag=0;
-
- i = *argv+1;
- while (c= *i++) switch(c)
- {
- case 'k':
- ++kflag;
- break;
- case 'u':
- ++uflag;
- break;
- default:
- fprintf(stderr, "%s: bad flag `-%c'\n", progname, c);
- fprintf(stderr,
- "Usage: %s [-ku] files [[-] [-ku] files]\n",
- progname);
- return -1;
- }
- }
- else {
- printf ("%s: ", *argv);
- status += fuser(*argv);
- putchar ('\n');
- }
- return status;
- }
-
-
- /* a fast, zeroizing, memory allocator for things */
- /* that will never need to be freed */
- char *myalloc(nbytes)
- long nbytes;
- {
- register char *ptr;
-
- ptr = malloc((unsigned) nbytes);
- if (! ptr)
- {
- sprintf(buf, "%s: no memory!", progname);
- perror(buf);
- exit(1);
- }
- memset (ptr, 0, nbytes);
-
- return ptr;
- }
-
-
- /* one-time setup of main data structures from the kernel */
- setup()
- {
- if ( (kmem=open("/dev/kmem", O_RDONLY)) < 0 )
- {
- sprintf(buf, "%s: can't open /dev/kmem", progname);
- perror(buf);
- exit(1);
- }
-
- if ( (mem=open("/dev/mem", O_RDONLY)) < 0 )
- {
- sprintf(buf, "%s: can't open /dev/mem", progname);
- perror(buf);
- exit(1);
- }
-
- if ( (swap=open("/dev/swap", O_RDONLY)) < 0 )
- {
- sprintf(buf, "%s: can't open /dev/swap", progname);
- perror(buf);
- exit(1);
- }
-
- if (xlist("/xenix", mysyms))
- {
- sprintf(buf, "%s: can't xlist /xenix", progname);
- perror(buf);
- exit(1);
- }
-
- setuid(getuid());
-
- #ifdef DEBUG
- fprintf(stderr, "inode: 0x%08lx\n", inodeaddr);
- fprintf(stderr, "file: 0x%08lx\n", fileaddr);
- fprintf(stderr, "proc: 0x%08lx\n", procaddr);
- fprintf(stderr, "var: 0x%08lx\n", varaddr);
- #endif DEBUG
-
- var = (struct var *)myalloc((long) sizeof (struct var));
- kcopy((char *)var, varaddr, (long) sizeof (struct var));
-
- NINODE = var->v_inode;
- NFILE = var->v_file;
- NPROC = var->v_proc;
-
- #ifdef DEBUG
- fprintf(stderr, "NOFILE: %d\n", NOFILE);
- fprintf(stderr, "NINODE: %d\n", NINODE);
- fprintf(stderr, "NFILE: %d\n", NFILE);
- fprintf(stderr, "NPROC: %d\n", NPROC);
- #endif DEBUG
-
- inodep = (struct inode *)myalloc((long) sizeof (struct inode) * NINODE);
- filep = (struct file *)myalloc((long) sizeof (struct file) * NFILE);
- procp = (struct proc *)myalloc((long) sizeof (struct proc) * NPROC);
-
- kcopy((char *)inodep, inodeaddr, (long) sizeof (struct inode) * NINODE);
- kcopy((char *)filep, fileaddr, (long) sizeof (struct file) * NFILE);
- kcopy((char *)procp, procaddr, (long) sizeof (struct proc) * NPROC);
- }
-
-
- /* copy bytes from physical address space to this process */
- pcopy(caddr, paddr, nbytes)
- char *caddr;
- long paddr;
- long nbytes;
- {
- if ( lseek(mem, paddr, 0)<0L ||
- read(mem, caddr, (unsigned)nbytes) != nbytes )
- {
- sprintf(buf, "%s: can't read /dev/mem", progname);
- perror(buf);
- exit(1);
- }
- }
-
-
- /* copy bytes from kernel address space to this process */
- kcopy(caddr, kaddr, nbytes)
- char *caddr;
- long kaddr;
- long nbytes;
- {
- if ( lseek(kmem, kaddr, 0)<0L ||
- read(kmem, caddr, (unsigned)nbytes) != nbytes )
- {
- sprintf(buf, "%s: can't read /dev/kmem", progname);
- perror(buf);
- exit(1);
- }
- }
-
- findu (proc, slot, user)
- struct proc *proc;
- int slot;
- struct user *user;
- {
- long swapaddr;
- int i;
-
- if ((proc->p_flag & (SSWAP|SSPART)) || ! (proc->p_flag & SLOAD)) {
- swapaddr = proc->p_addr[0].te_frameno * NBPC;
- lseek (swap, swapaddr, 0);
- if (read (swap, user, sizeof *user) < 0)
- return (0);
- } else {
- lseek (mem, proc->p_addr[0].te_frameno * NBPC, 0);
- if (read (mem, user, sizeof *user) < 0)
- return (0);
- }
- if ((user->u_procp - (struct proc *) procaddr) == slot)
- return (1);
- else
- return (0);
- }
- /* Return a pointer to a local copy of the user structure */
- /* for process number `procidx'. Returns NULL if procidx */
- /* refers to an invalid (not-in-use or otherwise) slot. */
- struct user *getuser(procidx)
- int procidx;
- {
- static struct user **users;
- struct file **ofile;
- long upage;
-
- #ifdef DEBUG
- fprintf (stderr, "Looking for upage for proc %d\n", procidx);
- #endif
- if (!procp[procidx].p_stat ||
- procp[procidx].p_stat == SIDL ||
- procp[procidx].p_stat == SZOMB)
- return 0;
-
- if (!users)
- users = (struct user **)myalloc((long) sizeof (struct user *) * NPROC);
-
- if (!users[procidx])
- {
- /* allocate and copy in the user structure */
- users[procidx] = (struct user *)myalloc((long) sizeof (struct user));
- if (! findu (&procp[procidx], procidx, users[procidx]))
- return 0;
- }
- return users[procidx];
- }
-
-
- /* find all users of the file `name' */
- fuser(name)
- char *name;
- {
- register i;
- int filesys;
- struct stat Stat;
-
- if (stat(name, &Stat))
- {
- sprintf(buf, "%s: can't stat %s", progname, name);
- perror(buf);
- return 1;
- }
-
- /* see if we are looking for a whole filesystem */
- filesys = ((Stat.st_mode & S_IFMT) == S_IFBLK);
-
- #ifdef DEBUG
- if (filesys)
- fprintf(stderr, "looking for files on dev=%d,%d\n",
- bmajor(Stat.st_rdev), minor(Stat.st_rdev));
- else
- fprintf(stderr, "looking for dev=%d,%d, ino=%d\n",
- bmajor(Stat.st_dev), minor(Stat.st_dev), Stat.st_ino);
- #endif DEBUG
-
- for ( i=0 ; i<NINODE ; ++i )
- {
- if ( inodep[i].i_count &&
- ((filesys && (inodep[i].i_dev == Stat.st_rdev))
- || (inodep[i].i_dev == Stat.st_dev &&
- inodep[i].i_number == Stat.st_ino)) )
- {
- #ifdef DEBUG
- fprintf(stderr, "Found it! inodep[%d], i_size is %ld\n",
- i, inodep[i].i_size);
- #endif DEBUG
-
- iuser((struct inode *)inodeaddr + i);
- }
- }
-
- return 0;
- }
-
-
- #define CHECK(kaddr, type) if (kaddr==kinode) { if (++flag==1) printf(" %d", procp[i].p_pid); if (type) putchar(type); }
-
- /* find all users of the inode at kernel address `kinode' */
- iuser(kinode)
- struct inode *kinode;
- {
- register int i, j;
- int flag;
- struct user *user;
- struct passwd *pwd;
- struct text text;
-
- #ifdef DEBUG
- fprintf(stderr, "Looking for users of inode at kernel address 0x%08lx\n",
- kinode);
- #endif DEBUG
-
- for ( i=0 ; i<NPROC ; ++i )
- if (user = getuser(i))
- {
- #ifdef DEBUG
- fprintf(stderr, "%03d: pid=%5d addr[0]=%05x addr[1]=%05x\n",
- i, procp[i].p_pid, procp[i].p_addr[0], procp[i].p_addr[1]);
- #endif DEBUG
-
- #ifdef DEBUG
- fprintf(stderr, " user = 0x%08lx\n", user);
- #endif DEBUG
-
- fflush(stderr);
- flag=0;
- if (procp[i].p_textp) {
- kcopy((char *)&text, procp[i].p_textp, (long) sizeof (struct text));
- CHECK(text.x_iptr, 't');
- }
-
- CHECK(user->u_cdir, 'c');
- CHECK(user->u_rdir, 'r');
- CHECK(user->u_pdir, 'p');
-
- for ( j=0 ; !flag && j<NOFILE ; ++j )
- if (user->u_ofile[j])
- CHECK(filep[user->u_ofile[j]-(struct file *)fileaddr].f_inode, 0);
- fflush(stdout);
-
- if (flag)
- {
- if (uflag)
- {
- if ( (pwd=getpwuid((int)procp[i].p_uid)) )
- fprintf(stderr, "(%s)", pwd->pw_name);
- else
- fprintf(stderr, "(%d)", procp[i].p_uid);
- }
- if (kflag && procp[i].p_pid)
- if (kill(procp[i].p_pid, SIGKILL))
- {
- sprintf(buf, "%s: can't kill process %d",
- progname, procp[i].p_pid);
- perror(buf);
- }
- }
- }
- }
-