📄 fstat.c
字号:
filename = badtype = NULL; if (!KVM_READ(vp, &vn, sizeof (struct vnode))) { dprintf(stderr, "can't read vnode at %x for pid %d\n", vp, Pid); return; } if (vn.v_type == VNON || vn.v_tag == VT_NON) badtype = "none"; else if (vn.v_type == VBAD) badtype = "bad"; else switch (vn.v_tag) { case VT_UFS: if (!ufs_filestat(&vn, &fst)) badtype = "error"; break; case VT_MFS: if (!ufs_filestat(&vn, &fst)) badtype = "error"; break; case VT_NFS: if (!nfs_filestat(&vn, &fst)) badtype = "error"; break; default: { static char unknown[10]; sprintf(badtype = unknown, "?(%x)", vn.v_tag); break;; } } if (checkfile) { int fsmatch = 0; register DEVS *d; if (badtype) return; for (d = devs; d != NULL; d = d->next) if (d->fsid == fst.fsid) { fsmatch = 1; if (d->ino == fst.fileid) { filename = d->name; break; } } if (fsmatch == 0 || (filename == NULL && fsflg == 0)) return; } PREFIX(i); if (badtype) { (void)printf(" - - %10s -\n", badtype); return; } if (nflg) (void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid)); else (void)printf(" %-8s", getmnton(vn.v_mount)); if (nflg) (void)sprintf(mode, "%o", fst.mode); else strmode(fst.mode, mode); (void)printf(" %6d %10s", fst.fileid, mode); switch (vn.v_type) { case VBLK: case VCHR: { char *name; if (nflg || ((name = devname(fst.rdev, vn.v_type == VCHR ? S_IFCHR : S_IFBLK)) == NULL)) printf(" %2d,%-2d", major(fst.rdev), minor(fst.rdev)); else printf(" %6s", name); break; } default: printf(" %6d", fst.size); } rw[0] = '\0'; if (flag & FREAD) strcat(rw, "r"); if (flag & FWRITE) strcat(rw, "w"); printf(" %2s", rw); if (filename && !fsflg) printf(" %s", filename); putchar('\n');}intufs_filestat(vp, fsp) struct vnode *vp; struct filestat *fsp;{ struct inode inode; if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) { dprintf(stderr, "can't read inode at %x for pid %d\n", VTOI(vp), Pid); return 0; } fsp->fsid = inode.i_dev & 0xffff; fsp->fileid = (long)inode.i_number; fsp->mode = (mode_t)inode.i_mode; fsp->size = (u_long)inode.i_size; fsp->rdev = inode.i_rdev; return 1;}intnfs_filestat(vp, fsp) struct vnode *vp; struct filestat *fsp;{ struct nfsnode nfsnode; register mode_t mode; if (!KVM_READ(VTONFS(vp), &nfsnode, sizeof (nfsnode))) { dprintf(stderr, "can't read nfsnode at %x for pid %d\n", VTONFS(vp), Pid); return 0; } fsp->fsid = nfsnode.n_vattr.va_fsid; fsp->fileid = nfsnode.n_vattr.va_fileid; fsp->size = nfsnode.n_size; fsp->rdev = nfsnode.n_vattr.va_rdev; mode = (mode_t)nfsnode.n_vattr.va_mode; switch (vp->v_type) { case VREG: mode |= S_IFREG; break; case VDIR: mode |= S_IFDIR; break; case VBLK: mode |= S_IFBLK; break; case VCHR: mode |= S_IFCHR; break; case VLNK: mode |= S_IFLNK; break; case VSOCK: mode |= S_IFSOCK; break; case VFIFO: mode |= S_IFIFO; break; }; fsp->mode = mode; return 1;}char *getmnton(m) struct mount *m;{ static struct mount mount; static struct mtab { struct mtab *next; struct mount *m; char mntonname[MNAMELEN]; } *mhead = NULL; register struct mtab *mt; for (mt = mhead; mt != NULL; mt = mt->next) if (m == mt->m) return (mt->mntonname); if (!KVM_READ(m, &mount, sizeof(struct mount))) { fprintf(stderr, "can't read mount table at %x\n", m); return (NULL); } if ((mt = malloc(sizeof (struct mtab))) == NULL) { fprintf(stderr, "fstat: %s\n", strerror(errno)); exit(1); } mt->m = m; bcopy(&mount.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN); mt->next = mhead; mhead = mt; return (mt->mntonname);}voidsocktrans(sock, i) struct socket *sock; int i;{ static char *stypename[] = { "unused", /* 0 */ "stream", /* 1 */ "dgram", /* 2 */ "raw", /* 3 */ "rdm", /* 4 */ "seqpak" /* 5 */ };#define STYPEMAX 5 struct socket so; struct protosw proto; struct domain dom; struct inpcb inpcb; struct unpcb unpcb; int len; char dname[32], *strcpy(); PREFIX(i); /* fill in socket */ if (!KVM_READ(sock, &so, sizeof(struct socket))) { dprintf(stderr, "can't read sock at %x\n", sock); goto bad; } /* fill in protosw entry */ if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) { dprintf(stderr, "can't read protosw at %x", so.so_proto); goto bad; } /* fill in domain */ if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) { dprintf(stderr, "can't read domain at %x\n", proto.pr_domain); goto bad; } if ((len = kvm_read(kd, (u_long)dom.dom_name, dname, sizeof(dname) - 1)) < 0) { dprintf(stderr, "can't read domain name at %x\n", dom.dom_name); dname[0] = '\0'; } else dname[len] = '\0'; if ((u_short)so.so_type > STYPEMAX) printf("* %s ?%d", dname, so.so_type); else printf("* %s %s", dname, stypename[so.so_type]); /* * protocol specific formatting * * Try to find interesting things to print. For tcp, the interesting * thing is the address of the tcpcb, for udp and others, just the * inpcb (socket pcb). For unix domain, its the address of the socket * pcb and the address of the connected pcb (if connected). Otherwise * just print the protocol number and address of the socket itself. * The idea is not to duplicate netstat, but to make available enough * information for further analysis. */ switch(dom.dom_family) { case AF_INET: getinetproto(proto.pr_protocol); if (proto.pr_protocol == IPPROTO_TCP ) { if (so.so_pcb) { if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb, sizeof(struct inpcb)) != sizeof(struct inpcb)) { dprintf(stderr, "can't read inpcb at %x\n", so.so_pcb); goto bad; } printf(" %x", (int)inpcb.inp_ppcb); } } else if (so.so_pcb) printf(" %x", (int)so.so_pcb); break; case AF_UNIX: /* print address of pcb and connected pcb */ if (so.so_pcb) { printf(" %x", (int)so.so_pcb); if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb, sizeof(struct unpcb)) != sizeof(struct unpcb)){ dprintf(stderr, "can't read unpcb at %x\n", so.so_pcb); goto bad; } if (unpcb.unp_conn) { char shoconn[4], *cp; cp = shoconn; if (!(so.so_state & SS_CANTRCVMORE)) *cp++ = '<'; *cp++ = '-'; if (!(so.so_state & SS_CANTSENDMORE)) *cp++ = '>'; *cp = '\0'; printf(" %s %x", shoconn, (int)unpcb.unp_conn); } } break; default: /* print protocol number and socket address */ printf(" %d %x", proto.pr_protocol, (int)sock); } printf("\n"); return;bad: printf("* error\n");}/* * getinetproto -- * print name of protocol number */voidgetinetproto(number) int number;{ char *cp; switch(number) { case IPPROTO_IP: cp = "ip"; break; case IPPROTO_ICMP: cp ="icmp"; break; case IPPROTO_GGP: cp ="ggp"; break; case IPPROTO_TCP: cp ="tcp"; break; case IPPROTO_EGP: cp ="egp"; break; case IPPROTO_PUP: cp ="pup"; break; case IPPROTO_UDP: cp ="udp"; break; case IPPROTO_IDP: cp ="idp"; break; case IPPROTO_RAW: cp ="raw"; break; default: printf(" %d", number); return; } printf(" %s", cp);}getfname(filename) char *filename;{ struct stat statbuf; DEVS *cur; if (stat(filename, &statbuf)) { fprintf(stderr, "fstat: %s: %s\n", filename, strerror(errno)); return(0); } if ((cur = malloc(sizeof(DEVS))) == NULL) { fprintf(stderr, "fstat: %s\n", strerror(errno)); exit(1); } cur->next = devs; devs = cur; cur->ino = statbuf.st_ino; cur->fsid = statbuf.st_dev & 0xffff; cur->name = filename; return(1);}voidusage(){ (void)fprintf(stderr, "usage: fstat [-fnv] [-p pid] [-u user] [-N system] [-M core] [file ...]\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -