From d073c75df5afca85c621a7f89f1e1ff45a1835b4 Mon Sep 17 00:00:00 2001 From: green Date: Thu, 16 Mar 2000 02:02:34 +0000 Subject: Support more filesystems in fstat(1): now you can use fstat(1) to find out if files on msdosfs and cd9660 filestores are open. There was also a movement of some common things to a header, a small cleanup. PR: bin/16364 bin/7043 Submitted by: Peter Edwards --- usr.bin/fstat/Makefile | 1 + usr.bin/fstat/cd9660.c | 78 +++++++++++++++++++++++++ usr.bin/fstat/fstat.c | 36 +++++------- usr.bin/fstat/fstat.h | 73 +++++++++++++++++++++++ usr.bin/fstat/msdosfs.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 22 deletions(-) create mode 100644 usr.bin/fstat/cd9660.c create mode 100644 usr.bin/fstat/fstat.h create mode 100644 usr.bin/fstat/msdosfs.c (limited to 'usr.bin') diff --git a/usr.bin/fstat/Makefile b/usr.bin/fstat/Makefile index 8e9e277..ae51fb6 100644 --- a/usr.bin/fstat/Makefile +++ b/usr.bin/fstat/Makefile @@ -2,6 +2,7 @@ # $FreeBSD$ PROG= fstat +SRCS= cd9660.c fstat.c msdosfs.c CFLAGS+=-Wall CFLAGS+=-I${.CURDIR}/../../sys DPADD= ${LIBKVM} diff --git a/usr.bin/fstat/cd9660.c b/usr.bin/fstat/cd9660.c new file mode 100644 index 0000000..0d739a6 --- /dev/null +++ b/usr.bin/fstat/cd9660.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000 Peter Edwards + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by Peter Edwards + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * XXX - + * This had to be separated from fstat.c because cd9660s has namespace + * conflicts with UFS. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "fstat.h" + +int +isofs_filestat(vp, fsp) + struct vnode *vp; + struct filestat *fsp; +{ + struct iso_node isonode; + + if (!KVM_READ(VTOI(vp), &isonode, sizeof (isonode))) { + dprintf(stderr, "can't read iso_node at %p for pid %d\n", + (void *)VTOI(vp), Pid); + return 0; + } + fsp->fsid = dev2udev(isonode.i_dev) & 0xffff; + fsp->mode = (mode_t)isonode.inode.iso_mode; + fsp->rdev = isonode.i_dev; + + fsp->fileid = (long)isonode.i_number; + fsp->size = (u_long)isonode.i_size; + return 1; +} + diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index ec8df44..c600198 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -73,6 +73,7 @@ static const char rcsid[] = #include #include + #include #include #include @@ -93,27 +94,15 @@ static const char rcsid[] = #include #include +#include "fstat.h" + #define TEXT -1 #define CDIR -2 #define RDIR -3 #define TRACE -4 -typedef struct devs { - struct devs *next; - long fsid; - ino_t ino; - char *name; -} DEVS; DEVS *devs; -struct filestat { - long fsid; - long fileid; - mode_t mode; - u_long size; - dev_t rdev; -}; - #ifdef notdef struct nlist nl[] = { { "" }, @@ -127,7 +116,6 @@ int checkfile; /* true if restricting to particular files or filesystems */ int nflg; /* (numerical) display f.s. and rdev as dev_t */ int vflg; /* display errors in locating kernel data objects etc... */ -#define dprintf if (vflg) fprintf struct file **ofiles; /* buffer of pointers to file structures */ int maxfiles; @@ -141,12 +129,6 @@ int maxfiles; maxfiles = (d); \ } -/* - * a kvm_read that returns true if everything is read - */ -#define KVM_READ(kaddr, paddr, len) \ - (kvm_read(kd, (u_long)(kaddr), (char *)(paddr), (len)) == (len)) - kvm_t *kd; void dofiles __P((struct kinfo_proc *kp)); @@ -158,7 +140,6 @@ void pipetrans __P((struct pipe *pi, int i, int flag)); void socktrans __P((struct socket *sock, int i)); void getinetproto __P((int number)); int getfname __P((char *filename)); -udev_t dev2udev __P((dev_t dev)); void usage __P((void)); @@ -414,6 +395,17 @@ vtrans(vp, i, flag) if (!nfs_filestat(&vn, &fst)) badtype = "error"; break; + + case VT_MSDOSFS: + if (!msdosfs_filestat(&vn, &fst)) + badtype = "error"; + break; + + case VT_ISOFS: + if (!isofs_filestat(&vn, &fst)) + badtype = "error"; + break; + default: { static char unknown[10]; sprintf(badtype = unknown, "?(%x)", vn.v_tag); diff --git a/usr.bin/fstat/fstat.h b/usr.bin/fstat/fstat.h new file mode 100644 index 0000000..02ce12a --- /dev/null +++ b/usr.bin/fstat/fstat.h @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __FSTAT_H__ +#define __FSTAT_H__ + +/* + * a kvm_read that returns true if everything is read + */ +#define KVM_READ(kaddr, paddr, len) \ + (kvm_read(kd, (u_long)(kaddr), (char *)(paddr), (len)) == (len)) + +#define dprintf if (vflg) fprintf + +typedef struct devs { + struct devs *next; + long fsid; + ino_t ino; + char *name; +} DEVS; + +struct filestat { + long fsid; + long fileid; + mode_t mode; + u_long size; + dev_t rdev; +}; + +/* Ugh */ +extern kvm_t *kd; +extern int vflg; +extern int Pid; + +udev_t dev2udev __P((dev_t dev)); + +/* Additional filesystem types */ +int isofs_filestat __P((struct vnode *vp, struct filestat *fsp)); +int msdosfs_filestat __P((struct vnode *vp, struct filestat *fsp)); + +#endif /* __FSTAT_H__ */ diff --git a/usr.bin/fstat/msdosfs.c b/usr.bin/fstat/msdosfs.c new file mode 100644 index 0000000..809477d --- /dev/null +++ b/usr.bin/fstat/msdosfs.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2000 Peter Edwards + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by Peter Edwards + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#define _KERNEL +#include +#include +#include +#undef _KERNEL + +#include +#include +#include + +#include +#include +#include +#include + +/* + * XXX - + * VTODE is defined in denode.h only if _KERNEL is defined, but that leads to + * header explosion + */ +#define VTODE(vp) ((struct denode *)(vp)->v_data) + +#include "fstat.h" + +struct dosmount { + struct dosmount *next; + struct msdosfsmount *kptr; /* Pointer in kernel space */ + struct msdosfsmount data; /* User space copy of structure */ +}; + +int +msdosfs_filestat(vp, fsp) + struct vnode *vp; + struct filestat *fsp; +{ + struct denode denode; + static struct dosmount *mounts; + struct dosmount *mnt; + u_long dirsperblk; + int fileid; + + if (!KVM_READ(VTODE(vp), &denode, sizeof (denode))) { + dprintf(stderr, "can't read denode at %p for pid %d\n", + (void *)VTODE(vp), Pid); + return 0; + } + + /* + * Find msdosfsmount structure for the vnode's filesystem. Needed + * for some filesystem parameters + */ + for (mnt = mounts; mnt; mnt = mnt->next) + if (mnt->kptr == denode.de_pmp) + break; + + if (!mnt) { + if ((mnt = malloc(sizeof(struct dosmount))) == NULL) + err(1, NULL); + mnt->next = mounts; + mounts = mnt; + mnt->kptr = denode.de_pmp; + if (!KVM_READ(denode.de_pmp, &mnt->data, sizeof mnt->data)) { + dprintf(stderr, + "can't read mount info at %p for pid %d\n", + (void *)denode.de_pmp, Pid); + return 0; + } + } + + fsp->fsid = dev2udev(denode.de_dev) & 0xffff; + fsp->mode = 0555; + fsp->mode |= denode.de_Attributes & ATTR_READONLY ? 0 : 0222; + fsp->mode &= mnt->data.pm_mask; + + /* Distinguish directories and files. No "special" files in FAT. */ + fsp->mode |= denode.de_Attributes & ATTR_DIRECTORY ? S_IFDIR : S_IFREG; + + fsp->size = denode.de_FileSize; + fsp->rdev = denode.de_dev; + + /* + * XXX - + * Culled from msdosfs_vnops.c. There appears to be a problem + * here, in that a directory has the same inode number as the first + * file in the directory. stat(2) suffers from this problem also, so + * I won't try to fix it here. + * + * The following computation of the fileid must be the same as that + * used in msdosfs_readdir() to compute d_fileno. If not, pwd + * doesn't work. + */ + dirsperblk = mnt->data.pm_BytesPerSec / sizeof(struct direntry); + if (denode.de_Attributes & ATTR_DIRECTORY) { + fileid = cntobn(&mnt->data, denode.de_StartCluster) + * dirsperblk; + if (denode.de_StartCluster == MSDOSFSROOT) + fileid = 1; + } else { + fileid = cntobn(&mnt->data, denode.de_dirclust) * dirsperblk; + if (denode.de_dirclust == MSDOSFSROOT) + fileid = roottobn(&mnt->data, 0) * dirsperblk; + fileid += denode.de_diroffset / sizeof(struct direntry); + } + + fsp->fileid = fileid; + return 1; +} -- cgit v1.1