diff options
| -rw-r--r-- | disk-utils/fdisk.c | 50 | ||||
| -rw-r--r-- | disk-utils/sfdisk.8 | 47 | ||||
| -rw-r--r-- | disk-utils/sfdisk.c | 7 | ||||
| -rw-r--r-- | libfdisk/src/dos.c | 16 | ||||
| -rw-r--r-- | libfdisk/src/fdiskP.h | 17 | ||||
| -rw-r--r-- | libfdisk/src/gpt.c | 13 | ||||
| -rw-r--r-- | libfdisk/src/libfdisk.h.in | 36 | ||||
| -rw-r--r-- | libfdisk/src/libfdisk.sym | 3 | ||||
| -rw-r--r-- | libfdisk/src/parttype.c | 236 | ||||
| -rw-r--r-- | libfdisk/src/script.c | 94 |
10 files changed, 366 insertions, 153 deletions
diff --git a/disk-utils/fdisk.c b/disk-utils/fdisk.c index a539c70ef1..17d60b1a94 100644 --- a/disk-utils/fdisk.c +++ b/disk-utils/fdisk.c @@ -480,9 +480,15 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int return NULL; *canceled = 0; - q = fdisk_label_has_code_parttypes(lb) ? - _("Hex code (type L to list all codes): ") : - _("Partition type (type L to list all types): "); + + if (fdisk_label_has_parttypes_shortcuts(lb)) + q = fdisk_label_has_code_parttypes(lb) ? + _("Hex code or alias (type L to list all): ") : + _("Partition type or alias (type L to list all): "); + else + q = fdisk_label_has_code_parttypes(lb) ? + _("Hex code (type L to list all codes): ") : + _("Partition type (type L to list all types): "); do { char buf[256] = { '\0' }; int rc = get_user_reply(q, buf, sizeof(buf)); @@ -496,8 +502,10 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int if (buf[1] == '\0' && toupper(*buf) == 'L') list_partition_types(cxt); else if (*buf) { - struct fdisk_parttype *t = fdisk_label_parse_parttype(lb, buf); - + struct fdisk_parttype *t = fdisk_label_advparse_parttype(lb, buf, + FDISK_PARTTYPE_PARSE_DATA + | FDISK_PARTTYPE_PARSE_ALIAS + | FDISK_PARTTYPE_PARSE_SEQNUM); if (!t) fdisk_info(cxt, _("Failed to parse '%s' partition type."), buf); return t; @@ -510,8 +518,9 @@ static struct fdisk_parttype *ask_partition_type(struct fdisk_context *cxt, int void list_partition_types(struct fdisk_context *cxt) { - size_t ntypes = 0; + size_t ntypes = 0, next = 0; struct fdisk_label *lb; + int pager = 0; assert(cxt); lb = fdisk_get_label(cxt, NULL); @@ -525,7 +534,7 @@ void list_partition_types(struct fdisk_context *cxt) /* * Prints in 4 columns in format <hex> <name> */ - size_t last[4], done = 0, next = 0, size; + size_t last[4], done = 0, size; int i; size = ntypes; @@ -562,6 +571,7 @@ void list_partition_types(struct fdisk_context *cxt) } } while (done < last[0]); + putchar('\n'); } else { /* * Prints 1 column in format <idx> <name> <typestr> @@ -569,6 +579,7 @@ void list_partition_types(struct fdisk_context *cxt) size_t i; pager_open(); + pager = 1; for (i = 0; i < ntypes; i++) { const struct fdisk_parttype *t = fdisk_label_get_parttype(lb, i); @@ -577,9 +588,30 @@ void list_partition_types(struct fdisk_context *cxt) fdisk_parttype_get_string(t)); } - pager_close(); } - putchar('\n'); + + + /* + * Aliases + */ + if (fdisk_label_has_parttypes_shortcuts(lb)) { + const char *alias = NULL, *typestr = NULL; + int rc = 0; + + fputs(_("\nAliases:\n"), stdout); + + for (next = 0; rc == 0 || rc == 2; next++) { + /* rc: <0 error, 0 success, 1 end, 2 deprecated */ + rc = fdisk_label_get_parttype_shortcut(lb, + next, &typestr, NULL, &alias); + if (rc == 0) + printf(" %-14s - %s\n", alias, typestr); + } + } + + if (pager) + pager_close(); + } void toggle_dos_compatibility_flag(struct fdisk_context *cxt) diff --git a/disk-utils/sfdisk.8 b/disk-utils/sfdisk.8 index 8b96b2e316..d5d273b1f0 100644 --- a/disk-utils/sfdisk.8 +++ b/disk-utils/sfdisk.8 @@ -136,7 +136,9 @@ List the free unpartitioned areas on all or the specified devices. .TP .BR "\-\-part\-attrs \fIdevice partition-number " [ \fIattributes ] Change the GPT partition attribute bits. If \fIattributes\fR is not specified, -then print the current partition settings. The \fIattributes\fR argument is a +then print the current partition settings. +.sp +The \fIattributes\fR argument is a comma- or space-delimited list of bits. The currently supported attribute bits are: RequiredPartition, NoBlockIOProtocol, LegacyBIOSBootable and GUID-specific bits in the range from 48 to 63. For example, the string @@ -148,8 +150,11 @@ then print the current partition label. .TP .BR "\-\-part\-type \fIdevice partition-number " [ \fItype ] Change the partition type. If \fItype\fR is not specified, then print the -current partition type. The \fItype\fR argument is hexadecimal for MBR, -or a GUID for GPT. For backward compatibility the options \fB\-c\fR and +current partition type. +.sp +The \fItype\fR argument is hexadecimal for MBR, +GUID for GPT, type alias (e.g. "linux") or type shortcut (e.g. 'L'). +For backward compatibility the options \fB\-c\fR and \fB\-\-id\fR have the same meaning as this one. .TP .BR "\-\-part\-uuid \fIdevice partition-number " [ \fIuuid ] @@ -413,42 +418,48 @@ partition; existing partitions will be resized as required. The partition .I type is given in hex for MBR (DOS) where 0x prefix is optional; a GUID string for -GPT; or a shortcut. It's recommended to use two letters for MBR hex codes to -avoid collision between shortcut 'E' and '0E' MBR hex code. For backward +GPT; a shortcut or an alias. It's recommended to use two letters for MBR hex codes to +avoid collision between deprecated shortcut 'E' and '0E' MBR hex code. For backward compatibility sfdisk tries to interpret .I type -as a shortcut as a first possibility. Supported shortcuts: +as a shortcut as a first possibility in partitioning scripts although on another places (e.g. +\fB\-\-part-type command)\fR it tries shortcuts as the last possibility. + +Since v2.36 libfdisk supports partition type aliases as extension to shortcuts. The alias is a +simple human readable word (e.g. "linux"). + +Supported shortcuts and aliases: .RS .TP -.B L +.B L - alias 'linux' Linux; means 83 for MBR and 0FC63DAF-8483-4772-8E79-3D69D8477DE4 for GPT. .TP -.B S +.B S - alias 'swap' swap area; means 82 for MBR and 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F for GPT .TP -.B E -extended partition; means 05 for MBR +.B Ex - alias 'extended' +MBR extended partition; means 05 for MBR. The original shortcut 'E' is deprecated due to collision with +0x0E MBR partition type. .TP -.B H +.B H - alias 'home' home partition; means 933AC7E1-2EB4-4F13-B844-0E14E2AEF915 for GPT .TP -.B X -linux extended partition; means 85 for MBR. -.TP -.B U +.B U - alias 'uefi' EFI System partition, means EF for MBR and C12A7328-F81F-11D2-BA4B-00A0C93EC93B for GPT .TP -.B R +.B R - alias 'raid' Linux RAID; means FD for MBR and A19D880F-05FC-4D3B-A006-743F0F84911E for GPT .TP -.B V +.B V - alias 'lvm' LVM; means 8E for MBR and E6D6D379-F507-44C2-A23C-238F2A3DF928 for GPT .RE .PP The default .I type value is -.I L +.I linux +.sp +The shortcut 'X' for Linux extended partition (85) is deprecated in favour of 'Ex'. .I bootable is specified as [\fB*\fR|\fB-\fR], with as default not-bootable. The diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index c77d4942a5..0c14627799 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -1153,7 +1153,10 @@ static int command_parttype(struct sfdisk *sf, int argc, char **argv) backup_partition_table(sf, devname); /* parse <type> and apply to PT */ - type = fdisk_label_parse_parttype(lb, typestr); + type = fdisk_label_advparse_parttype(lb, typestr, + FDISK_PARTTYPE_PARSE_DATA + | FDISK_PARTTYPE_PARSE_ALIAS + | FDISK_PARTTYPE_PARSE_SHORTCUT); if (!type) errx(EXIT_FAILURE, _("failed to parse %s partition type '%s'"), fdisk_label_get_name(lb), typestr); @@ -1468,7 +1471,7 @@ static void command_fdisk_help(void) fputc('\n', stdout); fputs(_(" <type> The partition type. Default is a Linux data partition.\n"), stdout); - fputs(_(" MBR: hex or L,S,E,X,U,R,V shortcuts.\n"), stdout); + fputs(_(" MBR: hex or L,S,Ex,X,U,R,V shortcuts.\n"), stdout); fputs(_(" GPT: UUID or L,S,H,U,R,V shortcuts.\n"), stdout); fputc('\n', stdout); diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index ae06e179da..a79912e8b5 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -70,6 +70,18 @@ static struct fdisk_parttype dos_parttypes[] = { #include "pt-mbr-partnames.h" }; +static const struct fdisk_shortcut dos_parttype_cuts[] = +{ + { .shortcut = "L", .alias = "linux", .data = "83" }, + { .shortcut = "S", .alias = "swap", .data = "82" }, + { .shortcut = "E", .alias = "extended", .data = "05", .deprecated = 1 }, /* collision with 0x0e type */ + { .shortcut = "Ex",.alias = "extended", .data = "05" }, /* MBR extended */ + { .shortcut = "U", .alias = "uefi", .data = "EF" }, /* UEFI system */ + { .shortcut = "R", .alias = "raid", .data = "FD" }, /* Linux RAID */ + { .shortcut = "V", .alias = "lvm", .data = "8E" }, /* LVM */ + { .shortcut = "X", .alias = "linuxex", .data = "85" } /* Linux extended */ +}; + #define set_hsc(h,s,c,sector) { \ s = sector % cxt->geom.sectors + 1; \ sector /= cxt->geom.sectors; \ @@ -2556,8 +2568,12 @@ struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt __attribute__ lb->name = "dos"; lb->id = FDISK_DISKLABEL_DOS; lb->op = &dos_operations; + lb->parttypes = dos_parttypes; lb->nparttypes = ARRAY_SIZE(dos_parttypes) - 1; + lb->parttype_cuts = dos_parttype_cuts; + lb->nparttype_cuts = ARRAY_SIZE(dos_parttype_cuts); + lb->fields = dos_fields; lb->nfields = ARRAY_SIZE(dos_fields); diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index ec07f1fc89..f291c08b61 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -123,6 +123,17 @@ enum { #define fdisk_parttype_is_invisible(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE)) #define fdisk_parttype_is_allocated(_x) ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED)) +/* + * Shortcut (used for partition types) + */ +struct fdisk_shortcut { + const char *shortcut; /* shortcut, usually one letter (e.h. "H") */ + const char *alias; /* human readable alias (e.g. "home") */ + const char *data; /* for example partition type */ + + unsigned int deprecated : 1; +}; + struct fdisk_partition { int refcount; /* reference counter */ @@ -278,6 +289,9 @@ struct fdisk_label { struct fdisk_parttype *parttypes; /* supported partitions types */ size_t nparttypes; /* number of items in parttypes[] */ + const struct fdisk_shortcut *parttype_cuts; /* partition type shortcuts */ + size_t nparttype_cuts; /* number of items in parttype_cuts */ + size_t nparts_max; /* maximal number of partitions */ size_t nparts_cur; /* number of currently used partitions */ @@ -519,4 +533,7 @@ int fdisk_do_wipe(struct fdisk_context *cxt); int fdisk_has_wipe_area(struct fdisk_context *cxt, uint64_t start, uint64_t size); int fdisk_check_collisions(struct fdisk_context *cxt); +/* parttype.c */ +const char *fdisk_label_translate_type_shortcut(const struct fdisk_label *lb, char *cut); + #endif /* _LIBFDISK_PRIVATE_H */ diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 4915b9a37c..25555a3958 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -156,6 +156,16 @@ static struct fdisk_parttype gpt_parttypes[] = #include "pt-gpt-partnames.h" }; +static const struct fdisk_shortcut gpt_parttype_cuts[] = +{ + { .shortcut = "L", .alias = "linux", .data = "0FC63DAF-8483-4772-8E79-3D69D8477DE4" }, /* Linux */ + { .shortcut = "S", .alias = "swap", .data = "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" }, /* Swap */ + { .shortcut = "H", .alias = "home", .data = "933AC7E1-2EB4-4F13-B844-0E14E2AEF915" }, /* Home */ + { .shortcut = "U", .alias = "uefi", .data = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, /* UEFI system */ + { .shortcut = "R", .alias = "raid", .data = "A19D880F-05FC-4D3B-A006-743F0F84911E" }, /* Linux RAID */ + { .shortcut = "V", .alias = "lvm", .data = "E6D6D379-F507-44C2-A23C-238F2A3DF928" } /* LVM */ +}; + #define alignment_required(_x) ((_x)->grain != (_x)->sector_size) /* gpt_entry macros */ @@ -3134,8 +3144,11 @@ struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt __attribute__ lb->name = "gpt"; lb->id = FDISK_DISKLABEL_GPT; lb->op = &gpt_operations; + lb->parttypes = gpt_parttypes; lb->nparttypes = ARRAY_SIZE(gpt_parttypes); + lb->parttype_cuts = gpt_parttype_cuts; + lb->nparttype_cuts = ARRAY_SIZE(gpt_parttype_cuts); lb->fields = gpt_fields; lb->nfields = ARRAY_SIZE(gpt_fields); diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in index 89fad448e7..bf05290f9c 100644 --- a/libfdisk/src/libfdisk.h.in +++ b/libfdisk/src/libfdisk.h.in @@ -264,7 +264,13 @@ int fdisk_parttype_set_typestr(struct fdisk_parttype *t, const char *str); int fdisk_parttype_set_code(struct fdisk_parttype *t, int code); size_t fdisk_label_get_nparttypes(const struct fdisk_label *lb); struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, size_t n); +int fdisk_label_get_parttype_shortcut( + const struct fdisk_label *lb, size_t n, + const char **typestr, + const char **shortcut, + const char **alias); int fdisk_label_has_code_parttypes(const struct fdisk_label *lb); +int fdisk_label_has_parttypes_shortcuts(const struct fdisk_label *lb); struct fdisk_parttype *fdisk_label_get_parttype_from_code( const struct fdisk_label *lb, unsigned int code); @@ -277,6 +283,36 @@ struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type); struct fdisk_parttype *fdisk_label_parse_parttype( const struct fdisk_label *lb, const char *str); +struct fdisk_parttype *fdisk_label_advparse_parttype( + const struct fdisk_label *lb, + const char *str, + int flags); + +/** + * fdisk_parttype_parser_flags: + * @FDISK_PARTTYPE_PARSE_DATA: parse hex or UUID from string + * @FDISK_PARTTYPE_PARSE_DATALAST: try hex or UUID as the last possibility (don't use!) + * @FDISK_PARTTYPE_PARSE_SHORTCUT: try input interpret as type shortcut (e.g 'L' for linux partition) + * @FDISK_PARTTYPE_PARSE_ALIAS: try input interpret as type alias (e.g. 'linux' for linux partition) + * @FDISK_PARTTYPE_PARSE_DEPRECATED: accept also deprecated aliases and shortcuts + * @FDISK_PARTTYPE_PARSE_DEFAULT: recommended flags for new code + * @FDISK_PARTTYPE_PARSE_NOUNKNOWN: ignore unknown types + */ +enum fdisk_parttype_parser_flags { + FDISK_PARTTYPE_PARSE_DATA = (1 << 1), + FDISK_PARTTYPE_PARSE_DATALAST = (1 << 2), + FDISK_PARTTYPE_PARSE_SHORTCUT = (1 << 3), + FDISK_PARTTYPE_PARSE_ALIAS = (1 << 4), + FDISK_PARTTYPE_PARSE_DEPRECATED = (1 << 5), + FDISK_PARTTYPE_PARSE_NOUNKNOWN = (1 << 6), + FDISK_PARTTYPE_PARSE_SEQNUM = (1 << 7), + + FDISK_PARTTYPE_PARSE_DEFAULT = (FDISK_PARTTYPE_PARSE_DATA | \ + FDISK_PARTTYPE_PARSE_SHORTCUT | \ + FDISK_PARTTYPE_PARSE_ALIAS | \ + FDISK_PARTTYPE_PARSE_SEQNUM ) +}; + const char *fdisk_parttype_get_string(const struct fdisk_parttype *t); unsigned int fdisk_parttype_get_code(const struct fdisk_parttype *t); const char *fdisk_parttype_get_name(const struct fdisk_parttype *t); diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym index f37d18e1ac..3e30310571 100644 --- a/libfdisk/src/libfdisk.sym +++ b/libfdisk/src/libfdisk.sym @@ -312,4 +312,7 @@ FDISK_2.36 { fdisk_set_disklabel_id_from_string; fdisk_gpt_disable_relocation; fdisk_gpt_enable_minimize; + fdisk_label_has_parttypes_shortcuts; + fdisk_label_advparse_parttype; + fdisk_label_get_parttype_shortcut; } FDISK_2.35; diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c index d5ad434f0b..36d12216d5 100644 --- a/libfdisk/src/parttype.c +++ b/libfdisk/src/parttype.c @@ -146,6 +146,41 @@ struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, si } /** + * fdisk_label_get_parttype_shortcut: + * @lb: label + * @n: number + * @typestr: returns type as string + * @shortcut: returns type shortcut string + * @alias: returns type alias string + * + * Returns: return 0 on success, <0 on error, 2 for deprecated alias, 1 for @n out of range + * + * Since: v2.36 + */ +int fdisk_label_get_parttype_shortcut(const struct fdisk_label *lb, size_t n, + const char **typestr, const char **shortcut, const char **alias) +{ + const struct fdisk_shortcut *sc; + + if (!lb) + return -EINVAL; + if (n >= lb->nparttype_cuts) + return 1; + + sc = &lb->parttype_cuts[n]; + if (typestr) + *typestr = sc->data; + if (shortcut) + *shortcut = sc->shortcut; + if (alias) + *alias = sc->alias; + + return sc->deprecated == 1 ? 2 : 0; + +} + + +/** * fdisk_label_has_code_parttypes: * @lb: label * @@ -161,6 +196,20 @@ int fdisk_label_has_code_parttypes(const struct fdisk_label *lb) return 1; } +/** + * fdisk_label_has_parttypes_shortcuts + * @lb: label + * + * Returns: 1 if the label support shortuts/aliases for partition types or 0. + * + * Since: 2.36 + */ +int fdisk_label_has_parttypes_shortcuts(const struct fdisk_label *lb) +{ + assert(lb); + return lb->nparttype_cuts ? 1 : 0; +} + /** * fdisk_label_get_parttype_from_code: @@ -266,79 +315,186 @@ struct fdisk_parttype *fdisk_copy_parttype(const struct fdisk_parttype *type) return t; } -/** - * fdisk_label_parse_parttype: - * @lb: label - * @str: string to parse from - * - * Parses partition type from @str according to the label. The function returns - * a pointer to static table of the partition types, or newly allocated - * partition type for unknown types (see fdisk_parttype_is_unknown(). It's - * safe to call fdisk_unref_parttype() for all results. - * - * Returns: pointer to type or NULL on error. - */ -struct fdisk_parttype *fdisk_label_parse_parttype( +static struct fdisk_parttype *parttype_from_data( const struct fdisk_label *lb, - const char *str) + const char *str, + unsigned int *xcode, + int use_seqnum) { struct fdisk_parttype *types, *ret = NULL; char *end = NULL; assert(lb); + assert(str); + if (xcode) + *xcode = 0; if (!lb->nparttypes) return NULL; - DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) partition type", - str, lb->name)); + DBG(LABEL, ul_debugobj(lb, " parsing '%s' data", str)); types = lb->parttypes; if (types[0].typestr == NULL) { - unsigned int code = 0; + unsigned int code; - DBG(LABEL, ul_debugobj(lb, " parsing hex")); + DBG(LABEL, ul_debugobj(lb, " +hex")); errno = 0; code = strtol(str, &end, 16); if (errno || *end != '\0') { - DBG(LABEL, ul_debugobj(lb, "parsing failed: %m")); + DBG(LABEL, ul_debugobj(lb, " failed: %m")); return NULL; } + if (xcode) + *xcode = code; ret = fdisk_label_get_parttype_from_code(lb, code); - if (ret) - goto done; - - ret = fdisk_new_unknown_parttype(code, NULL); } else { - int i; - - DBG(LABEL, ul_debugobj(lb, " parsing string")); + DBG(LABEL, ul_debugobj(lb, " +string")); /* maybe specified by type string (e.g. UUID) */ ret = fdisk_label_get_parttype_from_string(lb, str); - if (ret) - goto done; - /* maybe specified by order number */ - errno = 0; - i = strtol(str, &end, 0); - if (errno == 0 && *end == '\0' && i > 0 - && i - 1 < (int) lb->nparttypes) { - ret = &types[i - 1]; - goto done; - } + if (!ret) { + /* maybe specified by order number */ + int i; + + errno = 0; + i = strtol(str, &end, 0); - ret = fdisk_new_unknown_parttype(0, str); + if (use_seqnum && errno == 0 + && *end == '\0' && i > 0 + && i - 1 < (int) lb->nparttypes) + ret = &types[i - 1]; + } } -done: - DBG(PARTTYPE, ul_debugobj(ret, "returns parsed '%s' [%s] partition type", - ret->name, ret->typestr ? : "")); + if (ret) + DBG(PARTTYPE, ul_debugobj(ret, " result '%s'", ret->name)); return ret; } +static struct fdisk_parttype *parttype_from_shortcut( + const struct fdisk_label *lb, + const char *str, int deprecated) +{ + size_t i; + + DBG(LABEL, ul_debugobj(lb, " parsing '%s' shortcut", str)); + + for (i = 0; i < lb->nparttype_cuts; i++) { + const struct fdisk_shortcut *sc = &lb->parttype_cuts[i]; + + if (sc->deprecated && !deprecated) + continue; + if (sc->shortcut && strcmp(sc->shortcut, str) == 0) + return parttype_from_data(lb, sc->data, NULL, 0); + } + return NULL; +} + +static struct fdisk_parttype *parttype_from_alias( + const struct fdisk_label *lb, + const char *str, int deprecated) +{ + size_t i; + + DBG(LABEL, ul_debugobj(lb, " parsing '%s' alias", str)); + + for (i = 0; i < lb->nparttype_cuts; i++) { + const struct fdisk_shortcut *sc = &lb->parttype_cuts[i]; + + if (sc->deprecated && !deprecated) + continue; + if (sc->alias && strcmp(sc->alias, str) == 0) + return parttype_from_data(lb, sc->data, NULL, 0); + } + return NULL; +} + +/** + * fdisk_label_advparse_parttype: + * @lb: label + * @str: string to parse from + * @flags: FDISK_PARTTYPE_PARSE_* + * + * This function is advanced partition types parser. It parses partition type + * from @str according to the label. The function returns a pointer to static + * table of the partition types, or newly allocated partition type for unknown + * types (see fdisk_parttype_is_unknown(). It's safe to call fdisk_unref_parttype() + * for all results. + * + * The @str may be type data (hex code or UUID), alias or shortcut. For GPT + * also sequence number of the type in the list of the supported types. + * + * Returns: pointer to type or NULL on error. + */ +struct fdisk_parttype *fdisk_label_advparse_parttype( + const struct fdisk_label *lb, + const char *str, + int flags) +{ + struct fdisk_parttype *res = NULL; + unsigned int code = 0; + + if (!lb->nparttypes) + return NULL; + + DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) type", str, lb->name)); + + if ((flags & FDISK_PARTTYPE_PARSE_DATA) + && !(flags & FDISK_PARTTYPE_PARSE_DATALAST)) + res = parttype_from_data(lb, str, &code, + flags & FDISK_PARTTYPE_PARSE_SEQNUM); + + if (!res && (flags & FDISK_PARTTYPE_PARSE_ALIAS)) + res = parttype_from_alias(lb, str, + flags & FDISK_PARTTYPE_PARSE_DEPRECATED); + + if (!res && (flags & FDISK_PARTTYPE_PARSE_SHORTCUT)) + res = parttype_from_shortcut(lb, str, + flags & FDISK_PARTTYPE_PARSE_DEPRECATED); + + if (!res && (flags & FDISK_PARTTYPE_PARSE_DATA) + && (flags & FDISK_PARTTYPE_PARSE_DATALAST)) + res = parttype_from_data(lb, str, &code, + flags & FDISK_PARTTYPE_PARSE_SEQNUM); + + if (!res && !(flags & FDISK_PARTTYPE_PARSE_NOUNKNOWN)) { + if (lb->parttypes[0].typestr) + res = fdisk_new_unknown_parttype(0, str); + else + res = fdisk_new_unknown_parttype(code, NULL); + } + + if (res) + DBG(PARTTYPE, ul_debugobj(res, "returns parsed '%s' [%s] partition type", + res->name, res->typestr ? : "")); + return res; +} + +/** + * fdisk_label_parse_parttype: + * @lb: label + * @str: string to parse from (type name, UUID, etc.) + * + * Parses partition type from @str according to the label. The function returns + * a pointer to static table of the partition types, or newly allocated + * partition type for unknown types (see fdisk_parttype_is_unknown(). It's + * safe to call fdisk_unref_parttype() for all results. + * + * Note that for GPT it accepts sequence number of UUID. + * + * Returns: pointer to type or NULL on error. + */ +struct fdisk_parttype *fdisk_label_parse_parttype( + const struct fdisk_label *lb, + const char *str) +{ + return fdisk_label_advparse_parttype(lb, str, FDISK_PARTTYPE_PARSE_DATA); +} + /** * fdisk_parttype_get_string: * @t: type diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index 6f66f88b94..e73c8dcdb1 100644 --- a/libfdisk/src/script.c +++ b/libfdisk/src/script.c @@ -61,9 +61,6 @@ struct fdisk_script { force_label : 1; /* label: <name> specified */ }; -static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str); - - static void fdisk_script_free_header(struct fdisk_scriptheader *fi) { if (!fi) @@ -969,6 +966,11 @@ static int partno_from_devname(char *s) return pno - 1; } +#define FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS \ + (FDISK_PARTTYPE_PARSE_DATA | FDISK_PARTTYPE_PARSE_DATALAST | \ + FDISK_PARTTYPE_PARSE_SHORTCUT | FDISK_PARTTYPE_PARSE_ALIAS | \ + FDISK_PARTTYPE_PARSE_DEPRECATED) + /* dump format * <device>: start=<num>, size=<num>, type=<string>, ... */ @@ -1069,19 +1071,14 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) if (rc) break; - pa->type = translate_type_shortcuts(dp, type); - if (!pa->type) - pa->type = fdisk_label_parse_parttype( - script_get_label(dp), type); + pa->type = fdisk_label_advparse_parttype(script_get_label(dp), + type, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); free(type); if (!pa->type) { rc = -EINVAL; - fdisk_unref_parttype(pa->type); - pa->type = NULL; break; } - } else { DBG(SCRIPT, ul_debugobj(dp, "script parse error: unknown field '%s'", p)); rc = -EINVAL; @@ -1098,71 +1095,6 @@ static int parse_line_nameval(struct fdisk_script *dp, char *s) return rc; } -/* original sfdisk supports partition types shortcuts like 'L' = Linux native - */ -static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp, char *str) -{ - struct fdisk_label *lb; - const char *type = NULL; - - if (strlen(str) != 1) - return NULL; - - lb = script_get_label(dp); - if (!lb) - return NULL; - - if (lb->id == FDISK_DISKLABEL_DOS) { - switch (*str) { - case 'L': /* Linux */ - type = "83"; - break; - case 'S': /* Swap */ - type = "82"; - break; - case 'E': /* Dos extended */ - type = "05"; - break; - case 'X': /* Linux extended */ - type = "85"; - break; - case 'U': /* UEFI system */ - type = "EF"; - break; - case 'R': /* Linux RAID */ - type = "FD"; - break; - case 'V': /* LVM */ - type = "8E"; - break; - - } - } else if (lb->id == FDISK_DISKLABEL_GPT) { - switch (*str) { - case 'L': /* Linux */ - type = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"; - break; - case 'S': /* Swap */ - type = "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"; - break; - case 'H': /* Home */ - type = "933AC7E1-2EB4-4F13-B844-0E14E2AEF915"; - break; - case 'U': /* UEFI system */ - type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"; - break; - case 'R': /* Linux RAID */ - type = "A19D880F-05FC-4D3B-A006-743F0F84911E"; - break; - case 'V': /* LVM */ - type = "E6D6D379-F507-44C2-A23C-238F2A3DF928"; - break; - } - } - - return type ? fdisk_label_parse_parttype(lb, type) : NULL; -} - #define TK_PLUS 1 #define TK_MINUS -1 @@ -1257,18 +1189,12 @@ static int parse_line_valcommas(struct fdisk_script *dp, char *s) if (rc) break; - pa->type = translate_type_shortcuts(dp, str); - if (!pa->type) - pa->type = fdisk_label_parse_parttype( - script_get_label(dp), str); + pa->type = fdisk_label_advparse_parttype(script_get_label(dp), + str, FDISK_SCRIPT_PARTTYPE_PARSE_FLAGS); free(str); - if (!pa->type) { + if (!pa->type) rc = -EINVAL; - fdisk_unref_parttype(pa->type); - pa->type = NULL; - break; - } break; case ITEM_BOOTABLE: if (*p == ',' || *p == ';') |
