@@ -15,11 +15,18 @@
static cmdinfo_t parent_cmd;
static char *mntpt;
+struct pptr_args {
+ uint64_t filter_ino;
+ char *filter_name;
+ bool shortformat;
+};
+
static int
pptr_print(
const struct parent_rec *rec,
void *arg)
{
+ struct pptr_args *args = arg;
const char *name = (char *)rec->p_name;
unsigned int namelen;
@@ -28,7 +35,22 @@ pptr_print(
return 0;
}
+ if (args->filter_ino && rec->p_ino != args->filter_ino)
+ return 0;
+ if (args->filter_name && strcmp(args->filter_name, name))
+ return 0;
+
namelen = strlen(name);
+
+ if (args->shortformat) {
+ printf("%llu/%u/%u/%s\n",
+ (unsigned long long)rec->p_ino,
+ (unsigned int)rec->p_gen,
+ namelen,
+ rec->p_name);
+ return 0;
+ }
+
printf(_("p_ino = %llu\n"), (unsigned long long)rec->p_ino);
printf(_("p_gen = %u\n"), (unsigned int)rec->p_gen);
printf(_("p_namelen = %u\n"), namelen);
@@ -39,32 +61,55 @@ pptr_print(
static int
print_parents(
- struct xfs_handle *handle)
+ struct xfs_handle *handle,
+ struct pptr_args *args)
{
int ret;
if (handle)
ret = handle_walk_parents(handle, sizeof(*handle), pptr_print,
- NULL);
+ args);
else
- ret = fd_walk_parents(file->fd, pptr_print, NULL);
+ ret = fd_walk_parents(file->fd, pptr_print, args);
if (ret)
fprintf(stderr, "%s: %s\n", file->name, strerror(ret));
return 0;
}
+static int
+filter_path_components(
+ const char *name,
+ uint64_t ino,
+ void *arg)
+{
+ struct pptr_args *args = arg;
+
+ if (args->filter_ino && ino == args->filter_ino)
+ return ECANCELED;
+ if (args->filter_name && !strcmp(args->filter_name, name))
+ return ECANCELED;
+ return 0;
+}
+
static int
path_print(
const char *mntpt,
const struct path_list *path,
void *arg)
{
+ struct pptr_args *args = arg;
char buf[PATH_MAX];
size_t len = PATH_MAX;
int mntpt_len = strlen(mntpt);
int ret;
+ if (args->filter_ino || args->filter_name) {
+ ret = path_walk_components(path, filter_path_components, args);
+ if (ret != ECANCELED)
+ return 0;
+ }
+
/* Trim trailing slashes from the mountpoint */
while (mntpt_len > 0 && mntpt[mntpt_len - 1] == '/')
mntpt_len--;
@@ -83,15 +128,16 @@ path_print(
static int
print_paths(
- struct xfs_handle *handle)
+ struct xfs_handle *handle,
+ struct pptr_args *args)
{
int ret;
if (handle)
ret = handle_walk_parent_paths(handle, sizeof(*handle),
- path_print, NULL);
+ path_print, args);
else
- ret = fd_walk_parent_paths(file->fd, path_print, NULL);
+ ret = fd_walk_parent_paths(file->fd, path_print, args);
if (ret)
fprintf(stderr, "%s: %s\n", file->name, strerror(ret));
return 0;
@@ -103,6 +149,7 @@ parent_f(
char **argv)
{
struct xfs_handle handle;
+ struct pptr_args args = { 0 };
void *hanp = NULL;
size_t hlen;
struct fs_path *fs;
@@ -127,11 +174,27 @@ parent_f(
}
mntpt = fs->fs_dir;
- while ((c = getopt(argc, argv, "p")) != EOF) {
+ while ((c = getopt(argc, argv, "pfi:n:")) != EOF) {
switch (c) {
case 'p':
listpath_flag = 1;
break;
+ case 'i':
+ args.filter_ino = strtoull(optarg, &p, 0);
+ if (*p != '\0' || args.filter_ino == 0) {
+ fprintf(stderr,
+ _("Bad inode number '%s'.\n"),
+ optarg);
+ return 0;
+ }
+
+ break;
+ case 'n':
+ args.filter_name = optarg;
+ break;
+ case 'f':
+ args.shortformat = true;
+ break;
default:
return command_usage(&parent_cmd);
}
@@ -175,9 +238,9 @@ parent_f(
}
if (listpath_flag)
- exitcode = print_paths(ino ? &handle : NULL);
+ exitcode = print_paths(ino ? &handle : NULL, &args);
else
- exitcode = print_parents(ino ? &handle : NULL);
+ exitcode = print_parents(ino ? &handle : NULL, &args);
if (hanp)
free_handle(hanp, hlen);
@@ -195,6 +258,12 @@ printf(_(
" -p -- list the current file's paths up to the root\n"
"\n"
"If ino and gen are supplied, use them instead.\n"
+"\n"
+" -i -- Only show parent pointer records containing the given inode\n"
+"\n"
+" -n -- Only show parent pointer records containing the given filename\n"
+"\n"
+" -f -- Print records in short format: ino/gen/namelen/filename\n"
"\n"));
}
@@ -205,7 +274,7 @@ parent_init(void)
parent_cmd.cfunc = parent_f;
parent_cmd.argmin = 0;
parent_cmd.argmax = -1;
- parent_cmd.args = _("[-p] [ino gen]");
+ parent_cmd.args = _("[-p] [ino gen] [-i ino] [-n name] [-f]");
parent_cmd.flags = CMD_NOMAP_OK;
parent_cmd.oneline = _("print parent inodes");
parent_cmd.help = parent_help;
@@ -1013,7 +1013,7 @@ and
options behave as described above, in
.B chproj.
.TP
-.BR parent " [ " \-p " ] [" " ino gen " "]"
+.BR parent " [ " \-fp " ] [-i " ino "] [-n " name "] [" " ino gen " "]"
By default this command prints out the parent inode numbers,
inode generation numbers and basenames of all the hardlinks which
point to the inode of the current file.
@@ -1030,6 +1030,15 @@ the open file.
.RS 1.0i
.PD 0
.TP 0.4i
+.B \-f
+Print records in short format: ino/gen/namelen/name
+.TP 0.4i
+.B \-i
+Only show parent pointer records containing this inode number.
+.TP 0.4i
+.B \-n
+Only show parent pointer records containing this directory entry name.
+.TP 0.4i
.B \-p
the output is similar to the default output except pathnames up to
the mount-point are printed out instead of the component name.