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