From d696346689e161ee8a5623182ed65ab119adb203 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 4 Feb 2016 16:33:53 -0500 Subject: Implement -[ac]?newer. --- bfs.h | 1 + color.c | 2 +- eval.c | 37 +++++++++++++++++++++++++++++++++++++ parse.c | 43 +++++++++++++++++++++++++++++++++++++++++++ tests.sh | 12 +++++++++++- 5 files changed, 93 insertions(+), 2 deletions(-) diff --git a/bfs.h b/bfs.h index 2a9ba2e..6c691b4 100644 --- a/bfs.h +++ b/bfs.h @@ -146,6 +146,7 @@ bool eval_false(const struct expr *expr, struct eval_state *state); bool eval_access(const struct expr *expr, struct eval_state *state); bool eval_acmtime(const struct expr *expr, struct eval_state *state); +bool eval_acnewer(const struct expr *expr, struct eval_state *state); bool eval_gid(const struct expr *expr, struct eval_state *state); bool eval_uid(const struct expr *expr, struct eval_state *state); diff --git a/color.c b/color.c index 8e22340..d89be4f 100644 --- a/color.c +++ b/color.c @@ -318,7 +318,7 @@ void print_error(const struct color_table *colors, const char *path, int error) if (color) { print_esc(color, stderr); } - fprintf(stderr, "Error at %s: %s\n", path, strerror(error)); + fprintf(stderr, "'%s': %s\n", path, strerror(error)); if (color) { print_esc(colors->reset, stderr); } diff --git a/eval.c b/eval.c index 2463d86..33da8e4 100644 --- a/eval.c +++ b/eval.c @@ -1,3 +1,14 @@ +/********************************************************************* + * bfs * + * Copyright (C) 2015-2016 Tavian Barnes * + * * + * This program is free software. It comes without any warranty, to * + * the extent permitted by applicable law. You can redistribute it * + * and/or modify it under the terms of the Do What The Fuck You Want * + * To Public License, Version 2, as published by Sam Hocevar. See * + * the COPYING file or http://www.wtfpl.net/ for more details. * + *********************************************************************/ + #include "bfs.h" #include "bftw.h" #include @@ -121,6 +132,32 @@ bool eval_acmtime(const struct expr *expr, struct eval_state *state) { return do_cmp(expr, diff); } +/** + * -[ac]?newer tests. + */ +bool eval_acnewer(const struct expr *expr, struct eval_state *state) { + const struct stat *statbuf = fill_statbuf(state); + if (!statbuf) { + return false; + } + + const struct timespec *time; + switch (expr->timefield) { + case ATIME: + time = &statbuf->st_atim; + break; + case CTIME: + time = &statbuf->st_ctim; + break; + case MTIME: + time = &statbuf->st_mtim; + break; + } + + return time->tv_sec > expr->reftime.tv_sec + || (time->tv_sec == expr->reftime.tv_sec && time->tv_nsec > expr->reftime.tv_nsec); +} + /** * -gid test. */ diff --git a/parse.c b/parse.c index 898b5df..da9ee9c 100644 --- a/parse.c +++ b/parse.c @@ -1,8 +1,23 @@ +/********************************************************************* + * bfs * + * Copyright (C) 2015-2016 Tavian Barnes * + * * + * This program is free software. It comes without any warranty, to * + * the extent permitted by applicable law. You can redistribute it * + * and/or modify it under the terms of the Do What The Fuck You Want * + * To Public License, Version 2, as published by Sam Hocevar. See * + * the COPYING file or http://www.wtfpl.net/ for more details. * + *********************************************************************/ + #include "bfs.h" +#include +#include #include #include #include #include +#include +#include #include #include @@ -319,6 +334,28 @@ static struct expr *parse_acmtime(struct parser_state *state, const char *option return expr; } +/** + * Parse -[ac]?newer. + */ +static struct expr *parse_acnewer(struct parser_state *state, const char *option, enum timefield field) { + struct expr *expr = parse_test_sdata(state, option, eval_acnewer); + if (!expr) { + return NULL; + } + + struct stat sb; + if (fstatat(AT_FDCWD, expr->sdata, &sb, AT_SYMLINK_NOFOLLOW) != 0) { + print_error(NULL, expr->sdata, errno); + free_expr(expr); + return NULL; + } + + expr->reftime = sb.st_mtim; + expr->timefield = field; + + return expr; +} + /** * "Parse" -daystart. */ @@ -426,10 +463,14 @@ static struct expr *parse_literal(struct parser_state *state) { return parse_acmtime(state, arg, ATIME, MINUTES); } else if (strcmp(arg, "-atime") == 0) { return parse_acmtime(state, arg, ATIME, DAYS); + } else if (strcmp(arg, "-anewer") == 0) { + return parse_acnewer(state, arg, ATIME); } else if (strcmp(arg, "-cmin") == 0) { return parse_acmtime(state, arg, CTIME, MINUTES); } else if (strcmp(arg, "-ctime") == 0) { return parse_acmtime(state, arg, CTIME, DAYS); + } else if (strcmp(arg, "-cnewer") == 0) { + return parse_acnewer(state, arg, CTIME); } else if (strcmp(arg, "-color") == 0) { state->cl->color = true; return new_option(state, arg); @@ -468,6 +509,8 @@ static struct expr *parse_literal(struct parser_state *state) { return parse_acmtime(state, arg, MTIME, DAYS); } else if (strcmp(arg, "-name") == 0) { return parse_test_sdata(state, arg, eval_name); + } else if (strcmp(arg, "-newer") == 0) { + return parse_acnewer(state, arg, MTIME); } else if (strcmp(arg, "-path") == 0 || strcmp(arg, "-wholename") == 0) { return parse_test_sdata(state, arg, eval_path); } else if (strcmp(arg, "-print") == 0) { diff --git a/tests.sh b/tests.sh index 23a9aba..a45af5f 100755 --- a/tests.sh +++ b/tests.sh @@ -124,7 +124,17 @@ function test_0017() { find_diff "$1" -uid -10000 } -for i in {1..17}; do +function test_0018() { + basic_structure "$1" + find_diff "$1" -newer "$1/e/f" +} + +function test_0019() { + basic_structure "$1" + find_diff "$1" -cnewer "$1/e/f" +} + +for i in {1..19}; do dir="$(mktemp -d "${TMPDIR:-/tmp}"/bfs.XXXXXXXXXX)" test="test_$(printf '%04d' $i)" "$test" "$dir" -- cgit v1.2.3