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