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