commandline.c revision 702967afb1bebc97c0b8a23c075d4932820ef7a3
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
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;
49
50static char *product_file(const char *extra)
51{
52    int n;
53    char *x;
54
55    if (gProductOutPath == NULL) {
56        fprintf(stderr, "adb: Product directory not specified; "
57                "use -p or define ANDROID_PRODUCT_OUT\n");
58        exit(1);
59    }
60
61    n = strlen(gProductOutPath) + strlen(extra) + 2;
62    x = malloc(n);
63    if (x == 0) {
64        fprintf(stderr, "adb: Out of memory (product_file())\n");
65        exit(1);
66    }
67
68    snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
69    return x;
70}
71
72void version(FILE * out) {
73    fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
74         ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
75}
76
77void help()
78{
79    version(stderr);
80
81    fprintf(stderr,
82        "\n"
83        " -d                            - directs command to the only connected USB device\n"
84        "                                 returns an error if more than one USB device is present.\n"
85        " -e                            - directs command to the only running emulator.\n"
86        "                                 returns an error if more than one emulator is running.\n"
87        " -s <serial number>            - directs command to the USB device or emulator with\n"
88        "                                 the given serial number. Overrides ANDROID_SERIAL\n"
89        "                                 environment variable.\n"
90        " -p <product name or path>     - simple product name like 'sooner', or\n"
91        "                                 a relative/absolute path to a product\n"
92        "                                 out directory like 'out/target/product/sooner'.\n"
93        "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
94        "                                 environment variable is used, which must\n"
95        "                                 be an absolute path.\n"
96        " devices                       - list all connected devices\n"
97        " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
98        "                                 Port 5555 is used by default if no port number is specified.\n"
99        " disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.\n"
100        "                                 Port 5555 is used by default if no port number is specified.\n"
101        "                                 Using this command with no additional arguments\n"
102        "                                 will disconnect from all connected TCP/IP devices.\n"
103        "\n"
104        "device commands:\n"
105        "  adb push <local> <remote>    - copy file/dir to device\n"
106        "  adb pull <remote> [<local>]  - copy file/dir from device\n"
107        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
108        "                                 (-l means list but don't copy)\n"
109        "                                 (see 'adb help all')\n"
110        "  adb shell                    - run remote shell interactively\n"
111        "  adb shell <command>          - run remote shell command\n"
112        "  adb emu <command>            - run emulator console command\n"
113        "  adb logcat [ <filter-spec> ] - View device log\n"
114        "  adb forward <local> <remote> - forward socket connections\n"
115        "                                 forward specs are one of: \n"
116        "                                   tcp:<port>\n"
117        "                                   localabstract:<unix domain socket name>\n"
118        "                                   localreserved:<unix domain socket name>\n"
119        "                                   localfilesystem:<unix domain socket name>\n"
120        "                                   dev:<character device name>\n"
121        "                                   jdwp:<process pid> (remote only)\n"
122        "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
123        "  adb install [-l] [-r] [-s] <file> - push this package file to the device and install it\n"
124        "                                 ('-l' means forward-lock the app)\n"
125        "                                 ('-r' means reinstall the app, keeping its data)\n"
126        "                                 ('-s' means install on SD card instead of internal storage)\n"
127        "  adb uninstall [-k] <package> - remove this app package from the device\n"
128        "                                 ('-k' means keep the data and cache directories)\n"
129        "  adb bugreport                - return all information from the device\n"
130        "                                 that should be included in a bug report.\n"
131        "\n"
132        "  adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] [<packages...>]\n"
133        "                               - Write a tarfile backup of the device's data to <file>.\n"
134        "                                 The -f option must come first; if not specified then the data\n"
135        "                                 is written to \"backup.tar\" in the current directory.\n"
136        "                                 (-apk|-noapk enable/disable backup of the .apks themselves\n"
137        "                                    in the tarfile; the default is noapk.)\n"
138        "                                 (-shared|-noshared enable/disable backup of the device's\n"
139        "                                    shared storage / SD card contents; the default is noshared.)\n"
140        "                                 (-all means to back up all installed applications)\n"
141        "                                 (<packages...> is the list of applications to be backed up.  If\n"
142        "                                    the -all or -shared flags are passed, then the package\n"
143        "                                    list is optional.)\n"
144        "\n"
145        "  adb restore <file>           - restore device contents from the <file> backup tarfile\n"
146        "\n"
147        "  adb help                     - show this help message\n"
148        "  adb version                  - show version num\n"
149        "\n"
150        "scripting:\n"
151        "  adb wait-for-device          - block until device is online\n"
152        "  adb start-server             - ensure that there is a server running\n"
153        "  adb kill-server              - kill the server if it is running\n"
154        "  adb get-state                - prints: offline | bootloader | device\n"
155        "  adb get-serialno             - prints: <serial-number>\n"
156        "  adb status-window            - continuously print device status for a specified device\n"
157        "  adb remount                  - remounts the /system partition on the device read-write\n"
158        "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
159        "  adb reboot-bootloader        - reboots the device into the bootloader\n"
160        "  adb root                     - restarts the adbd daemon with root permissions\n"
161        "  adb usb                      - restarts the adbd daemon listening on USB\n"
162        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
163        "\n"
164        "networking:\n"
165        "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
166        " Note: you should not automatically start a PPP connection.\n"
167        " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
168        " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
169        "\n"
170        "adb sync notes: adb sync [ <directory> ]\n"
171        "  <localdir> can be interpreted in several ways:\n"
172        "\n"
173        "  - If <directory> is not specified, both /system and /data partitions will be updated.\n"
174        "\n"
175        "  - If it is \"system\" or \"data\", only the corresponding partition\n"
176        "    is updated.\n"
177        "\n"
178        "environmental variables:\n"
179        "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
180        "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
181        "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
182        "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
183        );
184}
185
186int usage()
187{
188    help();
189    return 1;
190}
191
192#ifdef HAVE_TERMIO_H
193static struct termios tio_save;
194
195static void stdin_raw_init(int fd)
196{
197    struct termios tio;
198
199    if(tcgetattr(fd, &tio)) return;
200    if(tcgetattr(fd, &tio_save)) return;
201
202    tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
203
204        /* no timeout but request at least one character per read */
205    tio.c_cc[VTIME] = 0;
206    tio.c_cc[VMIN] = 1;
207
208    tcsetattr(fd, TCSANOW, &tio);
209    tcflush(fd, TCIFLUSH);
210}
211
212static void stdin_raw_restore(int fd)
213{
214    tcsetattr(fd, TCSANOW, &tio_save);
215    tcflush(fd, TCIFLUSH);
216}
217#endif
218
219static void read_and_dump(int fd)
220{
221    char buf[4096];
222    int len;
223
224    while(fd >= 0) {
225        D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
226        len = adb_read(fd, buf, 4096);
227        D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
228        if(len == 0) {
229            break;
230        }
231
232        if(len < 0) {
233            if(errno == EINTR) continue;
234            break;
235        }
236        fwrite(buf, 1, len, stdout);
237        fflush(stdout);
238    }
239}
240
241static void copy_to_file(int inFd, int outFd) {
242    char buf[4096];
243    int len;
244
245    D("copy_to_file(%d -> %d)\n", inFd, outFd);
246    for (;;) {
247        len = adb_read(inFd, buf, sizeof(buf));
248        if (len == 0) {
249            break;
250        }
251        if (len < 0) {
252            if (errno == EINTR) continue;
253            D("copy_to_file() : error %d\n", errno);
254            break;
255        }
256        adb_write(outFd, buf, len);
257    }
258}
259
260static void *stdin_read_thread(void *x)
261{
262    int fd, fdi;
263    unsigned char buf[1024];
264    int r, n;
265    int state = 0;
266
267    int *fds = (int*) x;
268    fd = fds[0];
269    fdi = fds[1];
270    free(fds);
271
272    for(;;) {
273        /* fdi is really the client's stdin, so use read, not adb_read here */
274        D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
275        r = unix_read(fdi, buf, 1024);
276        D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
277        if(r == 0) break;
278        if(r < 0) {
279            if(errno == EINTR) continue;
280            break;
281        }
282        for(n = 0; n < r; n++){
283            switch(buf[n]) {
284            case '\n':
285                state = 1;
286                break;
287            case '\r':
288                state = 1;
289                break;
290            case '~':
291                if(state == 1) state++;
292                break;
293            case '.':
294                if(state == 2) {
295                    fprintf(stderr,"\n* disconnect *\n");
296#ifdef HAVE_TERMIO_H
297                    stdin_raw_restore(fdi);
298#endif
299                    exit(0);
300                }
301            default:
302                state = 0;
303            }
304        }
305        r = adb_write(fd, buf, r);
306        if(r <= 0) {
307            break;
308        }
309    }
310    return 0;
311}
312
313int interactive_shell(void)
314{
315    adb_thread_t thr;
316    int fdi, fd;
317    int *fds;
318
319    fd = adb_connect("shell:");
320    if(fd < 0) {
321        fprintf(stderr,"error: %s\n", adb_error());
322        return 1;
323    }
324    fdi = 0; //dup(0);
325
326    fds = malloc(sizeof(int) * 2);
327    fds[0] = fd;
328    fds[1] = fdi;
329
330#ifdef HAVE_TERMIO_H
331    stdin_raw_init(fdi);
332#endif
333    adb_thread_create(&thr, stdin_read_thread, fds);
334    read_and_dump(fd);
335#ifdef HAVE_TERMIO_H
336    stdin_raw_restore(fdi);
337#endif
338    return 0;
339}
340
341
342static void format_host_command(char* buffer, size_t  buflen, const char* command, transport_type ttype, const char* serial)
343{
344    if (serial) {
345        snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
346    } else {
347        const char* prefix = "host";
348        if (ttype == kTransportUsb)
349            prefix = "host-usb";
350        else if (ttype == kTransportLocal)
351            prefix = "host-local";
352
353        snprintf(buffer, buflen, "%s:%s", prefix, command);
354    }
355}
356
357static void status_window(transport_type ttype, const char* serial)
358{
359    char command[4096];
360    char *state = 0;
361    char *laststate = 0;
362
363        /* silence stderr */
364#ifdef _WIN32
365    /* XXX: TODO */
366#else
367    int  fd;
368    fd = unix_open("/dev/null", O_WRONLY);
369    dup2(fd, 2);
370    adb_close(fd);
371#endif
372
373    format_host_command(command, sizeof command, "get-state", ttype, serial);
374
375    for(;;) {
376        adb_sleep_ms(250);
377
378        if(state) {
379            free(state);
380            state = 0;
381        }
382
383        state = adb_query(command);
384
385        if(state) {
386            if(laststate && !strcmp(state,laststate)){
387                continue;
388            } else {
389                if(laststate) free(laststate);
390                laststate = strdup(state);
391            }
392        }
393
394        printf("%c[2J%c[2H", 27, 27);
395        printf("Android Debug Bridge\n");
396        printf("State: %s\n", state ? state : "offline");
397        fflush(stdout);
398    }
399}
400
401/** duplicate string and quote all \ " ( ) chars + space character. */
402static char *
403dupAndQuote(const char *s)
404{
405    const char *ts;
406    size_t alloc_len;
407    char *ret;
408    char *dest;
409
410    ts = s;
411
412    alloc_len = 0;
413
414    for( ;*ts != '\0'; ts++) {
415        alloc_len++;
416        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
417            alloc_len++;
418        }
419    }
420
421    ret = (char *)malloc(alloc_len + 1);
422
423    ts = s;
424    dest = ret;
425
426    for ( ;*ts != '\0'; ts++) {
427        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
428            *dest++ = '\\';
429        }
430
431        *dest++ = *ts;
432    }
433
434    *dest++ = '\0';
435
436    return ret;
437}
438
439/**
440 * Run ppp in "notty" mode against a resource listed as the first parameter
441 * eg:
442 *
443 * ppp dev:/dev/omap_csmi_tty0 <ppp options>
444 *
445 */
446int ppp(int argc, char **argv)
447{
448#ifdef HAVE_WIN32_PROC
449    fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
450    return -1;
451#else
452    char *adb_service_name;
453    pid_t pid;
454    int fd;
455
456    if (argc < 2) {
457        fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
458                argv[0]);
459
460        return 1;
461    }
462
463    adb_service_name = argv[1];
464
465    fd = adb_connect(adb_service_name);
466
467    if(fd < 0) {
468        fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
469                adb_service_name, adb_error());
470        return 1;
471    }
472
473    pid = fork();
474
475    if (pid < 0) {
476        perror("from fork()");
477        return 1;
478    } else if (pid == 0) {
479        int err;
480        int i;
481        const char **ppp_args;
482
483        // copy args
484        ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
485        ppp_args[0] = "pppd";
486        for (i = 2 ; i < argc ; i++) {
487            //argv[2] and beyond become ppp_args[1] and beyond
488            ppp_args[i - 1] = argv[i];
489        }
490        ppp_args[i-1] = NULL;
491
492        // child side
493
494        dup2(fd, STDIN_FILENO);
495        dup2(fd, STDOUT_FILENO);
496        adb_close(STDERR_FILENO);
497        adb_close(fd);
498
499        err = execvp("pppd", (char * const *)ppp_args);
500
501        if (err < 0) {
502            perror("execing pppd");
503        }
504        exit(-1);
505    } else {
506        // parent side
507
508        adb_close(fd);
509        return 0;
510    }
511#endif /* !HAVE_WIN32_PROC */
512}
513
514static int send_shellcommand(transport_type transport, char* serial, char* buf)
515{
516    int fd, ret;
517
518    for(;;) {
519        fd = adb_connect(buf);
520        if(fd >= 0)
521            break;
522        fprintf(stderr,"- waiting for device -\n");
523        adb_sleep_ms(1000);
524        do_cmd(transport, serial, "wait-for-device", 0);
525    }
526
527    read_and_dump(fd);
528    ret = adb_close(fd);
529    if (ret)
530        perror("close");
531
532    return ret;
533}
534
535static int logcat(transport_type transport, char* serial, int argc, char **argv)
536{
537    char buf[4096];
538
539    char *log_tags;
540    char *quoted_log_tags;
541
542    log_tags = getenv("ANDROID_LOG_TAGS");
543    quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
544
545    snprintf(buf, sizeof(buf),
546        "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
547        quoted_log_tags);
548
549    free(quoted_log_tags);
550
551    argc -= 1;
552    argv += 1;
553    while(argc-- > 0) {
554        char *quoted;
555
556        quoted = dupAndQuote (*argv++);
557
558        strncat(buf, " ", sizeof(buf)-1);
559        strncat(buf, quoted, sizeof(buf)-1);
560        free(quoted);
561    }
562
563    send_shellcommand(transport, serial, buf);
564    return 0;
565}
566
567static int backup(int argc, char** argv) {
568    char buf[4096];
569    const char* filename = "./backup.tar";
570    int fd, outFd;
571
572    if (!strcmp("-f", argv[1])) {
573        if (argc < 3) return usage();
574        filename = argv[2];
575        argc -= 2;
576        argv += 2;
577    }
578
579    outFd = adb_open_mode(filename, O_WRONLY | O_CREAT | O_TRUNC, 0640);
580    if (outFd < 0) {
581        fprintf(stderr, "adb: unable to open file %s\n", filename);
582        return -1;
583    }
584
585    snprintf(buf, sizeof(buf), "backup");
586    for (argc--, argv++; argc; argc--, argv++) {
587        strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
588        strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
589    }
590
591    D("backup. filename=%s buf=%s\n", filename, buf);
592    fd = adb_connect(buf);
593    if (fd < 0) {
594        fprintf(stderr, "adb: unable to connect for backup\n");
595        adb_close(outFd);
596        return -1;
597    }
598
599    copy_to_file(fd, outFd);
600
601    adb_close(fd);
602    adb_close(outFd);
603    return 0;
604}
605
606static int restore(int argc, char** argv) {
607    const char* filename;
608    int fd, tarFd;
609
610    if (argc != 2) return usage();
611
612    filename = argv[1];
613    tarFd = adb_open(filename, O_RDONLY);
614    if (tarFd < 0) {
615        fprintf(stderr, "adb: unable to open file %s\n", filename);
616        return -1;
617    }
618
619    fd = adb_connect("restore:");
620    if (fd < 0) {
621        fprintf(stderr, "adb: unable to connect for backup\n");
622        adb_close(tarFd);
623        return -1;
624    }
625
626    copy_to_file(tarFd, fd);
627
628    adb_close(fd);
629    adb_close(tarFd);
630    return 0;
631}
632
633#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
634static int top_works(const char *top)
635{
636    if (top != NULL && adb_is_absolute_host_path(top)) {
637        char path_buf[PATH_MAX];
638        snprintf(path_buf, sizeof(path_buf),
639                "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
640        return access(path_buf, F_OK) == 0;
641    }
642    return 0;
643}
644
645static char *find_top_from(const char *indir, char path_buf[PATH_MAX])
646{
647    strcpy(path_buf, indir);
648    while (1) {
649        if (top_works(path_buf)) {
650            return path_buf;
651        }
652        char *s = adb_dirstop(path_buf);
653        if (s != NULL) {
654            *s = '\0';
655        } else {
656            path_buf[0] = '\0';
657            return NULL;
658        }
659    }
660}
661
662static char *find_top(char path_buf[PATH_MAX])
663{
664    char *top = getenv("ANDROID_BUILD_TOP");
665    if (top != NULL && top[0] != '\0') {
666        if (!top_works(top)) {
667            fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
668            return NULL;
669        }
670    } else {
671        top = getenv("TOP");
672        if (top != NULL && top[0] != '\0') {
673            if (!top_works(top)) {
674                fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
675                return NULL;
676            }
677        } else {
678            top = NULL;
679        }
680    }
681
682    if (top != NULL) {
683        /* The environment pointed to a top directory that works.
684         */
685        strcpy(path_buf, top);
686        return path_buf;
687    }
688
689    /* The environment didn't help.  Walk up the tree from the CWD
690     * to see if we can find the top.
691     */
692    char dir[PATH_MAX];
693    top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
694    if (top == NULL) {
695        /* If the CWD isn't under a good-looking top, see if the
696         * executable is.
697         */
698        get_my_path(dir, PATH_MAX);
699        top = find_top_from(dir, path_buf);
700    }
701    return top;
702}
703
704/* <hint> may be:
705 * - A simple product name
706 *   e.g., "sooner"
707TODO: debug?  sooner-debug, sooner:debug?
708 * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
709 *   e.g., "out/target/product/sooner"
710 * - An absolute path to the PRODUCT_OUT dir
711 *   e.g., "/src/device/out/target/product/sooner"
712 *
713 * Given <hint>, try to construct an absolute path to the
714 * ANDROID_PRODUCT_OUT dir.
715 */
716static const char *find_product_out_path(const char *hint)
717{
718    static char path_buf[PATH_MAX];
719
720    if (hint == NULL || hint[0] == '\0') {
721        return NULL;
722    }
723
724    /* If it's already absolute, don't bother doing any work.
725     */
726    if (adb_is_absolute_host_path(hint)) {
727        strcpy(path_buf, hint);
728        return path_buf;
729    }
730
731    /* If there are any slashes in it, assume it's a relative path;
732     * make it absolute.
733     */
734    if (adb_dirstart(hint) != NULL) {
735        if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
736            fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
737            return NULL;
738        }
739        if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
740            fprintf(stderr, "adb: Couldn't assemble path\n");
741            return NULL;
742        }
743        strcat(path_buf, OS_PATH_SEPARATOR_STR);
744        strcat(path_buf, hint);
745        return path_buf;
746    }
747
748    /* It's a string without any slashes.  Try to do something with it.
749     *
750     * Try to find the root of the build tree, and build a PRODUCT_OUT
751     * path from there.
752     */
753    char top_buf[PATH_MAX];
754    const char *top = find_top(top_buf);
755    if (top == NULL) {
756        fprintf(stderr, "adb: Couldn't find top of build tree\n");
757        return NULL;
758    }
759//TODO: if we have a way to indicate debug, look in out/debug/target/...
760    snprintf(path_buf, sizeof(path_buf),
761            "%s" OS_PATH_SEPARATOR_STR
762            "out" OS_PATH_SEPARATOR_STR
763            "target" OS_PATH_SEPARATOR_STR
764            "product" OS_PATH_SEPARATOR_STR
765            "%s", top_buf, hint);
766    if (access(path_buf, F_OK) < 0) {
767        fprintf(stderr, "adb: Couldn't find a product dir "
768                "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
769        return NULL;
770    }
771    return path_buf;
772}
773
774int adb_commandline(int argc, char **argv)
775{
776    char buf[4096];
777    int no_daemon = 0;
778    int is_daemon = 0;
779    int is_server = 0;
780    int persist = 0;
781    int r;
782    int quote;
783    transport_type ttype = kTransportAny;
784    char* serial = NULL;
785    char* server_port_str = NULL;
786
787        /* If defined, this should be an absolute path to
788         * the directory containing all of the various system images
789         * for a particular product.  If not defined, and the adb
790         * command requires this information, then the user must
791         * specify the path using "-p".
792         */
793    gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
794    if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
795        gProductOutPath = NULL;
796    }
797    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
798
799    serial = getenv("ANDROID_SERIAL");
800
801    /* Validate and assign the server port */
802    server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
803    int server_port = DEFAULT_ADB_PORT;
804    if (server_port_str && strlen(server_port_str) > 0) {
805        server_port = (int) strtol(server_port_str, NULL, 0);
806        if (server_port <= 0) {
807            fprintf(stderr,
808                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
809                    server_port_str);
810            return usage();
811        }
812    }
813
814    /* modifiers and flags */
815    while(argc > 0) {
816        if(!strcmp(argv[0],"server")) {
817            is_server = 1;
818        } else if(!strcmp(argv[0],"nodaemon")) {
819            no_daemon = 1;
820        } else if (!strcmp(argv[0], "fork-server")) {
821            /* this is a special flag used only when the ADB client launches the ADB Server */
822            is_daemon = 1;
823        } else if(!strcmp(argv[0],"persist")) {
824            persist = 1;
825        } else if(!strncmp(argv[0], "-p", 2)) {
826            const char *product = NULL;
827            if (argv[0][2] == '\0') {
828                if (argc < 2) return usage();
829                product = argv[1];
830                argc--;
831                argv++;
832            } else {
833                product = argv[1] + 2;
834            }
835            gProductOutPath = find_product_out_path(product);
836            if (gProductOutPath == NULL) {
837                fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
838                        product);
839                return usage();
840            }
841        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
842            if (isdigit(argv[0][2])) {
843                serial = argv[0] + 2;
844            } else {
845                if(argc < 2 || argv[0][2] != '\0') return usage();
846                serial = argv[1];
847                argc--;
848                argv++;
849            }
850        } else if (!strcmp(argv[0],"-d")) {
851            ttype = kTransportUsb;
852        } else if (!strcmp(argv[0],"-e")) {
853            ttype = kTransportLocal;
854        } else {
855                /* out of recognized modifiers and flags */
856            break;
857        }
858        argc--;
859        argv++;
860    }
861
862    adb_set_transport(ttype, serial);
863    adb_set_tcp_specifics(server_port);
864
865    if (is_server) {
866        if (no_daemon || is_daemon) {
867            r = adb_main(is_daemon, server_port);
868        } else {
869            r = launch_server(server_port);
870        }
871        if(r) {
872            fprintf(stderr,"* could not start server *\n");
873        }
874        return r;
875    }
876
877top:
878    if(argc == 0) {
879        return usage();
880    }
881
882    /* adb_connect() commands */
883
884    if(!strcmp(argv[0], "devices")) {
885        char *tmp;
886        snprintf(buf, sizeof buf, "host:%s", argv[0]);
887        tmp = adb_query(buf);
888        if(tmp) {
889            printf("List of devices attached \n");
890            printf("%s\n", tmp);
891            return 0;
892        } else {
893            return 1;
894        }
895    }
896
897    if(!strcmp(argv[0], "connect")) {
898        char *tmp;
899        if (argc != 2) {
900            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
901            return 1;
902        }
903        snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
904        tmp = adb_query(buf);
905        if(tmp) {
906            printf("%s\n", tmp);
907            return 0;
908        } else {
909            return 1;
910        }
911    }
912
913    if(!strcmp(argv[0], "disconnect")) {
914        char *tmp;
915        if (argc > 2) {
916            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
917            return 1;
918        }
919        if (argc == 2) {
920            snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
921        } else {
922            snprintf(buf, sizeof buf, "host:disconnect:");
923        }
924        tmp = adb_query(buf);
925        if(tmp) {
926            printf("%s\n", tmp);
927            return 0;
928        } else {
929            return 1;
930        }
931    }
932
933    if (!strcmp(argv[0], "emu")) {
934        return adb_send_emulator_command(argc, argv);
935    }
936
937    if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
938        int r;
939        int fd;
940
941        char h = (argv[0][0] == 'h');
942
943        if (h) {
944            printf("\x1b[41;33m");
945            fflush(stdout);
946        }
947
948        if(argc < 2) {
949            D("starting interactive shell\n");
950            r = interactive_shell();
951            if (h) {
952                printf("\x1b[0m");
953                fflush(stdout);
954            }
955            return r;
956        }
957
958        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
959        argc -= 2;
960        argv += 2;
961        while(argc-- > 0) {
962            strcat(buf, " ");
963
964            /* quote empty strings and strings with spaces */
965            quote = (**argv == 0 || strchr(*argv, ' '));
966            if (quote)
967                strcat(buf, "\"");
968            strcat(buf, *argv++);
969            if (quote)
970                strcat(buf, "\"");
971        }
972
973        for(;;) {
974            D("interactive shell loop. buff=%s\n", buf);
975            fd = adb_connect(buf);
976            if(fd >= 0) {
977                D("about to read_and_dump(fd=%d)\n", fd);
978                read_and_dump(fd);
979                D("read_and_dump() done.\n");
980                adb_close(fd);
981                r = 0;
982            } else {
983                fprintf(stderr,"error: %s\n", adb_error());
984                r = -1;
985            }
986
987            if(persist) {
988                fprintf(stderr,"\n- waiting for device -\n");
989                adb_sleep_ms(1000);
990                do_cmd(ttype, serial, "wait-for-device", 0);
991            } else {
992                if (h) {
993                    printf("\x1b[0m");
994                    fflush(stdout);
995                }
996                D("interactive shell loop. return r=%d\n", r);
997                return r;
998            }
999        }
1000    }
1001
1002    if(!strcmp(argv[0], "kill-server")) {
1003        int fd;
1004        fd = _adb_connect("host:kill");
1005        if(fd == -1) {
1006            fprintf(stderr,"* server not running *\n");
1007            return 1;
1008        }
1009        return 0;
1010    }
1011
1012    if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
1013            || !strcmp(argv[0], "reboot-bootloader")
1014            || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
1015            || !strcmp(argv[0], "root")) {
1016        char command[100];
1017        if (!strcmp(argv[0], "reboot-bootloader"))
1018            snprintf(command, sizeof(command), "reboot:bootloader");
1019        else if (argc > 1)
1020            snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
1021        else
1022            snprintf(command, sizeof(command), "%s:", argv[0]);
1023        int fd = adb_connect(command);
1024        if(fd >= 0) {
1025            read_and_dump(fd);
1026            adb_close(fd);
1027            return 0;
1028        }
1029        fprintf(stderr,"error: %s\n", adb_error());
1030        return 1;
1031    }
1032
1033    if(!strcmp(argv[0], "bugreport")) {
1034        if (argc != 1) return usage();
1035        do_cmd(ttype, serial, "shell", "bugreport", 0);
1036        return 0;
1037    }
1038
1039    /* adb_command() wrapper commands */
1040
1041    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1042        char* service = argv[0];
1043        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1044            if (ttype == kTransportUsb) {
1045                service = "wait-for-usb";
1046            } else if (ttype == kTransportLocal) {
1047                service = "wait-for-local";
1048            } else {
1049                service = "wait-for-any";
1050            }
1051        }
1052
1053        format_host_command(buf, sizeof buf, service, ttype, serial);
1054
1055        if (adb_command(buf)) {
1056            D("failure: %s *\n",adb_error());
1057            fprintf(stderr,"error: %s\n", adb_error());
1058            return 1;
1059        }
1060
1061        /* Allow a command to be run after wait-for-device,
1062            * e.g. 'adb wait-for-device shell'.
1063            */
1064        if(argc > 1) {
1065            argc--;
1066            argv++;
1067            goto top;
1068        }
1069        return 0;
1070    }
1071
1072    if(!strcmp(argv[0], "forward")) {
1073        if(argc != 3) return usage();
1074        if (serial) {
1075            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
1076        } else if (ttype == kTransportUsb) {
1077            snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
1078        } else if (ttype == kTransportLocal) {
1079            snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
1080        } else {
1081            snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
1082        }
1083        if(adb_command(buf)) {
1084            fprintf(stderr,"error: %s\n", adb_error());
1085            return 1;
1086        }
1087        return 0;
1088    }
1089
1090    /* do_sync_*() commands */
1091
1092    if(!strcmp(argv[0], "ls")) {
1093        if(argc != 2) return usage();
1094        return do_sync_ls(argv[1]);
1095    }
1096
1097    if(!strcmp(argv[0], "push")) {
1098        if(argc != 3) return usage();
1099        return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1100    }
1101
1102    if(!strcmp(argv[0], "pull")) {
1103        if (argc == 2) {
1104            return do_sync_pull(argv[1], ".");
1105        } else if (argc == 3) {
1106            return do_sync_pull(argv[1], argv[2]);
1107        } else {
1108            return usage();
1109        }
1110    }
1111
1112    if(!strcmp(argv[0], "install")) {
1113        if (argc < 2) return usage();
1114        return install_app(ttype, serial, argc, argv);
1115    }
1116
1117    if(!strcmp(argv[0], "uninstall")) {
1118        if (argc < 2) return usage();
1119        return uninstall_app(ttype, serial, argc, argv);
1120    }
1121
1122    if(!strcmp(argv[0], "sync")) {
1123        char *srcarg, *android_srcpath, *data_srcpath;
1124        int listonly = 0;
1125
1126        int ret;
1127        if(argc < 2) {
1128            /* No local path was specified. */
1129            srcarg = NULL;
1130        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1131            listonly = 1;
1132            if (argc == 3) {
1133                srcarg = argv[2];
1134            } else {
1135                srcarg = NULL;
1136            }
1137        } else if(argc == 2) {
1138            /* A local path or "android"/"data" arg was specified. */
1139            srcarg = argv[1];
1140        } else {
1141            return usage();
1142        }
1143        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1144        if(ret != 0) return usage();
1145
1146        if(android_srcpath != NULL)
1147            ret = do_sync_sync(android_srcpath, "/system", listonly);
1148        if(ret == 0 && data_srcpath != NULL)
1149            ret = do_sync_sync(data_srcpath, "/data", listonly);
1150
1151        free(android_srcpath);
1152        free(data_srcpath);
1153        return ret;
1154    }
1155
1156    /* passthrough commands */
1157
1158    if(!strcmp(argv[0],"get-state") ||
1159        !strcmp(argv[0],"get-serialno"))
1160    {
1161        char *tmp;
1162
1163        format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1164        tmp = adb_query(buf);
1165        if(tmp) {
1166            printf("%s\n", tmp);
1167            return 0;
1168        } else {
1169            return 1;
1170        }
1171    }
1172
1173    /* other commands */
1174
1175    if(!strcmp(argv[0],"status-window")) {
1176        status_window(ttype, serial);
1177        return 0;
1178    }
1179
1180    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1181        return logcat(ttype, serial, argc, argv);
1182    }
1183
1184    if(!strcmp(argv[0],"ppp")) {
1185        return ppp(argc, argv);
1186    }
1187
1188    if (!strcmp(argv[0], "start-server")) {
1189        return adb_connect("host:start-server");
1190    }
1191
1192    if (!strcmp(argv[0], "backup")) {
1193        return backup(argc, argv);
1194    }
1195
1196    if (!strcmp(argv[0], "restore")) {
1197        return restore(argc, argv);
1198    }
1199
1200    if (!strcmp(argv[0], "jdwp")) {
1201        int  fd = adb_connect("jdwp");
1202        if (fd >= 0) {
1203            read_and_dump(fd);
1204            adb_close(fd);
1205            return 0;
1206        } else {
1207            fprintf(stderr, "error: %s\n", adb_error());
1208            return -1;
1209        }
1210    }
1211
1212    /* "adb /?" is a common idiom under Windows */
1213    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1214        help();
1215        return 0;
1216    }
1217
1218    if(!strcmp(argv[0], "version")) {
1219        version(stdout);
1220        return 0;
1221    }
1222
1223    usage();
1224    return 1;
1225}
1226
1227static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1228{
1229    char *argv[16];
1230    int argc;
1231    va_list ap;
1232
1233    va_start(ap, cmd);
1234    argc = 0;
1235
1236    if (serial) {
1237        argv[argc++] = "-s";
1238        argv[argc++] = serial;
1239    } else if (ttype == kTransportUsb) {
1240        argv[argc++] = "-d";
1241    } else if (ttype == kTransportLocal) {
1242        argv[argc++] = "-e";
1243    }
1244
1245    argv[argc++] = cmd;
1246    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1247    va_end(ap);
1248
1249#if 0
1250    int n;
1251    fprintf(stderr,"argc = %d\n",argc);
1252    for(n = 0; n < argc; n++) {
1253        fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1254    }
1255#endif
1256
1257    return adb_commandline(argc, argv);
1258}
1259
1260int find_sync_dirs(const char *srcarg,
1261        char **android_srcdir_out, char **data_srcdir_out)
1262{
1263    char *android_srcdir, *data_srcdir;
1264
1265    if(srcarg == NULL) {
1266        android_srcdir = product_file("system");
1267        data_srcdir = product_file("data");
1268    } else {
1269        /* srcarg may be "data", "system" or NULL.
1270         * if srcarg is NULL, then both data and system are synced
1271         */
1272        if(strcmp(srcarg, "system") == 0) {
1273            android_srcdir = product_file("system");
1274            data_srcdir = NULL;
1275        } else if(strcmp(srcarg, "data") == 0) {
1276            android_srcdir = NULL;
1277            data_srcdir = product_file("data");
1278        } else {
1279            /* It's not "system" or "data".
1280             */
1281            return 1;
1282        }
1283    }
1284
1285    if(android_srcdir_out != NULL)
1286        *android_srcdir_out = android_srcdir;
1287    else
1288        free(android_srcdir);
1289
1290    if(data_srcdir_out != NULL)
1291        *data_srcdir_out = data_srcdir;
1292    else
1293        free(data_srcdir);
1294
1295    return 0;
1296}
1297
1298static int pm_command(transport_type transport, char* serial,
1299                      int argc, char** argv)
1300{
1301    char buf[4096];
1302
1303    snprintf(buf, sizeof(buf), "shell:pm");
1304
1305    while(argc-- > 0) {
1306        char *quoted;
1307
1308        quoted = dupAndQuote(*argv++);
1309
1310        strncat(buf, " ", sizeof(buf)-1);
1311        strncat(buf, quoted, sizeof(buf)-1);
1312        free(quoted);
1313    }
1314
1315    send_shellcommand(transport, serial, buf);
1316    return 0;
1317}
1318
1319int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1320{
1321    /* if the user choose the -k option, we refuse to do it until devices are
1322       out with the option to uninstall the remaining data somehow (adb/ui) */
1323    if (argc == 3 && strcmp(argv[1], "-k") == 0)
1324    {
1325        printf(
1326            "The -k option uninstalls the application while retaining the data/cache.\n"
1327            "At the moment, there is no way to remove the remaining data.\n"
1328            "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1329            "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1330        return -1;
1331    }
1332
1333    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1334    return pm_command(transport, serial, argc, argv);
1335}
1336
1337static int delete_file(transport_type transport, char* serial, char* filename)
1338{
1339    char buf[4096];
1340    char* quoted;
1341
1342    snprintf(buf, sizeof(buf), "shell:rm ");
1343    quoted = dupAndQuote(filename);
1344    strncat(buf, quoted, sizeof(buf)-1);
1345    free(quoted);
1346
1347    send_shellcommand(transport, serial, buf);
1348    return 0;
1349}
1350
1351int install_app(transport_type transport, char* serial, int argc, char** argv)
1352{
1353    struct stat st;
1354    int err;
1355    const char *const DATA_DEST = "/data/local/tmp/%s";
1356    const char *const SD_DEST = "/sdcard/tmp/%s";
1357    const char* where = DATA_DEST;
1358    char to[PATH_MAX];
1359    char* filename = argv[argc - 1];
1360    const char* p;
1361    int i;
1362
1363    for (i = 0; i < argc; i++) {
1364        if (!strcmp(argv[i], "-s"))
1365            where = SD_DEST;
1366    }
1367
1368    p = adb_dirstop(filename);
1369    if (p) {
1370        p++;
1371        snprintf(to, sizeof to, where, p);
1372    } else {
1373        snprintf(to, sizeof to, where, filename);
1374    }
1375    if (p[0] == '\0') {
1376    }
1377
1378    err = stat(filename, &st);
1379    if (err != 0) {
1380        fprintf(stderr, "can't find '%s' to install\n", filename);
1381        return 1;
1382    }
1383    if (!S_ISREG(st.st_mode)) {
1384        fprintf(stderr, "can't install '%s' because it's not a file\n",
1385                filename);
1386        return 1;
1387    }
1388
1389    if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) {
1390        /* file in place; tell the Package Manager to install it */
1391        argv[argc - 1] = to;       /* destination name, not source location */
1392        pm_command(transport, serial, argc, argv);
1393        delete_file(transport, serial, to);
1394    }
1395
1396    return err;
1397}
1398