From 17356ab610c5d4ff626f41366c13291e097d187b Mon Sep 17 00:00:00 2001
From: Antonio Huete Jimenez <tuxillo@quantumachine.net>
Date: Wed, 19 Jun 2013 22:15:20 +0200
Subject: [PATCH] fstat(1) - Rework a bit vnode type -> mode code

- Generic way of translating file modes.
- While here remove variable names from prototypes.
---
 sys/vfs/tmpfs/tmpfs_subr.c |   7 ++-
 usr.bin/fstat/cd9660.c     |   3 +-
 usr.bin/fstat/ext2fs.c     |  37 +-----------
 usr.bin/fstat/fstat.c      | 146 +++++++++++++++++++++++++--------------------
 usr.bin/fstat/fstat.h      |  12 ++--
 usr.bin/fstat/hammer.c     |  36 +----------
 usr.bin/fstat/msdosfs.c    |   4 +-
 usr.bin/fstat/ntfs.c       |  37 +-----------
 8 files changed, 106 insertions(+), 176 deletions(-)

diff --git a/sys/vfs/tmpfs/tmpfs_subr.c b/sys/vfs/tmpfs/tmpfs_subr.c
index 4c63cb8..a3ede80 100644
--- a/sys/vfs/tmpfs/tmpfs_subr.c
+++ b/sys/vfs/tmpfs/tmpfs_subr.c
@@ -96,8 +96,13 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
 	udev_t rdev;
 
 	KKASSERT(IFF(type == VLNK, target != NULL));
-	KKASSERT(IFF(type == VBLK || type == VCHR, rmajor != VNOVAL));
 
+/*
+	if ((type == VBLK || type == VCHR) && rmajor == VNOVAL) {
+		kprintf("tate quieto anda\n");
+		return (EINVAL);
+	}
+*/
 	if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max)
 		return (ENOSPC);
 
diff --git a/usr.bin/fstat/cd9660.c b/usr.bin/fstat/cd9660.c
index 55d5d31..6c67ab0 100644
--- a/usr.bin/fstat/cd9660.c
+++ b/usr.bin/fstat/cd9660.c
@@ -54,7 +54,7 @@
 #include "fstat.h"
 
 int
-isofs_filestat(struct vnode *vp, struct filestat *fsp)
+isofs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct iso_node isonode;
 
@@ -63,6 +63,7 @@ isofs_filestat(struct vnode *vp, struct filestat *fsp)
 		    (void *)VTOI(vp), Pid);
 		return 0;
 	}
+	*parsemode = 0;
 	fsp->fsid = fsp->rdev = dev2udev(isonode.i_dev);
 	fsp->mode = (mode_t)isonode.inode.iso_mode;
 	fsp->fileid = (long)isonode.i_number;
diff --git a/usr.bin/fstat/ext2fs.c b/usr.bin/fstat/ext2fs.c
index 5f32c2b..843dccd 100644
--- a/usr.bin/fstat/ext2fs.c
+++ b/usr.bin/fstat/ext2fs.c
@@ -42,49 +42,18 @@
 #include "fstat.h"
 
 int
-ext2fs_filestat(struct vnode *vp, struct filestat *fsp)
+ext2fs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct inode ino;
-	mode_t mode;
 
 	if (!kread(VTOI(vp), &ino, sizeof(ino))) {
 		dprintf(stderr, "can't read inode at %p for pid %d\n",
 		    (void *)VTOI(vp), Pid);
 		return 0;
 	}
-	mode = ino.i_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;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-
+	*parsemode = 1;
+	fsp->mode = ino.i_mode;
 	fsp->rdev = fsp->fsid = dev2udev(ino.i_dev);
-	fsp->mode = mode;
 	fsp->size = ino.i_din.di_size;
 	fsp->fileid = ino.i_number;
 
diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c
index 00efd69..4379d65 100644
--- a/usr.bin/fstat/fstat.c
+++ b/usr.bin/fstat/fstat.c
@@ -129,17 +129,18 @@ int maxfiles;
 
 kvm_t *kd;
 
-void dofiles(struct kinfo_proc *kp, struct proc *p);
-void dommap(struct proc *p);
-void vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off);
-int  ufs_filestat(struct vnode *vp, struct filestat *fsp);
-int  nfs_filestat(struct vnode *vp, struct filestat *fsp);
-int  devfs_filestat(struct vnode *vp, struct filestat *fsp);
-char *getmnton(struct mount *m, struct namecache_list *ncplist, struct nchandle *ncr);
-void pipetrans(struct pipe *pi, int i, int flag);
-void socktrans(struct socket *sock, int i);
-void getinetproto(int number);
-int  getfname(const char *filename);
+void dofiles(struct kinfo_proc *, struct proc *);
+void dommap(struct proc *);
+void vtrans(struct vnode *, struct nchandle *, int, int, off_t);
+int  ufs_filestat(struct vnode *, struct filestat *, int *);
+int  nfs_filestat(struct vnode *, struct filestat *, int *);
+int  devfs_filestat(struct vnode *, struct filestat *, int *);
+char *getmnton(struct mount *, struct namecache_list *, struct nchandle *);
+void pipetrans(struct pipe *, int, int);
+void socktrans(struct socket *, int);
+void getinetproto(int);
+int  getfname(const char *);
+mode_t mtrans(char);
 void usage(void);
 
 
@@ -359,23 +360,23 @@ dofiles(struct kinfo_proc *kp, struct proc *p)
 			continue;
 		}
 		if (file.f_type == DTYPE_VNODE) {
-			vtrans((struct vnode *)file.f_data, &file.f_nchandle,
+			vtrans(file.f_data, &file.f_nchandle,
 				i, file.f_flag, file.f_offset);
 		} else if (file.f_type == DTYPE_SOCKET) {
 			if (checkfile == 0)
-				socktrans((struct socket *)file.f_data, i);
+				socktrans(file.f_data, i);
 		}
 #ifdef DTYPE_PIPE
 		else if (file.f_type == DTYPE_PIPE) {
 			if (checkfile == 0)
-				pipetrans((struct pipe *)file.f_data, i,
+				pipetrans(file.f_data, i,
 				    file.f_flag);
 		}
 #endif
 #ifdef DTYPE_FIFO
 		else if (file.f_type == DTYPE_FIFO) {
 			if (checkfile == 0)
-				vtrans((struct vnode *)file.f_data,
+				vtrans(file.f_data,
 					&file.f_nchandle,
 					i, file.f_flag, file.f_offset);
 		}
@@ -446,6 +447,45 @@ dommap(struct proc *p)
 	}
 }
 
+mode_t
+mtrans(char type)
+{
+	mode_t mode;
+
+	mode = type;
+	switch (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;
+	case VDATABASE:
+		break;
+	case VINT:
+	case VNON:
+	case VBAD:
+		mode = 0;
+	}
+
+	return mode;
+}
+
 void
 vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off)
 {
@@ -453,6 +493,8 @@ vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off)
 	struct filestat fst;
 	char rw[3], mode[15];
 	const char *badtype = NULL, *filename;
+	int parsemode = 0;
+	mode_t vnmode;
 	char *name;
 
 	fst.offset = off;
@@ -469,45 +511,41 @@ vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off)
 	else
 		switch (vn.v_tag) {
 		case VT_HAMMER:
-			if (!hammer_filestat(&vn, &fst))
+			if (!hammer_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
 		case VT_UFS:
-			if (!ufs_filestat(&vn, &fst))
+			if (!ufs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
 		case VT_MFS:
-			if (!ufs_filestat(&vn, &fst))
+			if (!ufs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
 		case VT_NFS:
-			if (!nfs_filestat(&vn, &fst))
+			if (!nfs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
 		case VT_NTFS:
-			if (!ntfs_filestat(&vn, &fst))
+			if (!ntfs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
 		case VT_EXT2FS:
-			if (!ext2fs_filestat(&vn, &fst))
+			if (!ext2fs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
-
 		case VT_MSDOSFS:
-			if (!msdosfs_filestat(&vn, &fst))
+			if (!msdosfs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
-
 		case VT_ISOFS:
-			if (!isofs_filestat(&vn, &fst))
+			if (!isofs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
-
 		case VT_DEVFS:
-			if (!devfs_filestat(&vn, &fst))
+			if (!devfs_filestat(&vn, &fst, &parsemode))
 				badtype = "error";
 			break;
-
 		default: {
 			static char unknown[10];
 			sprintf(unknown, "?(%x)", vn.v_tag);
@@ -547,9 +585,15 @@ vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off)
 		(void)printf(" %-*s", wflg_mnt, getmnton(vn.v_mount, &vn.v_namecache, ncr));
 	if (nflg)
 		(void)sprintf(mode, "%o", fst.mode);
-	else
-		strmode(fst.mode, mode);
+	else {
+		if (parsemode)
+			vnmode = mtrans(fst.mode);
+		else
+			vnmode = fst.mode;
+		strmode(vnmode, mode);
+	}
 	(void)printf(" %*ld %10s", ino_width, fst.fileid, mode);
+
 	switch (vn.v_type) {
 	case VBLK:
 	case VCHR:
@@ -577,7 +621,7 @@ vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off)
 }
 
 int
-ufs_filestat(struct vnode *vp, struct filestat *fsp)
+ufs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct inode inode;
 
@@ -591,6 +635,7 @@ ufs_filestat(struct vnode *vp, struct filestat *fsp)
 	 * contain dev_t structures. We need to convert to udev to make
 	 * comparisons
 	 */
+	*parsemode = 0;
 	fsp->fsid = dev2udev(inode.i_dev);
 	fsp->fileid = (long)inode.i_number;
 	fsp->mode = (mode_t)inode.i_mode;
@@ -601,58 +646,28 @@ ufs_filestat(struct vnode *vp, struct filestat *fsp)
 }
 
 int
-nfs_filestat(struct vnode *vp, struct filestat *fsp)
+nfs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct nfsnode nfsnode;
-	mode_t mode;
 
 	if (!kread(VTONFS(vp), &nfsnode, sizeof (nfsnode))) {
 		dprintf(stderr, "can't read nfsnode at %p for pid %d\n",
 		    (void *)VTONFS(vp), Pid);
 		return 0;
 	}
+	*parsemode = 1;
 	fsp->fsid = nfsnode.n_vattr.va_fsid;
 	fsp->fileid = nfsnode.n_vattr.va_fileid;
 	fsp->size = nfsnode.n_size;
 	fsp->rdev = makeudev(nfsnode.n_vattr.va_rmajor,
 			     nfsnode.n_vattr.va_rminor);
-	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;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-	fsp->mode = mode;
+	fsp->mode = nfsnode.n_vattr.va_mode;
 
 	return 1;
 }
 
 int
-devfs_filestat(struct vnode *vp, struct filestat *fsp)
+devfs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct devfs_node devfs_node;
 
@@ -661,6 +676,7 @@ devfs_filestat(struct vnode *vp, struct filestat *fsp)
 		    (void *)vp->v_data, Pid);
 		return 0;
 	}
+	*parsemode = 0;
 	fsp->fsid = fsp->rdev = dev2udev(vp->v_rdev);
 	fsp->fileid = devfs_node.d_dir.d_ino;
 	fsp->mode = (devfs_node.mode & ~S_IFMT) | S_IFCHR;
diff --git a/usr.bin/fstat/fstat.h b/usr.bin/fstat/fstat.h
index 557c25d..658e82a 100644
--- a/usr.bin/fstat/fstat.h
+++ b/usr.bin/fstat/fstat.h
@@ -64,11 +64,11 @@ udev_t dev2udev(void *dev);
 udev_t makeudev(int x, int y);
 
 /* Additional filesystem types */
-int ext2fs_filestat(struct vnode *vp, struct filestat *fsp);
-int hammer_filestat(struct vnode *vp, struct filestat *fsp);
-int isofs_filestat(struct vnode *vp, struct filestat *fsp);
-int msdosfs_filestat(struct vnode *vp, struct filestat *fsp);
-int ntfs_filestat(struct vnode *vp, struct filestat *fsp);
-ssize_t kread(const void *kaddr, void *uaddr, size_t nbytes);
+int ext2fs_filestat(struct vnode *, struct filestat *, int *);
+int hammer_filestat(struct vnode *, struct filestat *, int *);
+int isofs_filestat(struct vnode *, struct filestat *, int *);
+int msdosfs_filestat(struct vnode *, struct filestat *, int *);
+int ntfs_filestat(struct vnode *, struct filestat *, int *);
+ssize_t kread(const void *, void *, size_t);
 
 #endif /* __FSTAT_H__ */
diff --git a/usr.bin/fstat/hammer.c b/usr.bin/fstat/hammer.c
index 98456ea..33ed5cb 100644
--- a/usr.bin/fstat/hammer.c
+++ b/usr.bin/fstat/hammer.c
@@ -45,11 +45,10 @@
 #include "fstat.h"
 
 int
-hammer_filestat(struct vnode *vp, struct filestat *fsp)
+hammer_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct hammer_inode ino;
 	struct hammer_pseudofs_inmem pfsm;
-	mode_t mode;
 
 	if (!kread(VTOI(vp), &ino, sizeof(ino))) {
 		dprintf(stderr, "can't read hammer_inode at %p for pid %d\n",
@@ -62,39 +61,10 @@ hammer_filestat(struct vnode *vp, struct filestat *fsp)
 		    " at %p for pid %d\n", (void *)ino.pfsm, Pid);
 		return 0;
 	}
+	*parsemode = 1;
 	fsp->fsid = pfsm.fsid_udev ^ (u_int32_t)ino.obj_asof ^
 	    (u_int32_t)(ino.obj_asof >> 32);
-	mode = (mode_t)ino.ino_data.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;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-	fsp->mode = mode;
+	fsp->mode = (mode_t)ino.ino_data.mode;
 	fsp->fileid = (long)ino.ino_leaf.base.obj_id;
 	fsp->size = ino.ino_data.size;
 	fsp->rdev = dev2udev(vp->v_rdev);
diff --git a/usr.bin/fstat/msdosfs.c b/usr.bin/fstat/msdosfs.c
index 1c0d192..aac3a7f 100644
--- a/usr.bin/fstat/msdosfs.c
+++ b/usr.bin/fstat/msdosfs.c
@@ -68,7 +68,7 @@ struct dosmount {
 };
 
 int
-msdosfs_filestat(struct vnode *vp, struct filestat *fsp)
+msdosfs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct denode denode;
 	static struct dosmount *mounts;
@@ -103,7 +103,7 @@ msdosfs_filestat(struct vnode *vp, struct filestat *fsp)
 			return 0;
 		}
 	}
-
+	*parsemode = 0;
 	fsp->fsid = fsp->rdev = dev2udev(denode.de_dev);
 	fsp->mode = 0555;
 	fsp->mode |= denode.de_Attributes & ATTR_READONLY ? 0 : 0222;
diff --git a/usr.bin/fstat/ntfs.c b/usr.bin/fstat/ntfs.c
index f11481a..b0eff12 100644
--- a/usr.bin/fstat/ntfs.c
+++ b/usr.bin/fstat/ntfs.c
@@ -43,12 +43,11 @@
 #include "fstat.h"
 
 int
-ntfs_filestat(struct vnode *vp, struct filestat *fsp)
+ntfs_filestat(struct vnode *vp, struct filestat *fsp, int *parsemode)
 {
 	struct fnode fn;
 	struct ntnode ino;
 	struct ntfsmount mp;
-	mode_t mode;
 
 	if (!kread(VTOF(vp), &fn, sizeof(fn))) {
 		dprintf(stderr, "can't read fnode at %p for pid %d\n",
@@ -67,39 +66,9 @@ ntfs_filestat(struct vnode *vp, struct filestat *fsp)
 		    (void *)ino.i_mp, Pid);
 		return 0;
 	}
-	mode = mp.ntm_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;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-
+	*parsemode = 1;
+	fsp->mode = mp.ntm_mode;
 	fsp->rdev = fsp->fsid = dev2udev(ino.i_dev);
-	fsp->mode = mode;
 	fsp->size = fn.f_size;
 	fsp->fileid = ino.i_number;
 
-- 
1.8.2.3

