aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Oprala <ooprala@redhat.com>2015-02-03 16:30:15 +0100
committerKarel Zak <kzak@redhat.com>2015-02-24 10:22:37 +0100
commit6c4a7811f85fc64cb0b0fb9f3e266592ed9c40dc (patch)
treefa3dd1b62a64c4240171fa80e9c3946e08e91b03
parent85589c4c4975c3a9c12663cbd5e16904cdbdaac7 (diff)
downloadutil-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.h40
-rw-r--r--libblkid/src/encode.c6
-rw-r--r--libblkid/src/partitions/partitions.c30
-rw-r--r--libblkid/src/probe.c201
-rw-r--r--libblkid/src/superblocks/superblocks.c186
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)