Support for 3rd party USB Vendor IDs in adb.

Vendor IDs are read from ~/.android/adb_usb.ini. The format is very simple:
1 number per line. First number is ID count, followed by the ID themselves.
Lines starting with # are considered comments.

Other misc changes: moved VENDOR_ID_* to usb_vendors.c to prevent direct
access. Made transport_usb.c reuse the USB constant introduced in usb_osx
(moved them to adb.h)
diff --git a/adb/adb.c b/adb/adb.c
index 0b5ebac..6e170ae 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -919,9 +919,6 @@
     fdevent_loop();
 
     usb_cleanup();
-#if ADB_HOST
-    usb_vendors_cleanup();
-#endif
 
     return 0;
 }
diff --git a/adb/adb.h b/adb/adb.h
index 7762e00..3c4fe60 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -357,11 +357,10 @@
 #define ADB_PORT 5037
 #define ADB_LOCAL_TRANSPORT_PORT 5555
 
-// Google's USB Vendor ID
-#define VENDOR_ID_GOOGLE        0x18d1
+#define ADB_CLASS              0xff
+#define ADB_SUBCLASS           0x42
+#define ADB_PROTOCOL           0x1
 
-// HTC's USB Vendor ID
-#define VENDOR_ID_HTC           0x0bb4
 
 void local_init();
 int  local_connect(int  port);
diff --git a/adb/adb_client.c b/adb/adb_client.c
index 5868744..243f0fa 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.c
@@ -213,7 +213,7 @@
             fprintf(stdout,"* daemon started successfully *\n");
         }
         /* give the server some time to start properly and detect devices */
-        adb_sleep_ms(2000);
+        adb_sleep_ms(3000);
         // fall through to _adb_connect
     } else {
         // if server was running, check its version to make sure it is not out of date
diff --git a/adb/transport_usb.c b/adb/transport_usb.c
index 50ebff7..3737c5c 100644
--- a/adb/transport_usb.c
+++ b/adb/transport_usb.c
@@ -135,11 +135,9 @@
     unsigned i;
     for (i = 0; i < vendorIdCount; i++) {
         if (vid == vendorIds[i]) {
-            /* class:vendor (0xff) subclass:android (0x42) proto:adb (0x01) */
-            if(usb_class == 0xff) {
-                if((usb_subclass == 0x42) && (usb_protocol == 0x01)) {
-                    return 1;
-                }
+            if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS &&
+                    usb_protocol == ADB_PROTOCOL) {
+                return 1;
             }
 
             return 0;
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 171a9fc..4892c38 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -32,9 +32,6 @@
 
 #define  DBG   D
 
-#define ADB_SUBCLASS           0x42
-#define ADB_PROTOCOL           0x1
-
 static IONotificationPortRef    notificationPort = 0;
 static io_iterator_t*           notificationIterators;
 
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index f949249..9a15146 100644
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -16,25 +16,119 @@
 
 #include "usb_vendors.h"
 
-#include "sysdeps.h"
 #include <stdio.h>
+
+#ifdef _WIN32
+#  define WIN32_LEAN_AND_MEAN
+#  include "windows.h"
+#  include "shlobj.h"
+#else
+#  include <unistd.h>
+#  include <sys/stat.h>
+#endif
+
+#include "sysdeps.h"
 #include "adb.h"
 
-int* vendorIds = NULL;
+#define ANDROID_PATH            ".android"
+#define ANDROID_ADB_INI         "adb_usb.ini"
+
+#define TRACE_TAG               TRACE_USB
+
+// Google's USB Vendor ID
+#define VENDOR_ID_GOOGLE        0x18d1
+// HTC's USB Vendor ID
+#define VENDOR_ID_HTC           0x0bb4
+
+/** built-in vendor list */
+int builtInVendorIds[] = {
+    VENDOR_ID_GOOGLE,
+    VENDOR_ID_HTC,
+};
+
+#define BUILT_IN_VENDOR_COUNT    (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
+
+/* max number of supported vendor ids (built-in + 3rd party). increase as needed */
+#define VENDOR_COUNT_MAX         128
+
+int vendorIds[VENDOR_COUNT_MAX];
 unsigned vendorIdCount = 0;
 
-void usb_vendors_init(void) {
-    /* for now, only put the built-in VENDOR_ID_* */
-    vendorIdCount = 2;
-    vendorIds = (int*)malloc(vendorIdCount * sizeof(int));
-    vendorIds[0] = VENDOR_ID_GOOGLE;
-    vendorIds[1] = VENDOR_ID_HTC;
+int get_adb_usb_ini(char* buff, size_t len);
+
+void usb_vendors_init(void)
+{
+    if (VENDOR_COUNT_MAX < BUILT_IN_VENDOR_COUNT) {
+        fprintf(stderr, "VENDOR_COUNT_MAX not big enough for built-in vendor list.\n");
+        exit(2);
+    }
+
+    /* add the built-in vendors at the beginning of the array */
+    memcpy(vendorIds, builtInVendorIds, sizeof(builtInVendorIds));
+
+    /* default array size is the number of built-in vendors */
+    vendorIdCount = BUILT_IN_VENDOR_COUNT;
+
+    if (VENDOR_COUNT_MAX == BUILT_IN_VENDOR_COUNT)
+        return;
+
+    char temp[PATH_MAX];
+    if (get_adb_usb_ini(temp, sizeof(temp)) == 0) {
+        FILE * f = fopen(temp, "rt");
+
+        if (f != NULL) {
+            /* The vendor id file is pretty basic. 1 vendor id per line.
+               Lines starting with # are comments */
+            while (fgets(temp, sizeof(temp), f) != NULL) {
+                if (temp[0] == '#')
+                    continue;
+
+                long value = strtol(temp, NULL, 0);
+                if (errno == EINVAL || errno == ERANGE || value > INT_MAX || value < 0) {
+                    fprintf(stderr, "Invalid content in %s. Quitting.\n", ANDROID_ADB_INI);
+                    exit(2);
+                }
+
+                vendorIds[vendorIdCount++] = (int)value;
+
+                /* make sure we don't go beyond the array */
+                if (vendorIdCount == VENDOR_COUNT_MAX) {
+                    break;
+                }
+            }
+        }
+    }
 }
 
-void usb_vendors_cleanup(void) {
-    if (vendorIds != NULL) {
-        free(vendorIds);
-        vendorIds = NULL;
-        vendorIdCount = 0;
+/* Utils methods */
+
+/* builds the path to the adb vendor id file. returns 0 if success */
+int build_path(char* buff, size_t len, const char* format, const char* home)
+{
+    if (snprintf(buff, len, format, home, ANDROID_PATH, ANDROID_ADB_INI) >= len) {
+        return 1;
     }
+
+    return 0;
+}
+
+/* fills buff with the path to the adb vendor id file. returns 0 if success */
+int get_adb_usb_ini(char* buff, size_t len)
+{
+#ifdef _WIN32
+    const char* home = getenv("ANDROID_SDK_HOME");
+    if (home != NULL) {
+        return build_path(buff, len, "%s\\%s\\%s", home);
+    } else {
+        char path[MAX_PATH];
+        SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, path);
+        return build_path(buff, len, "%s\\%s\\%s", path);
+    }
+#else
+    const char* home = getenv("HOME");
+    if (home == NULL)
+        home = "/tmp";
+
+    return build_path(buff, len, "%s/%s/%s", home);
+#endif
 }
diff --git a/adb/usb_vendors.h b/adb/usb_vendors.h
index 43e5f99..43790b9 100644
--- a/adb/usb_vendors.h
+++ b/adb/usb_vendors.h
@@ -17,10 +17,9 @@
 #ifndef __USB_VENDORS_H
 #define __USB_VENDORS_H
 
-extern int* vendorIds;
+extern int vendorIds[];
 extern unsigned  vendorIdCount;
 
 void usb_vendors_init(void);
-void usb_vendors_cleanup(void);
 
 #endif
\ No newline at end of file