Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 May 2002 11:01:15 -0700 (PDT)
From:      Paul Herman <pherman@frenchfries.net>
To:        Giorgos Keramidas <keramida@ceid.upatras.gr>
Cc:        Bakul Shah <bakul@bitblocks.com>, <current@FreeBSD.ORG>
Subject:   Re: new fstat(1) feature (was Re: mergemaster(8) broken -- uses Perl)
Message-ID:  <20020519105046.T3802-100000@mammoth.eat.frenchfries.net>
In-Reply-To: <20020519120719.GA33585@hades.hell.gr>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

Here's the final fstat(1) patch which obeys the '-n' switch.
Inodes have a lot on info, so the output is very long.  Please nit
pick on the code, including any style(9) violations you see.

Bakul, I really like your "stat -a" because the output is compact,
but it's not as readable.  /me wonders if there's a happy medium...

-Paul.

Index: fstat.1
===================================================================
RCS file: /u02/ncvs/src/usr.bin/fstat/fstat.1,v
retrieving revision 1.9.2.6
diff -u -r1.9.2.6 fstat.1
--- fstat.1	16 Apr 2002 19:53:35 -0000	1.9.2.6
+++ fstat.1	19 May 2002 17:48:19 -0000
@@ -87,6 +87,10 @@
 and print the mode of the file in octal instead of symbolic form.
 .It Fl p
 Report all files open by the specified process.
+.It Fl s
+Print
+.Xr stat 2
+contents of files given on the command line.
 .It Fl u
 Report all files open by the specified user.
 .It Fl v
@@ -181,6 +185,42 @@
 .Xr ln 1 ) ,
 the name printed may not be the actual
 name that the process originally used to open that file.
+.El
+.Pp
+unless the
+.Fl s
+option is given in which case the following is printed:
+.Bl -tag -width DEV\&|MOUNT
+.It Li INODE
+The inode number of the file.
+.It Li DEV\&|MOUNT
+The device number the file resides on.
+.It Li SIZE
+The size in bytes of the file.
+.It Li BLOCKS
+The number of blocks used by the file.
+.It Li MODE
+The file's protection mode.
+.It Li FLAGS
+The file's
+.Xr chflags 2
+flags.
+.It Li LNK
+The number of hard links.
+.It Li UID\&|USER
+The user (ID) of the file's owner.
+.It Li GID\&|GROUP
+The group (ID) of the file's group.
+.It Li ATIME
+The time of last access.
+.It Li MTIME
+The time of last data modification.
+.It Li CTIME
+The time of last file status change.
+.It Li GEN
+The file generation number.
+.It Li NAME
+The file name.
 .El
 .Sh SOCKETS
 The formating of open sockets depends on the protocol domain.
Index: fstat.c
===================================================================
RCS file: /u02/ncvs/src/usr.bin/fstat/fstat.c,v
retrieving revision 1.21.2.7
diff -u -r1.21.2.7 fstat.c
--- fstat.c	21 Nov 2001 10:49:37 -0000	1.21.2.7
+++ fstat.c	19 May 2002 17:37:08 -0000
@@ -97,6 +97,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <netdb.h>
+#include <grp.h>

 #include "fstat.h"

@@ -121,6 +122,7 @@
 int	nflg;	/* (numerical) display f.s. and rdev as dev_t */
 int	vflg;	/* display errors in locating kernel data objects etc... */
 int	mflg;	/* include memory-mapped files */
+int	sflg;	/* display inode information */


 struct file **ofiles;	/* buffer of pointers to file structures */
@@ -137,6 +139,7 @@

 kvm_t *kd;

+void dostats __P((void));
 void dofiles __P((struct kinfo_proc *kp));
 void dommap __P((struct kinfo_proc *kp));
 void vtrans __P((struct vnode *vp, int i, int flag));
@@ -165,7 +168,7 @@
 	arg = 0;
 	what = KERN_PROC_ALL;
 	nlistf = memf = NULL;
-	while ((ch = getopt(argc, argv, "fmnp:u:vN:M:")) != -1)
+	while ((ch = getopt(argc, argv, "fmnp:su:vN:M:")) != -1)
 		switch((char)ch) {
 		case 'f':
 			fsflg = 1;
@@ -192,6 +195,9 @@
 			what = KERN_PROC_PID;
 			arg = atoi(optarg);
 			break;
+		case 's':
+			sflg = 1;
+			break;
 		case 'u':
 			if (uflg++)
 				usage();
@@ -217,6 +223,11 @@
 			exit(1);
 	}

+	if (sflg && !checkfile) {
+		warnx("must provide a filename");
+		usage();
+	}
+
 	ALLOC_OFILES(256);	/* reserve space for file pointers */

 	if (fsflg && !checkfile) {
@@ -242,11 +253,19 @@
 	if ((p = kvm_getprocs(kd, what, arg, &cnt)) == NULL)
 		errx(1, "%s", kvm_geterr(kd));
 	if (nflg)
-		printf("%s",
+		printf("%s", (sflg)?
+"INODE  DEV    SIZE     BLOCKS MODE   FLAGS  LNK UID  GID  ATIME      MTIME      CTIME      GEN        NAME\n" :
 "USER     CMD          PID   FD  DEV    INUM       MODE SZ|DV R/W");
 	else
-		printf("%s",
+		printf("%s", (sflg)?
+"INODE  MOUNT  SIZE     BLOCKS MODE        FLAGS  LNK USER     GROUP    ATIME                            MTIME                            CTIME                            GEN        NAME\n" :
 "USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W");
+
+	if (sflg) {
+		dostats();
+		exit(0);
+	}
+
 	if (checkfile && fsflg == 0)
 		printf(" NAME\n");
 	else
@@ -288,6 +307,71 @@
 	}

 /*
+ * print inode information for all files in devs
+ */
+void
+dostats() {
+	struct stat s;
+	struct statfs sf;
+	struct passwd *pw;
+	struct group *gr;
+	char mode[15], tstr[128];
+	register DEVS *d;
+
+	for (d = devs; d != NULL; d = d->next) {
+		if (d->name == NULL)	/* does this ever happen? */
+			errx(1, "invalid filename");
+		if (lstat(d->name, &s) == -1) {
+			warnx("couldn't stat file %s", d->name);
+			continue;
+		}
+		if (statfs(d->name, &sf) == -1) {
+			warnx("couldn't statfs file %s", d->name);
+			continue;
+		}
+		if (nflg) {
+			(void)printf("%-6u %-6d %-8qd %-6qd %-6.6o %-6.6o %-3d %-4d %-4d ",
+			    s.st_ino, s.st_dev,
+			    s.st_size, s.st_blocks,
+			    (unsigned int)s.st_mode,
+			    (unsigned int)s.st_flags,
+			    s.st_nlink, s.st_uid, s.st_gid);
+			(void)printf("%-10ld %-10ld %-10ld %-10d %s",
+			    (long int)s.st_atime,
+			    (long int)s.st_mtime,
+			    (long int)s.st_ctime,
+			    s.st_gen, d->name);
+			(void)putchar('\n');
+		} else {
+			strmode(s.st_mode, mode);
+			(void)printf("%-6u %-6s %-8qd %-6qd %-10s %-6s %-3d ",
+			    s.st_ino, sf.f_mntonname,
+			    s.st_size, s.st_blocks,
+			    mode, fflagstostr(s.st_flags),
+			    s.st_nlink);
+			pw = getpwuid(s.st_uid);
+			if (pw == NULL)
+			    printf("%-8d ", s.st_uid);
+			else
+			    printf("%-8s ", pw->pw_name);
+			gr = getgrgid(s.st_gid);
+			if (gr == NULL)
+			    printf("%-8d ", s.st_gid);
+			else
+			    printf("%-8s ", gr->gr_name);
+			strftime(tstr, 128, "%+", localtime(&s.st_atime));
+			(void)printf("%-32s ", tstr);
+			strftime(tstr, 128, "%+", localtime(&s.st_mtime));
+			(void)printf("%-32s ", tstr);
+			strftime(tstr, 128, "%+", localtime(&s.st_ctime));
+			(void)printf("%-32s ", tstr);
+			(void)printf("%-10d %s", s.st_gen, d->name);
+			(void)putchar('\n');
+		}
+	}
+}
+
+/*
  * print open files attributed to this process
  */
 void
@@ -874,6 +958,6 @@
 usage()
 {
 	(void)fprintf(stderr,
- "usage: fstat [-fmnv] [-p pid] [-u user] [-N system] [-M core] [file ...]\n");
+ "usage: fstat [-fmnsv] [-p pid] [-u user] [-N system] [-M core] [file ...]\n");
 	exit(1);
 }





To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020519105046.T3802-100000>