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