From: Karel Zak Date: Thu, 28 Aug 2014 10:37:46 +0000 (+0200) Subject: libfdisk: extend dump parsing function X-Git-Tag: v2.26-rc1~483 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c1ba5863954c30079ea5cbfb964f982a13514f5b;p=thirdparty%2Futil-linux.git libfdisk: extend dump parsing function Signed-off-by: Karel Zak --- diff --git a/libfdisk/src/dump.c b/libfdisk/src/dump.c index e1fb0031d9..561d9c140c 100644 --- a/libfdisk/src/dump.c +++ b/libfdisk/src/dump.c @@ -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 , ... 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; } diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index a65bb9e96f..69f2647451 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -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)) diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index 303b927b84..73ac7cb770 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -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 { diff --git a/libfdisk/src/parttype.c b/libfdisk/src/parttype.c index caf205a84e..bb25cc6dd4 100644 --- a/libfdisk/src/parttype.c +++ b/libfdisk/src/parttype.c @@ -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; +}