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