]> xenbits.xensource.com Git - libvirt.git/commitdiff
Extend NWFilter parameter parser to cope with lists of values
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Fri, 18 Nov 2011 16:58:18 +0000 (11:58 -0500)
committerStefan Berger <stefanb@us.ibm.com>
Fri, 18 Nov 2011 16:58:18 +0000 (11:58 -0500)
This patch modifies the NWFilter parameter parser to support multiple
elements with the same name and to internally build a list of items.
An example of the XML looks like this:

        <parameter name='TEST' value='10.1.2.3'/>
        <parameter name='TEST' value='10.2.3.4'/>
        <parameter name='TEST' value='10.1.1.1'/>

The list of values is then stored in the newly introduced data type
virNWFilterVarValue.

The XML formatter is also adapted to print out all items in alphabetical
order sorted by 'name'.

This patch also fixes a bug in the XML schema on the way.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
docs/schemas/nwfilter.rng
src/conf/nwfilter_params.c

index b9d72760afb0558331889251e951ceca132494ef..c81e410bd1a14602785b6a1d296709eeb7f5eeb7 100644 (file)
     <attribute name="filter">
       <data type="NCName"/>
     </attribute>
-    <optional>
+    <zeroOrMore>
       <element name="parameter">
         <attribute name="name">
           <ref name="filter-param-name"/>
           <ref name="filter-param-value"/>
         </attribute>
       </element>
-    </optional>
+    </zeroOrMore>
   </define>
 
   <define name="rule-node-attributes">
index c63c807a3395684ac1e015f3f79d3a25e8357e69..2fba3513908bb875ad8e17aff78aa864a2a34f44 100644 (file)
@@ -604,7 +604,7 @@ isValidVarName(const char *var)
 static bool
 isValidVarValue(const char *value)
 {
-    return value[strspn(value, VALID_VARVALUE)] == 0;
+    return (value[strspn(value, VALID_VARVALUE)] == 0) && (strlen(value) != 0);
 }
 
 static virNWFilterVarValuePtr
@@ -636,15 +636,22 @@ virNWFilterParseParamAttributes(xmlNodePtr cur)
                 if (nam != NULL && val != NULL) {
                     if (!isValidVarName(nam))
                         goto skip_entry;
-                    value = virNWFilterParseVarValue(val);
-                    if (!value)
+                    if (!isValidVarValue(val))
                         goto skip_entry;
-                    if (virNWFilterHashTablePut(table, nam, value, 1)) {
-                        VIR_FREE(nam);
-                        VIR_FREE(val);
-                        virNWFilterVarValueFree(value);
-                        virNWFilterHashTableFree(table);
-                        return NULL;
+                    value = virHashLookup(table->hashTable, nam);
+                    if (value) {
+                        /* add value to existing value -> list */
+                        if (virNWFilterVarValueAddValue(value, val) < 0) {
+                            value = NULL;
+                            goto err_exit;
+                        }
+                        val = NULL;
+                    } else {
+                        value = virNWFilterParseVarValue(val);
+                        if (!value)
+                            goto skip_entry;
+                        if (virNWFilterHashTablePut(table, nam, value, 1))
+                            goto err_exit;
                     }
                     value = NULL;
                 }
@@ -657,39 +664,66 @@ skip_entry:
         cur = cur->next;
     }
     return table;
+
+err_exit:
+    VIR_FREE(nam);
+    VIR_FREE(val);
+    virNWFilterVarValueFree(value);
+    virNWFilterHashTableFree(table);
+    return NULL;
 }
 
 
-static void
-_formatParameterAttrs(void *payload, const void *name, void *data)
+static int
+virNWFilterFormatParameterNameSorter(const virHashKeyValuePairPtr a,
+                                     const virHashKeyValuePairPtr b)
 {
-    virBufferPtr buf = data;
-
-    virBufferAsprintf(buf, "  <parameter name='%s' value='%s'/>\n",
-                      (const char *)name,
-                      (char *)payload);
+    return strcmp((const char *)a->key, (const char *)b->key);
 }
 
-
 int
 virNWFilterFormatParamAttributes(virBufferPtr buf,
                                  virNWFilterHashTablePtr table,
                                  const char *filterref)
 {
-    int count = virHashSize(table->hashTable);
+    virHashKeyValuePairPtr items;
+    int i, j, card, numKeys;
+
+    numKeys = virHashSize(table->hashTable);
 
-    if (count < 0) {
+    if (numKeys < 0) {
         virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("missing filter parameter table"));
         return -1;
     }
+
+    items = virHashGetItems(table->hashTable,
+                            virNWFilterFormatParameterNameSorter);
+    if (!items)
+        return -1;
+
     virBufferAsprintf(buf, "<filterref filter='%s'", filterref);
-    if (count) {
+    if (numKeys) {
         virBufferAddLit(buf, ">\n");
-        virHashForEach(table->hashTable, _formatParameterAttrs, buf);
+        for (i = 0; i < numKeys; i++) {
+            const virNWFilterVarValuePtr value =
+                (const virNWFilterVarValuePtr)items[i].value;
+
+            card = virNWFilterVarValueGetCardinality(value);
+
+            for (j = 0; j < card; j++)
+                virBufferAsprintf(buf,
+                                  "  <parameter name='%s' value='%s'/>\n",
+                                  (const char *)items[i].key,
+                                  virNWFilterVarValueGetNthValue(value, j));
+
+        }
         virBufferAddLit(buf, "</filterref>\n");
     } else {
         virBufferAddLit(buf, "/>\n");
     }
+
+    VIR_FREE(items);
+
     return 0;
 }