643 lines
20 KiB
Diff
643 lines
20 KiB
Diff
From f94e753b35cf7a8bdd3a27edb72e094917757334 Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Tue, 3 Mar 2020 15:59:49 +0100
|
|
Subject: [PATCH] libfdisk: add partition type aliases and shortcuts
|
|
|
|
Now, the type shortcuts are supported for sfdisk scripts only.
|
|
|
|
Unfortunately, the current implementation is not generic enough
|
|
and it's also fragile as 'E' shortcut is in collision with 0x0E
|
|
type for MBR. The another issue is 'L' which makes shortcuts useless
|
|
for fdisk where 'L' is used for another purpose in dialogs.
|
|
|
|
This patch introduces partition type aliases as extension to
|
|
shortcuts. The definition of the shortcut is part of the label
|
|
definition and it's not more hardcoded in sfdisk script code.
|
|
|
|
This patch also introduces 'Ex' shortcut as replacement for (now
|
|
deprecated) 'E'.
|
|
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libfdisk/src/dos.c | 16 +++
|
|
libfdisk/src/fdiskP.h | 17 +++
|
|
libfdisk/src/gpt.c | 13 ++
|
|
libfdisk/src/libfdisk.h.in | 36 ++++++
|
|
libfdisk/src/libfdisk.sym | 3 +
|
|
libfdisk/src/parttype.c | 236 ++++++++++++++++++++++++++++++-------
|
|
libfdisk/src/script.c | 94 ++-------------
|
|
7 files changed, 291 insertions(+), 124 deletions(-)
|
|
|
|
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
|
|
index ae06e179d..a79912e8b 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 ec07f1fc8..f291c08b6 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 4915b9a37..25555a395 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 89fad448e..bf05290f9 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 96fcadd..4a5ba0b 100644
|
|
--- a/libfdisk/src/libfdisk.sym
|
|
+++ b/libfdisk/src/libfdisk.sym
|
|
@@ -307,4 +307,7 @@ FDISK_2.33 {
|
|
FDISK_2.35 {
|
|
fdisk_script_set_table;
|
|
fdisk_assign_device_by_fd;
|
|
+ fdisk_label_has_parttypes_shortcuts;
|
|
+ fdisk_label_advparse_parttype;
|
|
+ fdisk_label_get_parttype_shortcut;
|
|
} FDISK_2.33;
|
|
diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c
|
|
index d5ad434f0..36d12216d 100644
|
|
--- a/libfdisk/src/parttype.c
|
|
+++ b/libfdisk/src/parttype.c
|
|
@@ -145,6 +145,41 @@ struct fdisk_parttype *fdisk_label_get_parttype(const struct fdisk_label *lb, si
|
|
return &lb->parttypes[n];
|
|
}
|
|
|
|
+/**
|
|
+ * 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 6f66f88b9..e73c8dcdb 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 == ';')
|