diff options
-rw-r--r-- | lib/libkvm/Makefile | 5 | ||||
-rw-r--r-- | lib/libkvm/kvm_cd9660.c | 60 | ||||
-rw-r--r-- | lib/libkvm/kvm_file2.c | 31 | ||||
-rw-r--r-- | lib/libkvm/kvm_private.h | 4 | ||||
-rw-r--r-- | lib/libkvm/kvm_udf.c | 121 |
5 files changed, 193 insertions, 28 deletions
diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile index 1871a9461b6..5a5c60ada1c 100644 --- a/lib/libkvm/Makefile +++ b/lib/libkvm/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.9 2009/06/07 03:09:34 millert Exp $ +# $OpenBSD: Makefile,v 1.10 2009/06/20 19:50:05 millert Exp $ # $NetBSD: Makefile,v 1.11 1996/03/18 22:33:07 thorpej Exp $ # from: @(#)Makefile 8.1 (Berkeley) 6/4/93 @@ -15,7 +15,8 @@ CFLAGS+=-D${MACHINE} SRCS= kvm_${MACHINE_ARCH}.c .endif -SRCS+= kvm.c kvm_file.c kvm_file2.c kvm_getloadavg.c kvm_proc.c +SRCS+= kvm.c kvm_file.c kvm_file2.c kvm_getloadavg.c kvm_proc.c \ + kvm_cd9660.c kvm_udf.c MAN= kvm.3 kvm_dump.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 \ kvm_getprocs.3 kvm_nlist.3 kvm_open.3 kvm_read.3 diff --git a/lib/libkvm/kvm_cd9660.c b/lib/libkvm/kvm_cd9660.c new file mode 100644 index 00000000000..e61079e67d7 --- /dev/null +++ b/lib/libkvm/kvm_cd9660.c @@ -0,0 +1,60 @@ +/* $OpenBSD: kvm_cd9660.c,v 1.1 2009/06/20 19:50:05 millert Exp $ */ + +/* + * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: kvm_cd9660.c,v 1.1 2009/06/20 19:50:05 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/ucred.h> +#define _KERNEL +#include <sys/mount.h> +#undef _KERNEL +#include <sys/vnode.h> +#include <sys/sysctl.h> + +#include <isofs/cd9660/iso.h> +#include <isofs/cd9660/cd9660_extern.h> +#include <isofs/cd9660/cd9660_node.h> + +#include <limits.h> +#include <kvm.h> +#include <db.h> + +#include "kvm_private.h" + +#define KREAD(kd, addr, obj) \ + (kvm_read(kd, addr, obj, sizeof(*obj)) != sizeof(*obj)) + +int +_kvm_stat_cd9660(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) +{ + struct iso_node inode; + + if (KREAD(kd, (u_long)VTOI(vp), &inode)) { + _kvm_err(kd, kd->program, "can't read inode at %p", VTOI(vp)); + return (-1); + } + kf->va_fsid = inode.i_dev & 0xffff; + kf->va_fileid = (long)inode.i_number; + kf->va_mode = inode.inode.iso_mode; + kf->va_size = inode.i_size; + kf->va_rdev = inode.i_dev; + + return (0); +} diff --git a/lib/libkvm/kvm_file2.c b/lib/libkvm/kvm_file2.c index 10e508921cf..00fd9e115d1 100644 --- a/lib/libkvm/kvm_file2.c +++ b/lib/libkvm/kvm_file2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm_file2.c,v 1.6 2009/06/20 13:10:21 millert Exp $ */ +/* $OpenBSD: kvm_file2.c,v 1.7 2009/06/20 19:50:05 millert Exp $ */ /* * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com> @@ -46,7 +46,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: kvm_file2.c,v 1.6 2009/06/20 13:10:21 millert Exp $"; +static char *rcsid = "$OpenBSD: kvm_file2.c,v 1.7 2009/06/20 19:50:05 millert Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -80,10 +80,6 @@ static char *rcsid = "$OpenBSD: kvm_file2.c,v 1.6 2009/06/20 13:10:21 millert Ex #include <sys/stat.h> #include <sys/sysctl.h> -#include <isofs/cd9660/iso.h> -#include <isofs/cd9660/cd9660_extern.h> -#include <isofs/cd9660/cd9660_node.h> - #define _KERNEL #include <ufs/ufs/quota.h> #include <ufs/ufs/inode.h> @@ -811,24 +807,6 @@ spec_filestat(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) } static int -isofs_filestat(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) -{ - struct iso_node inode; - - if (KREAD(kd, (u_long)VTOI(vp), &inode)) { - _kvm_err(kd, kd->program, "can't read inode at %p", VTOI(vp)); - return (-1); - } - kf->va_fsid = inode.i_dev & 0xffff; - kf->va_fileid = (long)inode.i_number; - kf->va_mode = inode.inode.iso_mode; - kf->va_size = inode.i_size; - kf->va_rdev = inode.i_dev; - - return (0); -} - -static int filestat(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) { int ret = 0; @@ -846,7 +824,7 @@ filestat(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) ret = ext2fs_filestat(kd, kf, vp); break; case VT_ISOFS: - ret = isofs_filestat(kd, kf, vp); + ret = _kvm_stat_cd9660(kd, kf, vp); break; case VT_MSDOSFS: ret = msdos_filestat(kd, kf, vp); @@ -854,6 +832,9 @@ filestat(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) case VT_NNPFS: ret = nnpfs_filestat(kd, kf, vp); break; + case VT_UDF: + ret = _kvm_stat_udf(kd, kf, vp); + break; case VT_NON: if (vp->v_flag & VCLONE) ret = spec_filestat(kd, kf, vp); diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h index 6783f3b4ad9..d0b11ff0513 100644 --- a/lib/libkvm/kvm_private.h +++ b/lib/libkvm/kvm_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm_private.h,v 1.12 2009/06/07 03:09:34 millert Exp $ */ +/* $OpenBSD: kvm_private.h,v 1.13 2009/06/20 19:50:05 millert Exp $ */ /* $NetBSD: kvm_private.h,v 1.7 1996/05/05 04:32:15 gwr Exp $ */ /*- @@ -101,3 +101,5 @@ void *_kvm_realloc(kvm_t *kd, void *, size_t); void _kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...); ssize_t _kvm_pread(kvm_t *, int, void *, size_t, off_t); ssize_t _kvm_pwrite(kvm_t *, int, const void *, size_t, off_t); +int _kvm_stat_cd9660(kvm_t *, struct kinfo_file2 *, struct vnode *); +int _kvm_stat_udf(kvm_t *, struct kinfo_file2 *, struct vnode *); diff --git a/lib/libkvm/kvm_udf.c b/lib/libkvm/kvm_udf.c new file mode 100644 index 00000000000..0ebea8916dd --- /dev/null +++ b/lib/libkvm/kvm_udf.c @@ -0,0 +1,121 @@ +/* $OpenBSD: kvm_udf.c,v 1.1 2009/06/20 19:50:05 millert Exp $ */ + +/* + * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: kvm_udf.c,v 1.1 2009/06/20 19:50:05 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/ucred.h> +#define _KERNEL +#include <sys/mount.h> +#undef _KERNEL +#include <sys/vnode.h> +#include <sys/sysctl.h> + +#include <isofs/udf/ecma167-udf.h> +#include <isofs/udf/udf.h> +#include <isofs/udf/udf_extern.h> + +#include <miscfs/specfs/specdev.h> + +#include <stdint.h> +#include <limits.h> +#include <kvm.h> +#include <db.h> + +#include "kvm_private.h" + +#define KREAD(kd, addr, obj) \ + (kvm_read(kd, addr, obj, sizeof(*obj)) != sizeof(*obj)) + +/* Convert file entry permission (5 bits per owner/group/user) to a mode_t */ +static mode_t +udf_permtomode(struct unode *up) +{ + uint32_t perm; + uint16_t flags; + mode_t mode; + + perm = letoh32(up->u_fentry->perm); + flags = letoh16(up->u_fentry->icbtag.flags); + + mode = perm & UDF_FENTRY_PERM_USER_MASK; + mode |= ((perm & UDF_FENTRY_PERM_GRP_MASK) >> 2); + mode |= ((perm & UDF_FENTRY_PERM_OWNER_MASK) >> 4); + mode |= ((flags & UDF_ICB_TAG_FLAGS_STICKY) << 4); + mode |= ((flags & UDF_ICB_TAG_FLAGS_SETGID) << 6); + mode |= ((flags & UDF_ICB_TAG_FLAGS_SETUID) << 8); + + return (mode); +} + +int +_kvm_stat_udf(kvm_t *kd, struct kinfo_file2 *kf, struct vnode *vp) +{ + struct unode up; + struct file_entry fentry; + struct umount um; + + if (KREAD(kd, (u_long)VTOU(vp), &up)) { + _kvm_err(kd, kd->program, "can't read unode at %p", VTOU(vp)); + return (-1); + } + if (KREAD(kd, (u_long)up.u_fentry, &fentry)) { + _kvm_err(kd, kd->program, "can't read file_entry at %p", + up.u_fentry); + return (-1); + } + if (KREAD(kd, (u_long)up.u_ump, &um)) { + _kvm_err(kd, kd->program, "can't read umount at %p", + up.u_ump); + return (-1); + } + kf->va_fsid = up.u_dev; + kf->va_fileid = (long)up.u_ino; + kf->va_mode = udf_permtomode(&up); /* XXX */ + kf->va_rdev = 0; + if (vp->v_type & VDIR) { + /* + * Directories that are recorded within their ICB will show + * as having 0 blocks recorded. Since tradition dictates + * that directories consume at least one logical block, + * make it appear so. + */ + if (fentry.logblks_rec != 0) { + kf->va_size = + letoh64(fentry.logblks_rec) * um.um_bsize; + } else { + kf->va_size = um.um_bsize; + } + } else { + kf->va_size = letoh64(fentry.inf_len); + } + + return (0); +} |