From 9c1f9dd3a0dec0ccb7afc63cc47f04f8edc1b5de Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 4 Sep 2014 14:05:16 +0200 Subject: sfdisk: implement --list Signed-off-by: Karel Zak --- disk-utils/sfdisk.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 136 insertions(+), 18 deletions(-) (limited to 'disk-utils/sfdisk.c') diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index ef280317d..41ede3306 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "c.h" #include "xalloc.h" @@ -36,8 +37,10 @@ #include "debug.h" #include "strutils.h" #include "closestream.h" +#include "colors.h" #include "libfdisk.h" +#include "fdisk-list.h" /* * sfdisk debug stuff (see fdisk.h and include/debug.h) @@ -53,12 +56,127 @@ UL_DEBUG_DEFINE_MASKANEMS(sfdisk) = UL_DEBUG_EMPTY_MASKNAMES; #define DBG(m, x) __UL_DBG(sfdisk, SFDISKPROG_DEBUG_, m, x) #define ON_DBG(m, x) __UL_DBG_CALL(sfdisk, SFDISKPROG_DEBUG_, m, x) +enum { + ACT_FDISK = 0, /* default */ + + ACT_ACTIVATE, + ACT_CHANGE_ID, + ACT_DUMP, + ACT_LIST, + ACT_LIST_SIZES, + ACT_LIST_TYPES, + ACT_VERIFY +}; + +struct sfdisk { + int act; /* action */ + size_t partno; /* partition number <1..N> */ + const char *devname; /* disk */ + + struct fdisk_context *cxt; /* libfdisk context */ +}; + static void sfdiskprog_init_debug(void) { __UL_INIT_DEBUG(sfdisk, SFDISKPROG_DEBUG_, 0, SFDISK_DEBUG); } +static int ask_callback(struct fdisk_context *cxt, struct fdisk_ask *ask, + void *data __attribute__((__unused__))) +{ + assert(cxt); + assert(ask); + + switch(fdisk_ask_get_type(ask)) { + case FDISK_ASKTYPE_INFO: + fputs(fdisk_ask_print_get_mesg(ask), stdout); + fputc('\n', stdout); + break; + case FDISK_ASKTYPE_WARNX: + color_scheme_fenable("warn", UL_COLOR_RED, stderr); + fputs(fdisk_ask_print_get_mesg(ask), stderr); + color_fdisable(stderr); + fputc('\n', stderr); + break; + case FDISK_ASKTYPE_WARN: + color_scheme_fenable("warn", UL_COLOR_RED, stderr); + fputs(fdisk_ask_print_get_mesg(ask), stderr); + errno = fdisk_ask_print_get_errno(ask); + fprintf(stderr, ": %m\n"); + color_fdisable(stderr); + break; + default: + break; + } + return 0; +} + +static void sfdisk_init(struct sfdisk *sf) +{ + fdisk_init_debug(0); + sfdiskprog_init_debug(); + + colors_init(UL_COLORMODE_UNDEF, "sfdisk"); + + sf->cxt = fdisk_new_context(); + if (!sf->cxt) + err(EXIT_FAILURE, _("failed to allocate libfdisk context")); + fdisk_set_ask(sf->cxt, ask_callback, NULL); +} + +static int sfdisk_deinit(struct sfdisk *sf) +{ + int rc; + + assert(sf); + assert(sf->cxt); + + if (sf->devname) + rc = fdisk_deassign_device(sf->cxt, 0); + + fdisk_unref_context(sf->cxt); + memset(sf, 0, sizeof(*sf)); + + return rc; +} + +/* --list backend */ +static int command_list_partitions(struct sfdisk *sf, int argc, char **argv) +{ + int i; + + fdisk_enable_listonly(sf->cxt, 1); + + if (argc > optind) { + for (i = optind; i < argc; i++) + print_device_pt(sf->cxt, argv[i], 0); + } else + print_all_devices_pt(sf->cxt); + + return 0; +} + +/* default command */ +static int command_fdisk(struct sfdisk *sf, int argc, char **argv) +{ + int rc; + + if (argc > 1) + sf->devname = argv[optind++]; + if (argc > 2) + sf->partno = strtou32_or_err(argv[optind++], + _("failed to parse partition number")); + if (!sf->devname) + errx(EXIT_FAILURE, _("no disk device specified")); + + rc = fdisk_assign_device(sf->cxt, sf->devname, 0); + if (rc != 0) + err(EXIT_FAILURE, _("cannot open %s"), sf->devname); + + return rc; +} + static void __attribute__ ((__noreturn__)) usage(FILE *out) { fputs(USAGE_HEADER, out); @@ -76,13 +194,15 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } + + int main(int argc, char *argv[]) { - struct fdisk_context *cxt; /* libfdisk stuff */ - const char *diskpath; + struct sfdisk _sf = { .partno = 0 }, *sf = &_sf; int rc, c; static const struct option longopts[] = { + { "list", no_argument, NULL, 'l' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, 0, 0 }, @@ -93,11 +213,14 @@ int main(int argc, char *argv[]) textdomain(PACKAGE); atexit(close_stdout); - while((c = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) { + while((c = getopt_long(argc, argv, "hlv", longopts, NULL)) != -1) { switch(c) { case 'h': usage(stdout); break; + case 'l': + sf->act = ACT_LIST; + break; case 'v': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); @@ -105,24 +228,19 @@ int main(int argc, char *argv[]) } } - fdisk_init_debug(0); - sfdiskprog_init_debug(); + sfdisk_init(sf); - if (argc - optind != 1) - usage(stderr); + switch (sf->act) { + case ACT_LIST: + rc = command_list_partitions(sf, argc - optind, argv + optind); + break; - diskpath = argv[optind]; - - cxt = fdisk_new_context(); - if (!cxt) - err(EXIT_FAILURE, _("failed to allocate libfdisk context")); - - rc = fdisk_assign_device(cxt, diskpath, 0); - if (rc != 0) - err(EXIT_FAILURE, _("cannot open %s"), diskpath); + case ACT_FDISK: + rc = command_fdisk(sf, argc - optind, argv + optind); + break; + } - rc = fdisk_deassign_device(cxt, 0); - fdisk_unref_context(cxt); + sfdisk_deinit(sf); DBG(MISC, ul_debug("bye! [rc=%d]", rc)); return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -- cgit v1.2.3-55-g7522