home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1002 / ofiles.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.3 KB  |  341 lines

  1. /* 
  2.  * UNIX PC Port programmed by Mike -=]Ford[=- Ditto (ditto@cbmvax.commodore.com)
  3.  *
  4.  * SCO XENIX/386 Port programmed by John F. Haugh II (jfh@rpp386.cactus.org)
  5.  */
  6.  
  7. #ifndef lint
  8. static char rcsid[]="$Header: ofiles.c,v 1.1 85/05/03 06:49:19 cspencer Exp $";
  9. #endif lint
  10. #include <sys/param.h>
  11. #include <sys/dir.h>
  12. #define KERNEL
  13. #include <sys/file.h>
  14. #undef KERNEL
  15. #include <sys/text.h>
  16. #include <sys/inode.h>
  17. #include <sys/user.h>
  18. #include <sys/proc.h>
  19. #include <sys/stat.h>
  20. #include <sys/sysmacros.h>
  21. #include <pwd.h>
  22. #include <sys/var.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25.  
  26.  
  27. #define CDIR    01
  28. #define OFILE    02
  29. #define RDIR    04
  30. #define    XFILE    010
  31.  
  32.  
  33. long eseek();
  34. long lseek();
  35.  
  36. int nproc;        /* number of entries in proc table         */
  37. int mem;        /* fd for /dev/mem                */
  38. int kmem;        /* fd for /dev/kmem                */
  39. int swap;        /* fd for /dev/swap                */
  40.  
  41. int pids_only = 0;    /* if non-zero, only output process ids    */
  42.  
  43. char *progname;
  44. struct nlist unix_nl[] = {
  45. #define X_PROC        0
  46.     {"_proc"},
  47. #define X_VAR         1
  48.     {"_v"},
  49.     {0}
  50. };
  51.  
  52. main(argc, argv)
  53. int     argc;
  54. char    *argv[];
  55. {
  56.     int    ruid = getuid ();
  57.     int    euid = geteuid ();
  58.     struct inode *i,*getinode(), *gettext();
  59.     struct stat s;
  60.     struct user *u, *getuser();
  61.     struct proc p;
  62.     register int filen, flags, procn;
  63.     register char *filename, *fsname;
  64.  
  65.     progname = argv[0];
  66.  
  67.     if(argc == 1) {
  68.         fprintf(stderr,"usage: %s [-p] files\n", progname);
  69.         exit(1);
  70.     }
  71.  
  72.     /* check for -p flag */
  73.     if(strcmp(argv[1],"-p") == 0) {
  74.             pids_only++;
  75.             --argc;
  76.             ++argv;
  77.     }
  78.  
  79.     setuid (euid);    /* get any SUID privileges */
  80.  
  81.     if((mem = open("/dev/mem", O_RDONLY)) < 0)
  82.         error("can't open /dev/mem. ");
  83.     if((kmem = open("/dev/kmem", O_RDONLY)) < 0)
  84.         error("can't open /dev/kmem. ");
  85.     if((swap = open("/dev/swap", O_RDONLY)) < 0) 
  86.         error("can't open /dev/swap. ");
  87.  
  88.     setuid (ruid);    /* give up any SUID privileges */
  89.  
  90.     getsyms();
  91.  
  92.     while(--argc) {
  93.         filename = *++argv;
  94.         fsname = "";
  95.  
  96.         if(stat(filename, &s)) {
  97.             fprintf(stderr,"can't stat %s. ",filename);
  98.             perror("");
  99.             continue;
  100.         }
  101.         if(! pids_only) {
  102.             printf("%s\t%s\n", filename,fsname);
  103.             printf("%-8.8s\tPID\tType\tCommand\n", "User");
  104.         }
  105.         for(procn = 0; procn < nproc; procn++){
  106.             procslot(procn, &p);
  107.             flags = 0;
  108.             if(p.p_stat == 0 || p.p_stat == SZOMB)
  109.                 continue;
  110.             u = getuser(&p);
  111.             if ( u == (struct user *)NULL)
  112.                 continue;
  113.  
  114.             if ((i = gettext (&p)) && check(&s,i))
  115.                 flags |= XFILE;
  116.  
  117.             i = getinode(u->u_rdir, "rdir");
  118.             if(check(&s,i))
  119.                 flags |= RDIR;
  120.  
  121.             i = getinode(u->u_cdir, "cdir");
  122.             if(check(&s,i))
  123.                 flags |= CDIR;
  124.  
  125.             for(filen = 0; filen < NOFILE; filen++) {
  126.                 struct file f;
  127.  
  128.                 if(u->u_ofile[filen] == NULL)
  129.                     continue;
  130.  
  131.                 eseek(kmem,(long)u->u_ofile[filen],0,"file");
  132.                 eread(kmem,(char *)&f, sizeof(f), "file");
  133.  
  134.                 if(f.f_count > 0) {
  135.                     i = getinode((char *)f.f_inode, "file");
  136.                     if(check(&s,i))
  137.                         flags |= OFILE;
  138.                 }
  139.             }
  140.             if(flags) gotone(u,&p,flags);
  141.         }
  142.         if(! pids_only)
  143.             printf("\n");
  144.     }
  145. }        
  146.  
  147. /*
  148.  * print the name of the user owning process "p" and the pid of that process
  149.  */
  150. gotone(u,p,f)
  151. struct user *u;
  152. struct proc *p;
  153. int f;
  154. {
  155.     register struct passwd *pw;
  156.     struct passwd *getpwuid();
  157.  
  158.     /* only print pids and return */
  159.     if(pids_only) {
  160.             printf("%d ",p->p_pid);
  161.             fflush(stdout);
  162.             return;
  163.     }
  164.     pw = getpwuid(u->u_uid);
  165.     if(pw)
  166.         printf("%-8.8s\t", pw->pw_name );
  167.     else
  168.         printf("(%d)\t", u->u_uid);
  169.     printf("%d\t", p->p_pid);
  170.     if(f & OFILE) putchar('f');    /* proc has a file            */    
  171.     if(f & CDIR)  putchar('p');    /* proc's current dir is on device */
  172.     if(f & RDIR)  putchar('r');    /* proc's root dir is on device       */
  173.     if(f & XFILE) putchar('x');    /* proc's text proto is file       */
  174.     printf("\t");
  175.     printf("%-14.14s", u->u_comm);
  176.     printf("\n");
  177. }
  178.  
  179. /*
  180.  * is inode "i" on device "s"? returns TRUE or FALSE 
  181.  */
  182.  
  183. check(s, i)
  184. struct stat *s;
  185. struct inode *i;
  186. {
  187.     if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == brdev(i->i_dev))
  188.             return 1;
  189.     else if((s->st_dev == brdev(i->i_dev)) && (s->st_ino == i->i_number))
  190.             return 1;
  191.     else return 0;
  192. }
  193.  
  194.  
  195. /* 
  196.  *    getinode - read an inode from from mem at address "addr"
  197.  *           return pointer to inode struct. 
  198.  */
  199. struct inode *getinode(ip,s)
  200. struct inode *ip;
  201. char *s;
  202. {
  203.     static struct inode i;
  204.  
  205.     eseek(kmem, (long)ip, 0, "inode");
  206.     eread(kmem, (char *)&i, sizeof(i), "inode");
  207.     return &i;
  208. }
  209.  
  210.  
  211. /*
  212.  *    gettext - read the text table entry for process "p"
  213.  *        return pointer to inode
  214.  */
  215.  
  216. struct    inode    *gettext (p)
  217. struct    proc    *p;
  218. {
  219.     struct    text    text;
  220.  
  221.     if (p->p_textp == 0)
  222.         return 0;
  223.  
  224.     eseek (kmem, (long) p->p_textp, 0, "text");
  225.     eread (kmem, (char *) &text, sizeof text, "text");
  226.  
  227.     return getinode (text.x_iptr);
  228. }
  229.  
  230.  
  231. /* 
  232.  * get user page for proc "p" from core or swap
  233.  * return pointer to user struct
  234.  */
  235. struct user *getuser(p)
  236. struct proc *p;
  237. {
  238.     static char buf[NBPC];
  239.     long upage;
  240.  
  241.     long    swapaddr;
  242.     int    i;
  243.  
  244.     if ((p->p_flag & (SSWAP|SSPART)) || ! (p->p_flag & SLOAD)) {
  245.         swapaddr = p->p_addr[0].te_frameno * NBPC;
  246.         lseek (swap, swapaddr, 0);
  247.         if (read (swap, buf, sizeof buf) < 0)
  248.             return (0);
  249.     } else {
  250.         lseek (mem, p->p_addr[0].te_frameno * NBPC, 0);
  251.         if (read (mem, buf, sizeof buf) < 0)
  252.             return (0);
  253.     }
  254.     return (struct user *) buf;
  255. }
  256.  
  257. /*
  258.  * read with error checking
  259.  */
  260. eread( fd, p, size, s)
  261. int fd;
  262. char *p;
  263. int size;
  264. char *s;
  265. {
  266.     int n;
  267.     char buf[100];
  268.     if(( n =  read(fd, p, size)) != size){
  269.         sprintf(buf, "read error for %s. ", s);
  270.         error(buf);
  271.     }
  272.     return n;
  273. }
  274.  
  275. /*
  276.  * seek with error checking
  277.  */
  278. long eseek(fd, off, whence, s)
  279. int fd;
  280. long off;
  281. int whence;
  282. char *s;
  283. {
  284.     long ret;
  285.     char buf[100];
  286.  
  287.     if(( ret = lseek(fd, off, whence)) != off) {
  288.         sprintf(buf, "seek for %s failed, wanted %o, got %o. ",
  289.             s, off, ret);
  290.         error(buf);
  291.     }
  292.     return ret;
  293. }
  294.  
  295. /*
  296.  * print mesg "s" followed by system erro msg. exit.
  297.  */
  298. error(s)
  299. char *s;
  300. {
  301.     if (s)
  302.         fprintf(stderr,s);
  303.     perror("");
  304.     exit(1);
  305. }
  306.  
  307. /*
  308.  * get some symbols form the kernel
  309.  */
  310. getsyms()
  311. {
  312.     register i;
  313.     struct var v;
  314.  
  315.     nlist("/xenix", unix_nl);
  316.  
  317.     for(i = 0; i < (sizeof(unix_nl)/sizeof(unix_nl[0]))-1; i++)
  318.         if(unix_nl[i].n_value == 0) {
  319.             fprintf(stderr,"%s: can't nlist for %s.\n",
  320.                 progname, unix_nl[i].n_name);
  321.             exit(1);
  322.         }
  323.     eseek(kmem, (long)unix_nl[X_VAR].n_value, 0);
  324.     eread(kmem, &v, sizeof(v), "var");
  325.     nproc = v.v_proc;
  326.     return;
  327. }
  328.  
  329.  
  330. /*
  331.  * read proc table entry "n" into buffer "p"
  332.  */
  333. procslot(n, p)
  334. int n;
  335. struct proc *p;
  336. {
  337.     eseek(kmem, &((struct proc *) unix_nl[X_PROC].n_value)[n], 0);
  338.     eread(kmem, (char *)p, sizeof(struct proc), "proc");
  339.     return;
  340. }
  341.