diff options
author | Ondrej Oprala <ooprala@redhat.com> | 2015-02-03 16:30:15 +0100 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2015-02-24 10:22:37 +0100 |
commit | 6c4a7811f85fc64cb0b0fb9f3e266592ed9c40dc (patch) | |
tree | fa3dd1b62a64c4240171fa80e9c3946e08e91b03 | |
parent | 85589c4c4975c3a9c12663cbd5e16904cdbdaac7 (diff) | |
download | util-linux-playground-6c4a7811f85fc64cb0b0fb9f3e266592ed9c40dc.tar.gz |
libblkid: make probing data structures more dynamic
* replace static probing result array with list
* use allocated buffers for probing result variables
[kzak@redhat.com: - rename some functions
- clean up \0 terminator usage in variables
- remove never used code to convert UUID to lower-case
- remove possible memory leaks on errors]
Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | libblkid/src/blkidP.h | 40 | ||||
-rw-r--r-- | libblkid/src/encode.c | 6 | ||||
-rw-r--r-- | libblkid/src/partitions/partitions.c | 30 | ||||
-rw-r--r-- | libblkid/src/probe.c | 201 | ||||
-rw-r--r-- | libblkid/src/superblocks/superblocks.c | 186 |
5 files changed, 273 insertions, 190 deletions
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index fbf4e719b1..4d440800e6 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -118,24 +118,14 @@ struct blkid_chaindrv { /* * Low-level probe result */ -#define BLKID_PROBVAL_BUFSIZ 128 - -#define BLKID_NVALS_SUBLKS 18 -#define BLKID_NVALS_TOPLGY 5 -#define BLKID_NVALS_PARTS 13 - -/* Max number of all values in probing result */ -#define BLKID_NVALS (BLKID_NVALS_SUBLKS + \ - BLKID_NVALS_TOPLGY + \ - BLKID_NVALS_PARTS) - struct blkid_prval { - const char *name; /* value name */ - unsigned char data[BLKID_PROBVAL_BUFSIZ]; /* value data */ - size_t len; /* length of value data */ + const char *name; /* value name */ + unsigned char *data; /* value data */ + size_t len; /* length of value data */ struct blkid_chain *chain; /* owner */ + struct list_head prvals; /* list of results */ }; /* @@ -208,8 +198,7 @@ struct blkid_struct_probe struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */ struct blkid_chain *cur_chain; /* current chain */ - struct blkid_prval vals[BLKID_NVALS]; /* results */ - int nvals; /* number of assigned vals */ + struct list_head vals; /* results */ struct blkid_struct_probe *parent; /* for clones */ struct blkid_struct_probe *disk_probe; /* whole-disk probing */ @@ -432,8 +421,7 @@ extern void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn __attribute__((nonnull)); extern int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, - struct blkid_prval *vals, - int nvals) + struct list_head *vals) __attribute__((nonnull)); extern struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, @@ -441,17 +429,19 @@ extern struct blkid_prval *blkid_probe_assign_value(blkid_probe pr, __attribute__((nonnull)) __attribute__((warn_unused_result)); -extern int blkid_probe_reset_last_value(blkid_probe pr) - __attribute__((nonnull)); +extern void blkid_probe_free_val(struct blkid_prval *v); + + extern void blkid_probe_append_vals(blkid_probe pr, - struct blkid_prval *vals, - int nvals) + struct list_head *vals) __attribute__((nonnull)); extern struct blkid_chain *blkid_probe_get_chain(blkid_probe pr) __attribute__((nonnull)) __attribute__((warn_unused_result)); +extern struct blkid_prval *blkid_probe_last_value(blkid_probe pr); + extern struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num) __attribute__((nonnull)) __attribute__((warn_unused_result)); @@ -475,9 +465,14 @@ extern void *blkid_probe_get_binary_data(blkid_probe pr, struct blkid_chain *chn __attribute__((nonnull)) __attribute__((warn_unused_result)); +extern struct blkid_prval *blkid_probe_new_val(void) + __attribute__((warn_unused_result)); extern int blkid_probe_set_value(blkid_probe pr, const char *name, unsigned char *data, size_t len) __attribute__((nonnull)); +extern int blkid_probe_value_set_data(struct blkid_prval *v, + unsigned char *data, size_t len) + __attribute__((nonnull)); extern int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, const char *fmt, va_list ap) @@ -535,6 +530,7 @@ extern void blkid_probe_use_wiper(blkid_probe pr, blkid_loff_t off, blkid_loff_t (blkid_bmp_nwords(max_items) * sizeof(unsigned long)) /* encode.c */ +extern unsigned char *blkid_encode_alloc(size_t count, size_t *reslen); extern size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, const unsigned char *src, size_t count) __attribute__((nonnull)); diff --git a/libblkid/src/encode.c b/libblkid/src/encode.c index ff57be4cb3..466e4540f9 100644 --- a/libblkid/src/encode.c +++ b/libblkid/src/encode.c @@ -268,6 +268,12 @@ size_t blkid_encode_to_utf8(int enc, unsigned char *dest, size_t len, return j; } +unsigned char *blkid_encode_alloc(size_t count, size_t *reslen) +{ + *reslen = (count * 3) + 1; + return calloc(1, *reslen); +} + /** * blkid_encode_string: * @str: input string to be encoded diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c index 4853f97e29..b28dfbd57a 100644 --- a/libblkid/src/partitions/partitions.c +++ b/libblkid/src/partitions/partitions.c @@ -1098,11 +1098,18 @@ int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid) return 0; v = blkid_probe_assign_value(pr, "PTUUID"); + if (!v) + return -ENOMEM; - blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data)); v->len = 37; + v->data = calloc(1, v->len); + if (v->data) { + blkid_unparse_uuid(uuid, (char *) v->data, v->len); + return 0; + } - return 0; + blkid_probe_free_val(v); + return -ENOMEM; } /* set PTUUID variable for non-binary API for tables where @@ -1110,27 +1117,14 @@ int blkid_partitions_set_ptuuid(blkid_probe pr, unsigned char *uuid) int blkid_partitions_strcpy_ptuuid(blkid_probe pr, char *str) { struct blkid_chain *chn = blkid_probe_get_chain(pr); - struct blkid_prval *v; - size_t len; if (chn->binary || !str || !*str) return 0; - len = strlen((char *) str); - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - - v = blkid_probe_assign_value(pr, "PTUUID"); - if (v) { - if (len == BLKID_PROBVAL_BUFSIZ) - len--; /* make a space for \0 */ + if (!blkid_probe_set_value(pr, "PTUUID", (unsigned char *) str, strlen(str) + 1)) + return -ENOMEM; - memcpy((char *) v->data, str, len); - v->data[len] = '\0'; - v->len = len + 1; - return 0; - } - return -1; + return 0; } /** diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 70e882ac9b..2f4e7c90e3 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -113,6 +113,7 @@ #include "all-io.h" #include "sysfs.h" #include "strutils.h" +#include "list.h" /* chains */ extern const struct blkid_chaindrv superblocks_drv; @@ -128,6 +129,7 @@ static const struct blkid_chaindrv *chains_drvs[] = { [BLKID_CHAIN_PARTS] = &partitions_drv }; +static struct blkid_prval *blkid_probe_new_value(void); static void blkid_probe_reset_vals(blkid_probe pr); static void blkid_probe_reset_buffer(blkid_probe pr); @@ -155,6 +157,7 @@ blkid_probe blkid_new_probe(void) pr->chains[i].enabled = chains_drvs[i]->dflt_enabled; } INIT_LIST_HEAD(&pr->buffers); + INIT_LIST_HEAD(&pr->vals); return pr; } @@ -265,29 +268,34 @@ void blkid_free_probe(blkid_probe pr) free(pr); } +void blkid_probe_free_val(struct blkid_prval *v) +{ + if (!v) + return; + + list_del(&v->prvals); + free(v->data); + free(v); +} /* * Removes chain values from probing result. */ void blkid_probe_chain_reset_vals(blkid_probe pr, struct blkid_chain *chn) { - int nvals = pr->nvals; - int i, x; - for (x = 0, i = 0; i < pr->nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; + struct list_head *p, *pnext; - if (v->chain != chn && x == i) { - x++; - continue; - } - if (v->chain == chn) { - --nvals; - continue; - } - memcpy(&pr->vals[x++], v, sizeof(struct blkid_prval)); + if (!pr || list_empty(&pr->vals)) + return; + + list_for_each_safe(p, pnext, &pr->vals) { + struct blkid_prval *v = list_entry(p, + struct blkid_prval, prvals); + + if (v->chain == chn) + blkid_probe_free_val(v); } - pr->nvals = nvals; } static void blkid_probe_chain_reset_position(struct blkid_chain *chn) @@ -296,42 +304,56 @@ static void blkid_probe_chain_reset_position(struct blkid_chain *chn) chn->idx = -1; } +static struct blkid_prval *blkid_probe_deep_copy_val(struct blkid_prval *dest, + struct blkid_prval *src) +{ + memcpy(dest, src, sizeof(struct blkid_prval)); + + dest->data = malloc(src->len); + if (!dest->data) + return NULL; + + memcpy(dest->data, src->data, src->len); + + INIT_LIST_HEAD(&dest->prvals); + + return dest; +} + /* - * Copies chain values from probing result to @vals, the max size of @vals is - * @nvals and returns real number of values. + * Copies chain values from probing result to @vals. */ int blkid_probe_chain_copy_vals(blkid_probe pr, struct blkid_chain *chn, - struct blkid_prval *vals, int nvals) + struct list_head *vals) { - int i, x; + struct list_head *p; + struct blkid_prval *new_v, *v; - for (x = 0, i = 0; i < pr->nvals && x < nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; + list_for_each(p, &pr->vals) { + + v = list_entry(p, struct blkid_prval, prvals); + + new_v = blkid_probe_new_value(); + if (!new_v) + break; if (v->chain != chn) continue; - memcpy(&vals[x++], v, sizeof(struct blkid_prval)); + + if (!blkid_probe_deep_copy_val(new_v, v)) + break; + + list_add_tail(&new_v->prvals, vals); } - return x; + return 0; } /* * Appends values from @vals to the probing result */ -void blkid_probe_append_vals(blkid_probe pr, struct blkid_prval *vals, int nvals) +void blkid_probe_append_vals(blkid_probe pr, struct list_head *vals) { - int i = 0; - - while (i < nvals && pr->nvals < BLKID_NVALS) { - memcpy(&pr->vals[pr->nvals++], &vals[i++], - sizeof(struct blkid_prval)); - } -} - -static void blkid_probe_reset_vals(blkid_probe pr) -{ - memset(pr->vals, 0, sizeof(pr->vals)); - pr->nvals = 0; + list_splice(vals, &pr->vals); } struct blkid_chain *blkid_probe_get_chain(blkid_probe pr) @@ -615,7 +637,6 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, return off ? bf->data + (off - bf->off) : bf->data; } - static void blkid_probe_reset_buffer(blkid_probe pr) { uint64_t read_ct = 0, len_ct = 0; @@ -641,6 +662,22 @@ static void blkid_probe_reset_buffer(blkid_probe pr) INIT_LIST_HEAD(&pr->buffers); } +static void blkid_probe_reset_vals(blkid_probe pr) +{ + if (!pr || list_empty(&pr->vals)) + return; + + DBG(LOWPROBE, ul_debug("resetting results pr=%p", pr)); + + while (!list_empty(&pr->vals)) { + struct blkid_prval *v = list_entry(pr->vals.next, + struct blkid_prval, prvals); + blkid_probe_free_val(v); + } + + INIT_LIST_HEAD(&pr->vals); +} + /* * Small devices need a special care. */ @@ -1273,37 +1310,47 @@ struct blkid_prval *blkid_probe_assign_value( blkid_probe pr, const char *name) { struct blkid_prval *v; - if (!name) return NULL; - if (pr->nvals >= BLKID_NVALS) + + v = blkid_probe_new_value(); + if (!v) return NULL; - v = &pr->vals[pr->nvals]; v->name = name; v->chain = pr->cur_chain; - pr->nvals++; + list_add_tail(&v->prvals, &pr->vals); DBG(LOWPROBE, ul_debug("assigning %s [%s]", name, v->chain->driver->name)); return v; } -int blkid_probe_reset_last_value(blkid_probe pr) +static struct blkid_prval *blkid_probe_new_value(void) { - struct blkid_prval *v; - - if (pr == NULL || pr->nvals == 0) - return -1; + struct blkid_prval *v = calloc(1, sizeof(struct blkid_prval)); + if (!v) + return NULL; - v = &pr->vals[pr->nvals - 1]; + INIT_LIST_HEAD(&v->prvals); - DBG(LOWPROBE, ul_debug("un-assigning %s [%s]", v->name, v->chain->driver->name)); + return v; +} - memset(v, 0, sizeof(struct blkid_prval)); - pr->nvals--; +/* Note that value data is always terminated by zero to keep things robust, + * this extra zero is not count to the value lenght. It's caller responsibility + * to set proper value lenght (for strings we count terminator to the lenght, + * for binary data it's without terminator). + */ +int blkid_probe_value_set_data(struct blkid_prval *v, + unsigned char *data, size_t len) +{ + v->data = calloc(1, len + 1); /* always terminate by \0 */ + if (!v->data) + return -ENOMEM; + memcpy(v->data, data, len); + v->len = len; return 0; - } int blkid_probe_set_value(blkid_probe pr, const char *name, @@ -1311,16 +1358,11 @@ int blkid_probe_set_value(blkid_probe pr, const char *name, { struct blkid_prval *v; - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; - v = blkid_probe_assign_value(pr, name); if (!v) return -1; - memcpy(v->data, data, len); - v->len = len; - return 0; + return blkid_probe_value_set_data(v, data, len); } int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, @@ -1331,13 +1373,13 @@ int blkid_probe_vsprintf_value(blkid_probe pr, const char *name, v = blkid_probe_assign_value(pr, name); if (!v) - return -1; + return -ENOMEM; - len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap); + len = vasprintf((char **) &v->data, fmt, ap); - if (len <= 0 || (size_t) len >= sizeof(v->data)) { - blkid_probe_reset_last_value(pr); - return -1; + if (len <= 0) { + blkid_probe_free_val(v); + return len == 0 ? -EINVAL : -ENOMEM; } v->len = len + 1; return 0; @@ -1586,9 +1628,14 @@ blkid_loff_t blkid_probe_get_sectors(blkid_probe pr) */ int blkid_probe_numof_values(blkid_probe pr) { + int i = 0; + struct list_head *p; if (!pr) return -1; - return pr->nvals; + + list_for_each(p, &pr->vals) + ++i; + return i; } /** @@ -1662,23 +1709,41 @@ int blkid_probe_has_value(blkid_probe pr, const char *name) return 0; } +struct blkid_prval *blkid_probe_last_value(blkid_probe pr) +{ + if (!pr || list_empty(&pr->vals)) + return NULL; + + return list_last_entry(&pr->vals, struct blkid_prval, prvals); +} + + struct blkid_prval *__blkid_probe_get_value(blkid_probe pr, int num) { - if (!pr || num < 0 || num >= pr->nvals) + int i = 0; + struct list_head *p; + + if (!pr || num < 0) return NULL; - return &pr->vals[num]; + list_for_each(p, &pr->vals) { + if (i++ != num) + continue; + return list_entry(p, struct blkid_prval, prvals); + } + return NULL; } struct blkid_prval *__blkid_probe_lookup_value(blkid_probe pr, const char *name) { - int i; + struct list_head *p; - if (!pr || !pr->nvals || !name) + if (!pr || list_empty(&pr->vals) || !name) return NULL; - for (i = 0; i < pr->nvals; i++) { - struct blkid_prval *v = &pr->vals[i]; + list_for_each(p, &pr->vals) { + struct blkid_prval *v = list_entry(p, struct blkid_prval, + prvals); if (v->name && strcmp(name, v->name) == 0) { DBG(LOWPROBE, ul_debug("returning %s value", v->name)); diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c index 975181d4c5..8d381599e0 100644 --- a/libblkid/src/superblocks/superblocks.c +++ b/libblkid/src/superblocks/superblocks.c @@ -451,13 +451,14 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn) */ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) { - struct blkid_prval vals[BLKID_NVALS_SUBLKS]; - int nvals = BLKID_NVALS_SUBLKS; + struct list_head vals; int idx = -1; int count = 0; int intol = 0; int rc; + INIT_LIST_HEAD(&vals); + if (pr->flags & BLKID_FL_NOSCAN_DEV) return BLKID_PROBE_NONE; @@ -478,7 +479,7 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) if (count == 1) { /* save the first result */ - nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals); + blkid_probe_chain_copy_vals(pr, chn, &vals); idx = chn->idx; } } @@ -498,7 +499,7 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn) if (idx != -1) { /* restore the first result */ blkid_probe_chain_reset_vals(pr, chn); - blkid_probe_append_vals(pr, vals, nvals); + blkid_probe_append_vals(pr, &vals); chn->idx = idx; } @@ -566,28 +567,28 @@ int blkid_probe_set_id_label(blkid_probe pr, const char *name, { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; + int rc = 0; if (!(chn->flags & BLKID_SUBLKS_LABEL)) return 0; v = blkid_probe_assign_value(pr, name); if (!v) - return -1; + return -ENOMEM; - if (len >= BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ - 1; /* make a space for \0 */ - - memcpy(v->data, data, len); - v->data[len] = '\0'; + rc = blkid_probe_value_set_data(v, data, len); + if (!rc) { + /* remove white spaces */ + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len > 1) + v->len = blkid_ltrim_whitespace(v->data) + 1; + if (v->len > 1) + return 0; + } - /* remove white spaces */ - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len > 1) - v->len = blkid_ltrim_whitespace(v->data) + 1; + blkid_probe_free_val(v); + return rc; - if (v->len <= 1) - blkid_probe_reset_last_value(pr); /* ignore empty */ - return 0; } int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name, @@ -595,50 +596,58 @@ int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name, { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; + int rc = 0; if (!(chn->flags & BLKID_SUBLKS_LABEL)) return 0; v = blkid_probe_assign_value(pr, name); if (!v) - return -1; + return -ENOMEM; - blkid_encode_to_utf8(enc, v->data, sizeof(v->data), data, len); - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len > 1) - v->len = blkid_ltrim_whitespace(v->data) + 1; + v->data = blkid_encode_alloc(len, &v->len); + if (!v->data) + rc = -ENOMEM; - if (v->len <= 1) - blkid_probe_reset_last_value(pr); - return 0; + if (!rc) { + blkid_encode_to_utf8(enc, v->data, v->len, data, len); + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len > 1) + v->len = blkid_ltrim_whitespace(v->data) + 1; + if (v->len > 1) + return 0; + } + + blkid_probe_free_val(v); + return rc; } int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len) { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; + int rc = 0; if ((chn->flags & BLKID_SUBLKS_LABELRAW) && - blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) - return -1; + (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0) + return rc; + if (!(chn->flags & BLKID_SUBLKS_LABEL)) return 0; + v = blkid_probe_assign_value(pr, "LABEL"); if (!v) - return -1; - - if (len == BLKID_PROBVAL_BUFSIZ) - len--; /* make a space for \0 */ + return -ENOMEM; - memcpy(v->data, label, len); - v->data[len] = '\0'; + rc = blkid_probe_value_set_data(v, label, len); + if (!rc) { + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len > 1) + return 0; + } - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len == 1) - blkid_probe_reset_last_value(pr); - return 0; + blkid_probe_free_val(v); + return rc; } int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, @@ -646,39 +655,47 @@ int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label, { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; + int rc = 0; if ((chn->flags & BLKID_SUBLKS_LABELRAW) && - blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0) - return -1; + (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0) + return rc; + if (!(chn->flags & BLKID_SUBLKS_LABEL)) return 0; + v = blkid_probe_assign_value(pr, "LABEL"); if (!v) - return -1; + return -ENOMEM; - blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len); - v->len = blkid_rtrim_whitespace(v->data) + 1; - if (v->len == 1) - blkid_probe_reset_last_value(pr); - return 0; + v->data = blkid_encode_alloc(len, &v->len); + if (!v->data) + rc = -ENOMEM; + if (!rc) { + blkid_encode_to_utf8(enc, v->data, v->len, label, len); + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len > 1) + return 0; + } + + blkid_probe_free_val(v); + return rc; } int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, size_t len, const char *fmt, ...) { struct blkid_chain *chn = blkid_probe_get_chain(pr); - int rc = -1; va_list ap; - - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; + int rc = 0; if (blkid_uuid_is_empty(uuid, len)) return 0; if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0) - return -1; + (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, len)) < 0) + return rc; + if (!(chn->flags & BLKID_SUBLKS_UUID)) return 0; @@ -686,17 +703,6 @@ int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid, rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap); va_end(ap); - /* convert to lower case (..be paranoid) */ - if (!rc) { - size_t i; - struct blkid_prval *v = __blkid_probe_get_value(pr, - blkid_probe_numof_values(pr)); - if (v) { - for (i = 0; i < v->len; i++) - if (v->data[i] >= 'A' && v->data[i] <= 'F') - v->data[i] = (v->data[i] - 'A') + 'a'; - } - } return rc; } @@ -705,31 +711,34 @@ int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len) { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; + int rc = 0; if (str == NULL || *str == '\0') - return -1; + return -EINVAL; + if (!len) len = strlen((char *) str); - if (len > BLKID_PROBVAL_BUFSIZ) - len = BLKID_PROBVAL_BUFSIZ; if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0) - return -1; + (rc = blkid_probe_set_value(pr, "UUID_RAW", str, len)) < 0) + return rc; + if (!(chn->flags & BLKID_SUBLKS_UUID)) return 0; v = blkid_probe_assign_value(pr, "UUID"); - if (v) { - if (len == BLKID_PROBVAL_BUFSIZ) - len--; /* make a space for \0 */ - - memcpy((char *) v->data, str, len); - v->data[len] = '\0'; - v->len = len + 1; - return 0; + if (!v) + rc= -ENOMEM; + if (!rc) + rc = blkid_probe_value_set_data(v, str, len); + if (!rc) { + v->len = blkid_rtrim_whitespace(v->data) + 1; + if (v->len > 1) + return 0; } - return -1; + + blkid_probe_free_val(v); + return rc; } /* default _set_uuid function to set DCE UUIDs */ @@ -737,14 +746,16 @@ int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *nam { struct blkid_chain *chn = blkid_probe_get_chain(pr); struct blkid_prval *v; + int rc = 0; if (blkid_uuid_is_empty(uuid, 16)) return 0; if (!name) { if ((chn->flags & BLKID_SUBLKS_UUIDRAW) && - blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0) - return -1; + (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, 16)) < 0) + return rc; + if (!(chn->flags & BLKID_SUBLKS_UUID)) return 0; @@ -752,10 +763,21 @@ int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *nam } else v = blkid_probe_assign_value(pr, name); - blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data)); + if (!v) + return -ENOMEM; + v->len = 37; + v->data = calloc(1, v->len); + if (!v->data) + rc = -ENOMEM; - return 0; + if (!rc) { + blkid_unparse_uuid(uuid, (char *) v->data, v->len); + return 0; + } + + blkid_probe_free_val(v); + return rc; } int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid) |