OSDN Git Service

kazzo 0.1.1 release
[unagi/old-svn-converted.git] / kazzo / tag / 0.1.1 / hostecho / opendevice.c
1 #include <stdio.h>
2 #include "opendevice.h"
3
4 enum{
5         MATCH_SUCCESS = 1,
6         MATCH_FAILED = 0,
7         MATCH_ABORT = -1
8 };
9 /* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */
10 static int  _shellStyleMatch(char *text, char *p)
11 {
12         int last, matched, reverse;
13
14     for(; *p; text++, p++){
15         if(*text == 0 && *p != '*')
16             return MATCH_ABORT;
17         switch(*p){
18         case '\\':
19             /* Literal match with following character. */
20             p++;
21             /* FALLTHROUGH */
22         default:
23             if(*text != *p)
24                 return MATCH_FAILED;
25             continue;
26         case '?':
27             /* Match anything. */
28             continue;
29         case '*':
30             while(*++p == '*')
31                 /* Consecutive stars act just like one. */
32                 continue;
33             if(*p == 0)
34                 /* Trailing star matches everything. */
35                 return MATCH_SUCCESS;
36             while(*text)
37                 if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
38                     return matched;
39             return MATCH_ABORT;
40         case '[':
41             reverse = p[1] == '^';
42             if(reverse) /* Inverted character class. */
43                 p++;
44             matched = MATCH_FAILED;
45             if(p[1] == ']' || p[1] == '-')
46                 if(*++p == *text)
47                     matched = MATCH_SUCCESS;
48             for(last = *p; *++p && *p != ']'; last = *p)
49                 if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p)
50                     matched = MATCH_SUCCESS;
51             if(matched == reverse)
52                 return MATCH_FAILED;
53             continue;
54         }
55     }
56     return *text == 0;
57 }
58
59 /* public interface for shell style matching: returns 0 if fails, 1 if matches */
60 static int shellStyleMatch(char *text, char *pattern)
61 {
62     if(pattern == NULL) /* NULL pattern is synonymous to "*" */
63         return 1;
64     return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
65 }
66
67 /* ------------------------------------------------------------------------- */
68
69 int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen)
70 {
71 char    buffer[256];
72 int     rval, i;
73
74     if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */
75         return rval;
76     if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0)
77         return rval;
78     if(buffer[1] != USB_DT_STRING){
79         *buf = 0;
80         return 0;
81     }
82     if((unsigned char)buffer[0] < rval)
83         rval = (unsigned char)buffer[0];
84     rval /= 2;
85     /* lossy conversion to ISO Latin1: */
86     for(i=1;i<rval;i++){
87         if(i > buflen)              /* destination buffer overflow */
88             break;
89         buf[i-1] = buffer[2 * i];
90         if(buffer[2 * i + 1] != 0)  /* outside of ISO Latin1 range */
91             buf[i-1] = '?';
92     }
93     buf[i-1] = 0;
94     return i-1;
95 }
96
97 /* ------------------------------------------------------------------------- */
98
99 int usbOpenDevice(
100         usb_dev_handle **device, int vendorID, char *vendorNamePattern,
101         int productID, char *productNamePattern, 
102         char *serialNamePattern, FILE *printMatchingDevicesFp, 
103         FILE *warningsFp
104 )
105 {
106         struct usb_bus *bus;
107         struct usb_device *dev;
108         usb_dev_handle *handle = NULL;
109         int errorCode = USBOPEN_ERR_NOTFOUND;
110
111     usb_find_busses();
112     usb_find_devices();
113     for(bus = usb_get_busses(); bus; bus = bus->next){
114         for(dev = bus->devices; dev; dev = dev->next){  /* iterate over all devices on all busses */
115             if((vendorID == 0 || dev->descriptor.idVendor == vendorID)
116                         && (productID == 0 || dev->descriptor.idProduct == productID)){
117                 char    vendor[256], product[256], serial[256];
118                 int     len;
119                 handle = usb_open(dev); /* we need to open the device in order to query strings */
120                 if(!handle){
121                     errorCode = USBOPEN_ERR_ACCESS;
122                     if(warningsFp != NULL)
123                         fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
124                     continue;
125                 }
126                 /* now check whether the names match: */
127                 len = vendor[0] = 0;
128                 if(dev->descriptor.iManufacturer > 0){
129                     len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor));
130                 }
131                 if(len < 0){
132                     errorCode = USBOPEN_ERR_ACCESS;
133                     if(warningsFp != NULL)
134                         fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
135                 }else{
136                     errorCode = USBOPEN_ERR_NOTFOUND;
137                     /* printf("seen device from vendor ->%s<-\n", vendor); */
138                     if(shellStyleMatch(vendor, vendorNamePattern)){
139                         len = product[0] = 0;
140                         if(dev->descriptor.iProduct > 0){
141                             len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product));
142                         }
143                         if(len < 0){
144                             errorCode = USBOPEN_ERR_ACCESS;
145                             if(warningsFp != NULL)
146                                 fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
147                         }else{
148                             errorCode = USBOPEN_ERR_NOTFOUND;
149                             /* printf("seen product ->%s<-\n", product); */
150                             if(shellStyleMatch(product, productNamePattern)){
151                                 len = serial[0] = 0;
152                                 if(dev->descriptor.iSerialNumber > 0){
153                                     len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial));
154                                 }
155                                 if(len < 0){
156                                     errorCode = USBOPEN_ERR_ACCESS;
157                                     if(warningsFp != NULL)
158                                         fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
159                                 }
160                                 if(shellStyleMatch(serial, serialNamePattern)){
161                                     if(printMatchingDevicesFp != NULL){
162                                         if(serial[0] == 0){
163                                             fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product);
164                                         }else{
165                                             fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial);
166                                         }
167                                     }else{
168                                         break;
169                                     }
170                                 }
171                             }
172                         }
173                     }
174                 }
175                 usb_close(handle);
176                 handle = NULL;
177             }
178         }
179         if(handle)  /* we have found a deice */
180             break;
181     }
182     if(handle != NULL){
183         errorCode = 0;
184         *device = handle;
185     }
186     if(printMatchingDevicesFp != NULL)  /* never return an error for listing only */
187         errorCode = 0;
188     return errorCode;
189 }
190
191 /* ------------------------------------------------------------------------- */