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