From: Karel Zak Date: Tue, 9 Sep 2014 13:51:19 +0000 (+0200) Subject: sfdisk: improve UI X-Git-Tag: v2.26-rc1~391 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3186f4a92719ac97c6a1a12ef3a2a417a0cd9bf0;p=thirdparty%2Futil-linux.git sfdisk: improve UI Signed-off-by: Karel Zak --- diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index d9608d770f..61d57cbe6b 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -343,6 +343,51 @@ static void sfdisk_print_partition(struct sfdisk *sf, int n) fdisk_unref_partition(pa); } +static void command_fdisk_help(void) +{ + fputs(_("\nHelp:\n"), stdout); + + fputc('\n', stdout); + color_scheme_enable("help-title", UL_COLOR_BOLD); + fputs(_(" Commands:\n"), stdout); + color_disable(); + fputs(_(" write interupts input and write the partition table.\n"), stdout); + fputs(_(" abort interupts input and exit.\n"), stdout); + fputs(_(" print print partition table.\n"), stdout); + fputs(_(" help this help.\n"), stdout); + + fputc('\n', stdout); + color_scheme_enable("help-title", UL_COLOR_BOLD); + fputs(_(" Input format:\n"), stdout); + color_disable(); + fputs(_(" \n"), stdout); + + fputc('\n', stdout); + fputs(_(" begin of the partition in sectors. The default is the first\n" + " free space.\n"), stdout); + + fputc('\n', stdout); + fputs(_(" size of the partition in sectors if specified in format\n" + " {K,M,G,T,P,E,Z,Y} then it's interpreted as size\n" + " in bytes. The default is all available space.\n"), stdout); + + fputc('\n', stdout); + fputs(_(" partition type. The default is Linux data partition.\n"), stdout); + fputs(_(" MBR: hex or L,S,E,X shortcuts.\n"), stdout); + fputs(_(" GPT: uuid or L,S,H shortcuts.\n"), stdout); + + fputc('\n', stdout); + fputs(_(" '*' to mark MBR partition as bootable. \n"), stdout); + + fputc('\n', stdout); + color_scheme_enable("help-title", UL_COLOR_BOLD); + fputs(_(" Example:\n"), stdout); + color_disable(); + fputs(_(" , 4G creates 4GiB partition on default start offset.\n"), stdout); + fputc('\n', stdout); +} + + /* * sfdisk [[-N] ] * @@ -373,9 +418,19 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) if (rc) err(EXIT_FAILURE, _("cannot open %s"), devname); + if (isatty(STDIN_FILENO)) { + color_scheme_enable("welcome", UL_COLOR_GREEN); + fdisk_info(sf->cxt, _("\nWelcome to sfdisk (%s)."), PACKAGE_STRING); + color_disable(); + fdisk_info(sf->cxt, _("Changes will remain in memory only, until you decide to write them.\n" + "Be careful before using the write command.\n")); + } + list_disk_geometry(sf->cxt); - printf(_("\nOld situation:")); - list_disklabel(sf->cxt); + if (fdisk_has_label(sf->cxt)) { + fdisk_info(sf->cxt, _("\nOld situation:")); + list_disklabel(sf->cxt); + } if (sf->label) label = sf->label; @@ -386,37 +441,34 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) fdisk_script_set_header(dp, "label", label); - fputc('\n', stdout); - printf(_("Input in the following format; absent fields get a default value.\n" - " \n")); - - fputc('\n', stdout); - printf(_("If the size is specified by {K,M,G,T,P,E,Z,Y} then\n" - "it's interpreted as size in bytes rather then in sectors.\n")); - - fputc('\n', stdout); - if (!fdisk_has_label(sf->cxt)) - printf(_("sfdisk is going to create a new '%s' disk label.\n" - "Use 'label: ' before you define a first partition\n" - "to override the default.\n\n"), label); + if (isatty(STDIN_FILENO)) { + if (!fdisk_has_label(sf->cxt) && !sf->label) + fdisk_info(sf->cxt, + _("\nsfdisk is going to create a new '%s' disk label.\n" + "Use 'label: ' before you define a first partition\n" + "to override the default."), label); + fdisk_info(sf->cxt, _("\nType 'help' to get more information.\n")); + } else + fputc('\n', stdout); tb = fdisk_script_get_table(dp); assert(tb); do { size_t nparts; - char *partname; DBG(PARSE, ul_debug("<---next-line--->")); if (next_partno == (size_t) -1) next_partno = fdisk_table_get_nents(tb); - partname = fdisk_partname(devname, next_partno + 1); - if (!partname) - err(EXIT_FAILURE, _("failed to allocate partition name")); - fflush(stdout); - printf("%s: ", partname); - free(partname); + if (created) { + char *partname = fdisk_partname(devname, next_partno + 1); + if (!partname) + err(EXIT_FAILURE, _("failed to allocate partition name")); + printf("%s: ", partname); + free(partname); + } else + printf(">>> "); rc = fdisk_script_read_line(dp, stdin, buf, sizeof(buf)); @@ -425,18 +477,30 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) rc = 0; break; } else if (rc < 0) { + const char *p; + DBG(PARSE, ul_debug("script parsing failed, trying sfdisk specific commands")); buf[sizeof(buf) - 1] = '\0'; - - if (strcmp(buf, "print") == 0) + p = skip_blank(buf); + rc = 0; + if (strcmp(p, "print") == 0) list_disklabel(sf->cxt); - else if (strcmp(buf, "quit") == 0) + else if (strcmp(p, "help") == 0) + command_fdisk_help(); + else if (strcmp(p, "write") == 0) break; - else if (strcmp(buf, "abort") == 0) { + else if (strcmp(p, "abort") == 0) { rc = -1; break; - } else - fdisk_warnx(sf->cxt, _("unsupported command")); + } else { + if (isatty(STDIN_FILENO)) + fdisk_warnx(sf->cxt, _("unsupported command")); + else { + fdisk_warnx(sf->cxt, _("line %d: unsupported command"), + fdisk_script_get_nlines(dp)); + break; + } + } continue; } @@ -445,9 +509,13 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) size_t cur_partno; struct fdisk_partition *pa = fdisk_table_get_partition(tb, nparts - 1); - fputc('\n', stdout); - assert(pa); + + if (!fdisk_partition_get_start(pa) && + !fdisk_partition_start_is_default(pa)) { + fdisk_info(sf->cxt, _("Ignore partition %zu"), next_partno + 1); + continue; + } if (!created) { /* create a disklabel */ rc = fdisk_apply_script_headers(sf->cxt, dp); created = !rc; @@ -461,19 +529,21 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) } else if (pa) /* error, drop partition from script */ fdisk_table_remove_partition(tb, pa); } else - printf(_("\nScript header accepted.\n")); + fdisk_info(sf->cxt, _("Script header accepted.")); } while (1); if (!rc) { - printf(_("\nNew situation:")); + fdisk_info(sf->cxt, _("\nNew situation:")); list_disklabel(sf->cxt); } if (!rc) rc = fdisk_write_disklabel(sf->cxt); - if (!rc) - rc = fdisk_deassign_device(sf->cxt, 1); - + if (!rc) { + fdisk_info(sf->cxt, _("\nThe partition table has been altered.")); + fdisk_reread_partition_table(sf->cxt); + rc = fdisk_deassign_device(sf->cxt, 0); + } fdisk_unref_script(dp); return rc; } diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index fc0025600a..e156c671ec 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -286,9 +286,8 @@ size_t fdisk_get_npartitions(struct fdisk_context *cxt) int fdisk_is_labeltype(struct fdisk_context *cxt, enum fdisk_labeltype id) { assert(cxt); - assert(cxt->label); - return fdisk_label_get_type(cxt->label) == id; + return cxt->label && fdisk_label_get_type(cxt->label) == id; } /** diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index b90a01f5ba..443830ba8e 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -1029,6 +1029,8 @@ static int add_partition(struct fdisk_context *cxt, size_t n, temp); temp = start; read = 0; + if (pa && (pa->start || pa->start_follow_default)) + break; } if (!read && start == temp) { diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index b806b349b0..9f9f28faf9 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -415,6 +415,7 @@ void fdisk_unref_script(struct fdisk_script *dp); const char *fdisk_script_get_header(struct fdisk_script *dp, const char *name); int fdisk_script_set_header(struct fdisk_script *dp, const char *name, const char *data); struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp); +int fdisk_script_get_nlines(struct fdisk_script *dp); int fdisk_script_read_context(struct fdisk_script *dp, struct fdisk_context *cxt); int fdisk_script_write_file(struct fdisk_script *dp, FILE *f); diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index ebfaf61a53..cafe471fbd 100644 --- a/libfdisk/src/script.c +++ b/libfdisk/src/script.c @@ -291,6 +291,18 @@ static struct fdisk_label *script_get_label(struct fdisk_script *dp) return dp->label; } +/** + * fdisk_script_get_nlines: + * @dp: script + * + * Returns: number of parsed lines or <0 on error. + */ +int fdisk_script_get_nlines(struct fdisk_script *dp) +{ + assert(dp); + return dp->nlines; +} + /** * fdisk_script_read_context: * @dp: script @@ -637,7 +649,8 @@ static int parse_script_line(struct fdisk_script *dp, char *s) } else if (!strncasecmp(p, "type=", 5) || !strncasecmp(p, "Id=", 3)) { /* backward compatiility */ char *type; - p += 5; + + p += (*p == 'I' ? 3 : 5); /* "Id=" or "type=" */ rc = next_string(&p, &type); if (rc) diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c index e5cc79aa30..efa55cd101 100644 --- a/libfdisk/src/table.c +++ b/libfdisk/src/table.c @@ -537,7 +537,9 @@ int fdisk_table_wrong_order(struct fdisk_table *tb) * @tb: table * * Add partitions from table @tb to the in-memory disk label. See - * fdisk_add_partition(), fdisk_delete_all_partitions(). + * fdisk_add_partition(), fdisk_delete_all_partitions(). The partitons + * that does not define start (or does not follow the default start) + * are ingored. * * Returns: 0 on success, <0 on error. */ @@ -554,6 +556,8 @@ int fdisk_apply_table(struct fdisk_context *cxt, struct fdisk_table *tb) fdisk_reset_iter(&itr, FDISK_ITER_FORWARD); while (tb && fdisk_table_next_partition(tb, &itr, &pa) == 0) { + if (!pa->start && !pa->start_follow_default) + continue; rc = fdisk_add_partition(cxt, pa, NULL); if (rc) break;