1 /*
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 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <limits.h>
23 #include <stdarg.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include "sysdeps.h"
30
31 #ifdef HAVE_TERMIO_H
32 #include <termios.h>
33 #endif
34
35 #define TRACE_TAG TRACE_ADB
36 #include "adb.h"
37 #include "adb_client.h"
38 #include "file_sync_service.h"
39
40 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
41
42 void get_my_path(char *s, size_t maxLen);
43 int find_sync_dirs(const char *srcarg,
44 char **android_srcdir_out, char **data_srcdir_out);
45 int install_app(transport_type transport, char* serial, int argc, char** argv);
46 int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
47
48 static const char *gProductOutPath = NULL;
49 extern int gListenAll;
50
product_file(const char * extra)51 static char *product_file(const char *extra)
52 {
53 int n;
54 char *x;
55
56 if (gProductOutPath == NULL) {
57 fprintf(stderr, "adb: Product directory not specified; "
58 "use -p or define ANDROID_PRODUCT_OUT\n");
59 exit(1);
60 }
61
62 n = strlen(gProductOutPath) + strlen(extra) + 2;
63 x = malloc(n);
64 if (x == 0) {
65 fprintf(stderr, "adb: Out of memory (product_file())\n");
66 exit(1);
67 }
68
69 snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
70 return x;
71 }
72
version(FILE * out)73 void version(FILE * out) {
74 fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
75 ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
76 }
77
help()78 void help()
79 {
80 version(stderr);
81
82 fprintf(stderr,
83 "\n"
84 " -a - directs adb to listen on all interfaces for a connection\n"
85 " -d - directs command to the only connected USB device\n"
86 " returns an error if more than one USB device is present.\n"
87 " -e - directs command to the only running emulator.\n"
88 " returns an error if more than one emulator is running.\n"
89 " -s <specific device> - directs command to the device or emulator with the given\n"
90 " serial number or qualifier. Overrides ANDROID_SERIAL\n"
91 " environment variable.\n"
92 " -p <product name or path> - simple product name like 'sooner', or\n"
93 " a relative/absolute path to a product\n"
94 " out directory like 'out/target/product/sooner'.\n"
95 " If -p is not specified, the ANDROID_PRODUCT_OUT\n"
96 " environment variable is used, which must\n"
97 " be an absolute path.\n"
98 " -H - Name of adb server host (default: localhost)\n"
99 " -P - Port of adb server (default: 5037)\n"
100 " devices [-l] - list all connected devices\n"
101 " ('-l' will also list device qualifiers)\n"
102 " connect <host>[:<port>] - connect to a device via TCP/IP\n"
103 " Port 5555 is used by default if no port number is specified.\n"
104 " disconnect [<host>[:<port>]] - disconnect from a TCP/IP device.\n"
105 " Port 5555 is used by default if no port number is specified.\n"
106 " Using this command with no additional arguments\n"
107 " will disconnect from all connected TCP/IP devices.\n"
108 "\n"
109 "device commands:\n"
110 " adb push <local> <remote> - copy file/dir to device\n"
111 " adb pull <remote> [<local>] - copy file/dir from device\n"
112 " adb sync [ <directory> ] - copy host->device only if changed\n"
113 " (-l means list but don't copy)\n"
114 " (see 'adb help all')\n"
115 " adb shell - run remote shell interactively\n"
116 " adb shell <command> - run remote shell command\n"
117 " adb emu <command> - run emulator console command\n"
118 " adb logcat [ <filter-spec> ] - View device log\n"
119 " adb forward --list - list all forward socket connections.\n"
120 " the format is a list of lines with the following format:\n"
121 " <serial> \" \" <local> \" \" <remote> \"\\n\"\n"
122 " adb forward <local> <remote> - forward socket connections\n"
123 " forward specs are one of: \n"
124 " tcp:<port>\n"
125 " localabstract:<unix domain socket name>\n"
126 " localreserved:<unix domain socket name>\n"
127 " localfilesystem:<unix domain socket name>\n"
128 " dev:<character device name>\n"
129 " jdwp:<process pid> (remote only)\n"
130 " adb forward --no-rebind <local> <remote>\n"
131 " - same as 'adb forward <local> <remote>' but fails\n"
132 " if <local> is already forwarded\n"
133 " adb forward --remove <local> - remove a specific forward socket connection\n"
134 " adb forward --remove-all - remove all forward socket connections\n"
135 " adb jdwp - list PIDs of processes hosting a JDWP transport\n"
136 " adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n"
137 " - push this package file to the device and install it\n"
138 " ('-l' means forward-lock the app)\n"
139 " ('-r' means reinstall the app, keeping its data)\n"
140 " ('-s' means install on SD card instead of internal storage)\n"
141 " ('--algo', '--key', and '--iv' mean the file is encrypted already)\n"
142 " adb uninstall [-k] <package> - remove this app package from the device\n"
143 " ('-k' means keep the data and cache directories)\n"
144 " adb bugreport - return all information from the device\n"
145 " that should be included in a bug report.\n"
146 "\n"
147 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
148 " - write an archive of the device's data to <file>.\n"
149 " If no -f option is supplied then the data is written\n"
150 " to \"backup.ab\" in the current directory.\n"
151 " (-apk|-noapk enable/disable backup of the .apks themselves\n"
152 " in the archive; the default is noapk.)\n"
153 " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
154 " (aka .obb) files associated with each application; the default\n"
155 " is noobb.)\n"
156 " (-shared|-noshared enable/disable backup of the device's\n"
157 " shared storage / SD card contents; the default is noshared.)\n"
158 " (-all means to back up all installed applications)\n"
159 " (-system|-nosystem toggles whether -all automatically includes\n"
160 " system applications; the default is to include system apps)\n"
161 " (<packages...> is the list of applications to be backed up. If\n"
162 " the -all or -shared flags are passed, then the package\n"
163 " list is optional. Applications explicitly given on the\n"
164 " command line will be included even if -nosystem would\n"
165 " ordinarily cause them to be omitted.)\n"
166 "\n"
167 " adb restore <file> - restore device contents from the <file> backup archive\n"
168 "\n"
169 " adb help - show this help message\n"
170 " adb version - show version num\n"
171 "\n"
172 "scripting:\n"
173 " adb wait-for-device - block until device is online\n"
174 " adb start-server - ensure that there is a server running\n"
175 " adb kill-server - kill the server if it is running\n"
176 " adb get-state - prints: offline | bootloader | device\n"
177 " adb get-serialno - prints: <serial-number>\n"
178 " adb get-devpath - prints: <device-path>\n"
179 " adb status-window - continuously print device status for a specified device\n"
180 " adb remount - remounts the /system partition on the device read-write\n"
181 " adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
182 " adb reboot-bootloader - reboots the device into the bootloader\n"
183 " adb root - restarts the adbd daemon with root permissions\n"
184 " adb usb - restarts the adbd daemon listening on USB\n"
185 " adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port"
186 "\n"
187 "networking:\n"
188 " adb ppp <tty> [parameters] - Run PPP over USB.\n"
189 " Note: you should not automatically start a PPP connection.\n"
190 " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
191 " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
192 "\n"
193 "adb sync notes: adb sync [ <directory> ]\n"
194 " <localdir> can be interpreted in several ways:\n"
195 "\n"
196 " - If <directory> is not specified, both /system and /data partitions will be updated.\n"
197 "\n"
198 " - If it is \"system\" or \"data\", only the corresponding partition\n"
199 " is updated.\n"
200 "\n"
201 "environmental variables:\n"
202 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
203 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
204 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
205 " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
206 );
207 }
208
usage()209 int usage()
210 {
211 help();
212 return 1;
213 }
214
215 #ifdef HAVE_TERMIO_H
216 static struct termios tio_save;
217
stdin_raw_init(int fd)218 static void stdin_raw_init(int fd)
219 {
220 struct termios tio;
221
222 if(tcgetattr(fd, &tio)) return;
223 if(tcgetattr(fd, &tio_save)) return;
224
225 tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
226
227 /* no timeout but request at least one character per read */
228 tio.c_cc[VTIME] = 0;
229 tio.c_cc[VMIN] = 1;
230
231 tcsetattr(fd, TCSANOW, &tio);
232 tcflush(fd, TCIFLUSH);
233 }
234
stdin_raw_restore(int fd)235 static void stdin_raw_restore(int fd)
236 {
237 tcsetattr(fd, TCSANOW, &tio_save);
238 tcflush(fd, TCIFLUSH);
239 }
240 #endif
241
read_and_dump(int fd)242 static void read_and_dump(int fd)
243 {
244 char buf[4096];
245 int len;
246
247 while(fd >= 0) {
248 D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
249 len = adb_read(fd, buf, 4096);
250 D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
251 if(len == 0) {
252 break;
253 }
254
255 if(len < 0) {
256 if(errno == EINTR) continue;
257 break;
258 }
259 fwrite(buf, 1, len, stdout);
260 fflush(stdout);
261 }
262 }
263
copy_to_file(int inFd,int outFd)264 static void copy_to_file(int inFd, int outFd) {
265 const size_t BUFSIZE = 32 * 1024;
266 char* buf = (char*) malloc(BUFSIZE);
267 int len;
268 long total = 0;
269
270 D("copy_to_file(%d -> %d)\n", inFd, outFd);
271 for (;;) {
272 len = adb_read(inFd, buf, BUFSIZE);
273 if (len == 0) {
274 D("copy_to_file() : read 0 bytes; exiting\n");
275 break;
276 }
277 if (len < 0) {
278 if (errno == EINTR) {
279 D("copy_to_file() : EINTR, retrying\n");
280 continue;
281 }
282 D("copy_to_file() : error %d\n", errno);
283 break;
284 }
285 adb_write(outFd, buf, len);
286 total += len;
287 }
288 D("copy_to_file() finished after %lu bytes\n", total);
289 free(buf);
290 }
291
stdin_read_thread(void * x)292 static void *stdin_read_thread(void *x)
293 {
294 int fd, fdi;
295 unsigned char buf[1024];
296 int r, n;
297 int state = 0;
298
299 int *fds = (int*) x;
300 fd = fds[0];
301 fdi = fds[1];
302 free(fds);
303
304 for(;;) {
305 /* fdi is really the client's stdin, so use read, not adb_read here */
306 D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
307 r = unix_read(fdi, buf, 1024);
308 D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
309 if(r == 0) break;
310 if(r < 0) {
311 if(errno == EINTR) continue;
312 break;
313 }
314 for(n = 0; n < r; n++){
315 switch(buf[n]) {
316 case '\n':
317 state = 1;
318 break;
319 case '\r':
320 state = 1;
321 break;
322 case '~':
323 if(state == 1) state++;
324 break;
325 case '.':
326 if(state == 2) {
327 fprintf(stderr,"\n* disconnect *\n");
328 #ifdef HAVE_TERMIO_H
329 stdin_raw_restore(fdi);
330 #endif
331 exit(0);
332 }
333 default:
334 state = 0;
335 }
336 }
337 r = adb_write(fd, buf, r);
338 if(r <= 0) {
339 break;
340 }
341 }
342 return 0;
343 }
344
interactive_shell(void)345 int interactive_shell(void)
346 {
347 adb_thread_t thr;
348 int fdi, fd;
349 int *fds;
350
351 fd = adb_connect("shell:");
352 if(fd < 0) {
353 fprintf(stderr,"error: %s\n", adb_error());
354 return 1;
355 }
356 fdi = 0; //dup(0);
357
358 fds = malloc(sizeof(int) * 2);
359 fds[0] = fd;
360 fds[1] = fdi;
361
362 #ifdef HAVE_TERMIO_H
363 stdin_raw_init(fdi);
364 #endif
365 adb_thread_create(&thr, stdin_read_thread, fds);
366 read_and_dump(fd);
367 #ifdef HAVE_TERMIO_H
368 stdin_raw_restore(fdi);
369 #endif
370 return 0;
371 }
372
373
format_host_command(char * buffer,size_t buflen,const char * command,transport_type ttype,const char * serial)374 static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial)
375 {
376 if (serial) {
377 snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
378 } else {
379 const char* prefix = "host";
380 if (ttype == kTransportUsb)
381 prefix = "host-usb";
382 else if (ttype == kTransportLocal)
383 prefix = "host-local";
384
385 snprintf(buffer, buflen, "%s:%s", prefix, command);
386 }
387 }
388
adb_download_buffer(const char * service,const char * fn,const void * data,int sz,unsigned progress)389 int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
390 unsigned progress)
391 {
392 char buf[4096];
393 unsigned total;
394 int fd;
395 const unsigned char *ptr;
396
397 sprintf(buf,"%s:%d", service, sz);
398 fd = adb_connect(buf);
399 if(fd < 0) {
400 fprintf(stderr,"error: %s\n", adb_error());
401 return -1;
402 }
403
404 int opt = CHUNK_SIZE;
405 opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
406
407 total = sz;
408 ptr = data;
409
410 if(progress) {
411 char *x = strrchr(service, ':');
412 if(x) service = x + 1;
413 }
414
415 while(sz > 0) {
416 unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
417 if(writex(fd, ptr, xfer)) {
418 adb_status(fd);
419 fprintf(stderr,"* failed to write data '%s' *\n", adb_error());
420 return -1;
421 }
422 sz -= xfer;
423 ptr += xfer;
424 if(progress) {
425 printf("sending: '%s' %4d%% \r", fn, (int)(100LL - ((100LL * sz) / (total))));
426 fflush(stdout);
427 }
428 }
429 if(progress) {
430 printf("\n");
431 }
432
433 if(readx(fd, buf, 4)){
434 fprintf(stderr,"* error reading response *\n");
435 adb_close(fd);
436 return -1;
437 }
438 if(memcmp(buf, "OKAY", 4)) {
439 buf[4] = 0;
440 fprintf(stderr,"* error response '%s' *\n", buf);
441 adb_close(fd);
442 return -1;
443 }
444
445 adb_close(fd);
446 return 0;
447 }
448
449
adb_download(const char * service,const char * fn,unsigned progress)450 int adb_download(const char *service, const char *fn, unsigned progress)
451 {
452 void *data;
453 unsigned sz;
454
455 data = load_file(fn, &sz);
456 if(data == 0) {
457 fprintf(stderr,"* cannot read '%s' *\n", fn);
458 return -1;
459 }
460
461 int status = adb_download_buffer(service, fn, data, sz, progress);
462 free(data);
463 return status;
464 }
465
status_window(transport_type ttype,const char * serial)466 static void status_window(transport_type ttype, const char* serial)
467 {
468 char command[4096];
469 char *state = 0;
470 char *laststate = 0;
471
472 /* silence stderr */
473 #ifdef _WIN32
474 /* XXX: TODO */
475 #else
476 int fd;
477 fd = unix_open("/dev/null", O_WRONLY);
478 dup2(fd, 2);
479 adb_close(fd);
480 #endif
481
482 format_host_command(command, sizeof command, "get-state", ttype, serial);
483
484 for(;;) {
485 adb_sleep_ms(250);
486
487 if(state) {
488 free(state);
489 state = 0;
490 }
491
492 state = adb_query(command);
493
494 if(state) {
495 if(laststate && !strcmp(state,laststate)){
496 continue;
497 } else {
498 if(laststate) free(laststate);
499 laststate = strdup(state);
500 }
501 }
502
503 printf("%c[2J%c[2H", 27, 27);
504 printf("Android Debug Bridge\n");
505 printf("State: %s\n", state ? state : "offline");
506 fflush(stdout);
507 }
508 }
509
510 /** duplicate string and quote all \ " ( ) chars + space character. */
511 static char *
dupAndQuote(const char * s)512 dupAndQuote(const char *s)
513 {
514 const char *ts;
515 size_t alloc_len;
516 char *ret;
517 char *dest;
518
519 ts = s;
520
521 alloc_len = 0;
522
523 for( ;*ts != '\0'; ts++) {
524 alloc_len++;
525 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
526 alloc_len++;
527 }
528 }
529
530 ret = (char *)malloc(alloc_len + 1);
531
532 ts = s;
533 dest = ret;
534
535 for ( ;*ts != '\0'; ts++) {
536 if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
537 *dest++ = '\\';
538 }
539
540 *dest++ = *ts;
541 }
542
543 *dest++ = '\0';
544
545 return ret;
546 }
547
548 /**
549 * Run ppp in "notty" mode against a resource listed as the first parameter
550 * eg:
551 *
552 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
553 *
554 */
ppp(int argc,char ** argv)555 int ppp(int argc, char **argv)
556 {
557 #ifdef HAVE_WIN32_PROC
558 fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
559 return -1;
560 #else
561 char *adb_service_name;
562 pid_t pid;
563 int fd;
564
565 if (argc < 2) {
566 fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
567 argv[0]);
568
569 return 1;
570 }
571
572 adb_service_name = argv[1];
573
574 fd = adb_connect(adb_service_name);
575
576 if(fd < 0) {
577 fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
578 adb_service_name, adb_error());
579 return 1;
580 }
581
582 pid = fork();
583
584 if (pid < 0) {
585 perror("from fork()");
586 return 1;
587 } else if (pid == 0) {
588 int err;
589 int i;
590 const char **ppp_args;
591
592 // copy args
593 ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
594 ppp_args[0] = "pppd";
595 for (i = 2 ; i < argc ; i++) {
596 //argv[2] and beyond become ppp_args[1] and beyond
597 ppp_args[i - 1] = argv[i];
598 }
599 ppp_args[i-1] = NULL;
600
601 // child side
602
603 dup2(fd, STDIN_FILENO);
604 dup2(fd, STDOUT_FILENO);
605 adb_close(STDERR_FILENO);
606 adb_close(fd);
607
608 err = execvp("pppd", (char * const *)ppp_args);
609
610 if (err < 0) {
611 perror("execing pppd");
612 }
613 exit(-1);
614 } else {
615 // parent side
616
617 adb_close(fd);
618 return 0;
619 }
620 #endif /* !HAVE_WIN32_PROC */
621 }
622
send_shellcommand(transport_type transport,char * serial,char * buf)623 static int send_shellcommand(transport_type transport, char* serial, char* buf)
624 {
625 int fd, ret;
626
627 for(;;) {
628 fd = adb_connect(buf);
629 if(fd >= 0)
630 break;
631 fprintf(stderr,"- waiting for device -\n");
632 adb_sleep_ms(1000);
633 do_cmd(transport, serial, "wait-for-device", 0);
634 }
635
636 read_and_dump(fd);
637 ret = adb_close(fd);
638 if (ret)
639 perror("close");
640
641 return ret;
642 }
643
logcat(transport_type transport,char * serial,int argc,char ** argv)644 static int logcat(transport_type transport, char* serial, int argc, char **argv)
645 {
646 char buf[4096];
647
648 char *log_tags;
649 char *quoted_log_tags;
650
651 log_tags = getenv("ANDROID_LOG_TAGS");
652 quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
653
654 snprintf(buf, sizeof(buf),
655 "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
656 quoted_log_tags);
657
658 free(quoted_log_tags);
659
660 if (!strcmp(argv[0],"longcat")) {
661 strncat(buf, " -v long", sizeof(buf)-1);
662 }
663
664 argc -= 1;
665 argv += 1;
666 while(argc-- > 0) {
667 char *quoted;
668
669 quoted = dupAndQuote (*argv++);
670
671 strncat(buf, " ", sizeof(buf)-1);
672 strncat(buf, quoted, sizeof(buf)-1);
673 free(quoted);
674 }
675
676 send_shellcommand(transport, serial, buf);
677 return 0;
678 }
679
mkdirs(char * path)680 static int mkdirs(char *path)
681 {
682 int ret;
683 char *x = path + 1;
684
685 for(;;) {
686 x = adb_dirstart(x);
687 if(x == 0) return 0;
688 *x = 0;
689 ret = adb_mkdir(path, 0775);
690 *x = OS_PATH_SEPARATOR;
691 if((ret < 0) && (errno != EEXIST)) {
692 return ret;
693 }
694 x++;
695 }
696 return 0;
697 }
698
backup(int argc,char ** argv)699 static int backup(int argc, char** argv) {
700 char buf[4096];
701 char default_name[32];
702 const char* filename = strcpy(default_name, "./backup.ab");
703 int fd, outFd;
704 int i, j;
705
706 /* find, extract, and use any -f argument */
707 for (i = 1; i < argc; i++) {
708 if (!strcmp("-f", argv[i])) {
709 if (i == argc-1) {
710 fprintf(stderr, "adb: -f passed with no filename\n");
711 return usage();
712 }
713 filename = argv[i+1];
714 for (j = i+2; j <= argc; ) {
715 argv[i++] = argv[j++];
716 }
717 argc -= 2;
718 argv[argc] = NULL;
719 }
720 }
721
722 /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
723 if (argc < 2) return usage();
724
725 adb_unlink(filename);
726 mkdirs((char *)filename);
727 outFd = adb_creat(filename, 0640);
728 if (outFd < 0) {
729 fprintf(stderr, "adb: unable to open file %s\n", filename);
730 return -1;
731 }
732
733 snprintf(buf, sizeof(buf), "backup");
734 for (argc--, argv++; argc; argc--, argv++) {
735 strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
736 strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
737 }
738
739 D("backup. filename=%s buf=%s\n", filename, buf);
740 fd = adb_connect(buf);
741 if (fd < 0) {
742 fprintf(stderr, "adb: unable to connect for backup\n");
743 adb_close(outFd);
744 return -1;
745 }
746
747 printf("Now unlock your device and confirm the backup operation.\n");
748 copy_to_file(fd, outFd);
749
750 adb_close(fd);
751 adb_close(outFd);
752 return 0;
753 }
754
restore(int argc,char ** argv)755 static int restore(int argc, char** argv) {
756 const char* filename;
757 int fd, tarFd;
758
759 if (argc != 2) return usage();
760
761 filename = argv[1];
762 tarFd = adb_open(filename, O_RDONLY);
763 if (tarFd < 0) {
764 fprintf(stderr, "adb: unable to open file %s\n", filename);
765 return -1;
766 }
767
768 fd = adb_connect("restore:");
769 if (fd < 0) {
770 fprintf(stderr, "adb: unable to connect for backup\n");
771 adb_close(tarFd);
772 return -1;
773 }
774
775 printf("Now unlock your device and confirm the restore operation.\n");
776 copy_to_file(tarFd, fd);
777
778 adb_close(fd);
779 adb_close(tarFd);
780 return 0;
781 }
782
783 #define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
top_works(const char * top)784 static int top_works(const char *top)
785 {
786 if (top != NULL && adb_is_absolute_host_path(top)) {
787 char path_buf[PATH_MAX];
788 snprintf(path_buf, sizeof(path_buf),
789 "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
790 return access(path_buf, F_OK) == 0;
791 }
792 return 0;
793 }
794
find_top_from(const char * indir,char path_buf[PATH_MAX])795 static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
796 {
797 strcpy(path_buf, indir);
798 while (1) {
799 if (top_works(path_buf)) {
800 return path_buf;
801 }
802 char *s = adb_dirstop(path_buf);
803 if (s != NULL) {
804 *s = '\0';
805 } else {
806 path_buf[0] = '\0';
807 return NULL;
808 }
809 }
810 }
811
find_top(char path_buf[PATH_MAX])812 static char *find_top(char path_buf[PATH_MAX])
813 {
814 char *top = getenv("ANDROID_BUILD_TOP");
815 if (top != NULL && top[0] != '\0') {
816 if (!top_works(top)) {
817 fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
818 return NULL;
819 }
820 } else {
821 top = getenv("TOP");
822 if (top != NULL && top[0] != '\0') {
823 if (!top_works(top)) {
824 fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
825 return NULL;
826 }
827 } else {
828 top = NULL;
829 }
830 }
831
832 if (top != NULL) {
833 /* The environment pointed to a top directory that works.
834 */
835 strcpy(path_buf, top);
836 return path_buf;
837 }
838
839 /* The environment didn't help. Walk up the tree from the CWD
840 * to see if we can find the top.
841 */
842 char dir[PATH_MAX];
843 top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
844 if (top == NULL) {
845 /* If the CWD isn't under a good-looking top, see if the
846 * executable is.
847 */
848 get_my_path(dir, PATH_MAX);
849 top = find_top_from(dir, path_buf);
850 }
851 return top;
852 }
853
854 /* <hint> may be:
855 * - A simple product name
856 * e.g., "sooner"
857 TODO: debug? sooner-debug, sooner:debug?
858 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
859 * e.g., "out/target/product/sooner"
860 * - An absolute path to the PRODUCT_OUT dir
861 * e.g., "/src/device/out/target/product/sooner"
862 *
863 * Given <hint>, try to construct an absolute path to the
864 * ANDROID_PRODUCT_OUT dir.
865 */
find_product_out_path(const char * hint)866 static const char *find_product_out_path(const char *hint)
867 {
868 static char path_buf[PATH_MAX];
869
870 if (hint == NULL || hint[0] == '\0') {
871 return NULL;
872 }
873
874 /* If it's already absolute, don't bother doing any work.
875 */
876 if (adb_is_absolute_host_path(hint)) {
877 strcpy(path_buf, hint);
878 return path_buf;
879 }
880
881 /* If there are any slashes in it, assume it's a relative path;
882 * make it absolute.
883 */
884 if (adb_dirstart(hint) != NULL) {
885 if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
886 fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
887 return NULL;
888 }
889 if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
890 fprintf(stderr, "adb: Couldn't assemble path\n");
891 return NULL;
892 }
893 strcat(path_buf, OS_PATH_SEPARATOR_STR);
894 strcat(path_buf, hint);
895 return path_buf;
896 }
897
898 /* It's a string without any slashes. Try to do something with it.
899 *
900 * Try to find the root of the build tree, and build a PRODUCT_OUT
901 * path from there.
902 */
903 char top_buf[PATH_MAX];
904 const char *top = find_top(top_buf);
905 if (top == NULL) {
906 fprintf(stderr, "adb: Couldn't find top of build tree\n");
907 return NULL;
908 }
909 //TODO: if we have a way to indicate debug, look in out/debug/target/...
910 snprintf(path_buf, sizeof(path_buf),
911 "%s" OS_PATH_SEPARATOR_STR
912 "out" OS_PATH_SEPARATOR_STR
913 "target" OS_PATH_SEPARATOR_STR
914 "product" OS_PATH_SEPARATOR_STR
915 "%s", top_buf, hint);
916 if (access(path_buf, F_OK) < 0) {
917 fprintf(stderr, "adb: Couldn't find a product dir "
918 "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
919 return NULL;
920 }
921 return path_buf;
922 }
923
adb_commandline(int argc,char ** argv)924 int adb_commandline(int argc, char **argv)
925 {
926 char buf[4096];
927 int no_daemon = 0;
928 int is_daemon = 0;
929 int is_server = 0;
930 int persist = 0;
931 int r;
932 int quote;
933 transport_type ttype = kTransportAny;
934 char* serial = NULL;
935 char* server_port_str = NULL;
936
937 /* If defined, this should be an absolute path to
938 * the directory containing all of the various system images
939 * for a particular product. If not defined, and the adb
940 * command requires this information, then the user must
941 * specify the path using "-p".
942 */
943 gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
944 if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
945 gProductOutPath = NULL;
946 }
947 // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
948
949 serial = getenv("ANDROID_SERIAL");
950
951 /* Validate and assign the server port */
952 server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
953 int server_port = DEFAULT_ADB_PORT;
954 if (server_port_str && strlen(server_port_str) > 0) {
955 server_port = (int) strtol(server_port_str, NULL, 0);
956 if (server_port <= 0 || server_port > 65535) {
957 fprintf(stderr,
958 "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number less than 65535. Got \"%s\"\n",
959 server_port_str);
960 return usage();
961 }
962 }
963
964 /* modifiers and flags */
965 while(argc > 0) {
966 if(!strcmp(argv[0],"server")) {
967 is_server = 1;
968 } else if(!strcmp(argv[0],"nodaemon")) {
969 no_daemon = 1;
970 } else if (!strcmp(argv[0], "fork-server")) {
971 /* this is a special flag used only when the ADB client launches the ADB Server */
972 is_daemon = 1;
973 } else if(!strcmp(argv[0],"persist")) {
974 persist = 1;
975 } else if(!strncmp(argv[0], "-p", 2)) {
976 const char *product = NULL;
977 if (argv[0][2] == '\0') {
978 if (argc < 2) return usage();
979 product = argv[1];
980 argc--;
981 argv++;
982 } else {
983 product = argv[0] + 2;
984 }
985 gProductOutPath = find_product_out_path(product);
986 if (gProductOutPath == NULL) {
987 fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
988 product);
989 return usage();
990 }
991 } else if (argv[0][0]=='-' && argv[0][1]=='s') {
992 if (isdigit(argv[0][2])) {
993 serial = argv[0] + 2;
994 } else {
995 if(argc < 2 || argv[0][2] != '\0') return usage();
996 serial = argv[1];
997 argc--;
998 argv++;
999 }
1000 } else if (!strcmp(argv[0],"-d")) {
1001 ttype = kTransportUsb;
1002 } else if (!strcmp(argv[0],"-e")) {
1003 ttype = kTransportLocal;
1004 } else if (!strcmp(argv[0],"-a")) {
1005 gListenAll = 1;
1006 } else if(!strncmp(argv[0], "-H", 2)) {
1007 const char *hostname = NULL;
1008 if (argv[0][2] == '\0') {
1009 if (argc < 2) return usage();
1010 hostname = argv[1];
1011 argc--;
1012 argv++;
1013 } else {
1014 hostname = argv[0] + 2;
1015 }
1016 adb_set_tcp_name(hostname);
1017
1018 } else if(!strncmp(argv[0], "-P", 2)) {
1019 if (argv[0][2] == '\0') {
1020 if (argc < 2) return usage();
1021 server_port_str = argv[1];
1022 argc--;
1023 argv++;
1024 } else {
1025 server_port_str = argv[0] + 2;
1026 }
1027 if (strlen(server_port_str) > 0) {
1028 server_port = (int) strtol(server_port_str, NULL, 0);
1029 if (server_port <= 0 || server_port > 65535) {
1030 fprintf(stderr,
1031 "adb: port number must be a positive number less than 65536. Got \"%s\"\n",
1032 server_port_str);
1033 return usage();
1034 }
1035 } else {
1036 fprintf(stderr,
1037 "adb: port number must be a positive number less than 65536. Got empty string.\n");
1038 return usage();
1039 }
1040 } else {
1041 /* out of recognized modifiers and flags */
1042 break;
1043 }
1044 argc--;
1045 argv++;
1046 }
1047
1048 adb_set_transport(ttype, serial);
1049 adb_set_tcp_specifics(server_port);
1050
1051 if (is_server) {
1052 if (no_daemon || is_daemon) {
1053 r = adb_main(is_daemon, server_port);
1054 } else {
1055 r = launch_server(server_port);
1056 }
1057 if(r) {
1058 fprintf(stderr,"* could not start server *\n");
1059 }
1060 return r;
1061 }
1062
1063 top:
1064 if(argc == 0) {
1065 return usage();
1066 }
1067
1068 /* adb_connect() commands */
1069
1070 if(!strcmp(argv[0], "devices")) {
1071 char *tmp;
1072 char *listopt;
1073 if (argc < 2)
1074 listopt = "";
1075 else if (argc == 2 && !strcmp(argv[1], "-l"))
1076 listopt = argv[1];
1077 else {
1078 fprintf(stderr, "Usage: adb devices [-l]\n");
1079 return 1;
1080 }
1081 snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
1082 tmp = adb_query(buf);
1083 if(tmp) {
1084 printf("List of devices attached \n");
1085 printf("%s\n", tmp);
1086 return 0;
1087 } else {
1088 return 1;
1089 }
1090 }
1091
1092 if(!strcmp(argv[0], "connect")) {
1093 char *tmp;
1094 if (argc != 2) {
1095 fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
1096 return 1;
1097 }
1098 snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
1099 tmp = adb_query(buf);
1100 if(tmp) {
1101 printf("%s\n", tmp);
1102 return 0;
1103 } else {
1104 return 1;
1105 }
1106 }
1107
1108 if(!strcmp(argv[0], "disconnect")) {
1109 char *tmp;
1110 if (argc > 2) {
1111 fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
1112 return 1;
1113 }
1114 if (argc == 2) {
1115 snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
1116 } else {
1117 snprintf(buf, sizeof buf, "host:disconnect:");
1118 }
1119 tmp = adb_query(buf);
1120 if(tmp) {
1121 printf("%s\n", tmp);
1122 return 0;
1123 } else {
1124 return 1;
1125 }
1126 }
1127
1128 if (!strcmp(argv[0], "emu")) {
1129 return adb_send_emulator_command(argc, argv);
1130 }
1131
1132 if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
1133 int r;
1134 int fd;
1135
1136 char h = (argv[0][0] == 'h');
1137
1138 if (h) {
1139 printf("\x1b[41;33m");
1140 fflush(stdout);
1141 }
1142
1143 if(argc < 2) {
1144 D("starting interactive shell\n");
1145 r = interactive_shell();
1146 if (h) {
1147 printf("\x1b[0m");
1148 fflush(stdout);
1149 }
1150 return r;
1151 }
1152
1153 snprintf(buf, sizeof buf, "shell:%s", argv[1]);
1154 argc -= 2;
1155 argv += 2;
1156 while(argc-- > 0) {
1157 strcat(buf, " ");
1158
1159 /* quote empty strings and strings with spaces */
1160 quote = (**argv == 0 || strchr(*argv, ' '));
1161 if (quote)
1162 strcat(buf, "\"");
1163 strcat(buf, *argv++);
1164 if (quote)
1165 strcat(buf, "\"");
1166 }
1167
1168 for(;;) {
1169 D("interactive shell loop. buff=%s\n", buf);
1170 fd = adb_connect(buf);
1171 if(fd >= 0) {
1172 D("about to read_and_dump(fd=%d)\n", fd);
1173 read_and_dump(fd);
1174 D("read_and_dump() done.\n");
1175 adb_close(fd);
1176 r = 0;
1177 } else {
1178 fprintf(stderr,"error: %s\n", adb_error());
1179 r = -1;
1180 }
1181
1182 if(persist) {
1183 fprintf(stderr,"\n- waiting for device -\n");
1184 adb_sleep_ms(1000);
1185 do_cmd(ttype, serial, "wait-for-device", 0);
1186 } else {
1187 if (h) {
1188 printf("\x1b[0m");
1189 fflush(stdout);
1190 }
1191 D("interactive shell loop. return r=%d\n", r);
1192 return r;
1193 }
1194 }
1195 }
1196
1197 if(!strcmp(argv[0], "kill-server")) {
1198 int fd;
1199 fd = _adb_connect("host:kill");
1200 if(fd == -1) {
1201 fprintf(stderr,"* server not running *\n");
1202 return 1;
1203 }
1204 return 0;
1205 }
1206
1207 if(!strcmp(argv[0], "sideload")) {
1208 if(argc != 2) return usage();
1209 if(adb_download("sideload", argv[1], 1)) {
1210 return 1;
1211 } else {
1212 return 0;
1213 }
1214 }
1215
1216 if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
1217 || !strcmp(argv[0], "reboot-bootloader")
1218 || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
1219 || !strcmp(argv[0], "root")) {
1220 char command[100];
1221 if (!strcmp(argv[0], "reboot-bootloader"))
1222 snprintf(command, sizeof(command), "reboot:bootloader");
1223 else if (argc > 1)
1224 snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
1225 else
1226 snprintf(command, sizeof(command), "%s:", argv[0]);
1227 int fd = adb_connect(command);
1228 if(fd >= 0) {
1229 read_and_dump(fd);
1230 adb_close(fd);
1231 return 0;
1232 }
1233 fprintf(stderr,"error: %s\n", adb_error());
1234 return 1;
1235 }
1236
1237 if(!strcmp(argv[0], "bugreport")) {
1238 if (argc != 1) return usage();
1239 do_cmd(ttype, serial, "shell", "bugreport", 0);
1240 return 0;
1241 }
1242
1243 /* adb_command() wrapper commands */
1244
1245 if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1246 char* service = argv[0];
1247 if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1248 if (ttype == kTransportUsb) {
1249 service = "wait-for-usb";
1250 } else if (ttype == kTransportLocal) {
1251 service = "wait-for-local";
1252 } else {
1253 service = "wait-for-any";
1254 }
1255 }
1256
1257 format_host_command(buf, sizeof buf, service, ttype, serial);
1258
1259 if (adb_command(buf)) {
1260 D("failure: %s *\n",adb_error());
1261 fprintf(stderr,"error: %s\n", adb_error());
1262 return 1;
1263 }
1264
1265 /* Allow a command to be run after wait-for-device,
1266 * e.g. 'adb wait-for-device shell'.
1267 */
1268 if(argc > 1) {
1269 argc--;
1270 argv++;
1271 goto top;
1272 }
1273 return 0;
1274 }
1275
1276 if(!strcmp(argv[0], "forward")) {
1277 char host_prefix[64];
1278 char remove = 0;
1279 char remove_all = 0;
1280 char list = 0;
1281 char no_rebind = 0;
1282
1283 // Parse options here.
1284 while (argc > 1 && argv[1][0] == '-') {
1285 if (!strcmp(argv[1], "--list"))
1286 list = 1;
1287 else if (!strcmp(argv[1], "--remove"))
1288 remove = 1;
1289 else if (!strcmp(argv[1], "--remove-all"))
1290 remove_all = 1;
1291 else if (!strcmp(argv[1], "--no-rebind"))
1292 no_rebind = 1;
1293 else {
1294 return usage();
1295 }
1296 argc--;
1297 argv++;
1298 }
1299
1300 // Ensure we can only use one option at a time.
1301 if (list + remove + remove_all + no_rebind > 1) {
1302 return usage();
1303 }
1304
1305 // Determine the <host-prefix> for this command.
1306 if (serial) {
1307 snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
1308 serial);
1309 } else if (ttype == kTransportUsb) {
1310 snprintf(host_prefix, sizeof host_prefix, "host-usb");
1311 } else if (ttype == kTransportLocal) {
1312 snprintf(host_prefix, sizeof host_prefix, "host-local");
1313 } else {
1314 snprintf(host_prefix, sizeof host_prefix, "host");
1315 }
1316
1317 // Implement forward --list
1318 if (list) {
1319 if (argc != 1)
1320 return usage();
1321 snprintf(buf, sizeof buf, "%s:list-forward", host_prefix);
1322 char* forwards = adb_query(buf);
1323 if (forwards == NULL) {
1324 fprintf(stderr, "error: %s\n", adb_error());
1325 return 1;
1326 }
1327 printf("%s", forwards);
1328 free(forwards);
1329 return 0;
1330 }
1331
1332 // Implement forward --remove-all
1333 else if (remove_all) {
1334 if (argc != 1)
1335 return usage();
1336 snprintf(buf, sizeof buf, "%s:killforward-all", host_prefix);
1337 }
1338
1339 // Implement forward --remove <local>
1340 else if (remove) {
1341 if (argc != 2)
1342 return usage();
1343 snprintf(buf, sizeof buf, "%s:killforward:%s", host_prefix, argv[1]);
1344 }
1345 // Or implement one of:
1346 // forward <local> <remote>
1347 // forward --no-rebind <local> <remote>
1348 else
1349 {
1350 if (argc != 3)
1351 return usage();
1352 const char* command = no_rebind ? "forward:norebind:" : "forward";
1353 snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
1354 }
1355
1356 if(adb_command(buf)) {
1357 fprintf(stderr,"error: %s\n", adb_error());
1358 return 1;
1359 }
1360 return 0;
1361 }
1362
1363 /* do_sync_*() commands */
1364
1365 if(!strcmp(argv[0], "ls")) {
1366 if(argc != 2) return usage();
1367 return do_sync_ls(argv[1]);
1368 }
1369
1370 if(!strcmp(argv[0], "push")) {
1371 if(argc != 3) return usage();
1372 return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1373 }
1374
1375 if(!strcmp(argv[0], "pull")) {
1376 if (argc == 2) {
1377 return do_sync_pull(argv[1], ".");
1378 } else if (argc == 3) {
1379 return do_sync_pull(argv[1], argv[2]);
1380 } else {
1381 return usage();
1382 }
1383 }
1384
1385 if(!strcmp(argv[0], "install")) {
1386 if (argc < 2) return usage();
1387 return install_app(ttype, serial, argc, argv);
1388 }
1389
1390 if(!strcmp(argv[0], "uninstall")) {
1391 if (argc < 2) return usage();
1392 return uninstall_app(ttype, serial, argc, argv);
1393 }
1394
1395 if(!strcmp(argv[0], "sync")) {
1396 char *srcarg, *android_srcpath, *data_srcpath;
1397 int listonly = 0;
1398
1399 int ret;
1400 if(argc < 2) {
1401 /* No local path was specified. */
1402 srcarg = NULL;
1403 } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1404 listonly = 1;
1405 if (argc == 3) {
1406 srcarg = argv[2];
1407 } else {
1408 srcarg = NULL;
1409 }
1410 } else if(argc == 2) {
1411 /* A local path or "android"/"data" arg was specified. */
1412 srcarg = argv[1];
1413 } else {
1414 return usage();
1415 }
1416 ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1417 if(ret != 0) return usage();
1418
1419 if(android_srcpath != NULL)
1420 ret = do_sync_sync(android_srcpath, "/system", listonly);
1421 if(ret == 0 && data_srcpath != NULL)
1422 ret = do_sync_sync(data_srcpath, "/data", listonly);
1423
1424 free(android_srcpath);
1425 free(data_srcpath);
1426 return ret;
1427 }
1428
1429 /* passthrough commands */
1430
1431 if(!strcmp(argv[0],"get-state") ||
1432 !strcmp(argv[0],"get-serialno") ||
1433 !strcmp(argv[0],"get-devpath"))
1434 {
1435 char *tmp;
1436
1437 format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1438 tmp = adb_query(buf);
1439 if(tmp) {
1440 printf("%s\n", tmp);
1441 return 0;
1442 } else {
1443 return 1;
1444 }
1445 }
1446
1447 /* other commands */
1448
1449 if(!strcmp(argv[0],"status-window")) {
1450 status_window(ttype, serial);
1451 return 0;
1452 }
1453
1454 if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
1455 return logcat(ttype, serial, argc, argv);
1456 }
1457
1458 if(!strcmp(argv[0],"ppp")) {
1459 return ppp(argc, argv);
1460 }
1461
1462 if (!strcmp(argv[0], "start-server")) {
1463 return adb_connect("host:start-server");
1464 }
1465
1466 if (!strcmp(argv[0], "backup")) {
1467 return backup(argc, argv);
1468 }
1469
1470 if (!strcmp(argv[0], "restore")) {
1471 return restore(argc, argv);
1472 }
1473
1474 if (!strcmp(argv[0], "jdwp")) {
1475 int fd = adb_connect("jdwp");
1476 if (fd >= 0) {
1477 read_and_dump(fd);
1478 adb_close(fd);
1479 return 0;
1480 } else {
1481 fprintf(stderr, "error: %s\n", adb_error());
1482 return -1;
1483 }
1484 }
1485
1486 /* "adb /?" is a common idiom under Windows */
1487 if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1488 help();
1489 return 0;
1490 }
1491
1492 if(!strcmp(argv[0], "version")) {
1493 version(stdout);
1494 return 0;
1495 }
1496
1497 usage();
1498 return 1;
1499 }
1500
do_cmd(transport_type ttype,char * serial,char * cmd,...)1501 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1502 {
1503 char *argv[16];
1504 int argc;
1505 va_list ap;
1506
1507 va_start(ap, cmd);
1508 argc = 0;
1509
1510 if (serial) {
1511 argv[argc++] = "-s";
1512 argv[argc++] = serial;
1513 } else if (ttype == kTransportUsb) {
1514 argv[argc++] = "-d";
1515 } else if (ttype == kTransportLocal) {
1516 argv[argc++] = "-e";
1517 }
1518
1519 argv[argc++] = cmd;
1520 while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1521 va_end(ap);
1522
1523 #if 0
1524 int n;
1525 fprintf(stderr,"argc = %d\n",argc);
1526 for(n = 0; n < argc; n++) {
1527 fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1528 }
1529 #endif
1530
1531 return adb_commandline(argc, argv);
1532 }
1533
find_sync_dirs(const char * srcarg,char ** android_srcdir_out,char ** data_srcdir_out)1534 int find_sync_dirs(const char *srcarg,
1535 char **android_srcdir_out, char **data_srcdir_out)
1536 {
1537 char *android_srcdir, *data_srcdir;
1538
1539 if(srcarg == NULL) {
1540 android_srcdir = product_file("system");
1541 data_srcdir = product_file("data");
1542 } else {
1543 /* srcarg may be "data", "system" or NULL.
1544 * if srcarg is NULL, then both data and system are synced
1545 */
1546 if(strcmp(srcarg, "system") == 0) {
1547 android_srcdir = product_file("system");
1548 data_srcdir = NULL;
1549 } else if(strcmp(srcarg, "data") == 0) {
1550 android_srcdir = NULL;
1551 data_srcdir = product_file("data");
1552 } else {
1553 /* It's not "system" or "data".
1554 */
1555 return 1;
1556 }
1557 }
1558
1559 if(android_srcdir_out != NULL)
1560 *android_srcdir_out = android_srcdir;
1561 else
1562 free(android_srcdir);
1563
1564 if(data_srcdir_out != NULL)
1565 *data_srcdir_out = data_srcdir;
1566 else
1567 free(data_srcdir);
1568
1569 return 0;
1570 }
1571
pm_command(transport_type transport,char * serial,int argc,char ** argv)1572 static int pm_command(transport_type transport, char* serial,
1573 int argc, char** argv)
1574 {
1575 char buf[4096];
1576
1577 snprintf(buf, sizeof(buf), "shell:pm");
1578
1579 while(argc-- > 0) {
1580 char *quoted;
1581
1582 quoted = dupAndQuote(*argv++);
1583
1584 strncat(buf, " ", sizeof(buf)-1);
1585 strncat(buf, quoted, sizeof(buf)-1);
1586 free(quoted);
1587 }
1588
1589 send_shellcommand(transport, serial, buf);
1590 return 0;
1591 }
1592
uninstall_app(transport_type transport,char * serial,int argc,char ** argv)1593 int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1594 {
1595 /* if the user choose the -k option, we refuse to do it until devices are
1596 out with the option to uninstall the remaining data somehow (adb/ui) */
1597 if (argc == 3 && strcmp(argv[1], "-k") == 0)
1598 {
1599 printf(
1600 "The -k option uninstalls the application while retaining the data/cache.\n"
1601 "At the moment, there is no way to remove the remaining data.\n"
1602 "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1603 "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1604 return -1;
1605 }
1606
1607 /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1608 return pm_command(transport, serial, argc, argv);
1609 }
1610
delete_file(transport_type transport,char * serial,char * filename)1611 static int delete_file(transport_type transport, char* serial, char* filename)
1612 {
1613 char buf[4096];
1614 char* quoted;
1615
1616 snprintf(buf, sizeof(buf), "shell:rm ");
1617 quoted = dupAndQuote(filename);
1618 strncat(buf, quoted, sizeof(buf)-1);
1619 free(quoted);
1620
1621 send_shellcommand(transport, serial, buf);
1622 return 0;
1623 }
1624
get_basename(const char * filename)1625 static const char* get_basename(const char* filename)
1626 {
1627 const char* basename = adb_dirstop(filename);
1628 if (basename) {
1629 basename++;
1630 return basename;
1631 } else {
1632 return filename;
1633 }
1634 }
1635
check_file(const char * filename)1636 static int check_file(const char* filename)
1637 {
1638 struct stat st;
1639
1640 if (filename == NULL) {
1641 return 0;
1642 }
1643
1644 if (stat(filename, &st) != 0) {
1645 fprintf(stderr, "can't find '%s' to install\n", filename);
1646 return 1;
1647 }
1648
1649 if (!S_ISREG(st.st_mode)) {
1650 fprintf(stderr, "can't install '%s' because it's not a file\n", filename);
1651 return 1;
1652 }
1653
1654 return 0;
1655 }
1656
install_app(transport_type transport,char * serial,int argc,char ** argv)1657 int install_app(transport_type transport, char* serial, int argc, char** argv)
1658 {
1659 static const char *const DATA_DEST = "/data/local/tmp/%s";
1660 static const char *const SD_DEST = "/sdcard/tmp/%s";
1661 const char* where = DATA_DEST;
1662 char apk_dest[PATH_MAX];
1663 char verification_dest[PATH_MAX];
1664 char* apk_file;
1665 char* verification_file = NULL;
1666 int file_arg = -1;
1667 int err;
1668 int i;
1669 int verify_apk = 1;
1670
1671 for (i = 1; i < argc; i++) {
1672 if (*argv[i] != '-') {
1673 file_arg = i;
1674 break;
1675 } else if (!strcmp(argv[i], "-i")) {
1676 // Skip the installer package name.
1677 i++;
1678 } else if (!strcmp(argv[i], "-s")) {
1679 where = SD_DEST;
1680 } else if (!strcmp(argv[i], "--algo")) {
1681 verify_apk = 0;
1682 i++;
1683 } else if (!strcmp(argv[i], "--iv")) {
1684 verify_apk = 0;
1685 i++;
1686 } else if (!strcmp(argv[i], "--key")) {
1687 verify_apk = 0;
1688 i++;
1689 }
1690 }
1691
1692 if (file_arg < 0) {
1693 fprintf(stderr, "can't find filename in arguments\n");
1694 return 1;
1695 } else if (file_arg + 2 < argc) {
1696 fprintf(stderr, "too many files specified; only takes APK file and verifier file\n");
1697 return 1;
1698 }
1699
1700 apk_file = argv[file_arg];
1701
1702 if (file_arg != argc - 1) {
1703 verification_file = argv[file_arg + 1];
1704 }
1705
1706 if (check_file(apk_file) || check_file(verification_file)) {
1707 return 1;
1708 }
1709
1710 snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
1711 if (verification_file != NULL) {
1712 snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file));
1713
1714 if (!strcmp(apk_dest, verification_dest)) {
1715 fprintf(stderr, "APK and verification file can't have the same name\n");
1716 return 1;
1717 }
1718 }
1719
1720 err = do_sync_push(apk_file, apk_dest, verify_apk);
1721 if (err) {
1722 goto cleanup_apk;
1723 } else {
1724 argv[file_arg] = apk_dest; /* destination name, not source location */
1725 }
1726
1727 if (verification_file != NULL) {
1728 err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
1729 if (err) {
1730 goto cleanup_apk;
1731 } else {
1732 argv[file_arg + 1] = verification_dest; /* destination name, not source location */
1733 }
1734 }
1735
1736 pm_command(transport, serial, argc, argv);
1737
1738 cleanup_apk:
1739 if (verification_file != NULL) {
1740 delete_file(transport, serial, verification_dest);
1741 }
1742
1743 delete_file(transport, serial, apk_dest);
1744
1745 return err;
1746 }
1747