Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: util/mtp-probe.c

Issue 2364793002: Revert "Uprev libmtp to 1.1.12" (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libmtp@master
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « util/mtp-hotplug.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * \file mtp-probe.c 2 * \file mtp-probe.c
3 * Program to probe newly connected device interfaces from 3 * Program to probe newly connected device interfaces from
4 * userspace to determine if they are MTP devices, used for 4 * userspace to determine if they are MTP devices, used for
5 * udev rules. 5 * udev rules.
6 * 6 *
7 * Invoke the program from udev to check it for MTP signatures, 7 * Invoke the program from udev to check it for MTP signatures,
8 * e.g. 8 * e.g.
9 * ATTR{bDeviceClass}=="ff", 9 * ATTR{bDeviceClass}=="ff",
10 * PROGRAM="<path>/mtp-probe /sys$env{DEVPATH} $attr{busnum} $attr{devnum}", 10 * PROGRAM="<path>/mtp-probe /sys$env{DEVPATH} $attr{busnum} $attr{devnum}",
(...skipping 27 matching lines...) Expand all
38 */ 38 */
39 #ifndef __linux__ 39 #ifndef __linux__
40 #error "This program should only be compiled for Linux!" 40 #error "This program should only be compiled for Linux!"
41 #endif 41 #endif
42 42
43 #include <unistd.h> 43 #include <unistd.h>
44 #include <stdlib.h> 44 #include <stdlib.h>
45 #include <stdio.h> 45 #include <stdio.h>
46 #include <string.h> 46 #include <string.h>
47 #include <syslog.h> 47 #include <syslog.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include <dirent.h>
51 #include <libmtp.h> 48 #include <libmtp.h>
52 #include <regex.h>
53 #include <fcntl.h>
54
55 enum ep_type {
56 OTHER_EP,
57 BULK_OUT_EP,
58 BULK_IN_EP,
59 INTERRUPT_IN_EP,
60 INTERRUPT_OUT_EP,
61 };
62
63 static enum ep_type get_ep_type(char *path)
64 {
65 char pbuf[FILENAME_MAX];
66 int len = strlen(path);
67 int fd;
68 char buf[128];
69 int bread;
70 int is_out = 0;
71 int is_in = 0;
72 int is_bulk = 0;
73 int is_interrupt = 0;
74 int i;
75
76 strcpy(pbuf, path);
77 pbuf[len++] = '/';
78
79 /* Check the type */
80 strncpy(pbuf + len, "type", FILENAME_MAX - len);
81 pbuf[FILENAME_MAX - 1] = '\0'; /* Sentinel */
82
83 fd = open(pbuf, O_RDONLY);
84 if (fd < 0)
85 return OTHER_EP;
86 bread = read(fd, buf, sizeof(buf));
87 close(fd);
88 if (bread < 2)
89 return OTHER_EP;
90
91 for (i = 0; i < bread; i++)
92 if(buf[i] == 0x0d || buf[i] == 0x0a)
93 buf[i] = '\0';
94
95 if (!strcmp(buf, "Bulk"))
96 is_bulk = 1;
97 if (!strcmp(buf, "Interrupt"))
98 is_interrupt = 1;
99
100 /* Check the direction */
101 strncpy(pbuf + len, "direction", FILENAME_MAX - len);
102 pbuf[FILENAME_MAX - 1] = '\0'; /* Sentinel */
103
104 fd = open(pbuf, O_RDONLY);
105 if (fd < 0)
106 return OTHER_EP;
107 bread = read(fd, buf, sizeof(buf));
108 close(fd);
109 if (bread < 2)
110 return OTHER_EP;
111
112 for (i = 0; i < bread; i++)
113 if(buf[i] == 0x0d || buf[i] == 0x0a)
114 buf[i] = '\0';
115
116 if (!strcmp(buf, "in"))
117 is_in = 1;
118 if (!strcmp(buf, "out"))
119 is_out = 1;
120
121 if (is_bulk && is_in)
122 return BULK_IN_EP;
123 if (is_bulk && is_out)
124 return BULK_OUT_EP;
125 if (is_interrupt && is_in)
126 return INTERRUPT_IN_EP;
127 if (is_interrupt && is_out)
128 return INTERRUPT_OUT_EP;
129
130 return OTHER_EP;
131 }
132
133 static int has_3_ep(char *path)
134 {
135 char pbuf[FILENAME_MAX];
136 int len = strlen(path);
137 int fd;
138 char buf[128];
139 int bread;
140
141 strcpy(pbuf, path);
142 pbuf[len++] = '/';
143 strncpy(pbuf + len, "bNumEndpoints", FILENAME_MAX - len);
144 pbuf[FILENAME_MAX - 1] = '\0'; /* Sentinel */
145
146 fd = open(pbuf, O_RDONLY);
147 if (fd < 0)
148 return -1;
149 /* Read all contents to buffer */
150 bread = read(fd, buf, sizeof(buf));
151 close(fd);
152 if (bread < 2)
153 return 0;
154
155 /* 0x30, 0x33 = "03", maybe we should parse it? */
156 if (buf[0] == 0x30 && buf[1] == 0x33)
157 return 1;
158
159 return 0;
160 }
161
162 static int check_interface(char *sysfspath)
163 {
164 char dirbuf[FILENAME_MAX];
165 int len = strlen(sysfspath);
166 DIR *dir;
167 struct dirent *dent;
168 regex_t r;
169 int ret;
170 int bulk_out_ep_found = 0;
171 int bulk_in_ep_found = 0;
172 int interrupt_in_ep_found = 0;
173
174 ret = has_3_ep(sysfspath);
175 if (ret <= 0)
176 return ret;
177
178 /* Yes it has three endpoints ... look even closer! */
179 dir = opendir(sysfspath);
180 if (!dir)
181 return -1;
182
183 strcpy(dirbuf, sysfspath);
184 dirbuf[len++] = '/';
185
186 /* Check for dirs that identify endpoints */
187 ret = regcomp(&r, "^ep_[0-9a-f]+$", REG_EXTENDED | REG_NOSUB);
188 if (ret) {
189 closedir(dir);
190 return -1;
191 }
192
193 while ((dent = readdir(dir))) {
194 struct stat st;
195
196 /* No need to check those beginning with a period */
197 if (dent->d_name[0] == '.')
198 continue;
199
200 strncpy(dirbuf + len, dent->d_name, FILENAME_MAX - len);
201 dirbuf[FILENAME_MAX - 1] = '\0'; /* Sentinel */
202 ret = lstat(dirbuf, &st);
203 if (ret)
204 continue;
205 if (S_ISDIR(st.st_mode) && !regexec(&r, dent->d_name, 0, 0, 0)) {
206 enum ep_type ept;
207
208 ept = get_ep_type(dirbuf);
209 if (ept == BULK_OUT_EP)
210 bulk_out_ep_found = 1;
211 else if (ept == BULK_IN_EP)
212 bulk_in_ep_found = 1;
213 else if (ept == INTERRUPT_IN_EP)
214 interrupt_in_ep_found = 1;
215 }
216 }
217
218 regfree(&r);
219 closedir(dir);
220
221 /*
222 * If this is fulfilled the interface is an MTP candidate
223 */
224 if (bulk_out_ep_found &&
225 bulk_in_ep_found &&
226 interrupt_in_ep_found) {
227 return 1;
228 }
229
230 return 0;
231 }
232
233 static int check_sysfs(char *sysfspath)
234 {
235 char dirbuf[FILENAME_MAX];
236 int len = strlen(sysfspath);
237 DIR *dir;
238 struct dirent *dent;
239 regex_t r;
240 int ret;
241 int look_closer = 0;
242
243 dir = opendir(sysfspath);
244 if (!dir)
245 return -1;
246
247 strcpy(dirbuf, sysfspath);
248 dirbuf[len++] = '/';
249
250 /* Check for dirs that identify interfaces */
251 ret = regcomp(&r, "^[0-9]+-[0-9]+(\\.[0-9])*\\:[0-9]+\\.[0-9]+$", REG_EXTENDED | REG_NOSUB);
252 if (ret) {
253 closedir(dir);
254 return -1;
255 }
256
257 while ((dent = readdir(dir))) {
258 struct stat st;
259 int ret;
260
261 /* No need to check those beginning with a period */
262 if (dent->d_name[0] == '.')
263 continue;
264
265 strncpy(dirbuf + len, dent->d_name, FILENAME_MAX - len);
266 dirbuf[FILENAME_MAX - 1] = '\0'; /* Sentinel */
267 ret = lstat(dirbuf, &st);
268 if (ret)
269 continue;
270
271 /* Look closer at dirs that may be interfaces */
272 if (S_ISDIR(st.st_mode)) {
273 if (!regexec(&r, dent->d_name, 0, 0, 0))
274 if (check_interface(dirbuf) > 0)
275 /* potential MTP interface! */
276 look_closer = 1;
277 }
278 }
279
280 regfree(&r);
281 closedir(dir);
282 return look_closer;
283 }
284 49
285 int main (int argc, char **argv) 50 int main (int argc, char **argv)
286 { 51 {
287 char *fname; 52 char *fname;
288 int busno; 53 int busno;
289 int devno; 54 int devno;
290 int ret; 55 int ret;
291 56
292 if (argc < 4) { 57 if (argc < 4) {
293 syslog(LOG_INFO, "need device path, busnumber, device number as argument\n") ; 58 syslog(LOG_INFO, "need device path, busnumber, device number as argument\n") ;
294 printf("0"); 59 printf("0");
295 exit(0); 60 exit(0);
296 } 61 }
297 62
298 fname = argv[1]; 63 fname = argv[1];
299 busno = atoi(argv[2]); 64 busno = atoi(argv[2]);
300 devno = atoi(argv[3]); 65 devno = atoi(argv[3]);
301 66
302 syslog(LOG_INFO, "checking bus %d, device %d: \"%s\"\n", busno, devno, fname); 67 syslog(LOG_INFO, "checking bus %d, device %d: \"%s\"\n", busno, devno, fname);
303 68
304 ret = check_sysfs(fname); 69 ret = LIBMTP_Check_Specific_Device(busno, devno);
305 /*
306 * This means that regular directory check either agrees that this may be a
307 * MTP device, or that it doesn't know (failed). In that case, kick the deeper
308 * check inside LIBMTP.
309 */
310 if (ret != 0)
311 ret = LIBMTP_Check_Specific_Device(busno, devno);
312 if (ret) { 70 if (ret) {
313 syslog(LOG_INFO, "bus: %d, device: %d was an MTP device\n", busno, devno); 71 syslog(LOG_INFO, "bus: %d, device: %d was an MTP device\n", busno, devno);
314 printf("1"); 72 printf("1");
315 } else { 73 } else {
316 syslog(LOG_INFO, "bus: %d, device: %d was not an MTP device\n", busno, devno ); 74 syslog(LOG_INFO, "bus: %d, device: %d was not an MTP device\n", busno, devno );
317 printf("0"); 75 printf("0");
318 } 76 }
319 77
320 exit(0); 78 exit(0);
321 } 79 }
OLDNEW
« no previous file with comments | « util/mtp-hotplug.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698