]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: extend dump parsing function
authorKarel Zak <kzak@redhat.com>
Thu, 28 Aug 2014 10:37:46 +0000 (12:37 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 28 Aug 2014 10:37:46 +0000 (12:37 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/src/dump.c
libfdisk/src/fdiskP.h
libfdisk/src/libfdisk.h
libfdisk/src/parttype.c

index e1fb0031d9b9bc390f0e1556a77bcc70998a1124..561d9c140c0caae98897a6459978731e2be7d8c7 100644 (file)
@@ -19,6 +19,7 @@ struct fdisk_dump {
        /* parser's state */
        size_t                  nlines;
        int                     fmt;            /* input format */
+       struct fdisk_label      *label;
 };
 
 
@@ -103,7 +104,7 @@ void fdisk_unref_dump(struct fdisk_dump *dp)
        }
 }
 
-static struct fdisk_dumpheader *fdisk_dump_get_header(struct fdisk_dump *dp,
+static struct fdisk_dumpheader *dump_get_header(struct fdisk_dump *dp,
                                                     const char *name)
 {
        struct list_head *p;
@@ -118,6 +119,24 @@ static struct fdisk_dumpheader *fdisk_dump_get_header(struct fdisk_dump *dp,
        return NULL;
 }
 
+/**
+ * fdisk_dump_get_header:
+ * @dp: dump instance
+ * @name: header name
+ *
+ * Returns: pointer to header data or NULL.
+ */
+const char *fdisk_dump_get_header(struct fdisk_dump *dp, const char *name)
+{
+       struct fdisk_dumpheader *fi;
+
+       assert(dp);
+       assert(name);
+
+       fi = dump_get_header(dp, name);
+       return fi ? fi->data : NULL;
+}
+
 
 /**
  * fdisk_dump_set_header:
@@ -149,7 +168,7 @@ int fdisk_dump_set_header(struct fdisk_dump *dp,
        if (!dp || !name)
                return -EINVAL;
 
-       fi = fdisk_dump_get_header(dp, name);
+       fi = dump_get_header(dp, name);
        if (!fi && !data)
                return 0;       /* want to remove header that does not exist, success */
 
@@ -201,6 +220,18 @@ struct fdisk_table *fdisk_dump_get_table(struct fdisk_dump *dp)
        return dp ? dp->table : NULL;
 }
 
+static struct fdisk_label *dump_get_label(struct fdisk_context *cxt, struct fdisk_dump *dp)
+{
+       assert(cxt);
+       assert(dp);
+
+       if (!dp->label) {
+               dp->label = fdisk_get_label(cxt, fdisk_dump_get_header(dp, "label"));
+               DBG(DUMP, ul_debug("label '%s'", dp->label ? dp->label->name : ""));
+       }
+       return dp->label;
+}
+
 /**
  * fdisk_dump_read_context:
  * @dp: dump
@@ -387,6 +418,37 @@ static int next_number(char **s, uint64_t *num)
        return rc;
 }
 
+static int next_string(char **s, char **str)
+{
+       char *end = NULL;
+
+       assert(str);
+       assert(s);
+
+       *s = (char *) skip_blank(*s);
+       if (!**s)
+               return -1;
+
+       end = strchr(*s, ',');
+       if (end) {
+               *str = strndup(*s, end - *s);
+               *s = end;
+       } else {
+               *str = strdup(*s);
+               while (**s) (*s)++;
+       }
+
+       if (!*str)
+               return -ENOMEM;
+
+       ltrim_whitespace((unsigned char *) *str);
+       if (!**str) {
+               free(*str);
+               *str = NULL;
+       }
+       return 0;
+}
+
 static int partno_from_devname(char *s)
 {
        int pno;
@@ -406,7 +468,8 @@ static int partno_from_devname(char *s)
        return pno - 1;
 }
 
-static int parse_dump_line(struct fdisk_dump *dp, char *s)
+static int parse_dump_line(struct fdisk_dump *dp, char *s,
+                          struct fdisk_context *cxt)
 {
        char *p;
        struct fdisk_partition *pa;
@@ -458,6 +521,47 @@ static int parse_dump_line(struct fdisk_dump *dp, char *s)
                        rc = next_number(&p, &num);
                        if (!rc)
                                fdisk_partition_set_end(pa, num);
+
+               } else if (!strncasecmp(p, "bootable", 8)) {
+                       p += 8;
+                       pa->boot = 1;
+
+               } else if (!strncasecmp(p, "attrs=", 6)) {
+                       p += 6;
+                       rc = next_string(&p, &pa->attrs);
+                       if (rc)
+                               break;
+
+               } else if (!strncasecmp(p, "uuid=", 5)) {
+                       p += 5;
+                       rc = next_string(&p, &pa->uuid);
+                       if (rc)
+                               break;
+
+               } else if (!strncasecmp(p, "name=", 5)) {
+                       p += 5;
+                       rc = next_string(&p, &pa->name);
+                       if (rc)
+                               break;
+
+               } else if (!strncasecmp(p, "type=", 5)) {
+                       char *type;
+                       p += 5;
+
+                       rc = next_string(&p, &type);
+                       if (rc)
+                               break;
+                       pa->type = fdisk_label_parse_parttype(
+                                       dump_get_label(cxt, dp), type);
+                       free(type);
+
+                       if (!pa->type || fdisk_parttype_is_unknown(pa->type)) {
+                               rc = -EINVAL;
+                               fdisk_free_parttype(pa->type);
+                               pa->type = NULL;
+                               break;
+                       }
+
                } else {
                        DBG(DUMP, ul_debug("dump parse error: unknown field '%s'", p));
                        rc = -EINVAL;
@@ -475,17 +579,19 @@ static int parse_dump_line(struct fdisk_dump *dp, char *s)
                DBG(DUMP, ul_debug("dump parse error: [rc=%d]", rc));
 
        fdisk_unref_partition(pa);
-       return 0;
+       return rc;
 }
 
-static int parse_commas_line(struct fdisk_dump *dp, const char *s)
+static int parse_commas_line(struct fdisk_dump *dp, const char *s,
+                            struct fdisk_context *cxt)
 {
        DBG(DUMP, ul_debug("   commas line parse error"));
        return -EINVAL;
 }
 
 /* modifies @s ! */
-int fdisk_dump_read_buffer(struct fdisk_dump *dp, char *s)
+int fdisk_dump_read_buffer(struct fdisk_dump *dp, char *s,
+                          struct fdisk_context *cxt)
 {
        int rc = 0;
 
@@ -510,11 +616,11 @@ int fdisk_dump_read_buffer(struct fdisk_dump *dp, char *s)
 
        /* parse dump format */
        else if (strchr(s, '='))
-               rc = parse_dump_line(dp, s);
+               rc = parse_dump_line(dp, s, cxt);
 
        /* parse simple <value>, ... format */
        else
-               rc = parse_commas_line(dp, s);
+               rc = parse_commas_line(dp, s, cxt);
 
        if (rc)
                DBG(DUMP, ul_debugobj(dp, "%zu: parse error [rc=%d]",
@@ -522,7 +628,8 @@ int fdisk_dump_read_buffer(struct fdisk_dump *dp, char *s)
        return rc;
 }
 
-char fdisk_dump_read_line(struct fdisk_dump *dp, FILE *f)
+char fdisk_dump_read_line(struct fdisk_dump *dp, FILE *f,
+                         struct fdisk_context *cxt)
 {
        char buf[BUFSIZ];
        char *s;
@@ -557,7 +664,7 @@ char fdisk_dump_read_line(struct fdisk_dump *dp, FILE *f)
                s = (char *) skip_blank(buf);
        } while (*s == '\0' || *s == '#');
 
-       return fdisk_dump_read_buffer(dp, s);
+       return fdisk_dump_read_buffer(dp, s, cxt);
 }
 
 
@@ -565,12 +672,16 @@ char fdisk_dump_read_line(struct fdisk_dump *dp, FILE *f)
  * fdisk_dump_read_file:
  * @dp: dump
  * @f input file
+ * @cxt: context
  *
- * Reads file @f into dump @dp.
+ * Reads file @f into dump @dp. The @cxt is never modified by this function,
+ * it's used to parse label specific stuff (context contais pointers to all
+ * enebled labels).
  *
  * Returns: 0 on success, <0 on error.
  */
-int fdisk_dump_read_file(struct fdisk_dump *dp, FILE *f)
+int fdisk_dump_read_file(struct fdisk_dump *dp, FILE *f,
+                        struct fdisk_context *cxt)
 {
        int rc = NULL;
 
@@ -579,8 +690,11 @@ int fdisk_dump_read_file(struct fdisk_dump *dp, FILE *f)
 
        DBG(DUMP, ul_debug("parsing file"));
 
-       while (rc == 0 && !feof(f))
-               rc = fdisk_dump_read_line(dp, f);
+       while (!feof(f)) {
+               rc = fdisk_dump_read_line(dp, f, cxt);
+               if (rc)
+                       break;
+       }
 
        return rc;
 }
@@ -612,18 +726,21 @@ int test_read(struct fdisk_test *ts, int argc, char *argv[])
 {
        char *filename = argv[1];
        struct fdisk_dump *dp;
+       struct fdisk_context *cxt;
        FILE *f;
 
        if (!(f = fopen(filename, "r")))
                err(EXIT_FAILURE, "%s: cannot open", filename);
 
+       cxt = fdisk_new_context();
        dp = fdisk_new_dump();
 
-       fdisk_dump_read_file(dp, f);
+       fdisk_dump_read_file(dp, f, cxt);
        fclose(f);
 
        fdisk_dump_write_file(dp, stdout);
        fdisk_unref_dump(dp);
+       fdisk_free_context(cxt);
 
        return 0;
 }
index a65bb9e96fb469be70d04b44a91baa6362cf83a0..69f26474516d0dd38c2a9ace122b407e4f9fca88 100644 (file)
@@ -108,7 +108,6 @@ enum {
        FDISK_PARTTYPE_ALLOCATED        = (1 << 3)
 };
 
-#define fdisk_parttype_is_unknown(_x)  ((_x) && ((_x)->flags & FDISK_PARTTYPE_UNKNONW))
 #define fdisk_parttype_is_invisible(_x)        ((_x) && ((_x)->flags & FDISK_PARTTYPE_INVISIBLE))
 #define fdisk_parttype_is_allocated(_x)        ((_x) && ((_x)->flags & FDISK_PARTTYPE_ALLOCATED))
 
index 303b927b84de734330f3cda2a7fbae2f56b4a717..73ac7cb77086d8b8b5d466051da5df18037d1d94 100644 (file)
@@ -149,6 +149,7 @@ void fdisk_free_parttype(struct fdisk_parttype *t);
 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);
+int fdisk_parttype_is_unknown(const struct fdisk_parttype *t);
 
 /* label.c */
 enum {
index caf205a84e39a5b02e39708b228947dea6255b57..bb25cc6dd41512a6b9b310a3b944ee09c12f426e 100644 (file)
@@ -161,7 +161,8 @@ struct fdisk_parttype *fdisk_label_parse_parttype(
        if (!lb->nparttypes)
                return NULL;
 
-       DBG(LABEL, ul_debugobj(lb, "parsing '%s' partition type", str));
+       DBG(LABEL, ul_debugobj(lb, "parsing '%s' (%s) partition type",
+                               str, lb->name));
 
        types = lb->parttypes;
 
@@ -234,5 +235,15 @@ const char *fdisk_parttype_get_name(const struct fdisk_parttype *t)
        return t->name;
 }
 
-
-
+/**
+ * fdisk_parttype_is_unknown:
+ * @t: type
+ *
+ * Checks for example result from fdisk_label_parse_parttype().
+ *
+ * Returns: 1 is type is "unknonw" or 0.
+ */
+int fdisk_parttype_is_unknown(const struct fdisk_parttype *t)
+{
+       return t && (t->flags & FDISK_PARTTYPE_UNKNOWN) ? 1 : 0;
+}