summaryrefslogtreecommitdiffstats
path: root/misc-utils/namei.c
diff options
context:
space:
mode:
authorSami Kerola2010-10-01 00:33:44 +0200
committerKarel Zak2010-10-01 00:36:45 +0200
commitc49e31f4ee7c35946f91335a8a3179f503bd9cf0 (patch)
treefeb1f3a8c700286cd6ced2e9bc38026470a10e84 /misc-utils/namei.c
parenttaskset: proper numbers parsing (diff)
downloadkernel-qcow2-util-linux-c49e31f4ee7c35946f91335a8a3179f503bd9cf0.tar.gz
kernel-qcow2-util-linux-c49e31f4ee7c35946f91335a8a3179f503bd9cf0.tar.xz
kernel-qcow2-util-linux-c49e31f4ee7c35946f91335a8a3179f503bd9cf0.zip
namei: parse all path arguments when an optarg path will fail
Old implementation of namei listed path all the way to non-existing file or directory, something like: f: /usr/bin/nxdir/file d / d usr d bin ? nxdir - No such file or directory (2) whiles the current implementation prints: 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. [kzak@redhat.com: - coding style changes] Signed-off-by: Sami Kerola <kerolasa@iki.fi> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/namei.c')
-rw-r--r--misc-utils/namei.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/misc-utils/namei.c b/misc-utils/namei.c
index 6853e1ec2..9873cda95 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,10 @@ 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);
+
+ nm->noent = (lstat(path, &nm->st) == -1);
+ if (nm->noent)
+ return nm;
if (S_ISLNK(nm->st.st_mode))
readlink_to_namei(nm, path);
@@ -331,7 +334,6 @@ add_namei(struct namei *parent, const char *orgpath, int start, struct namei **l
return first;
}
-
static int
follow_symlinks(struct namei *nm)
{
@@ -340,6 +342,8 @@ follow_symlinks(struct namei *nm)
for (; nm; nm = nm->next) {
struct namei *next, *last;
+ if (nm->noent)
+ continue;
if (!S_ISLNK(nm->st.st_mode))
continue;
if (++symcount > MAXSYMLINKS) {
@@ -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;
@@ -406,6 +410,11 @@ print_namei(struct namei *nm, char *path)
for (; nm; prev = nm, nm = nm->next) {
char md[11];
+ if (nm->noent) {
+ printf(_("%s - No such file or directory\n"), nm->name);
+ return -1;
+ }
+
strmode(nm->st.st_mode, md);
if (nm->mountpoint)
@@ -439,6 +448,7 @@ print_namei(struct namei *nm, char *path)
else
printf(" %s\n", nm->name);
}
+ return 0;
}
static void
@@ -482,6 +492,7 @@ main(int argc, char **argv)
{
extern int optind;
int c;
+ int rc = EXIT_SUCCESS;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -522,25 +533,29 @@ main(int argc, char **argv)
struct stat st;
if (stat(path, &st) != 0)
- err(EXIT_FAILURE, _("failed to stat: %s"), path);
+ rc = EXIT_FAILURE;
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)) {
+ rc = EXIT_FAILURE;
+ continue;
+ }
free_namei(nm);
- if (sml == -1)
- errx(EXIT_FAILURE,
- _("%s: exceeded limit of symlinks"),
- path);
+ if (sml == -1) {
+ rc = EXIT_FAILURE;
+ warnx(_("%s: exceeded limit of symlinks"), path);
+ continue;
+ }
}
}
free_idcache(ucache);
free_idcache(gcache);
- return EXIT_SUCCESS;
+ return rc;
}