Replace system_nosh call with android_fork_execvp

Replace the system_nosh call with the android_fork_execvp from
liblogwrap.

Change-Id: Idfbc6bcf0bef16d4ee90d6af6bd4b07bc79913bb
diff --git a/NatController.cpp b/NatController.cpp
index e44a29b..ff35d89 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <fcntl.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -28,13 +29,12 @@
 
 #define LOG_TAG "NatController"
 #include <cutils/log.h>
+#include <logwrap/logwrap.h>
 
 #include "NatController.h"
 #include "SecondaryTableController.h"
 #include "NetdConstants.h"
 
-extern "C" int system_nosh(const char *command);
-
 const char* NatController::LOCAL_FORWARD = "natctrl_FORWARD";
 const char* NatController::LOCAL_NAT_POSTROUTING = "natctrl_nat_POSTROUTING";
 
@@ -45,21 +45,11 @@
 NatController::~NatController() {
 }
 
-int NatController::runCmd(const char *path, const char *cmd) {
-    char *buffer;
-    size_t len = strnlen(cmd, 255);
+int NatController::runCmd(int argc, const char **argv) {
     int res;
 
-    if (len == 255) {
-        ALOGE("command too long");
-        errno = E2BIG;
-        return -1;
-    }
-
-    asprintf(&buffer, "%s %s", path, cmd);
-    res = system_nosh(buffer);
-    ALOGV("runCmd() buffer='%s' res=%d", buffer, res);
-    free(buffer);
+    res = android_fork_execvp(argc, (char **)argv, NULL, false, false);
+    ALOGV("runCmd() res=%d", res);
     return res;
 }
 
@@ -69,18 +59,100 @@
 }
 
 int NatController::setDefaults() {
-    if (runCmd(IPTABLES_PATH, "-F natctrl_FORWARD"))
-        return -1;
-    if (runCmd(IPTABLES_PATH, "-t nat -F natctrl_nat_POSTROUTING"))
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            "-F",
+            "natctrl_FORWARD"
+    };
+    if (runCmd(ARRAY_SIZE(cmd1), cmd1))
         return -1;
 
-    runCmd(IP_PATH, "rule flush");
-    runCmd(IP_PATH, "-6 rule flush");
-    runCmd(IP_PATH, "rule add from all lookup default prio 32767");
-    runCmd(IP_PATH, "rule add from all lookup main prio 32766");
-    runCmd(IP_PATH, "-6 rule add from all lookup default prio 32767");
-    runCmd(IP_PATH, "-6 rule add from all lookup main prio 32766");
-    runCmd(IP_PATH, "route flush cache");
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            "-t",
+            "nat",
+            "-F",
+            "natctrl_nat_POSTROUTING"
+    };
+    if (runCmd(ARRAY_SIZE(cmd2), cmd2))
+        return -1;
+
+    const char *cmd3[] = {
+            IP_PATH,
+            "rule",
+            "flush"
+    };
+    runCmd(ARRAY_SIZE(cmd3), cmd3);
+
+    const char *cmd4[] = {
+            IP_PATH,
+            "-6",
+            "rule",
+            "flush"
+    };
+    runCmd(ARRAY_SIZE(cmd4), cmd4);
+
+    const char *cmd5[] = {
+            IP_PATH,
+            "rule",
+            "add",
+            "from",
+            "all",
+            "lookup",
+            "default",
+            "prio",
+            "32767"
+    };
+    runCmd(ARRAY_SIZE(cmd5), cmd5);
+
+    const char *cmd6[] = {
+            IP_PATH,
+            "rule",
+            "add",
+            "from",
+            "all",
+            "lookup",
+            "main",
+            "prio",
+            "32766"
+    };
+    runCmd(ARRAY_SIZE(cmd6), cmd6);
+
+    const char *cmd7[] = {
+            IP_PATH,
+            "-6",
+            "rule",
+            "add",
+            "from",
+            "all",
+            "lookup",
+            "default",
+            "prio",
+            "32767"
+    };
+    runCmd(ARRAY_SIZE(cmd7), cmd7);
+
+    const char *cmd8[] = {
+            IP_PATH,
+            "-6",
+            "rule",
+            "add",
+            "from",
+            "all",
+            "lookup",
+            "main",
+            "prio",
+            "32766"
+    };
+    runCmd(ARRAY_SIZE(cmd8), cmd8);
+
+    const char *cmd9[] = {
+            IP_PATH,
+            "route",
+            "flush",
+            "cache"
+    };
+    runCmd(ARRAY_SIZE(cmd9), cmd9);
 
     natCount = 0;
 
@@ -95,7 +167,6 @@
 //  0    1       2       3       4            5
 // nat enable intface extface addrcnt nated-ipaddr/prelength
 int NatController::enableNat(const int argc, char **argv) {
-    char cmd[255];
     int i;
     int addrCount = atoi(argv[4]);
     int ret = 0;
@@ -122,7 +193,13 @@
 
             ret |= secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]);
         }
-        runCmd(IP_PATH, "route flush cache");
+        const char *cmd[] = {
+                IP_PATH,
+                "route",
+                "flush",
+                "cache"
+        };
+        runCmd(ARRAY_SIZE(cmd), cmd);
     }
 
     if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) {
@@ -132,7 +209,13 @@
 
                 secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
             }
-            runCmd(IP_PATH, "route flush cache");
+            const char *cmd[] = {
+                    IP_PATH,
+                    "route",
+                    "flush",
+                    "cache"
+            };
+            runCmd(ARRAY_SIZE(cmd), cmd);
         }
         ALOGE("Error setting forward rules");
         errno = ENODEV;
@@ -140,18 +223,40 @@
     }
 
     /* Always make sure the drop rule is at the end */
-    snprintf(cmd, sizeof(cmd), "-D natctrl_FORWARD -j DROP");
-    runCmd(IPTABLES_PATH, cmd);
-    snprintf(cmd, sizeof(cmd), "-A natctrl_FORWARD -j DROP");
-    runCmd(IPTABLES_PATH, cmd);
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            "-D",
+            "natctrl_FORWARD",
+            "-j",
+            "DROP"
+    };
+    runCmd(ARRAY_SIZE(cmd1), cmd1);
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            "-A",
+            "natctrl_FORWARD",
+            "-j",
+            "DROP"
+    };
+    runCmd(ARRAY_SIZE(cmd2), cmd2);
 
 
     natCount++;
     // add this if we are the first added nat
     if (natCount == 1) {
-        snprintf(cmd, sizeof(cmd), "-t nat -A natctrl_nat_POSTROUTING -o %s -j MASQUERADE", extIface);
-        if (runCmd(IPTABLES_PATH, cmd)) {
-            ALOGE("Error seting postroute rule: %s", cmd);
+        const char *cmd[] = {
+                IPTABLES_PATH,
+                "-t",
+                "nat",
+                "-A",
+                "natctrl_nat_POSTROUTING",
+                "-o",
+                extIface,
+                "-j",
+                "MASQUERADE"
+        };
+        if (runCmd(ARRAY_SIZE(cmd), cmd)) {
+            ALOGE("Error seting postroute rule: iface=%s", extIface);
             // unwind what's been done, but don't care about success - what more could we do?
             for (i = 0; i < addrCount; i++) {
                 secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]);
@@ -167,56 +272,82 @@
 }
 
 int NatController::setForwardRules(bool add, const char *intIface, const char * extIface) {
-    char cmd[255];
+    const char *cmd1[] = {
+            IPTABLES_PATH,
+            add ? "-A" : "-D",
+            "natctrl_FORWARD",
+            "-i",
+            extIface,
+            "-o",
+            intIface,
+            "-m",
+            "state",
+            "--state",
+            "ESTABLISHED,RELATED",
+            "-j",
+            "RETURN"
+    };
+    int rc = 0;
 
-    snprintf(cmd, sizeof(cmd),
-             "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
-             (add ? "A" : "D"),
-             extIface, intIface);
-    if (runCmd(IPTABLES_PATH, cmd) && add) {
+    if (runCmd(ARRAY_SIZE(cmd1), cmd1) && add) {
         return -1;
     }
 
-    snprintf(cmd, sizeof(cmd),
-            "-%s natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
-            (add ? "A" : "D"),
-            intIface, extIface);
-    if (runCmd(IPTABLES_PATH, cmd) && add) {
+    const char *cmd2[] = {
+            IPTABLES_PATH,
+            add ? "-A" : "-D",
+            "natctrl_FORWARD",
+            "-i",
+            intIface,
+            "-o",
+            extIface,
+            "-m",
+            "state",
+            "--state",
+            "INVALID",
+            "-j",
+            "DROP"
+    };
+
+    const char *cmd3[] = {
+            IPTABLES_PATH,
+            add ? "-A" : "-D",
+            "natctrl_FORWARD",
+            "-i",
+            intIface,
+            "-o",
+            extIface,
+            "-j",
+            "RETURN"
+    };
+
+    if (runCmd(ARRAY_SIZE(cmd2), cmd2) && add) {
         // bail on error, but only if adding
-        snprintf(cmd, sizeof(cmd),
-                "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
-                (!add ? "A" : "D"),
-                extIface, intIface);
-        runCmd(IPTABLES_PATH, cmd);
-        return -1;
+        rc = -1;
+        goto err_invalid_drop;
     }
 
-    snprintf(cmd, sizeof(cmd), "-%s natctrl_FORWARD -i %s -o %s -j RETURN", (add ? "A" : "D"),
-            intIface, extIface);
-    if (runCmd(IPTABLES_PATH, cmd) && add) {
+    if (runCmd(ARRAY_SIZE(cmd3), cmd3) && add) {
         // unwind what's been done, but don't care about success - what more could we do?
-        snprintf(cmd, sizeof(cmd),
-                "-%s natctrl_FORWARD -i %s -o %s -m state --state INVALID -j DROP",
-                (!add ? "A" : "D"),
-                intIface, extIface);
-        runCmd(IPTABLES_PATH, cmd);
-
-        snprintf(cmd, sizeof(cmd),
-                 "-%s natctrl_FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j RETURN",
-                 (!add ? "A" : "D"),
-                 extIface, intIface);
-        runCmd(IPTABLES_PATH, cmd);
-        return -1;
+        rc = -1;
+        goto err_return;
     }
 
     return 0;
+
+err_return:
+    cmd2[1] = "-D";
+    runCmd(ARRAY_SIZE(cmd2), cmd2);
+err_invalid_drop:
+    cmd1[1] = "-D";
+    runCmd(ARRAY_SIZE(cmd1), cmd1);
+    return rc;
 }
 
 // nat disable intface extface
 //  0    1       2       3       4            5
 // nat enable intface extface addrcnt nated-ipaddr/prelength
 int NatController::disableNat(const int argc, char **argv) {
-    char cmd[255];
     int i;
     int addrCount = atoi(argv[4]);
     const char *intIface = argv[2];
@@ -245,7 +376,13 @@
             secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]);
         }
 
-        runCmd(IP_PATH, "route flush cache");
+        const char *cmd[] = {
+                IP_PATH,
+                "route",
+                "flush",
+                "cache"
+        };
+        runCmd(ARRAY_SIZE(cmd), cmd);
     }
 
     if (--natCount <= 0) {