inetcat: Properly handle USB vs. network devices with new command line switches
diff --git a/tools/inetcat.c b/tools/inetcat.c
index e8b1b3a..d67e972 100644
--- a/tools/inetcat.c
+++ b/tools/inetcat.c
@@ -21,6 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -29,6 +32,7 @@
 #include <stddef.h>
 #include <unistd.h>
 #include <errno.h>
+#include <getopt.h>
 #ifdef WIN32
 #include <windows.h>
 #include <winsock2.h>
@@ -43,6 +47,8 @@
 #include "usbmuxd.h"
 #include "socket.h"
 
+static int debug_level = 0;
+
 static size_t read_data_socket(int fd, uint8_t* buf, size_t bufsize)
 {
 #ifdef WIN32
@@ -69,20 +75,82 @@
     return (size_t)ret;
 }
 
+static void print_usage(int argc, char **argv, int is_error)
+{
+    char *name = NULL;
+    name = strrchr(argv[0], '/');
+    fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] DEVICE_PORT\n", (name ? name + 1: argv[0]));
+    fprintf(is_error ? stderr : stdout,
+      "Proxy that enables TCP service access to iOS devices.\n\n" \
+      "  -u, --udid UDID    target specific device by UDID\n" \
+      "  -n, --network      connect to network device\n" \
+      "  -l, --local        connect to USB device (default)\n" \
+      "  -h, --help         prints usage information\n" \
+      "  -d, --debug        increase debug level\n" \
+      "\n" \
+      "Homepage: <" PACKAGE_URL ">\n"
+      "Bug reports: <" PACKAGE_BUGREPORT ">\n"
+      "\n"
+    );
+}
+
 int main(int argc, char **argv)
 {
-    if (argc < 2) {
-        printf("usage: %s DEVICE_TCP_PORT [UDID]\n", argv[0]);
-        return 1;
-    }
+    const struct option longopts[] = {
+        { "debug", no_argument, NULL, 'd' },
+        { "help", no_argument, NULL, 'h' },
+        { "udid", required_argument, NULL, 'u' },
+        { "local", no_argument, NULL, 'l' },
+        { "network", no_argument, NULL, 'n' },
+        { NULL, 0, NULL, 0}
+    };
 
-    int device_port = atoi(argv[1]);
     char* device_udid = NULL;
+    static enum usbmux_lookup_options lookup_opts = 0;
 
-    if (argc > 2) {
-        device_udid = argv[2];
+    int c = 0;
+    while ((c = getopt_long(argc, argv, "dhu:ln", longopts, NULL)) != -1) {
+        switch (c) {
+        case 'd':
+            libusbmuxd_set_debug_level(++debug_level);
+            break;
+        case 'u':
+            if (!*optarg) {
+                fprintf(stderr, "ERROR: UDID must not be empty!\n");
+                print_usage(argc, argv, 1);
+                return 2;
+            }
+            free(device_udid);
+            device_udid = strdup(optarg);
+            break;
+        case 'l':
+            lookup_opts |= DEVICE_LOOKUP_USBMUX;
+            break;
+        case 'n':
+            lookup_opts |= DEVICE_LOOKUP_NETWORK;
+            break;
+        case 'h':
+            print_usage(argc, argv, 0);
+            return 0;
+        default:
+            print_usage(argc, argv, 1);
+            return 2;
+        }
     }
 
+    if (lookup_opts == 0) {
+        lookup_opts = DEVICE_LOOKUP_USBMUX;
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if (argc < 1) {
+        print_usage(argc + optind, argv - optind, 1);
+        return 2;
+    }
+
+    int device_port = atoi(argv[0]);
     if (!device_port) {
         fprintf(stderr, "Invalid device_port specified!\n");
         return -EINVAL;
@@ -91,31 +159,39 @@
 #ifndef WIN32
     signal(SIGPIPE, SIG_IGN);
 #endif
+
     usbmuxd_device_info_t *dev_list = NULL;
-    int count;
-    if ((count = usbmuxd_get_device_list(&dev_list)) < 0) {
-        printf("Connecting to usbmuxd failed, terminating.\n");
-        free(dev_list);
-        return 1;
-    }
-
-    if (dev_list == NULL || dev_list[0].handle == 0) {
-        fprintf(stderr, "No connected device found, terminating.\n");
-        free(dev_list);
-        return 1;
-    }
-
     usbmuxd_device_info_t *dev = NULL;
+    usbmuxd_device_info_t muxdev;
+
     if (device_udid) {
+        if (usbmuxd_get_device(device_udid, &muxdev, lookup_opts) > 0) {
+            dev = &muxdev;
+        }
+    } else {
+        int count;
+        if ((count = usbmuxd_get_device_list(&dev_list)) < 0) {
+            printf("Connecting to usbmuxd failed, terminating.\n");
+            free(dev_list);
+            return 1;
+        }
+
+        if (dev_list == NULL || dev_list[0].handle == 0) {
+            fprintf(stderr, "No connected device found, terminating.\n");
+            free(dev_list);
+            return 1;
+        }
+
         int i;
         for (i = 0; i < count; i++) {
-            if (strncmp(dev_list[i].udid, device_udid, sizeof(dev_list[0].udid)) == 0) {
+            if (dev_list[i].conn_type == CONNECTION_TYPE_USB && (lookup_opts & DEVICE_LOOKUP_USBMUX)) {
+                dev = &(dev_list[i]);
+                break;
+            } else if (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK && (lookup_opts & DEVICE_LOOKUP_NETWORK)) {
                 dev = &(dev_list[i]);
                 break;
             }
         }
-    } else {
-        dev = &(dev_list[0]);
     }
 
     if (dev == NULL || dev->handle == 0) {