aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--disk-utils/fdisk.c50
-rw-r--r--disk-utils/sfdisk.847
-rw-r--r--disk-utils/sfdisk.c7
-rw-r--r--libfdisk/src/dos.c16
-rw-r--r--libfdisk/src/fdiskP.h17
-rw-r--r--libfdisk/src/gpt.c13
-rw-r--r--libfdisk/src/libfdisk.h.in36
-rw-r--r--libfdisk/src/libfdisk.sym3
-rw-r--r--libfdisk/src/parttype.c236
-rw-r--r--libfdisk/src/script.c94
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 == ';')