]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: (gpt) parse attr bits
authorKarel Zak <kzak@redhat.com>
Thu, 2 Oct 2014 13:49:05 +0000 (15:49 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 7 Oct 2014 12:55:32 +0000 (14:55 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/src/gpt.c
libfdisk/src/libfdisk.h
libfdisk/src/partition.c

index 6720ff0cfe517ef33b1ebb19ed4d178618052a7a..857318b00ce90b6f494ec00135a247aa96881629 100644 (file)
@@ -1370,6 +1370,75 @@ static int gpt_entry_attrs_to_string(struct gpt_entry *e, char **res)
        return 0;
 }
 
+static int gpt_entry_attrs_from_string(
+                       struct fdisk_context *cxt,
+                       struct gpt_entry *e,
+                       const char *str)
+{
+       const char *p = str;
+       uint64_t attrs = 0;
+       char *bits;
+
+       assert(e);
+       assert(p);
+
+       DBG(LABEL, ul_debug("GPT: parsing string attributes '%s'", p));
+
+       bits = (char *) &attrs;
+
+       while (p && *p) {
+               int bit = -1;
+
+               while (isblank(*p)) p++;
+               if (!*p)
+                       break;
+
+               DBG(LABEL, ul_debug(" parsing item '%s'", p));
+
+               if (strncmp(p, "GUID:", 5) == 0) {
+                       p += 5;
+                       continue;
+               } else if (strncmp(p, GPT_ATTRSTR_REQ,
+                                       sizeof(GPT_ATTRSTR_REQ) - 1) == 0) {
+                       bit = GPT_ATTRBIT_REQ;
+                       p += sizeof(GPT_ATTRSTR_REQ) - 1;
+               } else if (strncmp(p, GPT_ATTRSTR_LEGACY,
+                                       sizeof(GPT_ATTRSTR_LEGACY) - 1) == 0) {
+                       bit = GPT_ATTRBIT_LEGACY;
+                       p += sizeof(GPT_ATTRSTR_LEGACY) - 1;
+               } else if (strncmp(p, GPT_ATTRSTR_NOBLOCK,
+                                       sizeof(GPT_ATTRSTR_NOBLOCK) - 1) == 0) {
+                       bit = GPT_ATTRBIT_NOBLOCK;
+                       p += sizeof(GPT_ATTRSTR_NOBLOCK) - 1;
+               } else if (isdigit((unsigned int) *p)) {
+                       char *end = NULL;
+
+                       errno = 0;
+                       bit = strtol(p, &end, 0);
+                       if (errno || !end || end == str
+                           || bit < GPT_ATTRBIT_GUID_FIRST
+                           || bit >= GPT_ATTRBIT_GUID_FIRST + GPT_ATTRBIT_GUID_COUNT)
+                               bit = -1;
+                       else
+                               p = end;
+               }
+
+               if (bit < 0) {
+                       fdisk_warnx(cxt, _("unssuported GPT attribute bit '%s'"), p);
+                       return -EINVAL;
+               }
+
+               setbit(bits, bit);
+
+               while (isblank(*p)) p++;
+               if (*p == ',')
+                       p++;
+       }
+
+       e->attrs = cpu_to_le64(attrs);
+       return 0;
+}
+
 static int gpt_get_partition(struct fdisk_context *cxt, size_t n,
                             struct fdisk_partition *pa)
 {
@@ -1470,6 +1539,11 @@ static int gpt_set_partition(struct fdisk_context *cxt, size_t n,
                        return rc;
                gpt_entry_set_type(e, &typeid);
        }
+       if (pa->attrs) {
+               rc = gpt_entry_attrs_from_string(cxt, e, pa->attrs);
+               if (rc)
+                       return rc;
+       }
 
        if (pa->start)
                e->lba_start = cpu_to_le64(pa->start);
@@ -1991,6 +2065,8 @@ static int gpt_add_partition(
 
        if (pa && pa->name && *pa->name)
                gpt_entry_set_name(e, pa->name);
+       if (pa && pa->attrs)
+               gpt_entry_attrs_from_string(cxt, e, pa->attrs);
 
        DBG(LABEL, ul_debug("GPT new partition: partno=%zu, start=%ju, end=%ju, size=%ju",
                                partnum,
index ad19c41c671e62ce06bf9dd7980d7b87366333a0..ac0aad263dd30618820e733f4e8cd7b2a08d99c3 100644 (file)
@@ -256,6 +256,7 @@ extern const struct fdisk_parttype *fdisk_partition_get_type(struct fdisk_partit
 extern int fdisk_partition_set_name(struct fdisk_partition *pa, const char *name);
 extern const char *fdisk_partition_get_name(struct fdisk_partition *pa);
 extern int fdisk_partition_set_uuid(struct fdisk_partition *pa, const char *uuid);
+extern int fdisk_partition_set_attrs(struct fdisk_partition *pa, const char *attrs);
 extern const char *fdisk_partition_get_uuid(struct fdisk_partition *pa);
 extern const char *fdisk_partition_get_attrs(struct fdisk_partition *pa);
 extern int fdisk_partition_is_nested(struct fdisk_partition *pa);
index 4f83f727545417b20fd942d184a5b6c1fe512a8e..c9b596b6bb1bb461d3a8d6369519d92c65272961 100644 (file)
@@ -347,6 +347,22 @@ const char *fdisk_partition_get_attrs(struct fdisk_partition *pa)
        return pa ? pa->attrs : NULL;
 }
 
+int fdisk_partition_set_attrs(struct fdisk_partition *pa, const char *attrs)
+{
+       char *p = NULL;
+
+       if (!pa)
+               return -EINVAL;
+       if (attrs) {
+              p = strdup(attrs);
+              if (!p)
+                      return -ENOMEM;
+       }
+       free(pa->attrs);
+       pa->attrs = p;
+       return 0;
+}
+
 int fdisk_partition_is_nested(struct fdisk_partition *pa)
 {
        return pa && pa->parent_partno != FDISK_EMPTY_PARTNO;