Subject: bin/5907: -r flag added to cksum (sum, md5)
To: None <gnats-bugs@gnats.netbsd.org>
From: Ed Gould <ed@left.wing.org>
List: netbsd-bugs
Date: 08/04/1998 11:18:53
>Number:         5907
>Category:       bin
>Synopsis:       -r flag added to cksum (sum, md5)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Aug  4 11:20:00 1998
>Last-Modified:
>Originator:     Ed Gould
>Organization:
>Release:        netbsd-1.3.2
>Environment:
System: NetBSD left.wing.org 1.3.2 NetBSD 1.3.2 (LEFT) #1: Thu Jul 23 15:53:14 PDT 1998 ed@left.wing.org:/usr/src/netbsd-1.3.2/sys/arch/i386/compile/LEFT i386


>Description:
	The usr.bin/cksum (also sum and md5) program only operates on
	specified files.  This patch adds a -r flag to recurse through
	directories, and a -d flag (effective only when -r is
	specified) to checksum the directories themselves.
>How-To-Repeat:
	See code and documentation.
>Fix:

--- cksum.c-netbsd-1.3.2	Mon May  4 23:54:33 1998
+++ cksum.c	Mon Jul 27 12:05:20 1998
@@ -52,6 +52,7 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 
 #include <err.h>
 #include <errno.h>
@@ -62,6 +63,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fts.h>
 
 #include "extern.h"
 
@@ -81,6 +83,10 @@
 	int (*cfncn) __P((int, u_int32_t *, u_int32_t *));
 	void (*pfncn) __P((char *, u_int32_t, u_int32_t));
 	extern char *__progname;
+	int recurse = 0;
+	int dflag = 0;
+	FTS *ftsp;
+	FTSENT *entry;
 
 	cfncn = NULL;
 	pfncn = NULL;
@@ -99,8 +105,11 @@
 		pfncn = pcrc;
 	}
 
-	while ((ch = getopt(argc, argv, "mo:ps:tx")) != -1)
+	while ((ch = getopt(argc, argv, "dmo:prs:tx")) != -1)
 		switch(ch) {
+		case 'd':
+			dflag = 1;
+			break;
 		case 'm':
 			if (dosum) {
 				warnx("sum mutually exclusive with md5");
@@ -129,6 +138,9 @@
 				requiremd5("-p");
 			pflag = 1;
 			break;
+		case 'r':
+			recurse = 1;
+			break;
 		case 's':
 			if (!domd5)
 				requiremd5("-s");
@@ -151,30 +163,13 @@
 		default:
 			usage();
 		}
-	argc -= optind;
-	argv += optind;
 
 	fd = STDIN_FILENO;
 	fn = NULL;
 	rval = 0;
-	do {
-		if (*argv) {
-			fn = *argv++;
-			if (domd5) {
-				if (md5_digest_file(fn)) {
-					warn("%s", fn);
-					rval = 1;
-				}
-				continue;
-			}
-			if ((fd = open(fn, O_RDONLY, 0)) < 0) {
-				warn("%s", fn);
-				rval = 1;
-				continue;
-			}
-		} else if (domd5 && !nomd5stdin)
+	if (argv[optind] == NULL) {
+		if (domd5 && !nomd5stdin)
 			MDFilter(pflag);
-
 		if (!domd5) {
 			if (cfncn(fd, &val, &len)) {
 				warn("%s", fn ? fn : "stdin");
@@ -183,8 +178,66 @@
 				pfncn(fn, val, len);
 			(void)close(fd);
 		}
-	} while (*argv);
-	exit(rval);
+		return(rval);
+	}
+	if ((ftsp = fts_open(&argv[optind], FTS_LOGICAL, NULL)) == NULL) {
+		fprintf(stderr, "%s: can't open file tree: %s\n", argv[0],
+			strerror(errno));
+		return(1);
+	}
+	while ((entry = fts_read(ftsp)) != NULL) {
+	    switch (entry->fts_info) {
+		case FTS_D:
+		    /*
+		     * A directory.  If we have not been asked to recurse,
+		     * then skip it, and force checksumming.
+		     */
+		    if (!recurse) {
+			fts_set(ftsp, entry, FTS_SKIP);
+			goto process;
+		    }
+		    continue;
+
+		case FTS_DP:
+		    if (!dflag || !recurse)
+			continue;
+		    /*
+		     * If we're recursing, and -d was specified, then
+		     * fall through to checksum directories as well...
+		     */
+
+		case FTS_F:
+process:
+		    fn = entry->fts_path;
+		    if (domd5) {
+			    if (md5_digest_file(fn)) {
+				    warn("%s", fn);
+				    rval = 1;
+			    }
+			    continue;
+		    }
+		    if ((fd = open(fn, O_RDONLY, 0)) < 0) {
+			    warn("%s", fn);
+			    rval = 1;
+			    continue;
+		    }
+		    if (cfncn(fd, &val, &len)) {
+			    warn("%s", fn ? fn : "stdin");
+			    rval = 1;
+		    } else
+			    pfncn(fn, val, len);
+		    (void)close(fd);
+		    continue;
+
+		case FTS_DNR:
+		case FTS_ERR:
+		case FTS_NS:
+		    fprintf(stderr, "%s: %s: %s\n", argv[0],
+			    entry->fts_path, strerror(entry->fts_errno));
+		    continue;
+	    }
+	}
+	return(rval);
 }
 
 int
--- cksum.1-netbsd-1.3.2	Tue Jan 13 06:46:35 1998
+++ cksum.1	Mon Jul 27 12:07:41 1998
@@ -46,6 +46,7 @@
 .Nd display file checksums and block counts
 .Sh SYNOPSIS
 .Nm
+.Op Fl d
 .Oo Fl m \&|
 .Oo Fl o Ar \&1 No \&| Ar \&2
 .Oc
@@ -55,6 +56,7 @@
 .Op Ar file ...
 .Nm md5
 .Op Fl p
+.Op Fl r
 .Op Fl t
 .Op Fl x
 .Op Fl s Ar string
@@ -97,6 +99,9 @@
 .Pp
 The options are as follows:
 .Bl -tag -width indent
+.It Fl d
+When recursively descending through directories,
+checksum the directories as well.
 .It Fl m
 Use the MD5 algorithm rather than the default one.
 .It Fl o
@@ -135,6 +140,8 @@
 For historic reasons, the block size is 1024 for algorithm 1 and 512
 for algorithm 2.
 Partial blocks are rounded up.
+.It Fl r
+Recursively checksum the contents of all directories encountered.
 .El
 .Pp
 The following options apply only when using the MD5 algorithm:
>Audit-Trail:
>Unformatted: