[BACK]Return to fstat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / fstat

Diff for /src/usr.bin/fstat/fstat.c between version 1.67 and 1.68

version 1.67, 2009/06/15 04:19:59 version 1.68, 2009/07/08 16:04:00
Line 46 
Line 46 
  */   */
   
 #ifndef lint  #ifndef lint
 static char copyright[] =  static const char copyright[] =
 "@(#) Copyright (c) 1988, 1993\n\  "@(#) Copyright (c) 1988, 1993\n\
         The Regents of the University of California.  All rights reserved.\n";          The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */  #endif /* not lint */
   
 #ifndef lint  #ifndef lint
 /*static char sccsid[] = "from: @(#)fstat.c     8.1 (Berkeley) 6/6/93";*/  /*static const char sccsid[] = "from: @(#)fstat.c       8.1 (Berkeley) 6/6/93";*/
 static char *rcsid = "$OpenBSD$";  static const char rcsid[] = "$OpenBSD$";
 #endif /* not lint */  #endif /* not lint */
   
 #include <sys/param.h>  #include <sys/param.h>
   #include <sys/queue.h>
   #include <sys/mount.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/vnode.h>  #include <sys/vnode.h>
 #include <sys/socket.h>  #include <sys/socket.h>
Line 82 
Line 84 
 #include <limits.h>  #include <limits.h>
 #include <nlist.h>  #include <nlist.h>
 #include <pwd.h>  #include <pwd.h>
   #include <signal.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdint.h>  #include <stdint.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 89 
Line 92 
 #include <unistd.h>  #include <unistd.h>
 #include <err.h>  #include <err.h>
   
 typedef struct devs {  #include "fstat.h"
         struct  devs *next;  
         long    fsid;  
         ino_t   ino;  
         char    *name;  
 } DEVS;  
 DEVS *devs;  
   
   struct fileargs fileargs = SLIST_HEAD_INITIALIZER(fileargs);
   
 int     fsflg;  /* show files on same filesystem as file(s) argument */  int     fsflg;  /* show files on same filesystem as file(s) argument */
 int     pflg;   /* show files open by a particular pid */  int     pflg;   /* show files open by a particular pid */
 int     uflg;   /* show files open by a particular (effective) user */  int     uflg;   /* show files open by a particular (effective) user */
Line 105 
Line 104 
 int     oflg;   /* display file offset */  int     oflg;   /* display file offset */
 int     sflg;   /* display file xfer/bytes counters */  int     sflg;   /* display file xfer/bytes counters */
 int     vflg;   /* display errors in locating kernel data objects etc... */  int     vflg;   /* display errors in locating kernel data objects etc... */
   int     cflg;   /* fuser only */
   
   int     fuser;  /* 1 if we are fuser, 0 if we are fstat */
   int     signo;  /* signal to send (fuser only) */
   
 kvm_t *kd;  kvm_t *kd;
 uid_t uid;  uid_t uid;
   
   void fstat_dofile(struct kinfo_file2 *);
 void dofiles(struct kinfo_file2 *);  void fstat_header(void);
   void fuser_dofile(struct kinfo_file2 *);
 void getinetproto(int);  void getinetproto(int);
 void usage(void);  void usage(void);
 int getfname(char *);  int getfname(char *);
Line 121 
Line 125 
 void systracetrans(struct kinfo_file2 *);  void systracetrans(struct kinfo_file2 *);
 void vtrans(struct kinfo_file2 *);  void vtrans(struct kinfo_file2 *);
 const char *inet6_addrstr(struct in6_addr *);  const char *inet6_addrstr(struct in6_addr *);
   int signame_to_signum(char *);
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
Line 128 
Line 133 
         struct passwd *passwd;          struct passwd *passwd;
         struct kinfo_file2 *kf, *kflast;          struct kinfo_file2 *kf, *kflast;
         int arg, ch, what;          int arg, ch, what;
         char *memf, *nlistf;          char *memf, *nlistf, *optstr;
         char buf[_POSIX2_LINE_MAX];          char buf[_POSIX2_LINE_MAX];
         const char *errstr;          const char *errstr;
         int cnt, flags;          int cnt, flags;
Line 137 
Line 142 
         what = KERN_FILE_BYPID;          what = KERN_FILE_BYPID;
         nlistf = memf = NULL;          nlistf = memf = NULL;
         oflg = 0;          oflg = 0;
         while ((ch = getopt(argc, argv, "fnop:su:vN:M:")) != -1)  
           /* are we fstat(1) or fuser(1)? */
           if (strcmp(__progname, "fuser") == 0) {
                   fuser = 1;
                   optstr = "cfks:uM:N:";
           } else {
                   fuser = 0;
                   optstr = "fnop:su:vN:M:";
           }
   
           /*
            * fuser and fstat share three flags: -f, -s and -u.  In both cases
            * -f is a boolean, but for -u fstat wants an argument while fuser
            * does not and for -s fuser wants an argument whereas fstat does not.
            */
           while ((ch = getopt(argc, argv, optstr)) != -1)
                 switch ((char)ch) {                  switch ((char)ch) {
                   case 'c':
                           if (fsflg)
                                   usage();
                           cflg = 1;
                           break;
                 case 'f':                  case 'f':
                           if (cflg)
                                   usage();
                         fsflg = 1;                          fsflg = 1;
                         break;                          break;
                   case 'k':
                           sflg = 1;
                           signo = SIGKILL;
                           break;
                 case 'M':                  case 'M':
                         memf = optarg;                          memf = optarg;
                         break;                          break;
Line 167 
Line 198 
                         break;                          break;
                 case 's':                  case 's':
                         sflg = 1;                          sflg = 1;
                           if (fuser) {
                                   signo = signame_to_signum(optarg);
                                   if (signo == -1) {
                                           warnx("invalid signal %s", optarg);
                                           usage();
                                   }
                           }
                         break;                          break;
                 case 'u':                  case 'u':
                         if (uflg++)                          if (uflg++)
                                 usage();                                  usage();
                         if (!(passwd = getpwnam(optarg)))                          if (!fuser) {
                                 errx(1, "%s: unknown uid", optarg);                                  if (!(passwd = getpwnam(optarg)))
                         what = KERN_FILE_BYUID;                                          errx(1, "%s: unknown uid", optarg);
                         arg = passwd->pw_uid;                                  what = KERN_FILE_BYUID;
                                   arg = passwd->pw_uid;
                           }
                         break;                          break;
                 case 'v':                  case 'v':
                         vflg = 1;                          vflg = 1;
Line 204 
Line 244 
                         if (getfname(*argv))                          if (getfname(*argv))
                                 checkfile = 1;                                  checkfile = 1;
                 }                  }
                 if (!checkfile) /* file(s) specified, but none accessible */                  /* file(s) specified, but none accessible */
                   if (!checkfile)
                         exit(1);                          exit(1);
         }          } else if (fuser)
                   usage();
   
         if (fsflg && !checkfile) {          if (!fuser && fsflg && !checkfile) {
                 /* -f with no files means use wd */                  /* fstat -f with no files means use wd */
                 if (getfname(".") == 0)                  if (getfname(".") == 0)
                         exit(1);                          exit(1);
                 checkfile = 1;                  checkfile = 1;
Line 217 
Line 259 
   
         if ((kf = kvm_getfile2(kd, what, arg, sizeof(*kf), &cnt)) == NULL)          if ((kf = kvm_getfile2(kd, what, arg, sizeof(*kf), &cnt)) == NULL)
                 errx(1, "%s", kvm_geterr(kd));                  errx(1, "%s", kvm_geterr(kd));
   
           if (!fuser)
                   fstat_header();
           for (kflast = &kf[cnt]; kf < kflast; ++kf) {
                   if (fuser)
                           fuser_check(kf);
                   else
                           fstat_dofile(kf);
           }
           if (fuser)
                   fuser_run();
   
           exit(0);
   }
   
   void
   fstat_header(void)
   {
         if (nflg)          if (nflg)
                 printf("%s",                  printf("%s",
 "USER     CMD          PID   FD  DEV      INUM       MODE R/W    SZ|DV");  "USER     CMD          PID   FD  DEV      INUM       MODE R/W    SZ|DV");
Line 230 
Line 290 
         if (sflg)          if (sflg)
                 printf("    XFERS   KBYTES");                  printf("    XFERS   KBYTES");
         putchar('\n');          putchar('\n');
   
         for (kflast = &kf[cnt]; kf < kflast; ++kf)  
                 dofiles(kf);  
         exit(0);  
 }  }
   
 char    *Uname, *Comm;  char    *Uname, *Comm;
Line 265 
Line 321 
  * print open files attributed to this process   * print open files attributed to this process
  */   */
 void  void
 dofiles(struct kinfo_file2 *kf)  fstat_dofile(struct kinfo_file2 *kf)
 {  {
   
         Uname = user_from_uid(kf->p_uid, 0);          Uname = user_from_uid(kf->p_uid, 0);
Line 322 
Line 378 
   
         if (checkfile) {          if (checkfile) {
                 int fsmatch = 0;                  int fsmatch = 0;
                 DEVS *d;                  struct filearg *fa;
   
                 if (badtype)                  if (badtype)
                         return;                          return;
                 for (d = devs; d != NULL; d = d->next) {                  SLIST_FOREACH(fa, &fileargs, next) {
                         if (d->fsid == kf->va_fsid) {                          if (fa->dev == kf->va_fsid) {
                                 fsmatch = 1;                                  fsmatch = 1;
                                 if (d->ino == kf->va_fileid) {                                  if (fa->ino == kf->va_fileid) {
                                         filename = d->name;                                          filename = fa->name;
                                         break;                                          break;
                                 }                                  }
                         }                          }
Line 537 
Line 593 
                 memcpy(&faddr, kf->inp_faddru, sizeof(faddr));                  memcpy(&faddr, kf->inp_faddru, sizeof(faddr));
                 getinetproto(kf->so_protocol);                  getinetproto(kf->so_protocol);
                 if (kf->so_protocol == IPPROTO_TCP) {                  if (kf->so_protocol == IPPROTO_TCP) {
                         printf(" %p", kf->inp_ppcb);                          printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
                         printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :                          printf(" %s:%d", laddr.s_addr == INADDR_ANY ? "*" :
                             inet_ntoa(laddr), ntohs(kf->inp_lport));                              inet_ntoa(laddr), ntohs(kf->inp_lport));
                         if (kf->inp_fport) {                          if (kf->inp_fport) {
Line 558 
Line 614 
                                     inet_ntoa(faddr), ntohs(kf->inp_fport));                                      inet_ntoa(faddr), ntohs(kf->inp_fport));
                         }                          }
                 } else if (kf->so_pcb)                  } else if (kf->so_pcb)
                         printf(" %p", kf->so_pcb);                          printf(" %p", (void *)(uintptr_t)kf->so_pcb);
                 break;                  break;
 #ifdef INET6  #ifdef INET6
         case AF_INET6:          case AF_INET6:
Line 567 
Line 623 
                 memcpy(&faddr6, kf->inp_faddru, sizeof(faddr6));                  memcpy(&faddr6, kf->inp_faddru, sizeof(faddr6));
                 getinetproto(kf->so_protocol);                  getinetproto(kf->so_protocol);
                 if (kf->so_protocol == IPPROTO_TCP) {                  if (kf->so_protocol == IPPROTO_TCP) {
                         printf(" %p", kf->inp_ppcb);                          printf(" %p", (void *)(uintptr_t)kf->inp_ppcb);
                         snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",                          snprintf(xaddrbuf, sizeof(xaddrbuf), "[%s]",
                             inet6_addrstr(&laddr6));                              inet6_addrstr(&laddr6));
                         printf(" %s:%d",                          printf(" %s:%d",
Line 598 
Line 654 
                                     xaddrbuf, ntohs(kf->inp_fport));                                      xaddrbuf, ntohs(kf->inp_fport));
                         }                          }
                 } else if (kf->so_pcb)                  } else if (kf->so_pcb)
                         printf(" %p", kf->so_pcb);                          printf(" %p", (void *)(uintptr_t)kf->so_pcb);
                 break;                  break;
 #endif  #endif
         case AF_UNIX:          case AF_UNIX:
                 /* print address of pcb and connected pcb */                  /* print address of pcb and connected pcb */
                 printf("* unix %s", stype);                  printf("* unix %s", stype);
                 if (kf->so_pcb) {                  if (kf->so_pcb) {
                         printf(" %p", kf->so_pcb);                          printf(" %p", (void *)(uintptr_t)kf->so_pcb);
                         if (kf->unp_conn) {                          if (kf->unp_conn) {
                                 char shoconn[4], *cp;                                  char shoconn[4], *cp;
   
Line 686 
Line 742 
 int  int
 getfname(char *filename)  getfname(char *filename)
 {  {
         struct stat statbuf;          static struct statfs *mntbuf;
         DEVS *cur;          static int nmounts;
           int i;
           struct stat sb;
           struct filearg *cur;
   
         if (stat(filename, &statbuf)) {          if (stat(filename, &sb)) {
                 warn("%s", filename);                  warn("%s", filename);
                 return(0);                  return (0);
         }          }
         if ((cur = malloc(sizeof(DEVS))) == NULL)  
                 err(1, "malloc");  
         cur->next = devs;  
         devs = cur;  
   
         cur->ino = statbuf.st_ino;          /*
         cur->fsid = statbuf.st_dev & 0xffff;           * POSIX specifies "For block special devices, all processes using any
            * file on that device are listed".  However the -f flag description
            * states "The report shall be only for the named files", so we only
            * look up a block device if the -f flag has not be specified.
            */
           if (fuser && !fsflg && S_ISBLK(sb.st_mode)) {
                   if (mntbuf == NULL) {
                           nmounts = getmntinfo(&mntbuf, MNT_NOWAIT);
                           if (nmounts == -1)
                                   err(1, "getmntinfo");
                   }
                   for (i = 0; i < nmounts; i++) {
                           if (!strcmp(mntbuf[i].f_mntfromname, filename)) {
                                   if (stat(mntbuf[i].f_mntonname, &sb) == -1) {
                                           warn("%s", filename);
                                           return (0);
                                   }
                                   cflg = 1;
                                   break;
                           }
                   }
           }
   
           if ((cur = malloc(sizeof(*cur))) == NULL)
                   err(1, NULL);
   
           cur->ino = sb.st_ino;
           cur->dev = sb.st_dev & 0xffff;
         cur->name = filename;          cur->name = filename;
         return(1);          TAILQ_INIT(&cur->fusers);
           SLIST_INSERT_HEAD(&fileargs, cur, next);
           return (1);
 }  }
   
   int
   signame_to_signum(char *sig)
   {
           int n;
           const char *errstr = NULL;
   
           if (isdigit((unsigned char)*sig)) {
                   n = strtonum(sig, 0, NSIG - 1, &errstr);
                   return (errstr ? -1 : n);
           }
           if (!strncasecmp(sig, "sig", 3))
                   sig += 3;
           for (n = 1; n < NSIG; n++) {
                   if (!strcasecmp(sys_signame[n], sig))
                           return (n);
           }
           return (-1);
   }
   
 void  void
 usage(void)  usage(void)
 {  {
         fprintf(stderr, "usage: fstat [-fnosv] [-M core] [-N system] "          if (fuser) {
             "[-p pid] [-u user] [file ...]\n");                  fprintf(stderr, "usage: fuser [-cfku] [-M core] "
                       "[-N system] [-s signal] file ...\n");
           } else {
                   fprintf(stderr, "usage: fstat [-fnosv] [-M core] [-N system] "
                       "[-p pid] [-u user] [file ...]\n");
           }
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.67  
changed lines
  Added in v.1.68