summaryrefslogtreecommitdiff
path: root/sbin/ncheck_ffs/ncheck_ffs.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-01-17 18:27:59 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-01-17 18:27:59 +0000
commit7b99416af5591de5643723e05e9524cef8f878fa (patch)
treedd43af2cd83319f875b143071539ae574bae6291 /sbin/ncheck_ffs/ncheck_ffs.c
parentd7d7b409ce4c52ad33bc1c44ef63064700c5876d (diff)
Add a new option, -f, that allows the user to specify a custom output
format. Currently only supports printing the inode number and path (along with any arbitrary text) but other escapes may be added later. A useful invocation is: ncheck -s -f '\P\0' | xargs -0 ls -ldgT deraadt@ OK
Diffstat (limited to 'sbin/ncheck_ffs/ncheck_ffs.c')
-rw-r--r--sbin/ncheck_ffs/ncheck_ffs.c129
1 files changed, 110 insertions, 19 deletions
diff --git a/sbin/ncheck_ffs/ncheck_ffs.c b/sbin/ncheck_ffs/ncheck_ffs.c
index 5b89f460bf6..0757e56f964 100644
--- a/sbin/ncheck_ffs/ncheck_ffs.c
+++ b/sbin/ncheck_ffs/ncheck_ffs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ncheck_ffs.c,v 1.15 2003/01/17 17:56:53 millert Exp $ */
+/* $OpenBSD: ncheck_ffs.c,v 1.16 2003/01/17 18:27:58 millert Exp $ */
/*-
* Copyright (c) 1995, 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
@@ -31,7 +31,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: ncheck_ffs.c,v 1.15 2003/01/17 17:56:53 millert Exp $";
+static const char rcsid[] = "$OpenBSD: ncheck_ffs.c,v 1.16 2003/01/17 18:27:58 millert Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -65,6 +65,7 @@ int sflag; /* only suid and special files */
int aflag; /* print the . and .. entries too */
int mflag; /* verbose output */
int iflag; /* specific inode */
+char *format; /* output format */
struct icache_s {
ino_t ino;
@@ -76,7 +77,7 @@ void addinode(ino_t inum);
struct dinode *getino(ino_t inum);
void findinodes(ino_t);
void bread(daddr_t, char *, int);
-void usage(void);
+__dead void usage(void);
void scanonedir(ino_t, const char *);
void dirindir(ino_t, daddr_t, int, long *, const char *);
void searchdir(ino_t, daddr_t, long, long, const char *);
@@ -86,6 +87,7 @@ void cacheino(ino_t, struct dinode *);
struct dinode *cached(ino_t);
int main(int, char *[]);
char *rawname(char *);
+void format_entry(const char *, struct direct *);
/*
* Check to see if the indicated inodes are the same
@@ -354,7 +356,7 @@ searchdir(ino_t ino, daddr_t blkno, long size, long filesize,
for (loc = 0; loc < size;) {
dp = (struct direct *)(dblk + loc);
if (dp->d_reclen == 0) {
- warnx("corrupted directory, inode %lu", (long)ino);
+ warnx("corrupted directory, inode %u", ino);
break;
}
loc += dp->d_reclen;
@@ -368,12 +370,15 @@ searchdir(ino_t ino, daddr_t blkno, long size, long filesize,
di = getino(dp->d_ino);
mode = di->di_mode & IFMT;
if (bsearch(&dp->d_ino, ilist, ninodes, sizeof(*ilist), matchino)) {
- if (mflag)
- printf("mode %-6o uid %-5lu gid %-5lu ino ",
- di->di_mode, (unsigned long)di->di_uid,
- (unsigned long)di->di_gid);
- printf("%-7lu %s/%s%s\n", (unsigned long)dp->d_ino,
- path, dp->d_name, mode == IFDIR ? "/." : "");
+ if (format) {
+ format_entry(path, dp);
+ } else {
+ if (mflag)
+ printf("mode %-6o uid %-5u gid %-5u ino ",
+ di->di_mode, di->di_uid, di->di_gid);
+ printf("%-7u %s/%s%s\n", dp->d_ino, path,
+ dp->d_name, mode == IFDIR ? "/." : "");
+ }
}
if (mode == IFDIR) {
int len;
@@ -410,10 +415,13 @@ rawname(char *name)
return(newname);
}
-void
+__dead void
usage(void)
{
- fprintf(stderr, "Usage: ncheck_ffs [-i numbers] [-ams] filesystem\n");
+ extern char *__progname;
+
+ fprintf(stderr, "usage: %s [-f format] [-i numbers] [-ams] filesystem\n",
+ __progname);
exit(3);
}
@@ -422,11 +430,11 @@ main(int argc, char *argv[])
{
struct stat stblock;
struct fstab *fsp;
- u_long ulval;
+ unsigned long ulval;
char *ep;
int c;
- while ((c = getopt(argc, argv, "ai:ms")) != -1)
+ while ((c = getopt(argc, argv, "af:i:ms")) != -1)
switch (c) {
case 'a':
aflag++;
@@ -456,6 +464,9 @@ main(int argc, char *argv[])
optind++;
}
break;
+ case 'f':
+ format = optarg;
+ break;
case 'm':
mflag++;
break;
@@ -466,7 +477,7 @@ main(int argc, char *argv[])
usage();
exit(2);
}
- if (optind != argc - 1)
+ if (optind != argc - 1 || (mflag && format))
usage();
disk = argv[optind];
@@ -476,8 +487,7 @@ main(int argc, char *argv[])
if (S_ISBLK(stblock.st_mode)) {
disk = rawname(disk);
- }
- else if (!S_ISCHR(stblock.st_mode)) {
+ } else if (!S_ISCHR(stblock.st_mode)) {
if ((fsp = getfsfile(disk)) == NULL)
err(1, "cound not find file system %s", disk);
disk = rawname(fsp->fs_spec);
@@ -494,8 +504,89 @@ main(int argc, char *argv[])
if (dev_bsize != (1 << dev_bshift))
errx(2, "blocksize (%ld) not a power of 2", dev_bsize);
findinodes(sblock->fs_ipg * sblock->fs_ncg);
- printf("%s:\n", disk);
+ if (!format)
+ printf("%s:\n", disk);
scanonedir(ROOTINO, "");
close(diskfd);
- return 0;
+ exit (0);
+}
+
+void
+format_entry(const char *path, struct direct *dp)
+{
+ static size_t size;
+ static char *buf;
+ size_t len;
+ char *src, *dst;
+
+ if (buf == NULL) {
+ if ((buf = malloc(LINE_MAX)) == NULL)
+ err(1, "malloc");
+ size = LINE_MAX;
+ }
+
+ for (src = format, dst = buf; *src; src++) {
+ /* Need room for at least one character in buf. */
+ if (size <= dst - buf) {
+ expand_buf:
+ size <<= 1;
+ if ((buf = realloc(buf, size)) == NULL)
+ err(1, "realloc");
+ }
+ if (src[0] =='\\') {
+ switch (src[1]) {
+ case 'I':
+ len = snprintf(dst, size - (dst - buf), "%u",
+ dp->d_ino);
+ if (len >= size - (dst - buf))
+ goto expand_buf;
+ dst += len;
+ break;
+ case 'P':
+ len = snprintf(dst, size - (dst - buf), "%s/%s",
+ path, dp->d_name);
+ if (len >= size - (dst - buf))
+ goto expand_buf;
+ dst += len;
+ break;
+ case '\\':
+ *dst++ = '\\';
+ break;
+ case '0':
+ /* XXX - support other octal numbers? */
+ *dst++ = '\0';
+ break;
+ case 'a':
+ *dst++ = '\a';
+ break;
+ case 'b':
+ *dst++ = '\b';
+ break;
+ case 'e':
+ *dst++ = '\e';
+ break;
+ case 'f':
+ *dst++ = '\f';
+ break;
+ case 'n':
+ *dst++ = '\n';
+ break;
+ case 'r':
+ *dst++ = '\r';
+ break;
+ case 't':
+ *dst++ = '\t';
+ break;
+ case 'v':
+ *dst++ = '\v';
+ break;
+ default:
+ *dst++ = src[1];
+ break;
+ }
+ src++;
+ } else
+ *dst++ = *src;
+ }
+ fwrite(buf, dst - buf, 1, stdout);
}