[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