ndc: get rid of arbritrary command length limit

Change-Id: I6123aa916a1f69bbfba58c26e6f150dfdec8c991
diff --git a/TetherController.cpp b/TetherController.cpp
index 2c48074..5f571a1 100644
--- a/TetherController.cpp
+++ b/TetherController.cpp
@@ -282,8 +282,8 @@
             return -1;
         }
 
-        cmdLen += strlen(servers[i]);
-        if (cmdLen + 2 >= MAX_CMD_SIZE) {
+        cmdLen += (strlen(servers[i]) + 1);
+        if (cmdLen + 1 >= MAX_CMD_SIZE) {
             ALOGD("Too many DNS servers listed");
             break;
         }
diff --git a/ndc.c b/ndc.c
index 17750bd..29a399a 100644
--- a/ndc.c
+++ b/ndc.c
@@ -65,25 +65,40 @@
 }
 
 static int do_cmd(int sock, int argc, char **argv) {
-    char final_cmd[255] = { '0', ' ', '\0' };
+    char *final_cmd = strdup("0 ");
+    if (final_cmd == NULL) {
+        perror("strdup");
+        return errno;
+    }
+
     int i;
 
     for (i = 1; i < argc; i++) {
+        if (index(argv[i], '"')) {
+            perror("argument with embedded quotes not allowed");
+            free(final_cmd);
+            return 1;
+        }
+        bool needs_quoting = index(argv[i], ' ');
+        const char *format = needs_quoting ? "%s\"%s\"%s" : "%s%s%s";
         char *cmp;
 
-        if (!index(argv[i], ' '))
-            asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " ");
-        else
-            asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " ");
-
-        strcat(final_cmd, cmp);
-        free(cmp);
+        if (asprintf(&cmp, format, final_cmd, argv[i],
+                     (i == (argc -1)) ? "" : " ") < 0) {
+            perror("malloc");
+            free(final_cmd);
+            return errno;
+        }
+        free(final_cmd);
+        final_cmd = cmp;
     }
 
     if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) {
         perror("write");
+        free(final_cmd);
         return errno;
     }
+    free(final_cmd);
 
     return do_monitor(sock, 1);
 }