summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/parttype.c
diff options
context:
space:
mode:
authorKarel Zak2012-11-30 16:39:57 +0100
committerKarel Zak2013-03-11 11:20:40 +0100
commita5fe1b3f1d136b943fb73ab3b9a9c889c642dbfb (patch)
treec9b1c4e1838ef5888c1122dcc701e6adddccc2a0 /libfdisk/src/parttype.c
parentlibfdisk: add basic structs (diff)
downloadkernel-qcow2-util-linux-a5fe1b3f1d136b943fb73ab3b9a9c889c642dbfb.tar.gz
kernel-qcow2-util-linux-a5fe1b3f1d136b943fb73ab3b9a9c889c642dbfb.tar.xz
kernel-qcow2-util-linux-a5fe1b3f1d136b943fb73ab3b9a9c889c642dbfb.zip
libfdisk: add parttype code
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk/src/parttype.c')
-rw-r--r--libfdisk/src/parttype.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c
new file mode 100644
index 000000000..1d9f4e802
--- /dev/null
+++ b/libfdisk/src/parttype.c
@@ -0,0 +1,214 @@
+
+#include <ctype.h>
+
+#include "nls.h"
+
+#include "fdiskP.h"
+
+/**
+ * fdisk_get_parttype_from_code:
+ * @cxt: fdisk context
+ * @code: code to search for
+ *
+ * Search in lable-specific table of supported partition types by code.
+ *
+ * Returns partition type or NULL upon failure or invalid @code.
+ */
+struct fdisk_parttype *fdisk_get_parttype_from_code(
+ struct fdisk_context *cxt,
+ unsigned int code)
+{
+ size_t i;
+
+ if (!fdisk_get_nparttypes(cxt))
+ return NULL;
+
+ for (i = 0; i < cxt->label->nparttypes; i++)
+ if (cxt->label->parttypes[i].type == code)
+ return &cxt->label->parttypes[i];
+
+ return NULL;
+}
+
+/**
+ * fdisk_get_parttype_from_string:
+ * @cxt: fdisk context
+ * @str: string to search for
+ *
+ * Search in lable-specific table of supported partition types by typestr.
+ *
+ * Returns partition type or NULL upon failure or invalid @str.
+ */
+struct fdisk_parttype *fdisk_get_parttype_from_string(
+ struct fdisk_context *cxt,
+ const char *str)
+{
+ size_t i;
+
+ if (!fdisk_get_nparttypes(cxt))
+ return NULL;
+
+ for (i = 0; i < cxt->label->nparttypes; i++)
+ if (cxt->label->parttypes[i].typestr
+ &&strcasecmp(cxt->label->parttypes[i].typestr, str) == 0)
+ return &cxt->label->parttypes[i];
+
+ return NULL;
+}
+
+/**
+ * fdisk_new_unknown_parttype:
+ * @type: type as number
+ * @typestr: type as string
+
+ * Allocates new 'unknown' partition type. Use fdisk_free_parttype() to
+ * deallocate.
+ *
+ * Returns newly allocated partition type, or NULL upon failure.
+ */
+struct fdisk_parttype *fdisk_new_unknown_parttype(unsigned int type,
+ const char *typestr)
+{
+ struct fdisk_parttype *t;
+
+ t = calloc(1, sizeof(*t));
+ if (!t)
+ return NULL;
+
+ if (typestr) {
+ t->typestr = strdup(typestr);
+ if (!t->typestr) {
+ free(t);
+ return NULL;
+ }
+ }
+ t->name = _("unknown");
+ t->type = type;
+ t->flags |= FDISK_PARTTYPE_UNKNOWN | FDISK_PARTTYPE_ALLOCATED;
+
+ DBG(LABEL, dbgprint("allocated new unknown type [%p]", t));
+ return t;
+}
+
+/**
+ * fdisk_parse_parttype:
+ * @cxt: fdisk context
+ * @str: string to parse from
+ *
+ * Returns pointer to static table of the partition types, or newly allocated
+ * partition type for unknown types. It's safe to call fdisk_free_parttype()
+ * for all results.
+ */
+struct fdisk_parttype *fdisk_parse_parttype(
+ struct fdisk_context *cxt,
+ const char *str)
+{
+ struct fdisk_parttype *types, *ret;
+ unsigned int code = 0;
+ char *typestr = NULL, *end = NULL;
+
+ if (!fdisk_get_nparttypes(cxt))
+ return NULL;
+
+ DBG(LABEL, dbgprint("parsing '%s' partition type", str));
+
+ types = cxt->label->parttypes;
+
+ if (types[0].typestr == NULL && isxdigit(*str)) {
+
+ errno = 0;
+ code = strtol(str, &end, 16);
+
+ if (errno || *end != '\0') {
+ DBG(LABEL, dbgprint("parsing failed: %m"));
+ return NULL;
+ }
+ ret = fdisk_get_parttype_from_code(cxt, code);
+ if (ret)
+ goto done;
+ } else {
+ int i;
+
+ /* maybe specified by type string (e.g. UUID) */
+ ret = fdisk_get_parttype_from_string(cxt, 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) fdisk_get_nparttypes(cxt)) {
+ ret = &types[i - 1];
+ goto done;
+ }
+ }
+
+ ret = fdisk_new_unknown_parttype(code, typestr);
+done:
+ DBG(LABEL, dbgprint("returns '%s' partition type", ret->name));
+ return ret;
+}
+
+/**
+ * fdisk_free_parttype:
+ * @t: new type
+ *
+ * Free the @type.
+ */
+void fdisk_free_parttype(struct fdisk_parttype *t)
+{
+ if (t && (t->flags & FDISK_PARTTYPE_ALLOCATED)) {
+ DBG(LABEL, dbgprint("freeing %p partition type", t));
+ free(t->typestr);
+ free(t);
+ }
+}
+
+/**
+ * fdisk_get_partition_type:
+ * @cxt: fdisk context
+ * @partnum: partition number
+ *
+ * Returns partition type or NULL upon failure.
+ */
+struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum)
+{
+ if (!cxt || !cxt->label || !cxt->label->part_get_type)
+ return NULL;
+
+ DBG(LABEL, dbgprint("partition: %d: get type", partnum));
+ return cxt->label->part_get_type(cxt, partnum);
+}
+
+/**
+ * fdisk_set_partition_type:
+ * @cxt: fdisk context
+ * @partnum: partition number
+ * @t: new type
+ *
+ * Returns 0 on success, < 0 on error.
+ */
+int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
+ struct fdisk_parttype *t)
+{
+ if (!cxt || !cxt->label || !cxt->label->part_set_type)
+ return -EINVAL;
+
+ DBG(LABEL, dbgprint("partition: %d: set type", partnum));
+ return cxt->label->part_set_type(cxt, partnum, t);
+}
+
+/**
+ * fdisk_get_nparttypes:
+ * @cxt: fdisk context
+ *
+ * Returns: number of partition types supported by the current label
+ */
+size_t fdisk_get_nparttypes(struct fdisk_context *cxt)
+{
+ if (!cxt || !cxt->label)
+ return 0;
+
+ return cxt->label->nparttypes;
+}