Old implementation of namei listed path all the way to non-existing file or directory, something like: # namei /usr/bin/nxdir/file f: /usr/bin/nxdir/file d / d usr d bin ? nxdir - No such file or directory (2) whiles the current implementation prints: # namei /usr/bin/nxdir/file namei: failed to stat: /usr/bin/nxdir/file: No such file or directory The new output it's not helpful. I am especially interested see where the path is broken when a path is symlink to other path with symlink, and few more like that, and something somewhere is broken. -- Sami Kerola http://www.iki.fi/kerolasa/
Signed-off-by: Sami Kerola <kerolasa@xxxxxx> --- misc-utils/namei.c | 39 ++++++++++++++++++++++++++++----------- 1 files changed, 28 insertions(+), 11 deletions(-) diff --git a/misc-utils/namei.c b/misc-utils/namei.c index 6853e1e..a6e2064 100644 --- a/misc-utils/namei.c +++ b/misc-utils/namei.c @@ -60,6 +60,7 @@ struct namei { struct namei *next; /* next item */ int level; int mountpoint; /* is mount point */ + int noent; /* is this item not existing */ }; struct idcache { @@ -250,8 +251,11 @@ new_namei(struct namei *parent, const char *path, const char *fname, int lev) nm->name = strdup(fname); if (!nm->name) err(EXIT_FAILURE, _("out of memory?")); - if (lstat(path, &nm->st) == -1) - err(EXIT_FAILURE, _("could not stat '%s'"), path); + if (lstat(path, &nm->st) == -1) { + nm->noent = 1; + } else { + nm->noent = 0; + } if (S_ISLNK(nm->st.st_mode)) readlink_to_namei(nm, path); @@ -394,7 +398,7 @@ strmode(mode_t mode, char *str) str[10] = '\0'; } -static void +static int print_namei(struct namei *nm, char *path) { struct namei *prev = NULL; @@ -408,6 +412,12 @@ print_namei(struct namei *nm, char *path) strmode(nm->st.st_mode, md); + if (nm->noent) { + printf(" %s no such file or directory\n", + nm->name); + return 1; + } + if (nm->mountpoint) md[0] = 'D'; @@ -439,6 +449,7 @@ print_namei(struct namei *nm, char *path) else printf(" %s\n", nm->name); } + return 0; } static void @@ -482,6 +493,7 @@ main(int argc, char **argv) { extern int optind; int c; + int exitvalue = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -521,26 +533,31 @@ main(int argc, char **argv) struct namei *nm = NULL; struct stat st; - if (stat(path, &st) != 0) - err(EXIT_FAILURE, _("failed to stat: %s"), path); + if (stat(path, &st) != 0) { + exitvalue = 1; + } nm = add_namei(NULL, path, 0, NULL); if (nm) { int sml = 0; if (!(flags & NAMEI_NOLINKS)) sml = follow_symlinks(nm); - print_namei(nm, path); + if (print_namei(nm, path)) { + exitvalue = 1; + continue; + } free_namei(nm); - if (sml == -1) - errx(EXIT_FAILURE, - _("%s: exceeded limit of symlinks"), - path); + if (sml == -1) { + exitvalue = 1; + warnx(_("%s: exceeded limit of symlinks"), path); + continue; + } } } free_idcache(ucache); free_idcache(gcache); - return EXIT_SUCCESS; + return exitvalue; } -- 1.7.3