tools/virsh.c: New helper function vshStringToArray, use the helper in cmdUndefine. --- tools/virsh.c | 107 +++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 66 insertions(+), 41 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 40f3be3..9c3b565 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3014,6 +3014,51 @@ static const vshCmdOptDef opts_undefine[] = { {NULL, 0, 0, NULL} }; +/* + * Convert the strings separated by ',' into array. The caller + * must free the returned array after use. + * + * Returns the length of the filled array on success, or -1 + * on error. + */ +static int +vshStringToArray(char *str, + char ***array) +{ + char *str_tok = NULL; + unsigned int nstr_tokens = 0; + char **arr = NULL; + + /* tokenize the string from user and save it's parts into an array */ + if (str) { + nstr_tokens = 1; + + /* count the delimiters */ + str_tok = str; + while (*str_tok) { + if (*str_tok == ',') + nstr_tokens++; + str_tok++; + } + + if (VIR_ALLOC_N(arr, nstr_tokens) < 0) { + virReportOOMError(); + return -1; + } + + /* tokenize the input string */ + nstr_tokens = 0; + str_tok = str; + do { + arr[nstr_tokens] = strsep(&str_tok, ","); + nstr_tokens++; + } while (str_tok); + } + + *array = arr; + return nstr_tokens; +} + static bool cmdUndefine(vshControl *ctl, const vshCmd *cmd) { @@ -3039,21 +3084,21 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) int running; /* list of volumes to remove along with this domain */ const char *volumes_arg = NULL; - char *volumes = NULL; - char **volume_tokens = NULL; - char *volume_tok = NULL; - int nvolume_tokens = 0; + char *volumes_str = NULL; + char **volumes = NULL; + char *volume = NULL; + int volumes_len = 0; char *def = NULL; char *source = NULL; char *target = NULL; int vol_i; - int tok_i; xmlDocPtr doc = NULL; xmlXPathContextPtr ctxt = NULL; xmlNodePtr *vol_nodes = NULL; int nvolumes = 0; virStorageVolPtr vol = NULL; bool vol_del_failed = false; + int i; if (managed_save) { flags |= VIR_DOMAIN_UNDEFINE_MANAGED_SAVE; @@ -3072,7 +3117,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) /* check if a string that should contain list of volumes to remove is present */ if (vshCommandOptString(cmd, "storage", &volumes_arg) > 0) { - volumes = vshStrdup(ctl, volumes_arg); + volumes_str = vshStrdup(ctl, volumes_arg); if (remove_all_storage) { vshError(ctl, _("Specified both --storage and --remove-all-storage")); @@ -3212,27 +3257,8 @@ out: if (remove_storage || remove_all_storage) { ret = false; - /* tokenize the string from user and save it's parts into an array */ - if (volumes) { - /* count the delimiters */ - volume_tok = volumes; - nvolume_tokens = 1; /* we need at least one member */ - while (*volume_tok) { - if (*volume_tok == ',') - nvolume_tokens++; - volume_tok++; - } - - volume_tokens = vshCalloc(ctl, nvolume_tokens, sizeof(char *)); - - /* tokenize the input string */ - nvolume_tokens = 0; - volume_tok = volumes; - do { - volume_tokens[nvolume_tokens] = strsep(&volume_tok, ","); - nvolume_tokens++; - } while (volume_tok); - } + if ((volumes_len = vshStringToArray(volumes_str, &volumes)) < 0) + goto cleanup; doc = virXMLParseStringCtxt(def, _("(domain_definition)"), &ctxt); if (!doc) @@ -3268,17 +3294,17 @@ out: /* lookup if volume was selected by user */ if (volumes) { - volume_tok = NULL; - for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) { - if (volume_tokens[tok_i] && - (STREQ_NULLABLE(volume_tokens[tok_i], target) || - STREQ_NULLABLE(volume_tokens[tok_i], source))) { - volume_tok = volume_tokens[tok_i]; - volume_tokens[tok_i] = NULL; + volume = NULL; + for (i = 0; i < volumes_len; i++) { + if (volumes[i] && + (STREQ_NULLABLE(volumes[i], target) || + STREQ_NULLABLE(volumes[i], source))) { + volume = volumes[i]; + volumes[i] = NULL; break; } } - if (!volume_tok) + if (!volume) continue; } @@ -3311,16 +3337,16 @@ out: target, source); vol_del_failed = true; } - vshPrint(ctl, _("Volume '%s' removed.\n"), volume_tok?volume_tok:source); + vshPrint(ctl, _("Volume '%s' removed.\n"), volume ? volume :source); } /* print volumes specified by user that were not found in domain definition */ if (volumes) { - for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) { - if (volume_tokens[tok_i]) + for (i = 0; i < volumes_len; i++) { + if (volumes[i]) vshPrint(ctl, _("Volume '%s' was not found in domain's " "definition.\n"), - volume_tokens[tok_i]); + volumes[i]); } } @@ -3331,8 +3357,8 @@ out: cleanup: VIR_FREE(source); VIR_FREE(target); + VIR_FREE(volumes_str); VIR_FREE(volumes); - VIR_FREE(volume_tokens); VIR_FREE(def); VIR_FREE(vol_nodes); if (vol) @@ -3343,7 +3369,6 @@ cleanup: return ret; } - /* * "start" command */ -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list