mtpd: get rid of the separator of pppd arguments.

Change-Id: I0ebcac6f051dae63531afacdd62d7520a94f18d1
diff --git a/l2tp.c b/l2tp.c
index 339ae3d..f75fd6c 100644
--- a/l2tp.c
+++ b/l2tp.c
@@ -185,7 +185,10 @@
     uint16_t *p = (uint16_t *)incoming.buffer;
 
     incoming.length = recv(the_socket, incoming.buffer, MAX_PACKET_LENGTH, 0);
-    if (incoming.length == -1 && errno != EINTR) {
+    if (incoming.length == -1) {
+        if (errno == EINTR) {
+            return 0;
+        }
         log_print(FATAL, "Recv() %s", strerror(errno));
         exit(NETWORK_ERROR);
     }
@@ -309,12 +312,9 @@
     return get_attribute_raw(type, value, sizeof(uint16_t)) == sizeof(uint16_t);
 }
 
-static int l2tp_connect(int argc, char **argv)
+static int l2tp_connect(char **arguments)
 {
-    if (argc < 2) {
-        return -USAGE_ERROR;
-    }
-    create_socket(AF_INET, SOCK_DGRAM, argv[0], argv[1]);
+    create_socket(AF_INET, SOCK_DGRAM, arguments[0], arguments[1]);
 
     while (!local_tunnel) {
         local_tunnel = random();
@@ -329,7 +329,7 @@
     add_attribute_u16(ASSIGNED_TUNNEL, local_tunnel);
     add_attribute_u16(WINDOW_SIZE, htons(1));
 
-    if (argc >= 3) {
+    if (arguments[2][0]) {
         int fd = open(RANDOM_DEVICE, O_RDONLY);
         if (fd == -1 || read(fd, challenge, CHALLENGE_SIZE) != CHALLENGE_SIZE) {
             log_print(FATAL, "Cannot read %s", RANDOM_DEVICE);
@@ -338,8 +338,8 @@
         close(fd);
 
         add_attribute_raw(CHALLENGE, challenge, CHALLENGE_SIZE);
-        secret = argv[2];
-        secret_length = strlen(argv[2]);
+        secret = arguments[2];
+        secret_length = strlen(arguments[2]);
     }
 
     send_packet();
@@ -574,7 +574,8 @@
 
 struct protocol l2tp = {
     .name = "l2tp",
-    .usage = "<server> <port> [secret]",
+    .arguments = 3,
+    .usage = "<server> <port> <secret>",
     .connect = l2tp_connect,
     .process = l2tp_process,
     .timeout = l2tp_timeout,
diff --git a/mtpd.c b/mtpd.c
index fd553be..902fcc0 100644
--- a/mtpd.c
+++ b/mtpd.c
@@ -58,38 +58,29 @@
 
 static int initialize(int argc, char **argv)
 {
-    int timeout = 0;
     int i;
 
-    for (i = 2; i < argc; ++i) {
-        if (!argv[i][0]) {
-            pppd_argc = argc - i - 1;
-            pppd_argv = &argv[i + 1];
-            argc = i;
+    for (i = 0; protocols[i]; ++i) {
+        struct protocol *p = protocols[i];
+        if (argc - 2 >= p->arguments && !strcmp(argv[1], p->name)) {
+            log_print(INFO, "Using protocol %s", p->name);
+            the_protocol = p;
             break;
         }
     }
 
-    if (argc >= 2) {
+    if (!the_protocol) {
+        printf("Usages:\n");
         for (i = 0; protocols[i]; ++i) {
-            if (!strcmp(argv[1], protocols[i]->name)) {
-                log_print(INFO, "Using protocol %s", protocols[i]->name);
-                the_protocol = protocols[i];
-                timeout = the_protocol->connect(argc - 2, &argv[2]);
-                break;
-            }
+            struct protocol *p = protocols[i];
+            printf("  %s %s %s pppd-arguments\n", argv[0], p->name, p->usage);
         }
+        exit(0);
     }
 
-    if (!the_protocol || timeout == -USAGE_ERROR) {
-        printf("Usage: %s <protocol-args> '' <pppd-args>, "
-               "where protocol-args are one of:\n", argv[0]);
-        for (i = 0; protocols[i]; ++i) {
-            printf("       %s %s\n", protocols[i]->name, protocols[i]->usage);
-        }
-        exit(USAGE_ERROR);
-    }
-    return timeout;
+    pppd_argc = argc - 2 - the_protocol->arguments;
+    pppd_argv = &argv[2 + the_protocol->arguments];
+    return the_protocol->connect(&argv[2]);
 }
 
 static void stop_pppd()
@@ -106,7 +97,7 @@
 
 static int get_control_and_arguments(int *argc, char ***argv)
 {
-    static char *args[256];
+    static char *args[32];
     int control;
     int i;
 
@@ -122,7 +113,7 @@
     fcntl(control, F_SETFD, FD_CLOEXEC);
 
     args[0] = (*argv)[0];
-    for (i = 1; i < 256; ++i) {
+    for (i = 1; i < 32; ++i) {
         unsigned char length;
         if (recv(control, &length, 1, 0) != 1) {
             log_print(FATAL, "Cannot get argument length");
diff --git a/mtpd.h b/mtpd.h
index 673cfb7..478dc16 100644
--- a/mtpd.h
+++ b/mtpd.h
@@ -21,13 +21,12 @@
 extern int the_socket;
 
 enum exit_code {
-    USAGE_ERROR = 1,
-    SYSTEM_ERROR = 2,
-    NETWORK_ERROR = 3,
-    PROTOCOL_ERROR = 4,
-    CHALLENGE_FAILED = 5,
-    USER_REQUESTED = 6,
-    REMOTE_REQUESTED = 7,
+    SYSTEM_ERROR = 1,
+    NETWORK_ERROR = 2,
+    PROTOCOL_ERROR = 3,
+    CHALLENGE_FAILED = 4,
+    USER_REQUESTED = 5,
+    REMOTE_REQUESTED = 6,
     PPPD_EXITED = 32,
 };
 
@@ -48,12 +47,14 @@
  * timeout intervals are in milliseconds, where zero means forever. To indicate
  * an error, one should use a negative exit code such as -REMOTE_REQUESTED. */
 struct protocol {
-    /* The name specified in the first argument. */
+    /* The name of this protocol. */
     char *name;
-    /* The usage of the rest of the arguments. */
+    /* The number of arguments. */
+    int arguments;
+    /* The usage of the arguments. */
     char *usage;
     /* Connect to the server and return the next timeout interval. */
-    int (*connect)(int argc, char **argv);
+    int (*connect)(char **arguments);
     /* Process the incoming packet and return the next timeout interval. */
     int (*process)();
     /* Handle the timeout event and return the next timeout interval. */
diff --git a/pptp.c b/pptp.c
index ccd0faa..6c67afc 100644
--- a/pptp.c
+++ b/pptp.c
@@ -213,12 +213,9 @@
     return 0;
 }
 
-static int pptp_connect(int argc, char **argv)
+static int pptp_connect(char **arguments)
 {
-    if (argc < 2) {
-        return -USAGE_ERROR;
-    }
-    create_socket(AF_UNSPEC, SOCK_STREAM, argv[0], argv[1]);
+    create_socket(AF_UNSPEC, SOCK_STREAM, arguments[0], arguments[1]);
 
     log_print(DEBUG, "Sending SCCRQ");
     state = SCCRQ;
@@ -413,6 +410,7 @@
 
 struct protocol pptp = {
     .name = "pptp",
+    .arguments = 2,
     .usage = "<server> <port>",
     .connect = pptp_connect,
     .process = pptp_process,