commit: 7a0e72cddb82b17da2b1355405199387c10b646b
parent 48f6992741d06ac8701d39ccbf44cd0553271041
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Tue, 12 Mar 2024 13:02:03 +0100
cmd/chmod: Add -c option
Diffstat:
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
@@ -80,6 +80,6 @@ cmd/df: cmd/df.c lib/humanize.c Makefile
rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
$(CC) -std=c99 $(CFLAGS) -o $@ cmd/df.c lib/humanize.c $(LDFLAGS) $(LDSTATIC)
-cmd/chmod: cmd/chmod.c lib/mode.c Makefile
+cmd/chmod: cmd/chmod.c lib/mode.c lib/symbolize_mode.c Makefile
rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
- $(CC) -std=c99 $(CFLAGS) -o $@ cmd/chmod.c lib/mode.c $(LDFLAGS) $(LDSTATIC)
+ $(CC) -std=c99 $(CFLAGS) -o $@ cmd/chmod.c lib/mode.c lib/symbolize_mode.c $(LDFLAGS) $(LDSTATIC)
diff --git a/cmd/chmod.c b/cmd/chmod.c
@@ -16,6 +16,8 @@
#include <sys/stat.h> // chmod, fstatat, S_ISDIR
#include <unistd.h> // getopt
+bool opt_c = false;
+
static int
do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
{
@@ -48,6 +50,23 @@ do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
return 1;
}
+ if(opt_c && mode != stats.st_mode)
+ {
+ char ori_mode[11] = "";
+ symbolize_mode(stats.st_mode, ori_mode);
+
+ char cur_mode[11] = "";
+ symbolize_mode(mode, cur_mode);
+
+ printf("chmod: Mode changed from 0%o6/%s to 0%o6/%s for '%s%s'\n",
+ stats.st_mode & 07777,
+ ori_mode,
+ mode & 07777,
+ cur_mode,
+ fdname,
+ path);
+ }
+
if(recursive && S_ISDIR(stats.st_mode))
{
int dir = openat(fd, path, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
@@ -61,7 +80,11 @@ do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
DIR *dirp = fdopendir(dir);
if(dirp == NULL)
{
- fprintf(stderr, "chmod: Couldn't get DIR entry for opened '%s/%s': %s\n", fdname, path, strerror(errno));
+ fprintf(stderr,
+ "chmod: Couldn't get DIR entry for opened '%s/%s': %s\n",
+ fdname,
+ path,
+ strerror(errno));
return 1;
}
@@ -72,7 +95,8 @@ do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
{
if(errno == 0) break;
- fprintf(stderr, "chmod: Failed reading directory '%s/%s': %s\n", fdname, path, strerror(errno));
+ fprintf(
+ stderr, "chmod: Failed reading directory '%s/%s': %s\n", fdname, path, strerror(errno));
closedir(dirp);
return 1;
}
@@ -83,7 +107,11 @@ do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
char destdir[PATH_MAX] = "";
if(snprintf(destdir, PATH_MAX, "%s/%s", fdname, path) < 0)
{
- fprintf(stderr, "chmod: Couldn't concatenate '%s' into parent '%s', skipping to next entry: %s", fdname, path, strerror(errno));
+ fprintf(stderr,
+ "chmod: Couldn't concatenate '%s' into parent '%s', skipping to next entry: %s",
+ fdname,
+ path,
+ strerror(errno));
err++;
continue;
}
@@ -96,7 +124,11 @@ do_fchmodat(int fd, char *fdname, char *mode_arg, char *path, bool recursive)
// fdopendir allocates memory for DIR, needs closedir
if(closedir(dirp) != 0)
{
- fprintf(stderr, "chmod: Deallocating directory entry for '%s/%s' failed: %s\n", fdname, path, strerror(errno));
+ fprintf(stderr,
+ "chmod: Deallocating directory entry for '%s/%s' failed: %s\n",
+ fdname,
+ path,
+ strerror(errno));
return 1;
}
}
@@ -116,18 +148,21 @@ main(int argc, char *argv[])
bool opt_R = false;
int c = -1;
- while((c = getopt(argc, argv, ":R")) != -1)
+ while((c = getopt(argc, argv, ":cR")) != -1)
{
switch(c)
{
- case 'R':
+ case 'c': // GNU
+ opt_c = true;
+ break;
+ case 'R': // POSIX
opt_R = true;
break;
case ':':
fprintf(stderr, "chmod: Error: Missing operand for option: '-%c'\n", optopt);
usage();
return 1;
- case '?':
+ case '?': // GNU
switch(optopt)
{
case 'r':