summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c1875
1 files changed, 1028 insertions, 847 deletions
diff --git a/main.c b/main.c
index 43f0425..e7292cc 100644
--- a/main.c
+++ b/main.c
@@ -59,29 +59,29 @@ static int foreground = 0;
59static int exit_on_no_devices = 0; 59static int exit_on_no_devices = 0;
60 60
61struct device_info { 61struct device_info {
62 uint32_t device_id; 62 uint32_t device_id;
63 usbmux_device_t phone; 63 usbmux_device_t phone;
64 int use_count; 64 int use_count;
65 pthread_t bulk_reader; 65 pthread_t bulk_reader;
66 pthread_mutex_t mutex; 66 pthread_mutex_t mutex;
67 /* mutex for mutual exclusion of calling the usbmux_send function 67 /* mutex for mutual exclusion of calling the usbmux_send function
68 * TODO: I don't know if we need really need this? */ 68 * TODO: I don't know if we need really need this? */
69 pthread_mutex_t writer_mutex; 69 pthread_mutex_t writer_mutex;
70}; 70};
71 71
72struct client_data { 72struct client_data {
73 volatile int dead; 73 volatile int dead;
74 int socket; 74 int socket;
75 int tag; 75 int tag;
76 pthread_t thread; 76 pthread_t thread;
77 pthread_t handler; 77 pthread_t handler;
78 pthread_t reader; 78 pthread_t reader;
79 int reader_quit; 79 int reader_quit;
80 int reader_dead; 80 int reader_dead;
81 int handler_dead; 81 int handler_dead;
82 int connected; 82 int connected;
83 usbmux_client_t muxclient; 83 usbmux_client_t muxclient;
84 struct device_info *dev; 84 struct device_info *dev;
85}; 85};
86 86
87static struct device_info **devices = NULL; 87static struct device_info **devices = NULL;
@@ -97,69 +97,77 @@ static pthread_mutex_t usb_mutex = PTHREAD_MUTEX_INITIALIZER;
97 */ 97 */
98static void logmsg(int prio, const char *format, ...) 98static void logmsg(int prio, const char *format, ...)
99{ 99{
100 va_list args; 100 va_list args;
101 va_start(args, format); 101 va_start(args, format);
102 102
103 if (!foreground) { 103 if (!foreground) {
104 // daemon. log using syslog. 104 // daemon. log using syslog.
105 vsyslog(prio, format, args); 105 vsyslog(prio, format, args);
106 } else { 106 } else {
107 // running in foreground. log to stdout/stderr. 107 // running in foreground. log to stdout/stderr.
108 char msgbuf[256]; 108 char msgbuf[256];
109 FILE *lfp = stdout; 109 FILE *lfp = stdout;
110 switch(prio) { 110 switch (prio) {
111 case LOG_EMERG: 111 case LOG_EMERG:
112 case LOG_ALERT: 112 case LOG_ALERT:
113 case LOG_CRIT: 113 case LOG_CRIT:
114 case LOG_ERR: 114 case LOG_ERR:
115 case LOG_WARNING: 115 case LOG_WARNING:
116 lfp = stderr; 116 lfp = stderr;
117 break; 117 break;
118 default: 118 default:
119 lfp = stdout; 119 lfp = stdout;
120 }
121 strcpy(msgbuf, "usbmuxd: ");
122 vsnprintf(msgbuf + 9, 244, format, args);
123 strcat(msgbuf, "\n");
124 fputs(msgbuf, lfp);
120 } 125 }
121 strcpy(msgbuf, "usbmuxd: ");
122 vsnprintf(msgbuf+9, 244, format, args);
123 strcat(msgbuf, "\n");
124 fputs(msgbuf, lfp);
125 }
126 126
127 va_end(args); 127 va_end(args);
128} 128}
129 129
130#ifdef DEBUG 130#ifdef DEBUG
131/** 131/**
132 * for debugging purposes. 132 * for debugging purposes.
133 */ 133 */
134static void print_buffer(FILE *fp, const char *data, const int length) 134static void print_buffer(FILE * fp, const char *data, const int length)
135{ 135{
136 int i; 136 int i;
137 int j; 137 int j;
138 unsigned char c; 138 unsigned char c;
139 139
140 for(i=0; i<length; i+=16) { 140 for (i = 0; i < length; i += 16) {
141 if (verbose >= 4) fprintf(fp, "%04x: ", i); 141 if (verbose >= 4)
142 for (j=0;j<16;j++) { 142 fprintf(fp, "%04x: ", i);
143 if (i+j >= length) { 143 for (j = 0; j < 16; j++) {
144 if (verbose >= 4) fprintf(fp, " "); 144 if (i + j >= length) {
145 if (verbose >= 4)
146 fprintf(fp, " ");
145 continue; 147 continue;
146 } 148 }
147 if (verbose >= 4) fprintf(fp, "%02hhx ", *(data+i+j)); 149 if (verbose >= 4)
150 fprintf(fp, "%02hhx ", *(data + i + j));
148 } 151 }
149 if (verbose >= 4) fprintf(fp, " | "); 152 if (verbose >= 4)
150 for(j=0;j<16;j++) { 153 fprintf(fp, " | ");
151 if (i+j >= length) 154 for (j = 0; j < 16; j++) {
155 if (i + j >= length)
152 break; 156 break;
153 c = *(data+i+j); 157 c = *(data + i + j);
154 if ((c < 32) || (c > 127)) { 158 if ((c < 32) || (c > 127)) {
155 if (verbose >= 4) fprintf(fp, "."); 159 if (verbose >= 4)
160 fprintf(fp, ".");
156 continue; 161 continue;
157 } 162 }
158 if (verbose >= 4) fprintf(fp, "%c", c); 163 if (verbose >= 4)
164 fprintf(fp, "%c", c);
159 } 165 }
160 if (verbose >= 4) fprintf(fp, "\n"); 166 if (verbose >= 4)
167 fprintf(fp, "\n");
161 } 168 }
162 if (verbose >= 4) fprintf(fp, "\n"); 169 if (verbose >= 4)
170 fprintf(fp, "\n");
163} 171}
164#endif 172#endif
165 173
@@ -176,35 +184,40 @@ static void print_buffer(FILE *fp, const char *data, const int length)
176 */ 184 */
177static int usbmuxd_get_request(int fd, void **data, size_t len) 185static int usbmuxd_get_request(int fd, void **data, size_t len)
178{ 186{
179 uint32_t pktlen; 187 uint32_t pktlen;
180 int recv_len; 188 int recv_len;
181 189
182 if (peek_buf(fd, &pktlen, sizeof(pktlen)) < (int)sizeof(pktlen)) { 190 if (peek_buf(fd, &pktlen, sizeof(pktlen)) < (int) sizeof(pktlen)) {
183 return -errno; 191 return -errno;
184 } 192 }
185
186 if (len == 0) {
187 // allocate buffer space
188 *data = malloc(pktlen);
189 } else if (len < pktlen) {
190 // target buffer is to small to hold this packet! fix it!
191 if (verbose >= 2) logmsg(LOG_WARNING, "%s: WARNING -- packet (%d) is larger than target buffer (%d)! Truncating.", __func__, pktlen, len);
192 pktlen = len;
193 }
194
195 recv_len = recv_buf(fd, *data, pktlen);
196 if ((recv_len > 0) && ((uint32_t)recv_len < pktlen)) {
197 if (verbose >= 2) logmsg(LOG_WARNING, "%s: Uh-oh, we got less than the packet's size, %d instead of %d...", __func__, recv_len, pktlen);
198 }
199 193
194 if (len == 0) {
195 // allocate buffer space
196 *data = malloc(pktlen);
197 } else if (len < pktlen) {
198 // target buffer is to small to hold this packet! fix it!
199 if (verbose >= 2)
200 logmsg(LOG_WARNING,
201 "%s: WARNING -- packet (%d) is larger than target buffer (%d)! Truncating.",
202 __func__, pktlen, len);
203 pktlen = len;
204 }
205
206 recv_len = recv_buf(fd, *data, pktlen);
207 if ((recv_len > 0) && ((uint32_t) recv_len < pktlen)) {
208 if (verbose >= 2)
209 logmsg(LOG_WARNING,
210 "%s: Uh-oh, we got less than the packet's size, %d instead of %d...",
211 __func__, recv_len, pktlen);
212 }
200#ifdef DEBUG 213#ifdef DEBUG
201 if (*data && (recv_len > 0) && verbose >= 4) { 214 if (*data && (recv_len > 0) && verbose >= 4) {
202 fprintf(stderr, "%s: received:\n", __func__); 215 fprintf(stderr, "%s: received:\n", __func__);
203 print_buffer(stderr, *data, recv_len); 216 print_buffer(stderr, *data, recv_len);
204 } 217 }
205#endif 218#endif
206 219
207 return recv_len; 220 return recv_len;
208} 221}
209 222
210/** 223/**
@@ -218,20 +231,22 @@ static int usbmuxd_get_request(int fd, void **data, size_t len)
218 */ 231 */
219static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code) 232static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code)
220{ 233{
221 struct usbmuxd_result res; 234 struct usbmuxd_result res;
222 int ret; 235 int ret;
223 236
224 res.header.length = sizeof(res); 237 res.header.length = sizeof(res);
225 res.header.reserved = 0; 238 res.header.reserved = 0;
226 res.header.type = USBMUXD_RESULT; 239 res.header.type = USBMUXD_RESULT;
227 res.header.tag = tag; 240 res.header.tag = tag;
228 res.result = result_code; 241 res.result = result_code;
229 242
230 if (verbose >= 4) logmsg(LOG_NOTICE, "%s: tag=%d result=%d", __func__, res.header.tag, res.result); 243 if (verbose >= 4)
231 244 logmsg(LOG_NOTICE, "%s: tag=%d result=%d", __func__,
232 ret = send_buf(fd, &res, sizeof(res)); 245 res.header.tag, res.result);
233 fsync(fd); // let's get it sent 246
234 return ret; 247 ret = send_buf(fd, &res, sizeof(res));
248 fsync(fd); // let's get it sent
249 return ret;
235} 250}
236 251
237/** 252/**
@@ -244,69 +259,84 @@ static int usbmuxd_send_result(int fd, uint32_t tag, uint32_t result_code)
244 */ 259 */
245static void *usbmuxd_client_reader_thread(void *arg) 260static void *usbmuxd_client_reader_thread(void *arg)
246{ 261{
247 struct client_data *cdata; 262 struct client_data *cdata;
248 263
249 char rbuffer[512]; 264 char rbuffer[512];
250 uint32_t rbuffersize = 512; 265 uint32_t rbuffersize = 512;
251 uint32_t rlen; 266 uint32_t rlen;
252 int err; 267 int err;
253 char *cursor; 268 char *cursor;
254 ssize_t len; 269 ssize_t len;
255 int result; 270 int result;
256 271
257 if (!arg) { 272 if (!arg) {
258 if (verbose >= 2) logmsg(LOG_ERR, "%s: invalid client_data supplied!", __func__); 273 if (verbose >= 2)
259 cdata->reader_dead = 1; 274 logmsg(LOG_ERR, "%s: invalid client_data supplied!", __func__);
260 return NULL; 275 cdata->reader_dead = 1;
261 } 276 return NULL;
277 }
262 278
263 cdata = (struct client_data*)arg; 279 cdata = (struct client_data *) arg;
264 280
265 cdata->reader_dead = 0; 281 cdata->reader_dead = 0;
266 282
267 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__, cdata->dev->device_id, cdata->dev->use_count); 283 if (verbose >= 3)
284 logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__,
285 cdata->dev->device_id, cdata->dev->use_count);
268 286
269 while (!quit_flag && !cdata->reader_quit) { 287 while (!quit_flag && !cdata->reader_quit) {
270 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT); 288 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
271 if (result <= 0) { 289 if (result <= 0) {
272 if (result < 0) { 290 if (result < 0) {
273 if (verbose >= 2) logmsg(LOG_ERR, "%s: select error: %s", __func__, strerror(errno)); 291 if (verbose >= 2)
274 } 292 logmsg(LOG_ERR, "%s: select error: %s", __func__,
275 continue; 293 strerror(errno));
276 } 294 }
295 continue;
296 }
277 297
278 rlen = 0; 298 rlen = 0;
279 err = usbmux_recv_timeout(cdata->muxclient, rbuffer, rbuffersize, &rlen, DEFAULT_TIMEOUT); 299 err =
280 if (err != 0) { 300 usbmux_recv_timeout(cdata->muxclient, rbuffer, rbuffersize,
281 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: encountered USB read error: %d", __func__, cdata->dev->device_id, cdata->dev->use_count, err); 301 &rlen, DEFAULT_TIMEOUT);
282 break; 302 if (err != 0) {
283 } 303 if (verbose >= 2)
304 logmsg(LOG_ERR,
305 "%s[%d:%d]: encountered USB read error: %d",
306 __func__, cdata->dev->device_id,
307 cdata->dev->use_count, err);
308 break;
309 }
284 310
285 cursor = rbuffer; 311 cursor = rbuffer;
286 while (rlen > 0) { 312 while (rlen > 0) {
287 len = send_buf(cdata->socket, cursor, rlen); 313 len = send_buf(cdata->socket, cursor, rlen);
288 if (len <= 0) { 314 if (len <= 0) {
289 logmsg(LOG_ERR, "%s: Error: send returned %d", __func__, len); 315 logmsg(LOG_ERR, "%s: Error: send returned %d", __func__,
290 err = 1; 316 len);
291 break; 317 err = 1;
292 } 318 break;
293 // calculate remainder 319 }
294 rlen -= len; 320 // calculate remainder
295 // advance cursor 321 rlen -= len;
296 cursor += len; 322 // advance cursor
297 } 323 cursor += len;
298 if (err != 0) { 324 }
299 logmsg(LOG_ERR, "%s: Error when writing to client...", __func__); 325 if (err != 0) {
300 break; 326 logmsg(LOG_ERR, "%s: Error when writing to client...",
327 __func__);
328 break;
329 }
330 fsync(cdata->socket);
301 } 331 }
302 fsync(cdata->socket);
303 }
304 332
305 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__, cdata->dev->device_id, cdata->dev->use_count); 333 if (verbose >= 3)
334 logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__,
335 cdata->dev->device_id, cdata->dev->use_count);
306 336
307 cdata->reader_dead = 1; 337 cdata->reader_dead = 1;
308 338
309 return NULL; 339 return NULL;
310} 340}
311 341
312/** 342/**
@@ -321,60 +351,73 @@ static void *usbmuxd_client_reader_thread(void *arg)
321 */ 351 */
322static int usbmuxd_handleConnectResult(struct client_data *cdata) 352static int usbmuxd_handleConnectResult(struct client_data *cdata)
323{ 353{
324 int result; 354 int result;
325 char buffer[512]; 355 char buffer[512];
326 char err_type[64]; 356 char err_type[64];
327 int err_code; 357 int err_code;
328 ssize_t maxlen = 512; 358 ssize_t maxlen = 512;
329 uint32_t rlen; 359 uint32_t rlen;
330 int err; 360 int err;
331 361
332 if (!cdata) { 362 if (!cdata) {
333 if (verbose >= 2) logmsg(LOG_ERR, "%s: Invalid client_data provided!", __func__); 363 if (verbose >= 2)
334 return -EINVAL; 364 logmsg(LOG_ERR, "%s: Invalid client_data provided!", __func__);
335 } 365 return -EINVAL;
336
337 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
338 if (result <= 0) {
339 if (result < 0) {
340 if (verbose >= 2) logmsg(LOG_ERR, "%s: select error: %s", __func__, strerror(errno));
341 return result;
342 } 366 }
343 } else { 367
344 result = 0; 368 result = check_fd(cdata->socket, FD_WRITE, DEFAULT_TIMEOUT);
345 err = usbmux_recv_timeout(cdata->muxclient, buffer, maxlen, &rlen, 100); 369 if (result <= 0) {
346 if (err < 0) { 370 if (result < 0) {
347 if (verbose >= 2) logmsg(LOG_ERR, "%s: encountered USB read error: %d", __func__, err); 371 if (verbose >= 2)
348 usbmuxd_send_result(cdata->socket, cdata->tag, -err); 372 logmsg(LOG_ERR, "%s: select error: %s", __func__,
349 return err; 373 strerror(errno));
374 return result;
375 }
350 } else { 376 } else {
351 if (rlen > 0) { 377 result = 0;
352 if ((buffer[0] == 1) && (rlen > 20) && !memcmp(buffer+1, "handleConnectResult:", 20)) { 378 err =
353 // hm... we got an error message! 379 usbmux_recv_timeout(cdata->muxclient, buffer, maxlen, &rlen,
354 buffer[rlen] = 0; 380 100);
355 if (verbose >= 1) logmsg(LOG_ERR, "%s: %s\n", __func__, buffer+22); 381 if (err < 0) {
356 382 if (verbose >= 2)
357 if (sscanf(buffer+22, "%s - %d\n", err_type, &err_code) == 2) { 383 logmsg(LOG_ERR, "%s: encountered USB read error: %d",
358 usbmuxd_send_result(cdata->socket, cdata->tag, err_code); 384 __func__, err);
359 return -err_code; 385 usbmuxd_send_result(cdata->socket, cdata->tag, -err);
360 } else { 386 return err;
361 usbmuxd_send_result(cdata->socket, cdata->tag, ENODATA);
362 return -ENODATA;
363 }
364 } else { 387 } else {
365 // send success result 388 if (rlen > 0) {
366 usbmuxd_send_result(cdata->socket, cdata->tag, 0); 389 if ((buffer[0] == 1) && (rlen > 20)
367 // and the server greeting message 390 && !memcmp(buffer + 1, "handleConnectResult:", 20)) {
368 send_buf(cdata->socket, buffer, rlen); 391 // hm... we got an error message!
392 buffer[rlen] = 0;
393 if (verbose >= 1)
394 logmsg(LOG_ERR, "%s: %s\n", __func__, buffer + 22);
395
396 if (sscanf
397 (buffer + 22, "%s - %d\n", err_type, &err_code)
398 == 2) {
399 usbmuxd_send_result(cdata->socket, cdata->tag,
400 err_code);
401 return -err_code;
402 } else {
403 usbmuxd_send_result(cdata->socket, cdata->tag,
404 ENODATA);
405 return -ENODATA;
406 }
407 } else {
408 // send success result
409 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
410 // and the server greeting message
411 send_buf(cdata->socket, buffer, rlen);
412 }
413 } else {
414 // no server greeting? this seems to be ok. send success.
415 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
416 }
369 } 417 }
370 } else { 418 //fsync(cdata->socket);
371 // no server greeting? this seems to be ok. send success.
372 usbmuxd_send_result(cdata->socket, cdata->tag, 0);
373 }
374 } 419 }
375 //fsync(cdata->socket); 420 return result;
376 }
377 return result;
378} 421}
379 422
380/** 423/**
@@ -383,96 +426,115 @@ static int usbmuxd_handleConnectResult(struct client_data *cdata)
383 */ 426 */
384static void *usbmuxd_client_handler_thread(void *arg) 427static void *usbmuxd_client_handler_thread(void *arg)
385{ 428{
386 struct client_data *cdata; 429 struct client_data *cdata;
387 int result; 430 int result;
388 char *cursor; 431 char *cursor;
389 char buffer[65536]; 432 char buffer[65536];
390 ssize_t len; 433 ssize_t len;
391 ssize_t maxlen = sizeof(buffer); 434 ssize_t maxlen = sizeof(buffer);
392 uint32_t wlen; 435 uint32_t wlen;
393 int err; 436 int err;
394 437
395 if (!arg) { 438 if (!arg) {
396 if (verbose >= 2) logmsg(LOG_ERR, "%s: invalid client_data provided!", __func__); 439 if (verbose >= 2)
397 return NULL; 440 logmsg(LOG_ERR, "%s: invalid client_data provided!", __func__);
398 } 441 return NULL;
399 442 }
400 cdata = (struct client_data*)arg;
401
402 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__, cdata->dev->device_id,cdata->dev->use_count);
403 443
404 if (usbmuxd_handleConnectResult(cdata)) { 444 cdata = (struct client_data *) arg;
405 if (verbose >= 3) logmsg(LOG_ERR, "handleConnectResult: Error");
406 goto leave;
407 } else {
408 if (verbose >= 3) logmsg(LOG_NOTICE, "handleConnectResult: Success");
409 }
410 445
411 // starting mux reader thread 446 if (verbose >= 3)
412 cdata->reader_quit = 0; 447 logmsg(LOG_NOTICE, "%s[%d:%d]: started", __func__,
413 cdata->reader_dead = 0; 448 cdata->dev->device_id, cdata->dev->use_count);
414 if (pthread_create(&cdata->reader, NULL, usbmuxd_client_reader_thread, cdata) != 0) {
415 if (verbose >= 2) logmsg(LOG_ERR, "%s: could not start client_reader thread", __func__);
416 cdata->reader = 0;
417 }
418 449
419 while (!quit_flag && !cdata->reader_dead) { 450 if (usbmuxd_handleConnectResult(cdata)) {
420 result = check_fd(cdata->socket, FD_READ, DEFAULT_TIMEOUT); 451 if (verbose >= 3)
421 if (result <= 0) { 452 logmsg(LOG_ERR, "handleConnectResult: Error");
422 if (result < 0) { 453 goto leave;
423 if (verbose >= 3) logmsg(LOG_ERR, "%s: Error: checkfd: %s", __func__, strerror(errno)); 454 } else {
424 } 455 if (verbose >= 3)
425 continue; 456 logmsg(LOG_NOTICE, "handleConnectResult: Success");
426 } 457 }
427 458
428 // check_fd told us there's data available, so read from client 459 // starting mux reader thread
429 // and push to USB device. 460 cdata->reader_quit = 0;
430 len = recv(cdata->socket, buffer, maxlen, 0); 461 cdata->reader_dead = 0;
431 if (len == 0) { 462 if (pthread_create
432 break; 463 (&cdata->reader, NULL, usbmuxd_client_reader_thread, cdata) != 0) {
433 } 464 if (verbose >= 2)
434 if (len < 0) { 465 logmsg(LOG_ERR, "%s: could not start client_reader thread",
435 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: Error: recv: %s", __func__, cdata->dev->device_id, cdata->dev->use_count, strerror(errno)); 466 __func__);
436 break; 467 cdata->reader = 0;
437 } 468 }
438 469
439 cursor = buffer; 470 while (!quit_flag && !cdata->reader_dead) {
440 471 result = check_fd(cdata->socket, FD_READ, DEFAULT_TIMEOUT);
441 pthread_mutex_lock(&cdata->dev->writer_mutex); 472 if (result <= 0) {
442 do { 473 if (result < 0) {
443 wlen = 0; 474 if (verbose >= 3)
444 err = usbmux_send(cdata->muxclient, cursor, len, &wlen); 475 logmsg(LOG_ERR, "%s: Error: checkfd: %s", __func__,
445 if (err == -ETIMEDOUT) { 476 strerror(errno));
446 // some kind of timeout... just be patient and retry. 477 }
447 } else if (err < 0) { 478 continue;
448 if (verbose >= 2) logmsg(LOG_ERR, "%s[%d:%d]: USB write error: %d", __func__, cdata->dev->device_id, cdata->dev->use_count, err); 479 }
449 len = -1; 480 // check_fd told us there's data available, so read from client
450 break; 481 // and push to USB device.
451 } 482 len = recv(cdata->socket, buffer, maxlen, 0);
452 483 if (len == 0) {
453 // calculate remainder. 484 break;
454 len -= wlen; 485 }
455 // advance cursor appropiately. 486 if (len < 0) {
456 cursor += wlen; 487 if (verbose >= 2)
457 } while ((len > 0) && !quit_flag); 488 logmsg(LOG_ERR, "%s[%d:%d]: Error: recv: %s", __func__,
458 pthread_mutex_unlock(&cdata->dev->writer_mutex); 489 cdata->dev->device_id, cdata->dev->use_count,
459 if (len < 0) { 490 strerror(errno));
460 break; 491 break;
492 }
493
494 cursor = buffer;
495
496 pthread_mutex_lock(&cdata->dev->writer_mutex);
497 do {
498 wlen = 0;
499 err = usbmux_send(cdata->muxclient, cursor, len, &wlen);
500 if (err == -ETIMEDOUT) {
501 // some kind of timeout... just be patient and retry.
502 } else if (err < 0) {
503 if (verbose >= 2)
504 logmsg(LOG_ERR, "%s[%d:%d]: USB write error: %d",
505 __func__, cdata->dev->device_id,
506 cdata->dev->use_count, err);
507 len = -1;
508 break;
509 }
510 // calculate remainder.
511 len -= wlen;
512 // advance cursor appropiately.
513 cursor += wlen;
514 }
515 while ((len > 0) && !quit_flag);
516 pthread_mutex_unlock(&cdata->dev->writer_mutex);
517 if (len < 0) {
518 break;
519 }
461 } 520 }
462 }
463 521
464leave: 522 leave:
465 // cleanup 523 // cleanup
466 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminating", __func__, cdata->dev->device_id, cdata->dev->use_count); 524 if (verbose >= 3)
467 if (cdata->reader != 0) { 525 logmsg(LOG_NOTICE, "%s[%d:%d]: terminating", __func__,
468 cdata->reader_quit = 1; 526 cdata->dev->device_id, cdata->dev->use_count);
469 pthread_join(cdata->reader, NULL); 527 if (cdata->reader != 0) {
470 } 528 cdata->reader_quit = 1;
529 pthread_join(cdata->reader, NULL);
530 }
471 531
472 cdata->handler_dead = 1; 532 cdata->handler_dead = 1;
473 533
474 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__, cdata->dev->device_id, cdata->dev->use_count); 534 if (verbose >= 3)
475 return NULL; 535 logmsg(LOG_NOTICE, "%s[%d:%d]: terminated", __func__,
536 cdata->dev->device_id, cdata->dev->use_count);
537 return NULL;
476} 538}
477 539
478/** 540/**
@@ -481,36 +543,41 @@ leave:
481 */ 543 */
482static void *usbmuxd_bulk_reader_thread(void *arg) 544static void *usbmuxd_bulk_reader_thread(void *arg)
483{ 545{
484 struct device_info *cur_dev; 546 struct device_info *cur_dev;
485 int err; 547 int err;
486 548
487 if (!arg) { 549 if (!arg) {
488 if (verbose >= 2) logmsg(LOG_ERR, "%s: Invalid client_data provided", __func__); 550 if (verbose >= 2)
489 return NULL; 551 logmsg(LOG_ERR, "%s: Invalid client_data provided", __func__);
490 } 552 return NULL;
553 }
491 554
492 cur_dev = (struct device_info*)arg; 555 cur_dev = (struct device_info *) arg;
493 556
494 if (verbose >= 3) logmsg(LOG_NOTICE, "%s: started", __func__); 557 if (verbose >= 3)
558 logmsg(LOG_NOTICE, "%s: started", __func__);
495 559
496 while (!quit_flag && cur_dev) { 560 while (!quit_flag && cur_dev) {
497 561
498 pthread_mutex_lock(&cur_dev->mutex); 562 pthread_mutex_lock(&cur_dev->mutex);
499 if (cur_dev->use_count <= 0) { 563 if (cur_dev->use_count <= 0) {
500 pthread_mutex_unlock(&cur_dev->mutex); 564 pthread_mutex_unlock(&cur_dev->mutex);
501 break; 565 break;
502 } 566 }
503 pthread_mutex_unlock(&cur_dev->mutex); 567 pthread_mutex_unlock(&cur_dev->mutex);
504 568
505 if ((err = usbmux_pullbulk(cur_dev->phone)) < 0) { 569 if ((err = usbmux_pullbulk(cur_dev->phone)) < 0) {
506 if (verbose >= 1) logmsg(LOG_ERR, "%s: error %d when reading from device", __func__, err); 570 if (verbose >= 1)
507 break; 571 logmsg(LOG_ERR, "%s: error %d when reading from device",
572 __func__, err);
573 break;
574 }
508 } 575 }
509 }
510 576
511 if (verbose >= 3) logmsg(LOG_NOTICE, "%s: terminated", __func__); 577 if (verbose >= 3)
578 logmsg(LOG_NOTICE, "%s: terminated", __func__);
512 579
513 return NULL; 580 return NULL;
514} 581}
515 582
516/** 583/**
@@ -520,286 +587,374 @@ static void *usbmuxd_bulk_reader_thread(void *arg)
520 */ 587 */
521static void *usbmuxd_client_init_thread(void *arg) 588static void *usbmuxd_client_init_thread(void *arg)
522{ 589{
523 struct client_data *cdata; 590 struct client_data *cdata;
524 struct usbmuxd_scan_request *s_req = NULL; 591 struct usbmuxd_scan_request *s_req = NULL;
525 struct usbmuxd_device_info_record dev_info_rec; 592 struct usbmuxd_device_info_record dev_info_rec;
526 struct usbmuxd_connect_request *c_req = NULL; 593 struct usbmuxd_connect_request *c_req = NULL;
594
595 struct usb_bus *bus;
596 struct usb_device *dev;
597
598 int recv_len;
599 int found = 0;
600 int res;
601 int i;
602
603 usbmux_device_t phone = NULL;
604 struct device_info *cur_dev = NULL;
605
606 if (!arg) {
607 if (verbose >= 1)
608 logmsg(LOG_ERR, "%s[%x]: invalid client_data provided!",
609 __func__, THREAD);
610 return NULL;
611 }
527 612
528 struct usb_bus *bus; 613 cdata = (struct client_data *) arg;
529 struct usb_device *dev; 614 cdata->dead = 0;
530 615
531 int recv_len; 616 if (verbose >= 3)
532 int found = 0; 617 logmsg(LOG_NOTICE, "%s[%x]: started (fd=%d)", __func__, THREAD,
533 int res; 618 cdata->socket);
534 int i;
535 619
536 usbmux_device_t phone = NULL; 620 if ((recv_len =
537 struct device_info *cur_dev = NULL; 621 usbmuxd_get_request(cdata->socket, (void **) &s_req, 0)) <= 0) {
622 if (verbose >= 2)
623 logmsg(LOG_ERR, "%s[%x]: No scan packet received, error %s",
624 __func__, THREAD, strerror(errno));
625 goto leave;
626 }
538 627
539 if (!arg) { 628 if ((recv_len == sizeof(struct usbmuxd_scan_request))
540 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: invalid client_data provided!", __func__, THREAD); 629 && (s_req->header.length == sizeof(struct usbmuxd_scan_request))
541 return NULL; 630 && (s_req->header.reserved == 0)
542 } 631 && (s_req->header.type == USBMUXD_SCAN)) {
543 632 // send success response
544 cdata = (struct client_data*)arg; 633 if (verbose >= 3)
545 cdata->dead = 0; 634 logmsg(LOG_NOTICE, "%s[%x]: Got scan packet!", __func__,
546 635 THREAD);
547 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: started (fd=%d)", __func__, THREAD, cdata->socket); 636 usbmuxd_send_result(cdata->socket, s_req->header.tag, 0);
548 637 } else if ((recv_len == sizeof(struct usbmuxd_connect_request))
549 if ((recv_len = usbmuxd_get_request(cdata->socket, (void**)&s_req, 0)) <= 0) { 638 && (s_req->header.type == USBMUXD_CONNECT)) {
550 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: No scan packet received, error %s", __func__, THREAD, strerror(errno)); 639 c_req = (struct usbmuxd_connect_request *) s_req;
551 goto leave; 640 s_req = NULL;
552 } 641 goto connect;
553 642 } else {
554 if ((recv_len == sizeof(struct usbmuxd_scan_request)) && (s_req->header.length == sizeof(struct usbmuxd_scan_request)) 643 // send error response and exit
555 && (s_req->header.reserved == 0) && (s_req->header.type == USBMUXD_SCAN)) { 644 if (verbose >= 2)
556 // send success response 645 logmsg(LOG_ERR, "%s[%x]: Invalid scan packet received.",
557 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Got scan packet!", __func__, THREAD); 646 __func__, THREAD);
558 usbmuxd_send_result(cdata->socket, s_req->header.tag, 0); 647 // TODO is this required?!
559 } else if ((recv_len == sizeof(struct usbmuxd_connect_request)) && (s_req->header.type == USBMUXD_CONNECT)) { 648 usbmuxd_send_result(cdata->socket, s_req->header.tag, EINVAL);
560 c_req = (struct usbmuxd_connect_request*)s_req; 649 goto leave;
561 s_req = NULL; 650 }
562 goto connect;
563 } else {
564 // send error response and exit
565 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: Invalid scan packet received.", __func__, THREAD);
566 // TODO is this required?!
567 usbmuxd_send_result(cdata->socket, s_req->header.tag, EINVAL);
568 goto leave;
569 }
570
571 pthread_mutex_lock(&usb_mutex);
572 // gather data about all iPhones/iPods attached
573
574 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb init", __func__, THREAD);
575 usb_init();
576 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb find busses", __func__, THREAD);
577 usb_find_busses();
578 if (verbose >= 5) logmsg(LOG_DEBUG, "%s[%x]: usb find devices", __func__, THREAD);
579 usb_find_devices();
580
581 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: Looking for attached devices...", __func__, THREAD);
582
583 for (bus = usb_get_busses(); bus; bus = bus->next) {
584 for (dev = bus->devices; dev; dev = dev->next) {
585 if (dev->descriptor.idVendor == 0x05ac
586 && dev->descriptor.idProduct >= 0x1290
587 && dev->descriptor.idProduct <= 0x1293)
588 {
589 if (verbose >= 1) logmsg(LOG_NOTICE, "%s[%x]: Found device on bus %d, id %d", __func__, THREAD, bus->location, dev->devnum);
590 found++;
591
592 // construct packet
593 memset(&dev_info_rec, 0, sizeof(dev_info_rec));
594 dev_info_rec.header.length = sizeof(dev_info_rec);
595 dev_info_rec.header.type = USBMUXD_DEVICE_INFO;
596 dev_info_rec.device.device_id = dev->devnum;
597 dev_info_rec.device.product_id = dev->descriptor.idProduct;
598 if (dev->descriptor.iSerialNumber) {
599 usb_dev_handle *udev;
600 //pthread_mutex_lock(&usbmux_mutex);
601 udev = usb_open(dev);
602 if (udev) {
603 usb_get_string_simple(udev, dev->descriptor.iSerialNumber, dev_info_rec.device.serial_number, sizeof(dev_info_rec.device.serial_number)+1);
604 usb_close(udev);
605 }
606 //pthread_mutex_unlock(&usbmux_mutex);
607 }
608 651
652 pthread_mutex_lock(&usb_mutex);
653 // gather data about all iPhones/iPods attached
654
655 if (verbose >= 5)
656 logmsg(LOG_DEBUG, "%s[%x]: usb init", __func__, THREAD);
657 usb_init();
658 if (verbose >= 5)
659 logmsg(LOG_DEBUG, "%s[%x]: usb find busses", __func__, THREAD);
660 usb_find_busses();
661 if (verbose >= 5)
662 logmsg(LOG_DEBUG, "%s[%x]: usb find devices", __func__, THREAD);
663 usb_find_devices();
664
665 if (verbose >= 2)
666 logmsg(LOG_NOTICE, "%s[%x]: Looking for attached devices...",
667 __func__, THREAD);
668
669 for (bus = usb_get_busses(); bus; bus = bus->next) {
670 for (dev = bus->devices; dev; dev = dev->next) {
671 if (dev->descriptor.idVendor == 0x05ac
672 && dev->descriptor.idProduct >= 0x1290
673 && dev->descriptor.idProduct <= 0x1293) {
674 if (verbose >= 1)
675 logmsg(LOG_NOTICE,
676 "%s[%x]: Found device on bus %d, id %d",
677 __func__, THREAD, bus->location, dev->devnum);
678 found++;
679
680 // construct packet
681 memset(&dev_info_rec, 0, sizeof(dev_info_rec));
682 dev_info_rec.header.length = sizeof(dev_info_rec);
683 dev_info_rec.header.type = USBMUXD_DEVICE_INFO;
684 dev_info_rec.device.device_id = dev->devnum;
685 dev_info_rec.device.product_id = dev->descriptor.idProduct;
686 if (dev->descriptor.iSerialNumber) {
687 usb_dev_handle *udev;
688 //pthread_mutex_lock(&usbmux_mutex);
689 udev = usb_open(dev);
690 if (udev) {
691 usb_get_string_simple(udev,
692 dev->descriptor.
693 iSerialNumber,
694 dev_info_rec.device.
695 serial_number,
696 sizeof(dev_info_rec.device.
697 serial_number) + 1);
698 usb_close(udev);
699 }
700 //pthread_mutex_unlock(&usbmux_mutex);
701 }
609#ifdef DEBUG 702#ifdef DEBUG
610 if (verbose >= 4) print_buffer(stderr, (char*)&dev_info_rec, sizeof(dev_info_rec)); 703 if (verbose >= 4)
704 print_buffer(stderr, (char *) &dev_info_rec,
705 sizeof(dev_info_rec));
611#endif 706#endif
612 707
613 // send it 708 // send it
614 if (send_buf(cdata->socket, &dev_info_rec, sizeof(dev_info_rec)) <= 0) { 709 if (send_buf
615 if (verbose >= 3) logmsg(LOG_ERR, "%s[%x]: Error: Could not send device info: %s", __func__, THREAD, strerror(errno)); 710 (cdata->socket, &dev_info_rec,
616 found--; 711 sizeof(dev_info_rec)) <= 0) {
712 if (verbose >= 3)
713 logmsg(LOG_ERR,
714 "%s[%x]: Error: Could not send device info: %s",
715 __func__, THREAD, strerror(errno));
716 found--;
717 }
718 }
617 } 719 }
618 }
619 } 720 }
620 } 721 pthread_mutex_unlock(&usb_mutex);
621 pthread_mutex_unlock(&usb_mutex); 722
622 723 if (found <= 0) {
623 if (found <= 0) { 724 if (verbose >= 1)
624 if (verbose >= 1) logmsg(LOG_NOTICE, "%s[%x]: No attached iPhone/iPod devices found.", __func__, THREAD); 725 logmsg(LOG_NOTICE,
625 goto leave; 726 "%s[%x]: No attached iPhone/iPod devices found.",
626 } 727 __func__, THREAD);
627 728 goto leave;
628 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Waiting for connect request", __func__, THREAD);
629
630 // now wait for connect request
631 //memset(&c_req, 0, sizeof(c_req));
632 if ((recv_len = usbmuxd_get_request(cdata->socket, (void**)&c_req, 0)) <= 0) {
633 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Did not receive any connect request.", __func__, THREAD);
634 goto leave;
635 }
636
637connect:
638
639 if (c_req->header.type != USBMUXD_CONNECT) {
640 if (verbose >= 2) logmsg(LOG_ERR, "%s[%x]: Unexpected packet of type %d received.", __func__, THREAD, c_req->header.type);
641 goto leave;
642 }
643
644 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: Setting up connection to usb device #%d on port %d", __func__, THREAD, c_req->device_id, ntohs(c_req->tcp_dport));
645
646 // find the device, and open usb connection
647 pthread_mutex_lock(&usbmux_mutex);
648 phone = NULL;
649 cur_dev = NULL;
650 // first check if we already have an open connection
651 if (devices) {
652 for (i = 0; i < device_count; i++) {
653 if (devices[i]) {
654 if (devices[i]->device_id == c_req->device_id) {
655 devices[i]->use_count++;
656 cur_dev = devices[i];
657 phone = cur_dev->phone;
658 break;
659 }
660 }
661 } 729 }
662 }
663 if (!phone) {
664 // if not found, make a new connection
665 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: creating new usb connection, device_id=%d", __func__, THREAD, c_req->device_id);
666 730
667 pthread_mutex_lock(&usb_mutex); 731 if (verbose >= 3)
668 if (usbmux_get_specific_device(0, c_req->device_id, &phone) < 0) { 732 logmsg(LOG_NOTICE, "%s[%x]: Waiting for connect request", __func__,
669 pthread_mutex_unlock(&usb_mutex); 733 THREAD);
670 pthread_mutex_unlock(&usbmux_mutex); 734
671 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: device_id %d could not be opened", __func__, THREAD, c_req->device_id); 735 // now wait for connect request
672 usbmuxd_send_result(cdata->socket, c_req->header.tag, ENODEV); 736 //memset(&c_req, 0, sizeof(c_req));
673 goto leave; 737 if ((recv_len =
738 usbmuxd_get_request(cdata->socket, (void **) &c_req, 0)) <= 0) {
739 if (verbose >= 3)
740 logmsg(LOG_NOTICE,
741 "%s[%x]: Did not receive any connect request.",
742 __func__, THREAD);
743 goto leave;
674 } 744 }
675 pthread_mutex_unlock(&usb_mutex); 745
676 746 connect:
677 // create device object 747
678 if (verbose >= 3) logmsg(LOG_DEBUG, "%s[%x]: add to device list", __func__, THREAD); 748 if (c_req->header.type != USBMUXD_CONNECT) {
679 cur_dev = (struct device_info*)malloc(sizeof(struct device_info)); 749 if (verbose >= 2)
680 memset(cur_dev, 0, sizeof(struct device_info)); 750 logmsg(LOG_ERR,
681 cur_dev->use_count = 1; 751 "%s[%x]: Unexpected packet of type %d received.",
682 cur_dev->device_id = c_req->device_id; 752 __func__, THREAD, c_req->header.type);
683 cur_dev->phone = phone; 753 goto leave;
684 cur_dev->bulk_reader = 0; 754 }
685 pthread_mutex_init(&cur_dev->mutex, NULL); 755
686 pthread_mutex_init(&cur_dev->writer_mutex, NULL); 756 if (verbose >= 3)
687 757 logmsg(LOG_NOTICE,
688 if (verbose >= 3) logmsg(LOG_DEBUG, "%s[%x]: device_count = %d", __func__, THREAD, device_count); 758 "%s[%x]: Setting up connection to usb device #%d on port %d",
689 759 __func__, THREAD, c_req->device_id,
690 // add to list of devices 760 ntohs(c_req->tcp_dport));
691 devices = (struct device_info**)realloc(devices, sizeof(struct device_info*) * (device_count+1)); 761
762 // find the device, and open usb connection
763 pthread_mutex_lock(&usbmux_mutex);
764 phone = NULL;
765 cur_dev = NULL;
766 // first check if we already have an open connection
692 if (devices) { 767 if (devices) {
693 devices[device_count] = cur_dev; 768 for (i = 0; i < device_count; i++) {
694 device_count++; 769 if (devices[i]) {
770 if (devices[i]->device_id == c_req->device_id) {
771 devices[i]->use_count++;
772 cur_dev = devices[i];
773 phone = cur_dev->phone;
774 break;
775 }
776 }
777 }
778 }
779 if (!phone) {
780 // if not found, make a new connection
781 if (verbose >= 2)
782 logmsg(LOG_NOTICE,
783 "%s[%x]: creating new usb connection, device_id=%d",
784 __func__, THREAD, c_req->device_id);
785
786 pthread_mutex_lock(&usb_mutex);
787 if (usbmux_get_specific_device(0, c_req->device_id, &phone) < 0) {
788 pthread_mutex_unlock(&usb_mutex);
789 pthread_mutex_unlock(&usbmux_mutex);
790 if (verbose >= 1)
791 logmsg(LOG_ERR, "%s[%x]: device_id %d could not be opened",
792 __func__, THREAD, c_req->device_id);
793 usbmuxd_send_result(cdata->socket, c_req->header.tag, ENODEV);
794 goto leave;
795 }
796 pthread_mutex_unlock(&usb_mutex);
797
798 // create device object
799 if (verbose >= 3)
800 logmsg(LOG_DEBUG, "%s[%x]: add to device list", __func__,
801 THREAD);
802 cur_dev =
803 (struct device_info *) malloc(sizeof(struct device_info));
804 memset(cur_dev, 0, sizeof(struct device_info));
805 cur_dev->use_count = 1;
806 cur_dev->device_id = c_req->device_id;
807 cur_dev->phone = phone;
808 cur_dev->bulk_reader = 0;
809 pthread_mutex_init(&cur_dev->mutex, NULL);
810 pthread_mutex_init(&cur_dev->writer_mutex, NULL);
811
812 if (verbose >= 3)
813 logmsg(LOG_DEBUG, "%s[%x]: device_count = %d", __func__,
814 THREAD, device_count);
815
816 // add to list of devices
817 devices =
818 (struct device_info **) realloc(devices,
819 sizeof(struct device_info *) *
820 (device_count + 1));
821 if (devices) {
822 devices[device_count] = cur_dev;
823 device_count++;
824 }
825 } else {
826 if (verbose >= 2)
827 logmsg(LOG_NOTICE,
828 "%s[%x]: reusing usb connection, device_id=%d",
829 __func__, THREAD, c_req->device_id);
695 } 830 }
696 } else { 831 pthread_mutex_unlock(&usbmux_mutex);
697 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: reusing usb connection, device_id=%d", __func__, THREAD, c_req->device_id);
698 }
699 pthread_mutex_unlock(&usbmux_mutex);
700 832
701 // setup connection to iPhone/iPod 833 // setup connection to iPhone/iPod
702// pthread_mutex_lock(&usbmux_mutex); 834// pthread_mutex_lock(&usbmux_mutex);
703 res = usbmux_new_client(cur_dev->phone, 0, ntohs(c_req->tcp_dport), &(cdata->muxclient)); 835 res =
836 usbmux_new_client(cur_dev->phone, 0, ntohs(c_req->tcp_dport),
837 &(cdata->muxclient));
704// pthread_mutex_unlock(&usbmux_mutex); 838// pthread_mutex_unlock(&usbmux_mutex);
705 839
706 if (res != 0) { 840 if (res != 0) {
707 usbmuxd_send_result(cdata->socket, c_req->header.tag, res); 841 usbmuxd_send_result(cdata->socket, c_req->header.tag, res);
708 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: mux_new_client returned %d, aborting.", __func__, THREAD, res); 842 if (verbose >= 1)
709 goto leave; 843 logmsg(LOG_ERR,
710 } 844 "%s[%x]: mux_new_client returned %d, aborting.",
711 845 __func__, THREAD, res);
712 // start bulk reader thread (once per device) 846 goto leave;
713 pthread_mutex_lock(&cur_dev->mutex); 847 }
714 if (cur_dev->bulk_reader == 0) { 848 // start bulk reader thread (once per device)
715 pthread_create(&cur_dev->bulk_reader, NULL, usbmuxd_bulk_reader_thread, cur_dev);
716 }
717 pthread_mutex_unlock(&cur_dev->mutex);
718
719 // start connection handler thread
720 cdata->handler_dead = 0;
721 cdata->tag = c_req->header.tag;
722 cdata->dev = cur_dev;
723 if (pthread_create(&cdata->handler, NULL, usbmuxd_client_handler_thread, cdata) != 0) {
724 if (verbose >= 1) logmsg(LOG_ERR, "%s[%x]: could not create usbmuxd_client_handler_thread!", __func__, THREAD);
725 cdata->handler = 0;
726 goto leave;
727 }
728
729 // wait for handler thread to finish its work
730 if (cdata->handler != 0) {
731 pthread_join(cdata->handler, NULL);
732 }
733
734 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: closing connection", __func__, THREAD);
735
736 // time to clean up
737 if (cdata && cdata->muxclient) { // should be non-NULL
738 usbmux_free_client(cdata->muxclient);
739 }
740
741leave:
742 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: terminating", __func__, THREAD);
743
744 if (s_req) {
745 free(s_req);
746 }
747 if (c_req) {
748 free(c_req);
749 }
750
751 // this has to be freed only if it's not in use anymore as it closes
752 // the USB connection
753 pthread_mutex_lock(&usbmux_mutex);
754 if (cur_dev) {
755 pthread_mutex_lock(&cur_dev->mutex); 849 pthread_mutex_lock(&cur_dev->mutex);
756 if (cur_dev->use_count > 1) { 850 if (cur_dev->bulk_reader == 0) {
757 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: decreasing device use count (from %d to %d)", __func__, THREAD, cur_dev->use_count, cur_dev->use_count-1); 851 pthread_create(&cur_dev->bulk_reader, NULL,
758 cur_dev->use_count--; 852 usbmuxd_bulk_reader_thread, cur_dev);
759 pthread_mutex_unlock(&cur_dev->mutex); 853 }
760 } else { 854 pthread_mutex_unlock(&cur_dev->mutex);
761 if (verbose >= 2) logmsg(LOG_NOTICE, "%s[%x]: last client disconnected, cleaning up", __func__, THREAD); 855
762 cur_dev->use_count = 0; 856 // start connection handler thread
763 pthread_mutex_unlock(&cur_dev->mutex); 857 cdata->handler_dead = 0;
764 if (cur_dev->bulk_reader != 0) { 858 cdata->tag = c_req->header.tag;
765 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: joining bulk_reader...", __func__, THREAD); 859 cdata->dev = cur_dev;
766 pthread_join(cur_dev->bulk_reader, NULL); 860 if (pthread_create
767 } 861 (&cdata->handler, NULL, usbmuxd_client_handler_thread, cdata) != 0)
768 pthread_mutex_lock(&usb_mutex); 862 {
769 usbmux_free_device(cur_dev->phone); 863 if (verbose >= 1)
770 pthread_mutex_unlock(&usb_mutex); 864 logmsg(LOG_ERR,
771 pthread_mutex_destroy(&cur_dev->writer_mutex); 865 "%s[%x]: could not create usbmuxd_client_handler_thread!",
772 pthread_mutex_destroy(&cur_dev->mutex); 866 __func__, THREAD);
773 free(cur_dev); 867 cdata->handler = 0;
774 cur_dev = NULL; 868 goto leave;
775 if (device_count > 1) { 869 }
776 struct device_info **newlist; 870 // wait for handler thread to finish its work
777 int j; 871 if (cdata->handler != 0) {
778 872 pthread_join(cdata->handler, NULL);
779 newlist = (struct device_info**)malloc(sizeof(struct device_info*) * device_count-1); 873 }
780 for (i = 0; i < device_count; i++) { 874
781 if (devices[i] != NULL) { 875 if (verbose >= 2)
782 newlist[j++] = devices[i]; 876 logmsg(LOG_NOTICE, "%s[%x]: closing connection", __func__, THREAD);
783 } 877
878 // time to clean up
879 if (cdata && cdata->muxclient) { // should be non-NULL
880 usbmux_free_client(cdata->muxclient);
881 }
882
883 leave:
884 if (verbose >= 3)
885 logmsg(LOG_NOTICE, "%s[%x]: terminating", __func__, THREAD);
886
887 if (s_req) {
888 free(s_req);
889 }
890 if (c_req) {
891 free(c_req);
892 }
893 // this has to be freed only if it's not in use anymore as it closes
894 // the USB connection
895 pthread_mutex_lock(&usbmux_mutex);
896 if (cur_dev) {
897 pthread_mutex_lock(&cur_dev->mutex);
898 if (cur_dev->use_count > 1) {
899 if (verbose >= 2)
900 logmsg(LOG_NOTICE,
901 "%s[%x]: decreasing device use count (from %d to %d)",
902 __func__, THREAD, cur_dev->use_count,
903 cur_dev->use_count - 1);
904 cur_dev->use_count--;
905 pthread_mutex_unlock(&cur_dev->mutex);
906 } else {
907 if (verbose >= 2)
908 logmsg(LOG_NOTICE,
909 "%s[%x]: last client disconnected, cleaning up",
910 __func__, THREAD);
911 cur_dev->use_count = 0;
912 pthread_mutex_unlock(&cur_dev->mutex);
913 if (cur_dev->bulk_reader != 0) {
914 if (verbose >= 3)
915 logmsg(LOG_NOTICE, "%s[%x]: joining bulk_reader...",
916 __func__, THREAD);
917 pthread_join(cur_dev->bulk_reader, NULL);
918 }
919 pthread_mutex_lock(&usb_mutex);
920 usbmux_free_device(cur_dev->phone);
921 pthread_mutex_unlock(&usb_mutex);
922 pthread_mutex_destroy(&cur_dev->writer_mutex);
923 pthread_mutex_destroy(&cur_dev->mutex);
924 free(cur_dev);
925 cur_dev = NULL;
926 if (device_count > 1) {
927 struct device_info **newlist;
928 int j;
929
930 newlist =
931 (struct device_info **)
932 malloc(sizeof(struct device_info *)
933 * device_count - 1);
934 for (i = 0; i < device_count; i++) {
935 if (devices[i] != NULL) {
936 newlist[j++] = devices[i];
937 }
938 }
939 free(devices);
940 devices = newlist;
941 device_count--;
942 } else {
943 free(devices);
944 devices = NULL;
945 device_count = 0;
946 }
784 } 947 }
785 free(devices);
786 devices = newlist;
787 device_count--;
788 } else {
789 free(devices);
790 devices = NULL;
791 device_count = 0;
792 }
793 } 948 }
794 } 949 pthread_mutex_unlock(&usbmux_mutex);
795 pthread_mutex_unlock(&usbmux_mutex); 950
951 cdata->dead = 1;
952 close(cdata->socket);
796 953
797 cdata->dead = 1; 954 if (verbose >= 3)
798 close(cdata->socket); 955 logmsg(LOG_NOTICE, "%s[%x]: terminated", __func__, THREAD);
799
800 if (verbose >= 3) logmsg(LOG_NOTICE, "%s[%x]: terminated", __func__, THREAD);
801 956
802 return NULL; 957 return NULL;
803} 958}
804 959
805/** 960/**
@@ -807,44 +962,42 @@ leave:
807 */ 962 */
808static int daemonize() 963static int daemonize()
809{ 964{
810 pid_t pid; 965 pid_t pid;
811 pid_t sid; 966 pid_t sid;
812 967
813 // already a daemon 968 // already a daemon
814 if (getppid() == 1) return 0; 969 if (getppid() == 1)
970 return 0;
815 971
816 pid = fork(); 972 pid = fork();
817 if (pid < 0) { 973 if (pid < 0) {
818 exit(EXIT_FAILURE); 974 exit(EXIT_FAILURE);
819 } 975 }
820
821 if (pid > 0) {
822 // exit parent process
823 exit(EXIT_SUCCESS);
824 }
825
826 // At this point we are executing as the child process
827
828 // Change the file mode mask
829 umask(0);
830 976
831 // Create a new SID for the child process 977 if (pid > 0) {
832 sid = setsid(); 978 // exit parent process
833 if (sid < 0) { 979 exit(EXIT_SUCCESS);
834 return -1; 980 }
835 } 981 // At this point we are executing as the child process
836 982
837 // Change the current working directory. 983 // Change the file mode mask
838 if ((chdir("/")) < 0) { 984 umask(0);
839 return -2;
840 }
841 985
842 // Redirect standard files to /dev/null 986 // Create a new SID for the child process
843 freopen("/dev/null", "r", stdin); 987 sid = setsid();
844 freopen("/dev/null", "w", stdout); 988 if (sid < 0) {
845 freopen("/dev/null", "w", stderr); 989 return -1;
990 }
991 // Change the current working directory.
992 if ((chdir("/")) < 0) {
993 return -2;
994 }
995 // Redirect standard files to /dev/null
996 freopen("/dev/null", "r", stdin);
997 freopen("/dev/null", "w", stdout);
998 freopen("/dev/null", "w", stderr);
846 999
847 return 0; 1000 return 0;
848} 1001}
849 1002
850/** 1003/**
@@ -852,56 +1005,57 @@ static int daemonize()
852 */ 1005 */
853static void clean_exit(int sig) 1006static void clean_exit(int sig)
854{ 1007{
855 if (sig == SIGINT) { 1008 if (sig == SIGINT) {
856 if (verbose >= 1) fprintf(stderr, "CTRL+C pressed\n"); 1009 if (verbose >= 1)
857 } 1010 fprintf(stderr, "CTRL+C pressed\n");
858 quit_flag = 1; 1011 }
1012 quit_flag = 1;
859} 1013}
860 1014
861static void usage() 1015static void usage()
862{ 1016{
863 printf("usage: usbmuxd [options]\n"); 1017 printf("usage: usbmuxd [options]\n");
864 printf("\t-h|--help print this message.\n"); 1018 printf("\t-h|--help print this message.\n");
865 printf("\t-v|--verbose be verbose\n"); 1019 printf("\t-v|--verbose be verbose\n");
866 printf("\t-f|--foreground do not daemonize\n"); 1020 printf("\t-f|--foreground do not daemonize\n");
867 printf("\n"); 1021 printf("\n");
868} 1022}
869 1023
870static void parse_opts(int argc, char **argv) 1024static void parse_opts(int argc, char **argv)
871{ 1025{
872 static struct option longopts[] = { 1026 static struct option longopts[] = {
873 { "help", 0, NULL, 'h' }, 1027 {"help", 0, NULL, 'h'},
874 { "foreground", 0, NULL, 'f' }, 1028 {"foreground", 0, NULL, 'f'},
875 { "verbose", 0, NULL, 'v' }, 1029 {"verbose", 0, NULL, 'v'},
876 { "exit-on-no-devices", 0, NULL, 'e' }, 1030 {"exit-on-no-devices", 0, NULL, 'e'},
877 { NULL, 0, NULL, 0} 1031 {NULL, 0, NULL, 0}
878 }; 1032 };
879 int c; 1033 int c;
880 1034
881 while (1) { 1035 while (1) {
882 c = getopt_long(argc, argv, "hfve", longopts, (int *) 0); 1036 c = getopt_long(argc, argv, "hfve", longopts, (int *) 0);
883 if (c == -1) { 1037 if (c == -1) {
884 break; 1038 break;
885 } 1039 }
886 1040
887 switch (c) { 1041 switch (c) {
888 case 'h': 1042 case 'h':
889 usage(); 1043 usage();
890 exit(0); 1044 exit(0);
891 case 'f': 1045 case 'f':
892 foreground = 1; 1046 foreground = 1;
893 break; 1047 break;
894 case 'v': 1048 case 'v':
895 sock_stuff_set_verbose(++verbose); 1049 sock_stuff_set_verbose(++verbose);
896 break; 1050 break;
897 case 'e': 1051 case 'e':
898 exit_on_no_devices = 1; 1052 exit_on_no_devices = 1;
899 break; 1053 break;
900 default: 1054 default:
901 usage(); 1055 usage();
902 exit(2); 1056 exit(2);
1057 }
903 } 1058 }
904 }
905} 1059}
906 1060
907/** 1061/**
@@ -911,26 +1065,25 @@ static void parse_opts(int argc, char **argv)
911 */ 1065 */
912static int devices_attached() 1066static int devices_attached()
913{ 1067{
914 struct usb_bus *bus; 1068 struct usb_bus *bus;
915 struct usb_device *dev; 1069 struct usb_device *dev;
916 int res = 0; 1070 int res = 0;
917 1071
918 usb_init(); 1072 usb_init();
919 usb_find_busses(); 1073 usb_find_busses();
920 usb_find_devices(); 1074 usb_find_devices();
921 1075
922 for (bus = usb_get_busses(); bus; bus = bus->next) { 1076 for (bus = usb_get_busses(); bus; bus = bus->next) {
923 for (dev = bus->devices; dev; dev = dev->next) { 1077 for (dev = bus->devices; dev; dev = dev->next) {
924 if (dev->descriptor.idVendor == 0x05ac 1078 if (dev->descriptor.idVendor == 0x05ac
925 && dev->descriptor.idProduct >= 0x1290 1079 && dev->descriptor.idProduct >= 0x1290
926 && dev->descriptor.idProduct <= 0x1293) 1080 && dev->descriptor.idProduct <= 0x1293) {
927 { 1081 res++;
928 res++; 1082 }
929 } 1083 }
930 } 1084 }
931 }
932 1085
933 return res; 1086 return res;
934} 1087}
935 1088
936/** 1089/**
@@ -938,233 +1091,261 @@ static int devices_attached()
938 */ 1091 */
939int main(int argc, char **argv) 1092int main(int argc, char **argv)
940{ 1093{
941 struct sockaddr_un c_addr; 1094 struct sockaddr_un c_addr;
942 socklen_t len = sizeof(struct sockaddr_un); 1095 socklen_t len = sizeof(struct sockaddr_un);
943 struct client_data *cdata = NULL; 1096 struct client_data *cdata = NULL;
944 struct client_data **children = NULL; 1097 struct client_data **children = NULL;
945 int children_capacity = DEFAULT_CHILDREN_CAPACITY; 1098 int children_capacity = DEFAULT_CHILDREN_CAPACITY;
946 int i; 1099 int i;
947 int result = 0; 1100 int result = 0;
948 int cnt = 0; 1101 int cnt = 0;
949 FILE *lfd = NULL; 1102 FILE *lfd = NULL;
950 struct flock lock; 1103 struct flock lock;
951 1104
952 parse_opts(argc, argv); 1105 parse_opts(argc, argv);
953 1106
954 argc -= optind; 1107 argc -= optind;
955 argv += optind; 1108 argv += optind;
956 1109
957 if (!foreground) { 1110 if (!foreground) {
958 openlog("usbmuxd", LOG_PID, 0); 1111 openlog("usbmuxd", LOG_PID, 0);
959 }
960
961 if (verbose >= 2) logmsg(LOG_NOTICE, "starting");
962
963 // signal(SIGHUP, reload_conf); // none yet
964 signal(SIGINT, clean_exit);
965 signal(SIGQUIT, clean_exit);
966 signal(SIGTERM, clean_exit);
967 signal(SIGPIPE, SIG_IGN);
968
969 // check for other running instance
970 lfd = fopen(LOCKFILE, "r");
971 if (lfd) {
972 lock.l_type = 0;
973 lock.l_whence = SEEK_SET;
974 lock.l_start = 0;
975 lock.l_len = 0;
976 fcntl(fileno(lfd), F_GETLK, &lock);
977 fclose(lfd);
978 if (lock.l_type != F_UNLCK) {
979 logmsg(LOG_NOTICE, "another instance is already running. exiting.");
980 return -1;
981 } 1112 }
982 }
983 1113
984 if (exit_on_no_devices) { 1114 if (verbose >= 2)
985 if (devices_attached() <= 0) { 1115 logmsg(LOG_NOTICE, "starting");
986 logmsg(LOG_NOTICE, "no devices attached. exiting."); 1116
987 return 0; 1117 // signal(SIGHUP, reload_conf); // none yet
1118 signal(SIGINT, clean_exit);
1119 signal(SIGQUIT, clean_exit);
1120 signal(SIGTERM, clean_exit);
1121 signal(SIGPIPE, SIG_IGN);
1122
1123 // check for other running instance
1124 lfd = fopen(LOCKFILE, "r");
1125 if (lfd) {
1126 lock.l_type = 0;
1127 lock.l_whence = SEEK_SET;
1128 lock.l_start = 0;
1129 lock.l_len = 0;
1130 fcntl(fileno(lfd), F_GETLK, &lock);
1131 fclose(lfd);
1132 if (lock.l_type != F_UNLCK) {
1133 logmsg(LOG_NOTICE,
1134 "another instance is already running. exiting.");
1135 return -1;
1136 }
988 } 1137 }
989 }
990 1138
991 fsock = create_unix_socket(USBMUXD_SOCKET_FILE); 1139 if (exit_on_no_devices) {
992 if (fsock < 0) { 1140 if (devices_attached() <= 0) {
993 logmsg(LOG_ERR, "Could not create socket, exiting"); 1141 logmsg(LOG_NOTICE, "no devices attached. exiting.");
994 if (!foreground) { 1142 return 0;
995 closelog(); 1143 }
996 } 1144 }
997 return -1;
998 }
999 1145
1000 chmod(USBMUXD_SOCKET_FILE, 0666); 1146 fsock = create_unix_socket(USBMUXD_SOCKET_FILE);
1147 if (fsock < 0) {
1148 logmsg(LOG_ERR, "Could not create socket, exiting");
1149 if (!foreground) {
1150 closelog();
1151 }
1152 return -1;
1153 }
1001 1154
1002 if (verbose >= 3) usbmux_set_debug(1); 1155 chmod(USBMUXD_SOCKET_FILE, 0666);
1003 1156
1004 if (!foreground) { 1157 if (verbose >= 3)
1005 if (daemonize() < 0) { 1158 usbmux_set_debug(1);
1006 fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n");
1007 syslog(LOG_ERR, "FATAL: Could not daemonize!");
1008 closelog();
1009 exit(EXIT_FAILURE);
1010 }
1011 }
1012
1013 // now open the lockfile and place the lock
1014 lfd = fopen(LOCKFILE, "w");
1015 if (lfd) {
1016 lock.l_type = F_WRLCK;
1017 lock.l_whence = SEEK_SET;
1018 lock.l_start = 0;
1019 lock.l_len = 0;
1020 if (fcntl(fileno(lfd), F_SETLK, &lock) == -1) {
1021 logmsg(LOG_ERR, "ERROR: lockfile locking failed!");
1022 }
1023 }
1024 1159
1025 // drop elevated privileges 1160 if (!foreground) {
1026 if (getuid() == 0 || geteuid() == 0) { 1161 if (daemonize() < 0) {
1027 struct passwd *pw = getpwnam("nobody"); 1162 fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n");
1028 if (pw) { 1163 syslog(LOG_ERR, "FATAL: Could not daemonize!");
1029 setuid(pw->pw_uid); 1164 closelog();
1030 } else { 1165 exit(EXIT_FAILURE);
1031 logmsg(LOG_ERR, "ERROR: Dropping privileges failed, check if user 'nobody' exists! Will now terminate."); 1166 }
1032 exit(EXIT_FAILURE);
1033 } 1167 }
1168 // now open the lockfile and place the lock
1169 lfd = fopen(LOCKFILE, "w");
1170 if (lfd) {
1171 lock.l_type = F_WRLCK;
1172 lock.l_whence = SEEK_SET;
1173 lock.l_start = 0;
1174 lock.l_len = 0;
1175 if (fcntl(fileno(lfd), F_SETLK, &lock) == -1) {
1176 logmsg(LOG_ERR, "ERROR: lockfile locking failed!");
1177 }
1178 }
1179 // drop elevated privileges
1180 if (getuid() == 0 || geteuid() == 0) {
1181 struct passwd *pw = getpwnam("nobody");
1182 if (pw) {
1183 setuid(pw->pw_uid);
1184 } else {
1185 logmsg(LOG_ERR,
1186 "ERROR: Dropping privileges failed, check if user 'nobody' exists! Will now terminate.");
1187 exit(EXIT_FAILURE);
1188 }
1034 1189
1035 // security check 1190 // security check
1036 if (setuid(0) != -1) { 1191 if (setuid(0) != -1) {
1037 logmsg(LOG_ERR, "ERROR: Failed to drop privileges properly!"); 1192 logmsg(LOG_ERR, "ERROR: Failed to drop privileges properly!");
1038 exit(EXIT_FAILURE); 1193 exit(EXIT_FAILURE);
1194 }
1195 if (verbose >= 2)
1196 logmsg(LOG_NOTICE, "Successfully dropped privileges");
1039 } 1197 }
1040 if (verbose >= 2) logmsg(LOG_NOTICE, "Successfully dropped privileges"); 1198 // Reserve space for 10 clients which should be enough. If not, the
1041 } 1199 // buffer gets enlarged later.
1042 1200 children =
1043 // Reserve space for 10 clients which should be enough. If not, the 1201 (struct client_data **) malloc(sizeof(struct client_data *) *
1044 // buffer gets enlarged later. 1202 children_capacity);
1045 children = (struct client_data**)malloc(sizeof(struct client_data*) * children_capacity); 1203 if (!children) {
1046 if (!children) { 1204 logmsg(LOG_ERR,
1047 logmsg(LOG_ERR, "Out of memory when allocating memory for child threads. Terminating."); 1205 "Out of memory when allocating memory for child threads. Terminating.");
1048 if (!foreground) { 1206 if (!foreground) {
1049 closelog(); 1207 closelog();
1208 }
1209 exit(EXIT_FAILURE);
1050 } 1210 }
1051 exit(EXIT_FAILURE); 1211 memset(children, 0, sizeof(struct client_data *) * children_capacity);
1052 } 1212
1053 memset(children, 0, sizeof(struct client_data*) * children_capacity); 1213 if (verbose >= 2)
1054 1214 logmsg(LOG_NOTICE, "waiting for connection");
1055 if (verbose >= 2) logmsg(LOG_NOTICE, "waiting for connection"); 1215 while (!quit_flag) {
1056 while (!quit_flag) { 1216 // Check the file descriptor before accepting a connection.
1057 // Check the file descriptor before accepting a connection. 1217 // If no connection attempt is made, just repeat...
1058 // If no connection attempt is made, just repeat... 1218 result = check_fd(fsock, FD_READ, 1000);
1059 result = check_fd(fsock, FD_READ, 1000); 1219 if (result <= 0) {
1060 if (result <= 0) { 1220 if (result == 0) {
1061 if (result == 0) { 1221 // cleanup
1062 // cleanup 1222 for (i = 0; i < children_capacity; i++) {
1063 for (i = 0; i < children_capacity; i++) { 1223 if (children[i]) {
1064 if (children[i]) { 1224 if (children[i]->dead != 0) {
1065 if (children[i]->dead != 0) { 1225 pthread_join(children[i]->thread, NULL);
1066 pthread_join(children[i]->thread, NULL); 1226 if (verbose >= 3)
1067 if (verbose >= 3) logmsg(LOG_NOTICE, "reclaimed client thread (fd=%d)", children[i]->socket); 1227 logmsg(LOG_NOTICE,
1068 free(children[i]); 1228 "reclaimed client thread (fd=%d)",
1069 children[i] = NULL; 1229 children[i]->socket);
1070 cnt++; 1230 free(children[i]);
1231 children[i] = NULL;
1232 cnt++;
1233 } else {
1234 cnt = 0;
1235 }
1236 } else {
1237 cnt++;
1238 }
1239 }
1240
1241 if ((children_capacity > DEFAULT_CHILDREN_CAPACITY)
1242 && ((children_capacity - cnt) <=
1243 DEFAULT_CHILDREN_CAPACITY)) {
1244 children_capacity = DEFAULT_CHILDREN_CAPACITY;
1245 children =
1246 realloc(children,
1247 sizeof(struct client_data *) *
1248 children_capacity);
1249 }
1250 continue;
1071 } else { 1251 } else {
1072 cnt = 0; 1252 if (verbose >= 3)
1253 logmsg(LOG_ERR, "usbmuxd: select error: %s",
1254 strerror(errno));
1255 continue;
1073 } 1256 }
1074 } else {
1075 cnt++;
1076 }
1077 } 1257 }
1078 1258
1079 if ((children_capacity > DEFAULT_CHILDREN_CAPACITY) 1259 cdata = (struct client_data *) malloc(sizeof(struct client_data));
1080 && ((children_capacity - cnt) <= DEFAULT_CHILDREN_CAPACITY)) { 1260 memset(cdata, 0, sizeof(struct client_data));
1081 children_capacity = DEFAULT_CHILDREN_CAPACITY; 1261 if (!cdata) {
1082 children = realloc(children, sizeof(struct client_data*) * children_capacity); 1262 quit_flag = 1;
1263 logmsg(LOG_ERR, "Error: Out of memory! Terminating.");
1264 break;
1083 } 1265 }
1084 continue;
1085 } else {
1086 if (verbose >= 3) logmsg(LOG_ERR, "usbmuxd: select error: %s", strerror(errno));
1087 continue;
1088 }
1089 }
1090 1266
1091 cdata = (struct client_data*)malloc(sizeof(struct client_data)); 1267 cdata->socket = accept(fsock, (struct sockaddr *) &c_addr, &len);
1092 memset(cdata, 0, sizeof(struct client_data)); 1268 if (cdata->socket < 0) {
1093 if (!cdata) { 1269 free(cdata);
1094 quit_flag = 1; 1270 if (errno == EINTR) {
1095 logmsg(LOG_ERR, "Error: Out of memory! Terminating."); 1271 continue;
1096 break; 1272 } else {
1097 } 1273 if (verbose >= 3)
1098 1274 logmsg(LOG_ERR, "Error in accept: %s",
1099 cdata->socket = accept(fsock, (struct sockaddr*)&c_addr, &len); 1275 strerror(errno));
1100 if (cdata->socket < 0) { 1276 continue;
1101 free(cdata); 1277 }
1102 if (errno == EINTR) { 1278 }
1103 continue;
1104 } else {
1105 if (verbose >= 3) logmsg(LOG_ERR, "Error in accept: %s", strerror(errno));
1106 continue;
1107 }
1108 }
1109 1279
1110 if (verbose >= 1) logmsg(LOG_NOTICE, "new client connected (fd=%d)", cdata->socket); 1280 if (verbose >= 1)
1111 1281 logmsg(LOG_NOTICE, "new client connected (fd=%d)",
1112 // create client thread: 1282 cdata->socket);
1113 if (pthread_create(&cdata->thread, NULL, usbmuxd_client_init_thread, cdata) == 0) { 1283
1114 for (i = 0; i < children_capacity; i++) { 1284 // create client thread:
1115 if (children[i] == NULL) break; 1285 if (pthread_create
1116 } 1286 (&cdata->thread, NULL, usbmuxd_client_init_thread, cdata) == 0)
1117 if (i == children_capacity) { 1287 {
1118 // enlarge buffer 1288 for (i = 0; i < children_capacity; i++) {
1119 children_capacity++; 1289 if (children[i] == NULL)
1120 children = realloc(children, sizeof(struct client_data*) * children_capacity); 1290 break;
1121 if (!children) { 1291 }
1122 logmsg(LOG_ERR, "Out of memory when enlarging child thread buffer"); 1292 if (i == children_capacity) {
1293 // enlarge buffer
1294 children_capacity++;
1295 children =
1296 realloc(children,
1297 sizeof(struct client_data *) *
1298 children_capacity);
1299 if (!children) {
1300 logmsg(LOG_ERR,
1301 "Out of memory when enlarging child thread buffer");
1302 }
1303 }
1304 children[i] = cdata;
1305 } else {
1306 logmsg(LOG_ERR, "Failed to create client_init_thread.");
1307 close(cdata->socket);
1308 free(cdata);
1309 cdata = NULL;
1123 } 1310 }
1124 }
1125 children[i] = cdata;
1126 } else {
1127 logmsg(LOG_ERR, "Failed to create client_init_thread.");
1128 close(cdata->socket);
1129 free(cdata);
1130 cdata = NULL;
1131 } 1311 }
1132 }
1133 1312
1134 if (verbose >= 3) logmsg(LOG_NOTICE, "terminating"); 1313 if (verbose >= 3)
1314 logmsg(LOG_NOTICE, "terminating");
1135 1315
1136 // preparing for shutdown: wait for child threads to terminate (if any) 1316 // preparing for shutdown: wait for child threads to terminate (if any)
1137 if (verbose >= 2) logmsg(LOG_NOTICE, "waiting for child threads to terminate..."); 1317 if (verbose >= 2)
1138 for (i = 0; i < children_capacity; i++) { 1318 logmsg(LOG_NOTICE, "waiting for child threads to terminate...");
1139 if (children[i] != NULL) { 1319 for (i = 0; i < children_capacity; i++) {
1140 pthread_join(children[i]->thread, NULL); 1320 if (children[i] != NULL) {
1141 free(children[i]); 1321 pthread_join(children[i]->thread, NULL);
1142 } 1322 free(children[i]);
1143 } 1323 }
1324 }
1144 1325
1145 // delete the children set. 1326 // delete the children set.
1146 free(children); 1327 free(children);
1147 children = NULL; 1328 children = NULL;
1148 1329
1149 1330
1150 if (fsock >= 0) { 1331 if (fsock >= 0) {
1151 close(fsock); 1332 close(fsock);
1152 } 1333 }
1153 1334
1154 unlink(USBMUXD_SOCKET_FILE); 1335 unlink(USBMUXD_SOCKET_FILE);
1155 1336
1156 // unlock lock file and close it. 1337 // unlock lock file and close it.
1157 if (lfd) { 1338 if (lfd) {
1158 lock.l_type = F_UNLCK; 1339 lock.l_type = F_UNLCK;
1159 fcntl(fileno(lfd), F_SETLK, &lock); 1340 fcntl(fileno(lfd), F_SETLK, &lock);
1160 fclose(lfd); 1341 fclose(lfd);
1161 } 1342 }
1162 1343
1163 if (verbose >= 1) logmsg(LOG_NOTICE, "usbmuxd: terminated"); 1344 if (verbose >= 1)
1164 if (!foreground) { 1345 logmsg(LOG_NOTICE, "usbmuxd: terminated");
1165 closelog(); 1346 if (!foreground) {
1166 } 1347 closelog();
1348 }
1167 1349
1168 return 0; 1350 return 0;
1169} 1351}
1170