summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src/cli-cmd-parser.c')
-rw-r--r--cli/src/cli-cmd-parser.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index cd0370a..3d8ec5d 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -26,6 +26,8 @@
#include "protocol-common.h"
#include "cli1-xdr.h"
+#define MAX_SNAP_DESCRIPTION_LEN 1024
+
static const char *
id_sel (void *wcon)
{
@@ -2732,3 +2734,326 @@ out:
return ret;
}
+
+int32_t
+cli_snap_create_desc_parse (dict_t *dict, const char **words, int wordcount,
+ int32_t desc_opt_loc, int32_t no_of_wrds_in_desc)
+{
+ int32_t ret = -1;
+ char *desc = NULL;
+ int32_t i = 0;
+ int32_t desc_len = 0;
+
+ desc = GF_CALLOC (MAX_SNAP_DESCRIPTION_LEN + 1, sizeof(char),
+ gf_common_mt_char);
+ if (!desc) {
+ gf_log ("", GF_LOG_ERROR, "Out Of Memory");
+ ret = -1;
+ goto out;
+ }
+
+ /* Creating the description string */
+ for (i = 0; i < no_of_wrds_in_desc; i++) {
+ if ((strcmp (words[desc_opt_loc + 1 + i], "-n") == 0) ||
+ (strcmp (words[desc_opt_loc + 1 + i], "-d") == 0)) {
+ cli_out ("snapshot create: failed: Options(-n/-d) "
+ "are not valid descriptions");
+ ret = -1;
+ goto out;
+ }
+
+ strcat (desc, words[desc_opt_loc + 1 + i]);
+ strcat (desc, " ");
+ /* Calculating the size of the description as given by the user */
+ desc_len += strlen(words[desc_opt_loc + 1 + i]);
+ desc_len++;
+ }
+
+ /* Removing the last space in the string */
+ desc[--desc_len] = '\0';
+
+ if (desc_len > MAX_SNAP_DESCRIPTION_LEN) {
+ cli_out ("snapshot create: description truncated: "
+ "Description provided is longer than 1024 characters");
+ desc[MAX_SNAP_DESCRIPTION_LEN] = '\0';
+ }
+
+ ret = dict_set_dynstr (dict, "snap-description", desc);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save snap description");
+ goto out;
+ }
+
+ ret = 0;
+out:
+
+ if (ret) {
+ if (desc)
+ GF_FREE (desc);
+ }
+
+ return ret;
+}
+
+int32_t
+cli_snap_create_parse (dict_t *dict, const char **words, int wordcount,
+ int32_t cmdi)
+{
+ int32_t volcount = -1;
+ int32_t no_of_wrds_in_desc = -1;
+ int32_t name_opt_loc = -1;
+ int32_t desc_opt_loc = -1;
+ char volname_buf[PATH_MAX] = "";
+ int32_t ret = -1;
+ int32_t i = -1;
+
+ /* Finding the "-n" and "-d" in the cli */
+ for (i = cmdi + 1; i < wordcount; i++) {
+ if ((strcmp (words[i], "-n") == 0) &&
+ (name_opt_loc == -1))
+ name_opt_loc = i;
+
+ if ((strcmp (words[i], "-d") == 0) &&
+ (desc_opt_loc == -1))
+ desc_opt_loc = i;
+ }
+
+ if ((name_opt_loc == -1) && (desc_opt_loc == -1)) {
+ /* No snap-name and description has been given */
+
+ volcount = (wordcount - 1) - cmdi;
+ } else if ((name_opt_loc > cmdi + 1) && (desc_opt_loc == -1)) {
+ /* If only name and no description is given */
+
+ /* if more than one or no snap name is given */
+ if (((wordcount - 1) - name_opt_loc) != 1) {
+ cli_out ("snapshot create: failed: "
+ "Invalid snap name arguments");
+ ret = -1;
+ goto out;
+ }
+
+ volcount = (name_opt_loc - 1) - cmdi;
+ } else if ((name_opt_loc == -1) && (desc_opt_loc > cmdi + 1)) {
+ /* If no name and only description is given */
+
+ /* Description should not be blank */
+ no_of_wrds_in_desc = (wordcount - 1) - desc_opt_loc;
+ if (no_of_wrds_in_desc == 0) {
+ cli_out ("snapshot create: failed: "
+ "No description provided");
+ ret = -1;
+ goto out;
+ }
+
+ volcount = (desc_opt_loc - 1) - cmdi;
+ } else if ((name_opt_loc > cmdi + 1) && (desc_opt_loc > cmdi + 1)) {
+ /* Both name and description is given */
+
+ /* Figuring out which comes first */
+ if (name_opt_loc < desc_opt_loc) {
+ /* if more than one or no snap name is given */
+ if ((desc_opt_loc - name_opt_loc) != 2) {
+ cli_out ("snapshot create: failed: "
+ "Invalid snap name arguments");
+ ret = -1;
+ goto out;
+ }
+
+ /* Description should not be blank */
+ no_of_wrds_in_desc = (wordcount - 1) - desc_opt_loc;
+ if (no_of_wrds_in_desc == 0) {
+ cli_out ("snapshot create: failed: "
+ "No description provided");
+ ret = -1;
+ goto out;
+ }
+
+ volcount = (name_opt_loc - 1) - cmdi;
+ } else if (desc_opt_loc < name_opt_loc) {
+ /* if more than one or no snap name is given */
+ if (((wordcount - 1) - name_opt_loc) != 1) {
+ cli_out ("snapshot create: failed: "
+ "Invalid snap name arguments");
+ ret = -1;
+ goto out;
+ }
+
+ /* Description should not be blank */
+ no_of_wrds_in_desc = (name_opt_loc) - desc_opt_loc -1;
+ if (no_of_wrds_in_desc == 0) {
+ cli_out ("snapshot create: failed: "
+ "No description provided");
+ ret = -1;
+ goto out;
+ }
+
+ volcount = (desc_opt_loc - 1) - cmdi;
+ }
+ }
+
+ /*At least one volume name should be present */
+ if (volcount < 1) {
+ cli_out ("snapshot create: failed: No volume name provided");
+ ret = -1;
+ goto out;
+ }
+
+ /* Only one volume is present. volname
+ * should be set and not volname%d. */
+ if (volcount == 1) {
+ ret = dict_set_str (dict, "volname", (char *)words[2]);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save volname");
+ goto out;
+ }
+ } else {
+ /* Saving the volume names */
+ for (i = 2; i < volcount + 2; i++) {
+ ret = snprintf (volname_buf, sizeof(volname_buf) - 1,
+ "volname%d", i - 1);
+ volname_buf[ret] = '\0';
+
+ ret = dict_set_str (dict, volname_buf,
+ (char *)words[i]);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save %s",
+ volname_buf);
+ goto out;
+ }
+ }
+ }
+
+ /* Saving the volcount */
+ ret = dict_set_int32 (dict, "volcount", volcount);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save volcount");
+ goto out;
+ }
+
+ /* Saving snap-name/cg-name in dict */
+ if (name_opt_loc > cmdi + 1) {
+ if (strstr((char *)words[name_opt_loc + 1], " ")) {
+ cli_out ("snapshot create: failed: Invalid snap name");
+ ret = -1;
+ goto out;
+ }
+
+ if ((strcmp ((char *)words[name_opt_loc + 1], "-n") == 0) ||
+ (strcmp ((char *)words[name_opt_loc + 1], "-d") == 0)) {
+ cli_out ("snapshot create: failed: Options(-n/-d) "
+ "are not valid snap names");
+ ret = -1;
+ goto out;
+ }
+
+ /* Decide if it's a cg-name or a snap-name */
+ if (volcount > 1) {
+ ret = dict_set_str (dict, "cg-name",
+ (char *)words[name_opt_loc + 1]);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save cg-name");
+ goto out;
+ }
+ } else {
+ ret = dict_set_str (dict, "snap-name",
+ (char *)words[name_opt_loc + 1]);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to save snap-name");
+ goto out;
+ }
+ }
+ }
+
+ /* Parsing the description and saving it in the dict */
+ if (desc_opt_loc > cmdi + 1) {
+ ret = cli_snap_create_desc_parse (dict, words,
+ wordcount,
+ desc_opt_loc,
+ no_of_wrds_in_desc);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to parse snap-description");
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int32_t
+cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options)
+{
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
+ int32_t cmdi = 0;
+ char *opwords[] = {"create", NULL};
+ char *w = NULL;
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ /* syntax:
+ * snapshot create <volnames> [-n <snap-name/cg-name>] [-d <description>]
+ */
+
+ /* Lowest wordcount possible */
+ if (wordcount < 2) {
+ gf_log ("", GF_LOG_ERROR, "Invalid command: Not enough arguments");
+ goto out;
+ }
+
+ /* In cases where the vol-name is not given
+ * parsing fails. volname cannot be an opword.
+ * and that is what this check verifies */
+ w = str_getunamb (words[2], opwords);
+ if (w)
+ goto out;
+
+ w = str_getunamb (words[1], opwords);
+ if (!w) {
+ /* Checks if the operation is a valid operation */
+ gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
+ goto out;
+ }
+
+ /* Check which op is intended */
+ if (strcmp (w, "create") == 0) {
+ type = GF_SNAP_OPTION_TYPE_CREATE;
+ cmdi = 1;
+ ret = dict_set_int32 (dict, "type", type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Failed to set type.");
+ goto out;
+ }
+
+ ret = cli_snap_create_parse (dict, words,
+ wordcount, cmdi);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "create command parsing failed.");
+ goto out;
+ }
+ } else {
+ gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
+ goto out;
+ }
+
+ /* If you got so far, input is valid */
+ ret = 0;
+out:
+ if (ret) {
+ if (dict)
+ dict_destroy (dict);
+ } else
+ *options = dict;
+
+ return ret;
+}