blob: d1f05e413d3fb526f3fbf2eb988d84d1e611e67a [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define TRACE_TAG TRACE_ADB
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <ctype.h>
22#include <stdarg.h>
23#include <errno.h>
Scott Andersona40781d2012-05-25 13:55:46 -070024#include <stddef.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080025#include <string.h>
26#include <time.h>
Mike Lockwood4ac1e282009-05-25 18:17:55 -040027#include <sys/time.h>
Ray Donnellydccbca22012-11-29 01:36:08 +000028#include <stdint.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080029
30#include "sysdeps.h"
31#include "adb.h"
Benoit Goby2cc19e42012-04-12 12:23:49 -070032#include "adb_auth.h"
Dan Albert020292b2015-02-18 18:03:26 -080033#include "adb_listeners.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080034
Scott Andersonfa020922012-05-25 14:10:02 -070035#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
36
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080037#if !ADB_HOST
Nick Kralevich7472d292013-05-23 09:54:13 -070038#include <cutils/properties.h>
Nick Kralevich9de01bd2013-02-28 14:12:58 -080039#include <sys/capability.h>
Jeff Sharkey11987252012-08-14 21:00:22 -070040#include <sys/mount.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080041#endif
42
JP Abgrall2e5dd6e2011-03-16 15:57:42 -070043#if ADB_TRACE
44ADB_MUTEX_DEFINE( D_lock );
45#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080046
47int HOST = 0;
48
Scott Andersonfa020922012-05-25 14:10:02 -070049#if !ADB_HOST
Dan Albert432ffe22015-02-18 18:22:45 -080050const char *adb_device_banner = "device";
Scott Andersonfa020922012-05-25 14:10:02 -070051#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080052
53void fatal(const char *fmt, ...)
54{
55 va_list ap;
56 va_start(ap, fmt);
57 fprintf(stderr, "error: ");
58 vfprintf(stderr, fmt, ap);
59 fprintf(stderr, "\n");
60 va_end(ap);
61 exit(-1);
62}
63
64void fatal_errno(const char *fmt, ...)
65{
66 va_list ap;
67 va_start(ap, fmt);
68 fprintf(stderr, "error: %s: ", strerror(errno));
69 vfprintf(stderr, fmt, ap);
70 fprintf(stderr, "\n");
71 va_end(ap);
72 exit(-1);
73}
74
75int adb_trace_mask;
76
77/* read a comma/space/colum/semi-column separated list of tags
78 * from the ADB_TRACE environment variable and build the trace
79 * mask from it. note that '1' and 'all' are special cases to
80 * enable all tracing
81 */
82void adb_trace_init(void)
83{
84 const char* p = getenv("ADB_TRACE");
85 const char* q;
86
87 static const struct {
88 const char* tag;
89 int flag;
90 } tags[] = {
91 { "1", 0 },
92 { "all", 0 },
93 { "adb", TRACE_ADB },
94 { "sockets", TRACE_SOCKETS },
95 { "packets", TRACE_PACKETS },
96 { "rwx", TRACE_RWX },
97 { "usb", TRACE_USB },
98 { "sync", TRACE_SYNC },
99 { "sysdeps", TRACE_SYSDEPS },
100 { "transport", TRACE_TRANSPORT },
101 { "jdwp", TRACE_JDWP },
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700102 { "services", TRACE_SERVICES },
Benoit Goby2cc19e42012-04-12 12:23:49 -0700103 { "auth", TRACE_AUTH },
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800104 { NULL, 0 }
105 };
106
107 if (p == NULL)
108 return;
109
110 /* use a comma/column/semi-colum/space separated list */
111 while (*p) {
112 int len, tagn;
113
114 q = strpbrk(p, " ,:;");
115 if (q == NULL) {
116 q = p + strlen(p);
117 }
118 len = q - p;
119
120 for (tagn = 0; tags[tagn].tag != NULL; tagn++)
121 {
122 int taglen = strlen(tags[tagn].tag);
123
124 if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
125 {
126 int flag = tags[tagn].flag;
127 if (flag == 0) {
128 adb_trace_mask = ~0;
129 return;
130 }
131 adb_trace_mask |= (1 << flag);
132 break;
133 }
134 }
135 p = q;
136 if (*p)
137 p++;
138 }
139}
140
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800141apacket *get_apacket(void)
142{
143 apacket *p = malloc(sizeof(apacket));
144 if(p == 0) fatal("failed to allocate an apacket");
145 memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
146 return p;
147}
148
149void put_apacket(apacket *p)
150{
151 free(p);
152}
153
Benoit Goby2cc19e42012-04-12 12:23:49 -0700154void handle_online(atransport *t)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800155{
156 D("adb: online\n");
Benoit Goby2cc19e42012-04-12 12:23:49 -0700157 t->online = 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800158}
159
160void handle_offline(atransport *t)
161{
162 D("adb: offline\n");
163 //Close the associated usb
Benoit Goby2cc19e42012-04-12 12:23:49 -0700164 t->online = 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800165 run_transport_disconnects(t);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800166}
167
Benoit Goby2cc19e42012-04-12 12:23:49 -0700168#if DEBUG_PACKETS
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800169#define DUMPMAX 32
170void print_packet(const char *label, apacket *p)
171{
172 char *tag;
173 char *x;
174 unsigned count;
175
176 switch(p->msg.command){
177 case A_SYNC: tag = "SYNC"; break;
178 case A_CNXN: tag = "CNXN" ; break;
179 case A_OPEN: tag = "OPEN"; break;
180 case A_OKAY: tag = "OKAY"; break;
181 case A_CLSE: tag = "CLSE"; break;
182 case A_WRTE: tag = "WRTE"; break;
Benoit Goby2cc19e42012-04-12 12:23:49 -0700183 case A_AUTH: tag = "AUTH"; break;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800184 default: tag = "????"; break;
185 }
186
187 fprintf(stderr, "%s: %s %08x %08x %04x \"",
188 label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
189 count = p->msg.data_length;
190 x = (char*) p->data;
191 if(count > DUMPMAX) {
192 count = DUMPMAX;
193 tag = "\n";
194 } else {
195 tag = "\"\n";
196 }
197 while(count-- > 0){
198 if((*x >= ' ') && (*x < 127)) {
199 fputc(*x, stderr);
200 } else {
201 fputc('.', stderr);
202 }
203 x++;
204 }
Benoit Goby2cc19e42012-04-12 12:23:49 -0700205 fputs(tag, stderr);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800206}
207#endif
208
209static void send_ready(unsigned local, unsigned remote, atransport *t)
210{
211 D("Calling send_ready \n");
212 apacket *p = get_apacket();
213 p->msg.command = A_OKAY;
214 p->msg.arg0 = local;
215 p->msg.arg1 = remote;
216 send_packet(p, t);
217}
218
219static void send_close(unsigned local, unsigned remote, atransport *t)
220{
221 D("Calling send_close \n");
222 apacket *p = get_apacket();
223 p->msg.command = A_CLSE;
224 p->msg.arg0 = local;
225 p->msg.arg1 = remote;
226 send_packet(p, t);
227}
228
Scott Andersonfa020922012-05-25 14:10:02 -0700229static size_t fill_connect_data(char *buf, size_t bufsize)
230{
231#if ADB_HOST
232 return snprintf(buf, bufsize, "host::") + 1;
233#else
234 static const char *cnxn_props[] = {
235 "ro.product.name",
236 "ro.product.model",
237 "ro.product.device",
238 };
239 static const int num_cnxn_props = ARRAY_SIZE(cnxn_props);
240 int i;
241 size_t remaining = bufsize;
242 size_t len;
243
244 len = snprintf(buf, remaining, "%s::", adb_device_banner);
245 remaining -= len;
246 buf += len;
247 for (i = 0; i < num_cnxn_props; i++) {
248 char value[PROPERTY_VALUE_MAX];
249 property_get(cnxn_props[i], value, "");
250 len = snprintf(buf, remaining, "%s=%s;", cnxn_props[i], value);
251 remaining -= len;
252 buf += len;
253 }
254
255 return bufsize - remaining + 1;
256#endif
257}
258
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100259#if !ADB_HOST
260static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
261 char header[5];
262 if (msglen > 0xffff)
263 msglen = 0xffff;
264 snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
265 writex(fd, header, 4);
266 writex(fd, msg, msglen);
267}
268#endif
269
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700270#if ADB_HOST
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100271static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
Snild Dolkow4516a872014-01-30 10:08:38 +0100272 char header[9];
273 if (msglen > 0xffff)
274 msglen = 0xffff;
275 snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen);
276 writex(fd, header, 8);
277 writex(fd, msg, msglen);
278}
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700279#endif // ADB_HOST
Snild Dolkow4516a872014-01-30 10:08:38 +0100280
Dan Albert056ad0e2015-02-18 17:47:33 -0800281void send_connect(atransport *t)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800282{
283 D("Calling send_connect \n");
284 apacket *cp = get_apacket();
285 cp->msg.command = A_CNXN;
286 cp->msg.arg0 = A_VERSION;
287 cp->msg.arg1 = MAX_PAYLOAD;
Scott Andersonfa020922012-05-25 14:10:02 -0700288 cp->msg.data_length = fill_connect_data((char *)cp->data,
289 sizeof(cp->data));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800290 send_packet(cp, t);
Benoit Goby2cc19e42012-04-12 12:23:49 -0700291}
292
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700293#if ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800294static char *connection_state_name(atransport *t)
295{
296 if (t == NULL) {
297 return "unknown";
298 }
299
300 switch(t->connection_state) {
301 case CS_BOOTLOADER:
302 return "bootloader";
303 case CS_DEVICE:
304 return "device";
trevdd11cfc52013-04-17 14:34:23 +0100305 case CS_RECOVERY:
306 return "recovery";
307 case CS_SIDELOAD:
308 return "sideload";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800309 case CS_OFFLINE:
310 return "offline";
Nick Kralevich23b39f02013-02-15 10:22:08 -0800311 case CS_UNAUTHORIZED:
312 return "unauthorized";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800313 default:
314 return "unknown";
315 }
316}
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700317#endif // ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800318
Scott Andersonfa020922012-05-25 14:10:02 -0700319/* qual_overwrite is used to overwrite a qualifier string. dst is a
320 * pointer to a char pointer. It is assumed that if *dst is non-NULL, it
Scott Anderson27042382012-05-30 18:11:27 -0700321 * was malloc'ed and needs to freed. *dst will be set to a dup of src.
Scott Andersonfa020922012-05-25 14:10:02 -0700322 */
323static void qual_overwrite(char **dst, const char *src)
324{
325 if (!dst)
326 return;
327
328 free(*dst);
329 *dst = NULL;
330
331 if (!src || !*src)
332 return;
333
334 *dst = strdup(src);
335}
336
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800337void parse_banner(char *banner, atransport *t)
338{
Scott Andersonfa020922012-05-25 14:10:02 -0700339 static const char *prop_seps = ";";
340 static const char key_val_sep = '=';
Scott Anderson27042382012-05-30 18:11:27 -0700341 char *cp;
342 char *type;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800343
344 D("parse_banner: %s\n", banner);
345 type = banner;
Scott Andersonfa020922012-05-25 14:10:02 -0700346 cp = strchr(type, ':');
347 if (cp) {
348 *cp++ = 0;
349 /* Nothing is done with second field. */
350 cp = strchr(cp, ':');
351 if (cp) {
352 char *save;
353 char *key;
Scott Anderson0fa59782012-06-05 17:54:27 -0700354 key = adb_strtok_r(cp + 1, prop_seps, &save);
Scott Andersonfa020922012-05-25 14:10:02 -0700355 while (key) {
356 cp = strchr(key, key_val_sep);
357 if (cp) {
358 *cp++ = '\0';
359 if (!strcmp(key, "ro.product.name"))
360 qual_overwrite(&t->product, cp);
361 else if (!strcmp(key, "ro.product.model"))
362 qual_overwrite(&t->model, cp);
363 else if (!strcmp(key, "ro.product.device"))
364 qual_overwrite(&t->device, cp);
365 }
Scott Anderson0fa59782012-06-05 17:54:27 -0700366 key = adb_strtok_r(NULL, prop_seps, &save);
Scott Andersonfa020922012-05-25 14:10:02 -0700367 }
368 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800369 }
370
371 if(!strcmp(type, "bootloader")){
372 D("setting connection_state to CS_BOOTLOADER\n");
373 t->connection_state = CS_BOOTLOADER;
374 update_transports();
375 return;
376 }
377
378 if(!strcmp(type, "device")) {
379 D("setting connection_state to CS_DEVICE\n");
380 t->connection_state = CS_DEVICE;
381 update_transports();
382 return;
383 }
384
385 if(!strcmp(type, "recovery")) {
386 D("setting connection_state to CS_RECOVERY\n");
387 t->connection_state = CS_RECOVERY;
388 update_transports();
389 return;
390 }
391
Doug Zongker6b217ed2012-01-09 14:54:53 -0800392 if(!strcmp(type, "sideload")) {
393 D("setting connection_state to CS_SIDELOAD\n");
394 t->connection_state = CS_SIDELOAD;
395 update_transports();
396 return;
397 }
398
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800399 t->connection_state = CS_HOST;
400}
401
402void handle_packet(apacket *p, atransport *t)
403{
404 asocket *s;
405
Viral Mehta841f9a72010-06-16 18:41:28 +0530406 D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
407 ((char*) (&(p->msg.command)))[1],
408 ((char*) (&(p->msg.command)))[2],
409 ((char*) (&(p->msg.command)))[3]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800410 print_packet("recv", p);
411
412 switch(p->msg.command){
413 case A_SYNC:
414 if(p->msg.arg0){
415 send_packet(p, t);
416 if(HOST) send_connect(t);
417 } else {
418 t->connection_state = CS_OFFLINE;
419 handle_offline(t);
420 send_packet(p, t);
421 }
422 return;
423
424 case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
425 /* XXX verify version, etc */
426 if(t->connection_state != CS_OFFLINE) {
427 t->connection_state = CS_OFFLINE;
428 handle_offline(t);
429 }
Benoit Goby2cc19e42012-04-12 12:23:49 -0700430
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800431 parse_banner((char*) p->data, t);
Benoit Goby2cc19e42012-04-12 12:23:49 -0700432
433 if (HOST || !auth_enabled) {
434 handle_online(t);
435 if(!HOST) send_connect(t);
436 } else {
437 send_auth_request(t);
438 }
439 break;
440
441 case A_AUTH:
442 if (p->msg.arg0 == ADB_AUTH_TOKEN) {
Nick Kralevich23b39f02013-02-15 10:22:08 -0800443 t->connection_state = CS_UNAUTHORIZED;
Benoit Goby2cc19e42012-04-12 12:23:49 -0700444 t->key = adb_auth_nextkey(t->key);
445 if (t->key) {
446 send_auth_response(p->data, p->msg.data_length, t);
447 } else {
448 /* No more private keys to try, send the public key */
449 send_auth_publickey(t);
450 }
451 } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
452 if (adb_auth_verify(t->token, p->data, p->msg.data_length)) {
453 adb_auth_verified(t);
454 t->failed_auth_attempts = 0;
455 } else {
456 if (t->failed_auth_attempts++ > 10)
457 adb_sleep_ms(1000);
458 send_auth_request(t);
459 }
460 } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
461 adb_auth_confirm_key(p->data, p->msg.data_length, t);
462 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800463 break;
464
465 case A_OPEN: /* OPEN(local-id, 0, "destination") */
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100466 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800467 char *name = (char*) p->data;
468 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
469 s = create_local_service_socket(name);
470 if(s == 0) {
471 send_close(0, p->msg.arg0, t);
472 } else {
473 s->peer = create_remote_socket(p->msg.arg0, t);
474 s->peer->peer = s;
475 send_ready(s->id, s->peer->id, t);
476 s->ready(s);
477 }
478 }
479 break;
480
481 case A_OKAY: /* READY(local-id, remote-id, "") */
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100482 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
483 if((s = find_local_socket(p->msg.arg1, 0))) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800484 if(s->peer == 0) {
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100485 /* On first READY message, create the connection. */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800486 s->peer = create_remote_socket(p->msg.arg0, t);
487 s->peer->peer = s;
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100488 s->ready(s);
489 } else if (s->peer->id == p->msg.arg0) {
490 /* Other READY messages must use the same local-id */
491 s->ready(s);
492 } else {
493 D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s\n",
494 p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800495 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800496 }
497 }
498 break;
499
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100500 case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
501 if (t->online && p->msg.arg1 != 0) {
502 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
503 /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
504 * a failed OPEN only. However, due to a bug in previous ADB
505 * versions, CLOSE(0, remote-id, "") was also used for normal
506 * CLOSE() operations.
507 *
508 * This is bad because it means a compromised adbd could
509 * send packets to close connections between the host and
510 * other devices. To avoid this, only allow this if the local
511 * socket has a peer on the same transport.
512 */
513 if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
514 D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s\n",
515 p->msg.arg1, t->serial, s->peer->transport->serial);
516 } else {
517 s->close(s);
518 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800519 }
520 }
521 break;
522
David 'Digit' Turnere92344d2013-12-13 14:09:44 +0100523 case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
524 if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
525 if((s = find_local_socket(p->msg.arg1, p->msg.arg0))) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800526 unsigned rid = p->msg.arg0;
527 p->len = p->msg.data_length;
528
529 if(s->enqueue(s, p) == 0) {
530 D("Enqueue the socket\n");
531 send_ready(s->id, rid, t);
532 }
533 return;
534 }
535 }
536 break;
537
538 default:
539 printf("handle_packet: what is %08x?!\n", p->msg.command);
540 }
541
542 put_apacket(p);
543}
544
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800545#if ADB_HOST
Nick Kralevich23b39f02013-02-15 10:22:08 -0800546
Stefan Hilzinger92ca4fa2010-04-19 12:21:12 +0100547int launch_server(int server_port)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800548{
Yabin Cui2fa43212014-11-11 09:24:11 -0800549#if defined(_WIN32)
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800550 /* we need to start the server in the background */
551 /* we create a PIPE that will be used to wait for the server's "OK" */
552 /* message since the pipe handles must be inheritable, we use a */
553 /* security attribute */
554 HANDLE pipe_read, pipe_write;
Ray Donnellyc0324702012-11-29 01:18:50 +0000555 HANDLE stdout_handle, stderr_handle;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800556 SECURITY_ATTRIBUTES sa;
557 STARTUPINFO startup;
558 PROCESS_INFORMATION pinfo;
559 char program_path[ MAX_PATH ];
560 int ret;
561
562 sa.nLength = sizeof(sa);
563 sa.lpSecurityDescriptor = NULL;
564 sa.bInheritHandle = TRUE;
565
566 /* create pipe, and ensure its read handle isn't inheritable */
567 ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
568 if (!ret) {
569 fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
570 return -1;
571 }
572
573 SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
574
Ray Donnellyc0324702012-11-29 01:18:50 +0000575 /* Some programs want to launch an adb command and collect its output by
576 * calling CreateProcess with inheritable stdout/stderr handles, then
577 * using read() to get its output. When this happens, the stdout/stderr
578 * handles passed to the adb client process will also be inheritable.
579 * When starting the adb server here, care must be taken to reset them
580 * to non-inheritable.
581 * Otherwise, something bad happens: even if the adb command completes,
582 * the calling process is stuck while read()-ing from the stdout/stderr
583 * descriptors, because they're connected to corresponding handles in the
584 * adb server process (even if the latter never uses/writes to them).
585 */
586 stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
587 stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
588 if (stdout_handle != INVALID_HANDLE_VALUE) {
589 SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
590 }
591 if (stderr_handle != INVALID_HANDLE_VALUE) {
592 SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
593 }
594
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800595 ZeroMemory( &startup, sizeof(startup) );
596 startup.cb = sizeof(startup);
597 startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
598 startup.hStdOutput = pipe_write;
599 startup.hStdError = GetStdHandle( STD_ERROR_HANDLE );
600 startup.dwFlags = STARTF_USESTDHANDLES;
601
602 ZeroMemory( &pinfo, sizeof(pinfo) );
603
604 /* get path of current program */
605 GetModuleFileName( NULL, program_path, sizeof(program_path) );
Wenhao Lie0fa2c52013-11-13 16:23:37 +0800606 char args[64];
607 snprintf(args, sizeof(args), "adb -P %d fork-server server", server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800608 ret = CreateProcess(
609 program_path, /* program path */
Wenhao Lie0fa2c52013-11-13 16:23:37 +0800610 args,
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800611 /* the fork-server argument will set the
612 debug = 2 in the child */
613 NULL, /* process handle is not inheritable */
614 NULL, /* thread handle is not inheritable */
615 TRUE, /* yes, inherit some handles */
616 DETACHED_PROCESS, /* the new process doesn't have a console */
617 NULL, /* use parent's environment block */
618 NULL, /* use parent's starting directory */
619 &startup, /* startup info, i.e. std handles */
620 &pinfo );
621
622 CloseHandle( pipe_write );
623
624 if (!ret) {
625 fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
626 CloseHandle( pipe_read );
627 return -1;
628 }
629
630 CloseHandle( pinfo.hProcess );
631 CloseHandle( pinfo.hThread );
632
633 /* wait for the "OK\n" message */
634 {
635 char temp[3];
636 DWORD count;
637
638 ret = ReadFile( pipe_read, temp, 3, &count, NULL );
639 CloseHandle( pipe_read );
640 if ( !ret ) {
641 fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
642 return -1;
643 }
644 if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
645 fprintf(stderr, "ADB server didn't ACK\n" );
646 return -1;
647 }
648 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800649#else /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800650 char path[PATH_MAX];
651 int fd[2];
652
653 // set up a pipe so the child can tell us when it is ready.
654 // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
655 if (pipe(fd)) {
656 fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
657 return -1;
658 }
Alexey Tarasov857f17a2009-10-22 02:55:00 +1100659 get_my_path(path, PATH_MAX);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800660 pid_t pid = fork();
661 if(pid < 0) return -1;
662
663 if (pid == 0) {
664 // child side of the fork
665
666 // redirect stderr to the pipe
667 // we use stderr instead of stdout due to stdout's buffering behavior.
668 adb_close(fd[0]);
669 dup2(fd[1], STDERR_FILENO);
670 adb_close(fd[1]);
671
Matt Gumbel411775c2012-11-14 10:16:17 -0800672 char str_port[30];
673 snprintf(str_port, sizeof(str_port), "%d", server_port);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800674 // child process
Matt Gumbel411775c2012-11-14 10:16:17 -0800675 int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800676 // this should not return
677 fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
678 } else {
679 // parent side of the fork
680
681 char temp[3];
682
683 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
684 // wait for the "OK\n" message
685 adb_close(fd[1]);
686 int ret = adb_read(fd[0], temp, 3);
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700687 int saved_errno = errno;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800688 adb_close(fd[0]);
689 if (ret < 0) {
JP Abgrall2e5dd6e2011-03-16 15:57:42 -0700690 fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800691 return -1;
692 }
693 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
694 fprintf(stderr, "ADB server didn't ACK\n" );
695 return -1;
696 }
697
698 setsid();
699 }
Yabin Cui2fa43212014-11-11 09:24:11 -0800700#endif /* !defined(_WIN32) */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800701 return 0;
702}
Yabin Cui2fa43212014-11-11 09:24:11 -0800703#endif /* ADB_HOST */
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800704
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100705// Try to handle a network forwarding request.
706// This returns 1 on success, 0 on failure, and -1 to indicate this is not
707// a forwarding-related request.
708int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
709{
710 if (!strcmp(service, "list-forward")) {
711 // Create the list of forward redirections.
712 int buffer_size = format_listeners(NULL, 0);
713 // Add one byte for the trailing zero.
714 char* buffer = malloc(buffer_size + 1);
715 if (buffer == NULL) {
716 sendfailmsg(reply_fd, "not enough memory");
717 return 1;
718 }
719 (void) format_listeners(buffer, buffer_size + 1);
720#if ADB_HOST
721 send_msg_with_okay(reply_fd, buffer, buffer_size);
722#else
723 send_msg_with_header(reply_fd, buffer, buffer_size);
724#endif
725 free(buffer);
726 return 1;
727 }
728
729 if (!strcmp(service, "killforward-all")) {
730 remove_all_listeners();
731#if ADB_HOST
732 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
733 adb_write(reply_fd, "OKAY", 4);
734#endif
735 adb_write(reply_fd, "OKAY", 4);
736 return 1;
737 }
738
739 if (!strncmp(service, "forward:",8) ||
740 !strncmp(service, "killforward:",12)) {
741 char *local, *remote, *err;
742 int r;
743 atransport *transport;
744
745 int createForward = strncmp(service, "kill", 4);
746 int no_rebind = 0;
747
748 local = strchr(service, ':') + 1;
749
750 // Handle forward:norebind:<local>... here
751 if (createForward && !strncmp(local, "norebind:", 9)) {
752 no_rebind = 1;
753 local = strchr(local, ':') + 1;
754 }
755
756 remote = strchr(local,';');
757
758 if (createForward) {
759 // Check forward: parameter format: '<local>;<remote>'
760 if(remote == 0) {
761 sendfailmsg(reply_fd, "malformed forward spec");
762 return 1;
763 }
764
765 *remote++ = 0;
766 if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
767 sendfailmsg(reply_fd, "malformed forward spec");
768 return 1;
769 }
770 } else {
771 // Check killforward: parameter format: '<local>'
772 if (local[0] == 0) {
773 sendfailmsg(reply_fd, "malformed forward spec");
774 return 1;
775 }
776 }
777
778 transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
779 if (!transport) {
780 sendfailmsg(reply_fd, err);
781 return 1;
782 }
783
784 if (createForward) {
785 r = install_listener(local, remote, transport, no_rebind);
786 } else {
787 r = remove_listener(local, transport);
788 }
789 if(r == 0) {
790#if ADB_HOST
791 /* On the host: 1st OKAY is connect, 2nd OKAY is status */
792 writex(reply_fd, "OKAY", 4);
793#endif
794 writex(reply_fd, "OKAY", 4);
795 return 1;
796 }
797
798 if (createForward) {
799 const char* message;
800 switch (r) {
801 case INSTALL_STATUS_CANNOT_BIND:
802 message = "cannot bind to socket";
803 break;
804 case INSTALL_STATUS_CANNOT_REBIND:
805 message = "cannot rebind existing socket";
806 break;
807 default:
808 message = "internal error";
809 }
810 sendfailmsg(reply_fd, message);
811 } else {
812 sendfailmsg(reply_fd, "cannot remove listener");
813 }
814 return 1;
815 }
816 return 0;
817}
818
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800819int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
820{
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800821 if(!strcmp(service, "kill")) {
822 fprintf(stderr,"adb server killed by remote request\n");
823 fflush(stdout);
824 adb_write(reply_fd, "OKAY", 4);
825 usb_cleanup();
826 exit(0);
827 }
828
829#if ADB_HOST
Chih-Hung Hsiehf5de7662014-09-05 15:38:15 -0700830 atransport *transport = NULL;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800831 // "transport:" is used for switching transport with a specified serial number
832 // "transport-usb:" is used for switching transport to the only USB transport
833 // "transport-local:" is used for switching transport to the only local transport
834 // "transport-any:" is used for switching transport to the only transport
835 if (!strncmp(service, "transport", strlen("transport"))) {
836 char* error_string = "unknown failure";
837 transport_type type = kTransportAny;
838
839 if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
840 type = kTransportUsb;
841 } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
842 type = kTransportLocal;
843 } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
844 type = kTransportAny;
845 } else if (!strncmp(service, "transport:", strlen("transport:"))) {
846 service += strlen("transport:");
Tom Marlin851ee3a2011-07-27 12:56:14 -0500847 serial = service;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800848 }
849
850 transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
851
852 if (transport) {
853 s->transport = transport;
854 adb_write(reply_fd, "OKAY", 4);
855 } else {
856 sendfailmsg(reply_fd, error_string);
857 }
858 return 1;
859 }
860
861 // return a list of all connected devices
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700862 if (!strncmp(service, "devices", 7)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800863 char buffer[4096];
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700864 int use_long = !strcmp(service+7, "-l");
865 if (use_long || service[7] == 0) {
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700866 memset(buffer, 0, sizeof(buffer));
867 D("Getting device list \n");
868 list_transports(buffer, sizeof(buffer), use_long);
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700869 D("Wrote device list \n");
Snild Dolkow4516a872014-01-30 10:08:38 +0100870 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700871 return 0;
872 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800873 }
874
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400875 // remove TCP transport
876 if (!strncmp(service, "disconnect:", 11)) {
877 char buffer[4096];
878 memset(buffer, 0, sizeof(buffer));
879 char* serial = service + 11;
Mike Lockwood01c2c302010-05-24 10:44:35 -0400880 if (serial[0] == 0) {
881 // disconnect from all TCP devices
882 unregister_all_tcp_transports();
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400883 } else {
Mike Lockwood01c2c302010-05-24 10:44:35 -0400884 char hostbuf[100];
885 // assume port 5555 if no port is specified
886 if (!strchr(serial, ':')) {
887 snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
888 serial = hostbuf;
889 }
890 atransport *t = find_transport(serial);
891
892 if (t) {
893 unregister_transport(t);
894 } else {
895 snprintf(buffer, sizeof(buffer), "No such device %s", serial);
896 }
Mike Lockwood5f2c4a12009-10-11 23:04:18 -0400897 }
898
Snild Dolkow4516a872014-01-30 10:08:38 +0100899 send_msg_with_okay(reply_fd, buffer, strlen(buffer));
Mike Lockwoodb51ae572009-08-24 15:58:40 -0700900 return 0;
901 }
902
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800903 // returns our value for ADB_SERVER_VERSION
904 if (!strcmp(service, "version")) {
905 char version[12];
906 snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
Snild Dolkow4516a872014-01-30 10:08:38 +0100907 send_msg_with_okay(reply_fd, version, strlen(version));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800908 return 0;
909 }
910
911 if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
912 char *out = "unknown";
913 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
914 if (transport && transport->serial) {
915 out = transport->serial;
916 }
Snild Dolkow4516a872014-01-30 10:08:38 +0100917 send_msg_with_okay(reply_fd, out, strlen(out));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800918 return 0;
919 }
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700920 if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
921 char *out = "unknown";
922 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
923 if (transport && transport->devpath) {
924 out = transport->devpath;
925 }
Snild Dolkow4516a872014-01-30 10:08:38 +0100926 send_msg_with_okay(reply_fd, out, strlen(out));
Scott Anderson6dfaf4b2012-04-20 11:21:14 -0700927 return 0;
928 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800929 // indicates a new emulator instance has started
930 if (!strncmp(service,"emulator:",9)) {
931 int port = atoi(service+9);
932 local_connect(port);
933 /* we don't even need to send a reply */
934 return 0;
935 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800936
937 if(!strncmp(service,"get-state",strlen("get-state"))) {
938 transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
939 char *state = connection_state_name(transport);
Snild Dolkow4516a872014-01-30 10:08:38 +0100940 send_msg_with_okay(reply_fd, state, strlen(state));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800941 return 0;
942 }
Simon Yee51c11e2014-07-14 17:23:06 -0700943#endif // ADB_HOST
944
945 int ret = handle_forward_request(service, ttype, serial, reply_fd);
946 if (ret >= 0)
947 return ret - 1;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800948 return -1;
949}