X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-property.c;h=03bafa054701bea1609c0c30ab7d6b97804d5c88;hb=944974b4854e3f274e1beaa8165765eb385d8558;hp=6699e61510c874ed1f46080e343a599e8e2984f1;hpb=85be2aaf913f0e234058c56fab460c5d7a2c084b;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-property.c b/cmds-property.c index 6699e61..03bafa0 100644 --- a/cmds-property.c +++ b/cmds-property.c @@ -25,41 +25,14 @@ #include "commands.h" #include "props.h" #include "ctree.h" +#include "utils.h" +#include "help.h" static const char * const property_cmd_group_usage[] = { "btrfs property get/set/list [-t ] [] [value]", NULL }; -static const char * const cmd_get_usage[] = { - "btrfs property get [-t ] []", - "Gets a property from a btrfs object.", - "If no name is specified, all properties for the given object are", - "printed.", - "A filesystem object can be a the filesystem itself, a subvolume,", - "an inode or a device. The '-t ' option can be used to explicitly", - "specify what type of object you meant. This is only needed when a", - "property could be set for more then one object type. Possible types", - "are s[ubvol], f[ilesystem], i[node] and d[evice].", - NULL -}; - -static const char * const cmd_set_usage[] = { - "btrfs property set [-t ] ", - "Sets a property on a btrfs object.", - "Please see the help of 'btrfs property get' for a description of", - "objects and object types.", - NULL -}; - -static const char * const cmd_list_usage[] = { - "btrfs property list [-t ] ", - "Lists available properties with their descriptions for the given object.", - "Please see the help of 'btrfs property get' for a description of", - "objects and object types.", - NULL -}; - static int parse_prop(const char *arg, const struct prop_handler *props, const struct prop_handler **prop_ret) { @@ -75,41 +48,12 @@ static int parse_prop(const char *arg, const struct prop_handler *props, return -1; } -static int get_fsid(const char *path, u8 *fsid) -{ - int ret; - int fd; - struct btrfs_ioctl_fs_info_args args; - - fd = open(path, O_RDONLY); - if (fd < 0) { - ret = -errno; - fprintf(stderr, "ERROR: open %s failed. %s\n", path, - strerror(-ret)); - goto out; - } - - ret = ioctl(fd, BTRFS_IOC_FS_INFO, &args); - if (ret < 0) { - ret = -errno; - goto out; - } - - memcpy(fsid, args.fsid, BTRFS_FSID_SIZE); - ret = 0; - -out: - if (fd != -1) - close(fd); - return ret; -} - static int check_btrfs_object(const char *object) { int ret; u8 fsid[BTRFS_FSID_SIZE]; - ret = get_fsid(object, fsid); + ret = get_fsid(object, fsid, 0); if (ret < 0) ret = 0; else @@ -122,7 +66,18 @@ static int check_is_root(const char *object) int ret; u8 fsid[BTRFS_FSID_SIZE]; u8 fsid2[BTRFS_FSID_SIZE]; - char *tmp; + char *tmp = NULL; + char *rp; + + rp = realpath(object, NULL); + if (!rp) { + ret = -errno; + goto out; + } + if (!strcmp(rp, "/")) { + ret = 0; + goto out; + } tmp = malloc(strlen(object) + 5); if (!tmp) { @@ -134,20 +89,25 @@ static int check_is_root(const char *object) strcat(tmp, "/"); strcat(tmp, ".."); - ret = get_fsid(object, fsid); + ret = get_fsid(object, fsid, 0); if (ret < 0) { - fprintf(stderr, "ERROR: get_fsid for %s failed. %s\n", object, - strerror(-ret)); + error("get_fsid for %s failed: %s", object, strerror(-ret)); goto out; } - ret = get_fsid(tmp, fsid2); - if (ret < 0) { + ret = get_fsid(tmp, fsid2, 1); + if (ret == -ENOTTY) { ret = 0; goto out; + } else if (ret == -ENOTDIR) { + ret = 1; + goto out; + } else if (ret < 0) { + error("get_fsid for %s failed: %s", tmp, strerror(-ret)); + goto out; } - if (!memcmp(fsid, fsid2, BTRFS_FSID_SIZE)) { + if (memcmp(fsid, fsid2, BTRFS_FSID_SIZE)) { ret = 0; goto out; } @@ -156,6 +116,7 @@ static int check_is_root(const char *object) out: free(tmp); + free(rp); return ret; } @@ -195,7 +156,7 @@ static int autodetect_object_types(const char *object, int *types_out) ret = check_is_root(object); if (ret < 0) goto out; - if (ret) + if (!ret) types |= prop_object_root; } @@ -209,12 +170,6 @@ out: return ret; } -static int print_prop_help(const struct prop_handler *prop) -{ - fprintf(stdout, "%-20s%s\n", prop->name, prop->desc); - return 0; -} - static int dump_prop(const struct prop_handler *prop, const char *object, int types, @@ -227,7 +182,7 @@ static int dump_prop(const struct prop_handler *prop, if (!name_and_help) ret = prop->handler(type, object, prop->name, NULL); else - ret = print_prop_help(prop); + printf("%-20s%s\n", prop->name, prop->desc); } return ret; } @@ -264,32 +219,26 @@ static int setget_prop(int types, const char *object, ret = parse_prop(name, prop_handlers, &prop); if (ret == -1) { - fprintf(stderr, "ERROR: property is unknown\n"); + error("unknown property: %s", name); ret = 40; goto out; - } else if (ret) { - fprintf(stderr, "ERROR: parse_prop reported unknown error\n"); - ret = 42; - goto out; } types &= prop->types; if (!types) { - fprintf(stderr, - "ERROR: object is not compatible with property\n"); + error("object is not compatible with property: %s", prop->name); ret = 47; goto out; } if (count_bits(types) > 1) { - fprintf(stderr, - "ERROR: type of object is ambiguous. Please specify a type by hand.\n"); + error("type of object is ambiguous, please use option -t"); ret = 48; goto out; } if (value && prop->read_only) { - fprintf(stderr, "ERROR: %s is a read-only property.\n", + error("property is read-only property: %s", prop->name); ret = 51; goto out; @@ -310,10 +259,11 @@ out: static void parse_args(int argc, char **argv, const char * const *usage_str, int *types, char **object, - char **name, char **value) + char **name, char **value, int min_nonopt_args) { int ret; char *type_str = NULL; + int max_nonopt_args = 1; optind = 1; while (1) { @@ -327,10 +277,18 @@ static void parse_args(int argc, char **argv, break; default: usage(usage_str); - break; } } + if (name) + max_nonopt_args++; + if (value) + max_nonopt_args++; + + if (check_argc_min(argc - optind, min_nonopt_args) || + check_argc_max(argc - optind, max_nonopt_args)) + usage(usage_str); + *types = 0; if (type_str) { if (!strcmp(type_str, "s") || !strcmp(type_str, "subvol")) { @@ -345,54 +303,53 @@ static void parse_args(int argc, char **argv, !strcmp(type_str, "device")) { *types = prop_object_dev; } else { - fprintf(stderr, "ERROR: invalid object type.\n"); + error("invalid object type: %s", type_str); usage(usage_str); } } - if (object && optind < argc) - *object = argv[optind++]; - if (name && optind < argc) + *object = argv[optind++]; + if (optind < argc) *name = argv[optind++]; - if (value && optind < argc) + if (optind < argc) *value = argv[optind++]; - if (optind != argc) { - fprintf(stderr, "ERROR: invalid arguments.\n"); - usage(usage_str); - } - - if (!*types && object && *object) { + if (!*types) { ret = autodetect_object_types(*object, types); if (ret < 0) { - fprintf(stderr, - "ERROR: failed to detect object type. %s\n", + error("failed to detect object type: %s", strerror(-ret)); usage(usage_str); } if (!*types) { - fprintf(stderr, - "ERROR: object is not a btrfs object.\n"); + error("object is not a btrfs object: %s", *object); usage(usage_str); } } } -static int cmd_get(int argc, char **argv) +static const char * const cmd_property_get_usage[] = { + "btrfs property get [-t ] []", + "Gets a property from a btrfs object.", + "If no name is specified, all properties for the given object are", + "printed.", + "A filesystem object can be a the filesystem itself, a subvolume,", + "an inode or a device. The '-t ' option can be used to explicitly", + "specify what type of object you meant. This is only needed when a", + "property could be set for more then one object type. Possible types", + "are s[ubvol], f[ilesystem], i[node] and d[evice].", + NULL +}; + +static int cmd_property_get(int argc, char **argv) { int ret; - char *object; + char *object = NULL; char *name = NULL; int types = 0; - if (check_argc_min(argc, 2) || check_argc_max(argc, 4)) - usage(cmd_get_usage); - - parse_args(argc, argv, cmd_get_usage, &types, &object, &name, NULL); - if (!object) { - fprintf(stderr, "ERROR: invalid arguments.\n"); - usage(cmd_set_usage); - } + parse_args(argc, argv, cmd_property_get_usage, &types, &object, &name, + NULL, 1); if (name) ret = setget_prop(types, object, name, NULL); @@ -402,54 +359,64 @@ static int cmd_get(int argc, char **argv) return ret; } -static int cmd_set(int argc, char **argv) +static const char * const cmd_property_set_usage[] = { + "btrfs property set [-t ] ", + "Sets a property on a btrfs object.", + "Please see the help of 'btrfs property get' for a description of", + "objects and object types.", + NULL +}; + +static int cmd_property_set(int argc, char **argv) { int ret; - char *object; - char *name; - char *value; + char *object = NULL; + char *name = NULL; + char *value = NULL; int types = 0; - if (check_argc_min(argc, 4) || check_argc_max(argc, 5)) - usage(cmd_set_usage); - - parse_args(argc, argv, cmd_set_usage, &types, &object, &name, &value); - if (!object || !name || !value) { - fprintf(stderr, "ERROR: invalid arguments.\n"); - usage(cmd_set_usage); - } + parse_args(argc, argv, cmd_property_set_usage, &types, + &object, &name, &value, 3); ret = setget_prop(types, object, name, value); return ret; } -static int cmd_list(int argc, char **argv) +static const char * const cmd_property_list_usage[] = { + "btrfs property list [-t ] ", + "Lists available properties with their descriptions for the given object.", + "Please see the help of 'btrfs property get' for a description of", + "objects and object types.", + NULL +}; + +static int cmd_property_list(int argc, char **argv) { int ret; char *object = NULL; int types = 0; - if (check_argc_min(argc, 2) || check_argc_max(argc, 3)) - usage(cmd_list_usage); - - parse_args(argc, argv, cmd_list_usage, &types, &object, NULL, NULL); - if (!object) { - fprintf(stderr, "ERROR: invalid arguments.\n"); - usage(cmd_set_usage); - } + parse_args(argc, argv, cmd_property_list_usage, + &types, &object, NULL, NULL, 1); ret = dump_props(types, object, 1); return ret; } +static const char property_cmd_group_info[] = +"modify properties of filesystem objects"; + const struct cmd_group property_cmd_group = { - property_cmd_group_usage, NULL, { - { "get", cmd_get, cmd_get_usage, NULL, 0 }, - { "set", cmd_set, cmd_set_usage, NULL, 0 }, - { "list", cmd_list, cmd_list_usage, NULL, 0 }, - { 0, 0, 0, 0, 0 }, + property_cmd_group_usage, property_cmd_group_info, { + { "get", cmd_property_get, + cmd_property_get_usage, NULL, 0 }, + { "set", cmd_property_set, + cmd_property_set_usage, NULL, 0 }, + { "list", cmd_property_list, + cmd_property_list_usage, NULL, 0 }, + NULL_CMD_STRUCT } };