mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-08 13:01:23 +00:00
Implement argp support for ino-path
Signed-off-by: Andy Grover <agrover@versity.com>
This commit is contained in:
@@ -8,44 +8,32 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <argp.h>
|
||||
|
||||
#include "sparse.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "format.h"
|
||||
#include "ioctl.h"
|
||||
#include "parse.h"
|
||||
#include "cmd.h"
|
||||
|
||||
static int ino_path_cmd(int argc, char **argv)
|
||||
struct ino_args {
|
||||
char *path;
|
||||
u64 ino;
|
||||
};
|
||||
|
||||
static int do_ino_path(struct ino_args *args)
|
||||
{
|
||||
struct scoutfs_ioctl_ino_path args;
|
||||
struct scoutfs_ioctl_ino_path ioctl_args;
|
||||
struct scoutfs_ioctl_ino_path_result *res;
|
||||
unsigned int result_bytes;
|
||||
char *endptr = NULL;
|
||||
u64 ino;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "must specify ino and path\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ino = strtoull(argv[1], &endptr, 0);
|
||||
if (*endptr != '\0' ||
|
||||
((ino == LLONG_MIN || ino == LLONG_MAX) && errno == ERANGE)) {
|
||||
fprintf(stderr, "error parsing inode number '%s'\n",
|
||||
argv[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
fd = open(argv[2], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "failed to open '%s': %s (%d)\n",
|
||||
argv[2], strerror(errno), errno);
|
||||
return ret;
|
||||
}
|
||||
fd = get_path(args->path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
result_bytes = offsetof(struct scoutfs_ioctl_ino_path_result,
|
||||
path[PATH_MAX]);
|
||||
@@ -57,13 +45,13 @@ static int ino_path_cmd(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
args.ino = ino;
|
||||
args.dir_ino = 0;
|
||||
args.dir_pos = 0;
|
||||
args.result_ptr = (intptr_t)res;
|
||||
args.result_bytes = result_bytes;
|
||||
ioctl_args.ino = args->ino;
|
||||
ioctl_args.dir_ino = 0;
|
||||
ioctl_args.dir_pos = 0;
|
||||
ioctl_args.result_ptr = (intptr_t)res;
|
||||
ioctl_args.result_bytes = result_bytes;
|
||||
for (;;) {
|
||||
ret = ioctl(fd, SCOUTFS_IOC_INO_PATH, &args);
|
||||
ret = ioctl(fd, SCOUTFS_IOC_INO_PATH, &ioctl_args);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
if (ret == -ENOENT)
|
||||
@@ -73,10 +61,10 @@ static int ino_path_cmd(int argc, char **argv)
|
||||
|
||||
printf("%.*s\n", res->path_bytes, res->path);
|
||||
|
||||
args.dir_ino = res->dir_ino;
|
||||
args.dir_pos = res->dir_pos;
|
||||
if (++args.dir_pos == 0) {
|
||||
if (++args.dir_ino == 0)
|
||||
ioctl_args.dir_ino = res->dir_ino;
|
||||
ioctl_args.dir_pos = res->dir_pos;
|
||||
if (++ioctl_args.dir_pos == 0) {
|
||||
if (++ioctl_args.dir_ino == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -92,6 +80,58 @@ out:
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
struct ino_args *args = state->input;
|
||||
int ret;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
args->path = strdup_or_error(state, arg);
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (args->ino)
|
||||
argp_error(state, "more than one argument given");
|
||||
ret = parse_u64(arg, &args->ino);
|
||||
if (ret)
|
||||
argp_error(state, "inode parse error");
|
||||
break;
|
||||
case ARGP_KEY_FINI:
|
||||
if (!args->ino) {
|
||||
argp_error(state, "must provide inode number");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{ "path", 'p', "PATH", 0, "Path to ScoutFS filesystem"},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int ino_path_cmd(int argc, char **argv)
|
||||
{
|
||||
struct argp argp = {
|
||||
options,
|
||||
parse_opt,
|
||||
"INODE-NUM",
|
||||
"Print paths that refer to inode number"
|
||||
};
|
||||
struct ino_args ino_args = {NULL};
|
||||
int ret;
|
||||
|
||||
ret = argp_parse(&argp, argc, argv, 0, NULL, &ino_args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return do_ino_path(&ino_args);
|
||||
}
|
||||
|
||||
|
||||
static void __attribute__((constructor)) ino_path_ctor(void)
|
||||
{
|
||||
cmd_register("ino-path", "<ino> <path>",
|
||||
|
||||
Reference in New Issue
Block a user