Make fastboot say "no permissions" for non-writable devices.

Without this patch, "adb devices" will say "no permissions" when it sees
a device it can't write to, but "fastboot devices" will silently ignore it.
This is confusing to n00bs, especially since it doesn't seem to be widely
known that a device's USB id might be different in the bootloader (meaning
two udev rules are needed). It can also be confusing if you're sshed in,
when you can't access the device because you won't be in the "plugdev"
group, but "fastboot devices" won't make this clear.

I'm not sure about the Mac OS and Windows changes. AIUI, devices are always
writable on those platforms, but I don't use either, so I can't test this.
This patch shouldn't alter the behavior on either of those platforms.
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index c81222a..8e92017 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -165,6 +165,9 @@
 {
     if (match_fastboot(info) == 0) {
         char* serial = info->serial_number;
+        if (!info->writable) {
+            serial = "no permissions"; // like "adb devices"
+        }
         if (!serial[0]) {
             serial = "????????????";
         }
diff --git a/fastboot/usb.h b/fastboot/usb.h
index f3ec5bf..cc157d5 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -50,6 +50,8 @@
     unsigned char has_bulk_in;
     unsigned char has_bulk_out;
     
+    unsigned char writable;
+
     char serial_number[256];
 };
   
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index 3b40ba7..088c23a 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -89,7 +89,8 @@
     return 0;
 }
 
-static int filter_usb_device(int fd, char *ptr, int len, ifc_match_func callback,
+static int filter_usb_device(int fd, char *ptr, int len, int writable,
+                             ifc_match_func callback,
                              int *ept_in_id, int *ept_out_id, int *ifc_id)
 {
     struct usb_device_descriptor *dev;
@@ -119,7 +120,8 @@
     info.dev_class = dev->bDeviceClass;
     info.dev_subclass = dev->bDeviceSubClass;
     info.dev_protocol = dev->bDeviceProtocol;
-
+    info.writable = writable;
+    
     // read device serial number (if there is one)
     info.serial_number[0] = 0;
     if (dev->iSerialNumber) {
@@ -201,6 +203,7 @@
     DIR *busdir, *devdir;
     struct dirent *de;
     int fd;
+    int writable = 1;
     
     busdir = opendir(base);
     if(busdir == 0) return 0;
@@ -220,12 +223,18 @@
 
 //            DBG("[ scanning %s ]\n", devname);
             if((fd = open(devname, O_RDWR)) < 0) {
-                continue;
+                // Check if we have read-only access, so we can give a helpful
+                // diagnostic like "adb devices" does.
+                writable = 0;
+                if((fd = open(devname, O_RDONLY)) < 0) {
+                    continue;
+                }
             }
 
             n = read(fd, desc, sizeof(desc));
             
-            if(filter_usb_device(fd, desc, n, callback, &in, &out, &ifc) == 0){
+            if(filter_usb_device(fd, desc, n, writable, callback,
+                                 &in, &out, &ifc) == 0) {
                 usb = calloc(1, sizeof(usb_handle));
                 strcpy(usb->fname, devname);
                 usb->ep_in = in;
@@ -375,5 +384,3 @@
 {
     return find_usb_device("/dev/bus/usb", callback);
 }
-
-
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c
index d6a8260..0b0512d 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.c
@@ -351,6 +351,7 @@
         // device has no serial number
         handle->info.serial_number[0] = 0;
     }
+    handle->info.writable = 1;
 
     if (try_interfaces(dev, handle)) {
         goto error;
@@ -416,8 +417,6 @@
             break;
         }
 
-        usb_ifc_info info;
-
         if (try_device(device, &h) != 0) {
             IOObjectRelease(device);
             ret = -1;
diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c
index 9c0a9cb..54008a4 100644
--- a/fastboot/usb_windows.c
+++ b/fastboot/usb_windows.c
@@ -301,6 +301,7 @@
     info.ifc_class = interf_desc.bInterfaceClass;
     info.ifc_subclass = interf_desc.bInterfaceSubClass;
     info.ifc_protocol = interf_desc.bInterfaceProtocol;
+    info.writable = 1;
     
     // read serial number (if there is one)
     unsigned long serial_number_len = sizeof(info.serial_number);