]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix to some of the command line parsing (including rbd)
authorRajesh Nambiar <rajesh.n@msystechnologies.com>
Wed, 8 Apr 2015 06:39:07 +0000 (23:39 -0700)
committerJosh Durgin <jdurgin@redhat.com>
Wed, 8 Apr 2015 06:39:07 +0000 (23:39 -0700)
Fix#: 2862

Changes to some of the common files for command line parsing

Change to ceph_argparse.cc
-------------------------

Added function ceph_arg_value_type()
  Given an input it will determine
   i) If that input is an option or not
   ii) If input is numeric in nature or not.

  It will set the flag bool_option and bool_numeric appropriately.
  This function is called by ceph_argparse_witharg() to figure out if
  the input parameter to those functions are numeric in nature and not
  an option.  If the input parameter to ceph_argparse_witharg()
  happens to be an option then it implies that user didn't supply
  value to the option.

Changes to strol.cc
-------------------
Changes to strict_strtoll() and strict_strtol()

  Both these functions reponsibility is to convert the string to long or to int.
  I felt it may be not be good for it to display error message within this function,
  rather caller of this function who has better understanding of the function's purpose
  can display the error message.

  Made change in this function to just create a generic error message,Its the
  caller of this function decides what to do with this message.

Signed-off-by: Rajesh Nambiar <rajesh.n@msystechnologies.com>
src/common/ceph_argparse.cc
src/common/strtol.cc

index 26d1178d34c9bf3b047cdb088baa373e55401ab7..91ec13deee59333e2736dd5eb28f57ddf7de8b9c 100644 (file)
@@ -151,6 +151,44 @@ void vec_to_argv(const char *argv0, std::vector<const char*>& args,
     (*argv)[(*argc)++] = args[i];
 }
 
+void ceph_arg_value_type(const char * nextargstr, bool *bool_option, bool *bool_numeric)
+{
+  bool is_numeric = true;
+  bool is_option;
+
+  if (nextargstr == NULL) {
+    return;
+  }
+
+  if (strlen(nextargstr) < 2) {
+    is_option = false;
+  } else {
+    is_option = (nextargstr[0] == '-') && (nextargstr[1] == '-');
+  }
+
+  for (unsigned int i = 0; i < strlen(nextargstr); i++) {
+    if (!(nextargstr[i] >= '0' && nextargstr[i] <= '9')) {
+      // May be negative numeral value
+      if ((i == 0) && (strlen(nextargstr) >= 2))  {
+       if (nextargstr[0] == '-')
+         continue;
+      }
+      is_numeric = false;
+      break;
+    }
+  }
+
+  // -<option>
+  if (nextargstr[0] == '-' && is_numeric == false) {
+    is_option = true;
+  }
+
+  *bool_option = is_option;
+  *bool_numeric = is_numeric;
+
+  return;
+}
+
 bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec)
 {
   const char *p = s;
@@ -341,6 +379,8 @@ bool ceph_argparse_witharg(std::vector<const char*> &args,
 {
   bool r;
   va_list ap;
+  bool is_option = false;
+  bool is_numeric = true;
   std::string str;
   va_start(ap, oss);
   r = va_ceph_argparse_witharg(args, i, &str, ap);
@@ -349,6 +389,17 @@ bool ceph_argparse_witharg(std::vector<const char*> &args,
     return false;
   }
 
+  ceph_arg_value_type(str.c_str(), &is_option, &is_numeric);
+  if ((is_option == true) || (is_numeric == false)) {
+    *ret = EXIT_FAILURE;
+    if (is_option == true) {
+      *oss << "Missing option value";
+    } else {
+      *oss << "The option value '" << str << "' is invalid";
+    }
+    return true;
+  }
+
   std::string err;
   T myret = strict_str_convert(str.c_str(), &err);
   *ret = myret;
index 840b3d9c6a046df45c858818c8dde360e6953a75..ca15e2fad7169db2ff3e2fb2e2f56d3a8fae6357 100644 (file)
@@ -26,26 +26,32 @@ using std::ostringstream;
 long long strict_strtoll(const char *str, int base, std::string *err)
 {
   char *endptr;
+  std::string errStr;
   errno = 0; /* To distinguish success/failure after call (see man page) */
   long long ret = strtoll(str, &endptr, base);
 
   if ((errno == ERANGE && (ret == LLONG_MAX || ret == LLONG_MIN))
       || (errno != 0 && ret == 0)) {
-    ostringstream oss;
-    oss << "strict_strtoll: integer underflow or overflow parsing '" << str << "'";
-    *err = oss.str();
+    errStr = "The option value '";
+    errStr.append(str);
+    errStr.append("'");
+    errStr.append(" seems to be invalid");
+    *err = errStr;
     return 0;
   }
   if (endptr == str) {
-    ostringstream oss;
-    oss << "strict_strtoll: expected integer, got: '" << str << "'";
-    *err = oss.str();
+    errStr = "Expected option value to be integer, got '";
+    errStr.append(str);
+    errStr.append("'");
+    *err =  errStr;
     return 0;
   }
   if (*endptr != '\0') {
-    ostringstream oss;
-    oss << "strict_strtoll: garbage at end of string. got: '" << str << "'";
-    *err = oss.str();
+    errStr = "The option value '";
+    errStr.append(str);
+    errStr.append("'");
+    errStr.append(" seems to be invalid");
+    *err =  errStr;
     return 0;
   }
   *err = "";
@@ -54,19 +60,16 @@ long long strict_strtoll(const char *str, int base, std::string *err)
 
 int strict_strtol(const char *str, int base, std::string *err)
 {
+  std::string errStr;
   long long ret = strict_strtoll(str, base, err);
   if (!err->empty())
     return 0;
-  if (ret <= INT_MIN) {
-    ostringstream oss;
-    oss << "strict_strtol: integer underflow parsing '" << str << "'";
-    *err = oss.str();
-    return 0;
-  }
-  if (ret >= INT_MAX) {
-    ostringstream oss;
-    oss << "strict_strtol: integer overflow parsing '" << str << "'";
-    *err = oss.str();
+  if ((ret <= INT_MIN) || (ret >= INT_MAX)) {
+    errStr = "The option value '";
+    errStr.append(str);
+    errStr.append("'");
+    errStr.append(" seems to be invalid");
+    *err = errStr;
     return 0;
   }
   return static_cast<int>(ret);