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