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