[Libguestfs] [PATCH 5/9] daemon: More reliable parsing of the output from 'parted print'.
Richard W.M. Jones
rjones at redhat.com
Sat Apr 10 12:52:28 UTC 2010
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From cb9350019cc6382a35c98f522c9c4d221c92b605 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Sat, 10 Apr 2010 13:17:50 +0100
Subject: [PATCH 5/9] daemon: More reliable parsing of the output from 'parted print'.
Previously we used strtok. However this has the problem that
strtok considers multiple delimiter characters to be like a single
delimiter, eg. "1:::2" would be parsed the same as "1:2". In
other words, the previous code would skip over or fail if there
are empty fields.
---
daemon/parted.c | 52 +++++++++++++++++++++++++++++++++-------------------
1 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/daemon/parted.c b/daemon/parted.c
index ff6cca1..b1750a5 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -224,6 +224,36 @@ do_part_set_name (const char *device, int partnum, const char *name)
return 0;
}
+/* Return the nth field from a string of ':'/';'-delimited strings.
+ * Useful for parsing the return value from print_partition_table
+ * function below.
+ */
+static char *
+get_table_field (const char *line, int n)
+{
+ const char *p = line;
+
+ while (*p && n > 0) {
+ p += strcspn (p, ":;") + 1;
+ n--;
+ }
+
+ if (n > 0) {
+ reply_with_error ("not enough fields in output of parted print command: %s",
+ line);
+ return NULL;
+ }
+
+ size_t len = strcspn (p, ":;");
+ char *q = strndup (p, len);
+ if (q == NULL) {
+ reply_with_perror ("strndup");
+ return NULL;
+ }
+
+ return q;
+}
+
static char **
print_partition_table (const char *device)
{
@@ -269,31 +299,15 @@ print_partition_table (const char *device)
char *
do_part_get_parttype (const char *device)
{
- char **lines;
- char *r;
-
- lines = print_partition_table (device);
+ char **lines = print_partition_table (device);
if (!lines)
return NULL;
/* lines[1] is something like:
* "/dev/sda:1953525168s:scsi:512:512:msdos:ATA Hitachi HDT72101;"
*/
- if (strtok (lines[1], ":") == NULL /* device */
- || strtok (NULL, ":") == NULL /* size */
- || strtok (NULL, ":") == NULL /* transport */
- || strtok (NULL, ":") == NULL /* sector size */
- || strtok (NULL, ":") == NULL /* physical sector size */
- || (r = strtok (NULL, ":")) == NULL /* return value */
- ) {
- reply_with_error ("too few fields in output from parted print command: %s", lines[1]);
- free_strings (lines);
- return NULL;
- }
-
- r = strdup (r);
- if (!r) {
- reply_with_perror ("strdup");
+ char *r = get_table_field (lines[1], 5);
+ if (r == NULL) {
free_strings (lines);
return NULL;
}
--
1.6.6.1
More information about the Libguestfs
mailing list