commit: 519394ae92f2bf6ac129eb8d2f90a0e087fb2dc6
parent: 6d55b4afe079a1c29ba66871f6fcbf742de7a17a
author: Chris Noxz <chris@noxz.tech>
date: Thu, 9 Mar 2023 12:25:13 +0100
Remove unnecessary feature to process directories
5 files changed, 20 insertions(+), 110 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,7 +8,7 @@ OBJ = ${SRC:.c=.o}
all: options acst
options:
- @echo st build options:
+ @echo build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "CC = ${CC}"
diff --git a/acst.1 b/acst.1
@@ -4,7 +4,7 @@ acst \- Actual C-implementation of a Simple shaTag
.
.SH SYNOPSIS
.B acst
-.RB [ \-dhmnqrvx ]
+.RB [ \-dhmnqvx ]
.IR "" < FILE ...>
.
.SH DESCRIPTION
@@ -85,9 +85,6 @@ and
.BR malformed
files and errors are being reported.
.TP
-.BR -r
-Process directories and their contents recursively, not just files.
-.TP
.BR -x
Remove acts's extended attributes (xattrs) from
.IR FILE .
@@ -159,33 +156,27 @@ Duplicate of checksum among files checked.
.
.SH EXAMPLES
.TP
-.BR "find /strg/shr/media -xdev -type f | acst - > /root/acst.log"
+.BR "find /mnt/memorystick -xdev -type f | acst - > /root/acst.log"
will use
.B find
to recursively traverse through files in
/mnt/memorystick within the same file system and log the result to
-/root/acst.log. Using
-.B acst
-this way is many times faster than using the recursive argument and can also
-replace all examples below using the recursive argument. It should be treated
-as the preferred method of using
-.BR acst .
+/root/acst.log.
.TP
-.BR "acst -r /home/user01 /mnt/memorystick > /root/acst.log"
+.BR "find /home/user01 /strg/shr/media -type f | acst - > /root/acst.log"
will recursively process files in both /home/user01 and /mnt/memorystick even
-if they belong to different file systems, as they are both specified using the
-.IR FILE
-argument, and then log the result to /root/acst.log.
+if they belong to different file systems, and then log the result to
+/root/acst.log.
.TP
-.BR "acst -rm /home/user01 /mnt/memorystick > /root/acst.log"
+.BR "find /home/user01 /strg/shr/media -type f | acst -m - > /root/acst.log"
will perform the same operation as above with the addition of also summarizing
the result of the execution to the log.
.TP
-.BR "acst -rx /mnt/memorystick > /root/acst.log"
+.BR "find /mnt/memorystick -xdev -type f | acst -x - > /root/acst.log"
will recursively process and remove extended attributes from files in
/mnt/memorystick and log the result to /root/acst.log.
.TP
-.BR "acst -rd /mnt/memorystick"
+.BR "find /mnt/memorystick -xdev -type f | acst -d -
will recursively check for duplicates among files in /mnt/memorystick based on
checksums stored as extended attributes.
.
diff --git a/acst.c b/acst.c
@@ -16,9 +16,9 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#include <dirent.h> // for dirent, closedir, opendir, readdir, DIR
#include <errno.h> // for errno, ENODATA
#include <fcntl.h> // for open, O_NOFOLLOW, O_RDONLY
+#include <limits.h> // for PATH_MAX
#include <stdarg.h> // for va_end, va_list, va_start
#include <stdbool.h> // for true, false, bool
#include <stdio.h> // for fprintf, stdout, snprintf, sprintf
@@ -27,7 +27,7 @@
#include <time.h> // for timespec
#include <unistd.h> // for close, read
#include <bits/getopt_core.h> // for getopt, optind
-#include <sys/stat.h> // for stat, fstat, lstat, S_ISDIR, S_ISREG
+#include <sys/stat.h> // for stat, fstat, lstat, S_ISREG
#include <sys/xattr.h> // for fgetxattr, fremovexattr, fsetxattr
#include "sha256.h" // for SHA256_final, SHA256_init, SHA256_update
@@ -260,49 +260,12 @@ process_argument(const char *fn)
error(ER_OPENING, STR_ERR_OPNF, fn);
else if (S_ISREG(st.st_mode))
process_file(fn);
- else if (S_ISDIR(st.st_mode))
- process_directory(fn);
- /* make sure to only process regular files or directory walking */
+ /* make sure to only process regular files */
else
error(ER_NOT_REGULAR, STR_ERR_REGF, fn);
}
-static void
-process_directory(const char *fn)
-{
- DIR *d; // directory pointer
- struct dirent *dp; // directory entry pointer
- struct stat dst, // stat holder for directory
- st; // stat holder for children
- char *rp; // relative path holder
-
- if (!arg.recursive)
- return error(ER_NOT_REGULAR, STR_ERR_RECU, fn);
-
- /* open directory and get stats */
- if (!((d = opendir(fn)) && lstat(fn, &dst) == 0))
- return error(ER_OPENING, STR_ERR_OPND, fn);
-
- /* loop through directory (including hidden files), making sure to process
- * the relative path of each file */
- while ((dp = readdir(d)) != NULL) {
- if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
- continue;
- if (!(rp = (char*)malloc(strlen(fn) + strlen(dp->d_name) + 2)))
- error(ER_FATAL, STR_ERR_OOM);
- sprintf(rp, "%s/%s", fn, dp->d_name);
- /* make sure not to descend directories on other filesystems */
- if (!(lstat(rp, &st) == 0 && dst.st_dev == st.st_dev))
- error(ER_OPENING, STR_ERR_DDEV, rp, fn);
- else
- process_argument(rp);
- free(rp);
- }
- closedir(d);
-}
-
-
static void
process_file(const char *fn)
{
@@ -500,14 +463,13 @@ main(int argc, char *argv[])
gl.dup_head = NULL;
gl.prg = argv[0];
- while ((opt = getopt(argc, argv, "dhmnqrvx")) != -1)
+ while ((opt = getopt(argc, argv, "dhmnqvx")) != -1)
switch (opt) {
case 'd': arg.duplicates = true; break;
case 'h': USAGE(EXIT_SUCCESS); break;
case 'm': arg.summarize = true; break;
case 'n': arg.dryrun = true; break;
case 'q': arg.quiet++; break;
- case 'r': arg.recursive = true; break;
case 'v': VER(); break;
case 'x': arg.remove = true; break;
default: USAGE(EXIT_FAILURE);
diff --git a/acst.h b/acst.h
@@ -19,6 +19,7 @@
#ifndef ACST_H
#define ACST_H
+#include <limits.h> // for PATH_MAX
#include <stdbool.h> // for bool
#include <stdio.h> // for printf
#include <stdlib.h> // for exit, EXIT_SUCCESS, size_t
@@ -41,13 +42,10 @@
#define STR_ERR_PMAX "Error: PATH_MAX reached before end\n"
#define STR_ERR_ABNO "Error: abnormal changes detected \"%s\"\n"
#define STR_ERR_OPNF "Error: could not open file \"%s\"\n"
-#define STR_ERR_OPND "Error: could not open directory \"%s\"\n"
-#define STR_ERR_DDEV "Error: \"%s\" belong to a different devices than \"%s\"\n"
#define STR_ERR_REGF "Error: not a regular file \"%s\"\n"
#define STR_ERR_HASH "Error: could not compute hash \"%s\"\n"
#define STR_ERR_XARM "Error: could not remove extended attributes from file \"%s\": %s\n"
#define STR_ERR_XAWR "Error: could not write extended attributes to file \"\%s\"\n"
-#define STR_ERR_RECU "Error: path is a directory, did you mean to use the -r option? \"%s\"\n"
#define STR_OUT_STAT "<%s> %s\n"
#define STR_OUT_NEW "new"
#define STR_OUT_OK "ok"
@@ -76,7 +74,6 @@
" -m summarize information at end of execution\n" \
" -n don't create or update any file attributes\n" \
" -q quiet mode, lowers verbosity\n" \
- " -r process files and directories recursively\n" \
" -V output version information and exit\n" \
" -x remove extended attributes from file(s)\n" \
"\n" \
@@ -136,7 +133,7 @@ static const char zSHA256[] = "0000000000000000" /* zeroed out SHA256 */
enum Error {
ER_NOT_REGULAR, /* not a regular file error */
- ER_OPENING, /* error opening file or directory */
+ ER_OPENING, /* error opening file */
ER_XATTR_OPERATION, /* error when performing xattr operations */
ER_GENERIC, /* generic error */
ER_FATAL /* fatal error, should result in program ending */
@@ -175,7 +172,6 @@ typedef struct ExtendedAttribute {
struct Arguments {
bool dryrun; /* make a dry run */
int quiet; /* level of quietness */
- bool recursive; /* indicate to open and walk directories */
bool remove; /* remove xattrs */
bool summarize; /* show summery at end of program */
bool duplicates; /* use xattrs to find duplicates */
@@ -185,7 +181,7 @@ struct Arguments {
struct Counters {
int errs; /* all errors */
int errNotRegular; /* not a regular file errors */
- int errOpening; /* errors opening file or directory */
+ int errOpening; /* errors opening file */
int errWritingXattr; /* errors when performing xattr operations */
int errGeneric; /* generic errors */
@@ -318,21 +314,13 @@ static void error(enum Error er, const char *fmt, ...);
static enum FileState file_state(int fd, xa_t *xa_s, xa_t *xa_a);
/**
- * Processes arguments (file names) either from command line or from directory
+ * Processes arguments (file names) from command line
* output.
*
* @param fn Name of the file
*/
static void process_argument(const char *fn);
-/**
- * Processes directories if stated to do so (see arg.recursive) by looping
- * through their content (children).
- *
- * @param fn Name of the directory
- */
-static void process_directory(const char *fn);
-
/**
* Processes files and returns either error messages or other output if stated
* to do so (see arg.quiet) based on their file state (see enum FileState
diff --git a/test b/test
@@ -249,37 +249,6 @@ TMPFILE="$(mktemp -d XXXXXXXXXX)" && {
diff -u expected output
rm -f symlink
- #########################################################################
- header 'recursion'
- rm -f object
- mkdir -p object/level-1/level-2/level-3
- TZ=CET touch -t 202206220001 object/level-1/file-1
- TZ=CET touch -t 202206220002 object/level-1/level-2/file-2
- TZ=CET touch -t 202206220003 object/level-1/level-2/level-3/file-3
- set +e
- echo "Error: path is a directory, did you mean to use the -r option? \"object\"" > expected
- ../"${PRG}" object > output 2>&1
- if [ $? -ne 3 ]; then
- echo "should have returned error code 3, but returned 0"
- exit 1
- fi
- set -e
- diff -u expected output
- sort > expected <<- EOF
- <new> object/level-1/file-1
- stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
- actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848860.000000000
- <new> object/level-1/level-2/file-2
- stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
- actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848920.000000000
- <new> object/level-1/level-2/level-3/file-3
- stored: 0000000000000000000000000000000000000000000000000000000000000000 0000000000.000000000
- actual: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 1655848980.000000000
- EOF
- ../"${PRG}" -r object | sort > output
- diff -u expected output
- rm -rf object
-
#########################################################################
header 'multiple files, using command line'
sort > expected <<- EOF
@@ -379,8 +348,8 @@ TMPFILE="$(mktemp -d XXXXXXXXXX)" && {
echo "3" | tee object/level-1/file-3 object/level-1/level-2/file-3 >\
object/level-1/level-2/level-3/file-3
echo "4" > object/level-1/file-4
- ../"${PRG}" -r object > /dev/null 2>&1
- ../"${PRG}" -rd object 2>&1 | sort > output
+ find object -xdev -type f | ../"${PRG}" - > /dev/null 2>&1
+ find object -xdev -type f | ../"${PRG}" -d - 2>&1 | sort > output
diff -u expected output
#########################################################################