From 382057f588fbf2c2f7950b85dd317721b8d04c07 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 21 Nov 2016 16:47:23 -0600 Subject: Have dirtree_notdotdot() pass through !node->parent so . and .. on the command line aren't filtered out. Audited all the callers and removed redundant calls, adjusted call sequence, etc. (And let rm _not_ do this, because posix.) --- lib/dirtree.c | 13 +++++++------ lib/lib.h | 1 + toys/other/hwclock.c | 6 +++--- toys/other/lsusb.c | 2 +- toys/other/modinfo.c | 6 ++++-- toys/pending/diff.c | 2 +- toys/pending/tar.c | 2 +- toys/posix/chmod.c | 2 +- toys/posix/grep.c | 2 +- toys/posix/rm.c | 2 +- 10 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/dirtree.c b/lib/dirtree.c index 8f235ed4..07c1cdc7 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -5,19 +5,20 @@ #include "toys.h" -static int notdotdot(char *name) +int isdotdot(char *name) { - if (name[0]=='.' && (!name[1] || (name[1]=='.' && !name[2]))) return 0; + if (name[0]=='.' && (!name[1] || (name[1]=='.' && !name[2]))) return 1; - return 1; + return 0; } -// Default callback, filters out "." and "..". +// Default callback, filters out "." and ".." except at top level. int dirtree_notdotdot(struct dirtree *catch) { // Should we skip "." and ".."? - return notdotdot(catch->name)*(DIRTREE_SAVE|DIRTREE_RECURSE); + return (!catch->parent||!isdotdot(catch->name)) + *(DIRTREE_SAVE|DIRTREE_RECURSE); } // Create a dirtree node from a path, with stat and symlink info. @@ -54,7 +55,7 @@ struct dirtree *dirtree_add_node(struct dirtree *parent, char *name, int flags) return dt; error: - if (!(flags&DIRTREE_SHUTUP) && notdotdot(name)) { + if (!(flags&DIRTREE_SHUTUP) && !isdotdot(name)) { char *path = parent ? dirtree_path(parent, 0) : ""; perror_msg("%s%s%s", path, parent ? "/" : "", name); diff --git a/lib/lib.h b/lib/lib.h index 2afe558b..61a1975f 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -88,6 +88,7 @@ struct dirtree { char name[]; }; +int isdotdot(char *name); struct dirtree *dirtree_add_node(struct dirtree *p, char *name, int flags); char *dirtree_path(struct dirtree *node, int *plen); int dirtree_notdotdot(struct dirtree *catch); diff --git a/toys/other/hwclock.c b/toys/other/hwclock.c index 75e06416..1d313e3b 100644 --- a/toys/other/hwclock.c +++ b/toys/other/hwclock.c @@ -37,14 +37,14 @@ static int rtc_find(struct dirtree* node) if (!node->parent) return DIRTREE_RECURSE; - snprintf(toybuf, sizeof(toybuf), "/sys/class/rtc/%s/hctosys", node->name); + sprintf(toybuf, "/sys/class/rtc/%s/hctosys", node->name); fp = fopen(toybuf, "r"); if (fp) { int hctosys = 0, items = fscanf(fp, "%d", &hctosys); fclose(fp); if (items == 1 && hctosys == 1) { - snprintf(toybuf, sizeof(toybuf), "/dev/%s", node->name); + sprintf(toybuf, "/dev/%s", node->name); TT.fname = toybuf; return DIRTREE_ABORT; @@ -105,7 +105,7 @@ void hwclock_main() } if (toys.optflags & FLAG_w) { - /* The value of tm_isdst will positive if daylight saving time is in effect, + /* The value of tm_isdst is positive if daylight saving time is in effect, * zero if it is not and negative if the information is not available. * todo: so why isn't this negative...? */ tm.tm_isdst = 0; diff --git a/toys/other/lsusb.c b/toys/other/lsusb.c index 07886e8c..031dbd93 100644 --- a/toys/other/lsusb.c +++ b/toys/other/lsusb.c @@ -24,7 +24,7 @@ static int list_device(struct dirtree *new) if (!new->parent) return DIRTREE_RECURSE; if (new->name[0] == '.') return 0; name = dirtree_path(new, 0); - snprintf(toybuf, sizeof(toybuf), "%s/%s", name, "/uevent"); + sprintf(toybuf, "%s/uevent", name); file = fopen(toybuf, "r"); if (file) { int count = 0; diff --git a/toys/other/modinfo.c b/toys/other/modinfo.c index 61155b46..69cdf27e 100644 --- a/toys/other/modinfo.c +++ b/toys/other/modinfo.c @@ -74,6 +74,8 @@ static void modinfo_file(char *full_name) static int check_module(struct dirtree *new) { + if (!dirtree_notdotdot(new)) return 0; + if (S_ISREG(new->st.st_mode)) { char *s; @@ -88,14 +90,14 @@ static int check_module(struct dirtree *new) } if (s[len] || strcmp(new->name+len, ".ko")) break; - modinfo_file(s = dirtree_path(new, NULL)); + modinfo_file(s = dirtree_path(new, 0)); free(s); return DIRTREE_ABORT; } } - return dirtree_notdotdot(new); + return DIRTREE_RECURSE; } void modinfo_main(void) diff --git a/toys/pending/diff.c b/toys/pending/diff.c index 53bdbce3..b2177c4f 100644 --- a/toys/pending/diff.c +++ b/toys/pending/diff.c @@ -484,7 +484,7 @@ static int list_dir (struct dirtree *node) { int ret = 0; - if (node->parent && !dirtree_notdotdot(node)) return 0; + if (!dirtree_notdotdot(node)) return 0; if (S_ISDIR(node->st.st_mode) && !node->parent) { //add root dirs. add_to_list(node); diff --git a/toys/pending/tar.c b/toys/pending/tar.c index 8d4c3d60..d672d102 100644 --- a/toys/pending/tar.c +++ b/toys/pending/tar.c @@ -274,7 +274,7 @@ static int add_to_tar(struct dirtree *node) return ((DIRTREE_RECURSE | ((toys.optflags & FLAG_h)?DIRTREE_SYMFOLLOW:0))); } - if (node->parent && !dirtree_notdotdot(node)) return 0; + if (!dirtree_notdotdot(node)) return 0; path = dirtree_path(node, 0); add_file(hdl, &path, &(node->st)); //path may be modified free(path); diff --git a/toys/posix/chmod.c b/toys/posix/chmod.c index 572dff6a..42924399 100644 --- a/toys/posix/chmod.c +++ b/toys/posix/chmod.c @@ -43,7 +43,7 @@ static int do_chmod(struct dirtree *try) { mode_t mode; - if (try->parent && !dirtree_notdotdot(try)) return 0; + if (!dirtree_notdotdot(try)) return 0; mode = string_to_mode(TT.mode, try->st.st_mode); if (toys.optflags & FLAG_v) { diff --git a/toys/posix/grep.c b/toys/posix/grep.c index 2fe6ac27..a95203a0 100644 --- a/toys/posix/grep.c +++ b/toys/posix/grep.c @@ -313,7 +313,7 @@ static int do_grep_r(struct dirtree *new) { char *name; - if (new->parent && !dirtree_notdotdot(new)) return 0; + if (!dirtree_notdotdot(new)) return 0; if (S_ISDIR(new->st.st_mode)) return DIRTREE_RECURSE; // "grep -r onefile" doesn't show filenames, but "grep -r onedir" should. diff --git a/toys/posix/rm.c b/toys/posix/rm.c index 99fa8edf..2f99c326 100644 --- a/toys/posix/rm.c +++ b/toys/posix/rm.c @@ -28,7 +28,7 @@ static int do_rm(struct dirtree *try) int dir = S_ISDIR(try->st.st_mode), or = 0, using = 0; // Skip . and .. (yes, even explicitly on the command line: posix says to) - if (!dirtree_notdotdot(try)) return 0; + if (isdotdot(try->name)) return 0; // Intentionally fail non-recursive attempts to remove even an empty dir // (via wrong flags to unlinkat) because POSIX says to. -- cgit v1.2.3