summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2018-12-25 18:08:43 -0500
committerTavian Barnes <tavianator@tavianator.com>2018-12-25 18:13:15 -0500
commit36cb1762dd647a6c9cbb0ab36993c83798c854f1 (patch)
tree4bc2fc1cca1400774855e0b2618b967bb9466947
parentb2e69d3f76270fc4051801cac923307514184055 (diff)
downloadbfs-36cb1762dd647a6c9cbb0ab36993c83798c854f1.tar.xz
stat: Provide a helper for getting human-readable field names
And fix -newerXY if the Y time doesn't exist.
-rw-r--r--eval.c25
-rw-r--r--parse.c67
-rw-r--r--stat.c36
-rw-r--r--stat.h5
4 files changed, 73 insertions, 60 deletions
diff --git a/eval.c b/eval.c
index f636173..fa2be65 100644
--- a/eval.c
+++ b/eval.c
@@ -215,32 +215,11 @@ bool eval_capable(const struct expr *expr, struct eval_state *state) {
*/
static const struct timespec *eval_stat_time(const struct bfs_stat *statbuf, enum bfs_stat_field field, const struct eval_state *state) {
const struct timespec *ret = bfs_stat_time(statbuf, field);
-
if (!ret) {
- const char *kind;
- switch (field) {
- case BFS_STAT_ATIME:
- kind = "access";
- break;
- case BFS_STAT_BTIME:
- kind = "birth";
- break;
- case BFS_STAT_CTIME:
- kind = "change";
- break;
- case BFS_STAT_MTIME:
- kind = "modification";
- break;
- default:
- assert(false);
- kind = "???";
- break;
- }
-
- cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time: %s%{rs}\n", state->ftwbuf->path, kind, strerror(errno));
+ cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time: %m%{rs}\n",
+ state->ftwbuf->path, bfs_stat_field_name(field));
*state->ret = EXIT_FAILURE;
}
-
return ret;
}
diff --git a/parse.c b/parse.c
index 54d1a88..524a80d 100644
--- a/parse.c
+++ b/parse.c
@@ -1518,6 +1518,22 @@ static struct expr *parse_lname(struct parser_state *state, int casefold, int ar
return parse_fnmatch(state, expr, casefold);
}
+/** Get the bfs_stat_field for X/Y in -newerXY */
+static enum bfs_stat_field parse_newerxy_field(char c) {
+ switch (c) {
+ case 'a':
+ return BFS_STAT_ATIME;
+ case 'B':
+ return BFS_STAT_BTIME;
+ case 'c':
+ return BFS_STAT_CTIME;
+ case 'm':
+ return BFS_STAT_MTIME;
+ default:
+ return 0;
+ }
+}
+
/**
* Parse -newerXY.
*/
@@ -1535,21 +1551,8 @@ static struct expr *parse_newerxy(struct parser_state *state, int arg1, int arg2
goto fail;
}
- switch (arg[6]) {
- case 'a':
- expr->stat_field = BFS_STAT_ATIME;
- break;
- case 'c':
- expr->stat_field = BFS_STAT_CTIME;
- break;
- case 'm':
- expr->stat_field = BFS_STAT_MTIME;
- break;
- case 'B':
- expr->stat_field = BFS_STAT_BTIME;
- break;
-
- default:
+ expr->stat_field = parse_newerxy_field(arg[6]);
+ if (!expr->stat_field) {
cfprintf(cerr, "%{er}error: %s: For -newerXY, X should be 'a', 'c', 'm', or 'B'.%{rs}\n", arg);
goto fail;
}
@@ -1558,35 +1561,25 @@ static struct expr *parse_newerxy(struct parser_state *state, int arg1, int arg2
cfprintf(cerr, "%{er}error: %s: Explicit reference times ('t') are not supported.%{rs}\n", arg);
goto fail;
} else {
+ enum bfs_stat_field field = parse_newerxy_field(arg[7]);
+ if (!field) {
+ cfprintf(cerr, "%{er}error: %s: For -newerXY, Y should be 'a', 'c', 'm', 'B', or 't'.%{rs}\n", arg);
+ goto fail;
+ }
+
struct bfs_stat sb;
if (stat_arg(state, expr, &sb) != 0) {
goto fail;
}
- switch (arg[7]) {
- case 'a':
- expr->reftime = sb.atime;
- break;
- case 'c':
- expr->reftime = sb.ctime;
- break;
- case 'm':
- expr->reftime = sb.mtime;
- break;
-
- case 'B':
- if (sb.mask & BFS_STAT_BTIME) {
- expr->reftime = sb.btime;
- } else {
- cfprintf(cerr, "%{er}error: '%s': Couldn't get file birth time.%{rs}\n", expr->sdata);
- goto fail;
- }
- break;
-
- default:
- cfprintf(cerr, "%{er}error: %s: For -newerXY, Y should be 'a', 'c', 'm', 'B', or 't'.%{rs}\n", arg);
+ const struct timespec *reftime = bfs_stat_time(&sb, field);
+ if (!reftime) {
+ cfprintf(cerr, "%{er}error: '%s': Couldn't get file %s: %m.%{rs}\n",
+ expr->sdata, bfs_stat_field_name(field));
goto fail;
}
+
+ expr->reftime = *reftime;
}
return expr;
diff --git a/stat.c b/stat.c
index c567873..e78e206 100644
--- a/stat.c
+++ b/stat.c
@@ -42,6 +42,42 @@
# define st_birthtim st_birthtimespec
#endif
+const char *bfs_stat_field_name(enum bfs_stat_field field) {
+ switch (field) {
+ case BFS_STAT_DEV:
+ return "device number";
+ case BFS_STAT_INO:
+ return "inode nunmber";
+ case BFS_STAT_TYPE:
+ return "type";
+ case BFS_STAT_MODE:
+ return "mode";
+ case BFS_STAT_NLINK:
+ return "link count";
+ case BFS_STAT_GID:
+ return "group ID";
+ case BFS_STAT_UID:
+ return "user ID";
+ case BFS_STAT_SIZE:
+ return "size";
+ case BFS_STAT_BLOCKS:
+ return "block count";
+ case BFS_STAT_RDEV:
+ return "underlying device";
+ case BFS_STAT_ATIME:
+ return "access time";
+ case BFS_STAT_BTIME:
+ return "birth time";
+ case BFS_STAT_CTIME:
+ return "change time";
+ case BFS_STAT_MTIME:
+ return "modification time";
+ }
+
+ assert(false);
+ return "???";
+}
+
/**
* Check if we should retry a failed stat() due to a potentially broken link.
*/
diff --git a/stat.h b/stat.h
index 4bad74e..d9c9588 100644
--- a/stat.h
+++ b/stat.h
@@ -47,6 +47,11 @@ enum bfs_stat_field {
};
/**
+ * Get the human-readable name of a bfs_stat field.
+ */
+const char *bfs_stat_field_name(enum bfs_stat_field field);
+
+/**
* bfs_stat() flags.
*/
enum bfs_stat_flag {