commandline.c revision 704aa833382a73f8e02d49b7e9c2aef9a49c65bd
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\n"
100        " -p <product name or path>     - simple product name like 'sooner', or\n"
101        "                                 a relative/absolute path to a product\n"
102        "                                 out directory like 'out/target/product/sooner'.\n"
103        "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
104        "                                 environment variable is used, which must\n"
105        "                                 be an absolute path.\n"
106        " devices                       - list all connected devices\n"
107        "\n"
108        "device commands:\n"
109        "  adb push <local> <remote>    - copy file/dir to device\n"
110        "  adb pull <remote> <local>    - copy file/dir from device\n"
111        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
112        "                                 (see 'adb help all')\n"
113        "  adb shell                    - run remote shell interactively\n"
114        "  adb shell <command>          - run remote shell command\n"
115        "  adb emu <command>            - run emulator console command\n"
116        "  adb logcat [ <filter-spec> ] - View device log\n"
117        "  adb forward <local> <remote> - forward socket connections\n"
118        "                                 forward specs are one of: \n"
119        "                                   tcp:<port>\n"
120        "                                   localabstract:<unix domain socket name>\n"
121        "                                   localreserved:<unix domain socket name>\n"
122        "                                   localfilesystem:<unix domain socket name>\n"
123        "                                   dev:<character device name>\n"
124        "                                   jdwp:<process pid> (remote only)\n"
125        "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
126        "  adb install [-l] [-r] <file> - push this package file to the device and install it\n"
127        "                                 ('-l' means forward-lock the app)\n"
128        "                                 ('-r' means reinstall the app, keeping its data)\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 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        /* modifiers and flags */
771    while(argc > 0) {
772        if(!strcmp(argv[0],"nodaemon")) {
773            no_daemon = 1;
774        } else if (!strcmp(argv[0], "fork-server")) {
775            /* this is a special flag used only when the ADB client launches the ADB Server */
776            is_daemon = 1;
777        } else if(!strcmp(argv[0],"persist")) {
778            persist = 1;
779        } else if(!strncmp(argv[0], "-p", 2)) {
780            const char *product = NULL;
781            if (argv[0][2] == '\0') {
782                if (argc < 2) return usage();
783                product = argv[1];
784                argc--;
785                argv++;
786            } else {
787                product = argv[1] + 2;
788            }
789            gProductOutPath = find_product_out_path(product);
790            if (gProductOutPath == NULL) {
791                fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
792                        product);
793                return usage();
794            }
795        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
796            if (isdigit(argv[0][2])) {
797                serial = argv[0] + 2;
798            } else {
799                if(argc < 2) return usage();
800                serial = argv[1];
801                argc--;
802                argv++;
803            }
804        } else if (!strcmp(argv[0],"-d")) {
805            ttype = kTransportUsb;
806        } else if (!strcmp(argv[0],"-e")) {
807            ttype = kTransportLocal;
808        } else {
809                /* out of recognized modifiers and flags */
810            break;
811        }
812        argc--;
813        argv++;
814    }
815
816    adb_set_transport(ttype, serial);
817
818    if ((argc > 0) && (!strcmp(argv[0],"server"))) {
819        if (no_daemon || is_daemon) {
820            r = adb_main(is_daemon);
821        } else {
822            r = launch_server();
823        }
824        if(r) {
825            fprintf(stderr,"* could not start server *\n");
826        }
827        return r;
828    }
829
830top:
831    if(argc == 0) {
832        return usage();
833    }
834
835    /* adb_connect() commands */
836
837    if(!strcmp(argv[0], "devices")) {
838        char *tmp;
839        snprintf(buf, sizeof buf, "host:%s", argv[0]);
840        tmp = adb_query(buf);
841        if(tmp) {
842            printf("List of devices attached \n");
843            printf("%s\n", tmp);
844            return 0;
845        } else {
846            return 1;
847        }
848    }
849
850    if (!strcmp(argv[0], "emu")) {
851        return adb_send_emulator_command(argc, argv);
852    }
853
854    if(!strcmp(argv[0], "shell")) {
855        int r;
856        int fd;
857
858        if(argc < 2) {
859            return interactive_shell();
860        }
861
862        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
863        argc -= 2;
864        argv += 2;
865        while(argc-- > 0) {
866            strcat(buf, " ");
867
868            /* quote empty strings and strings with spaces */
869            quote = (**argv == 0 || strchr(*argv, ' '));
870            if (quote)
871            	strcat(buf, "\"");
872            strcat(buf, *argv++);
873            if (quote)
874            	strcat(buf, "\"");
875        }
876
877        for(;;) {
878            fd = adb_connect(buf);
879            if(fd >= 0) {
880                read_and_dump(fd);
881                adb_close(fd);
882                r = 0;
883            } else {
884                fprintf(stderr,"error: %s\n", adb_error());
885                r = -1;
886            }
887
888            if(persist) {
889                fprintf(stderr,"\n- waiting for device -\n");
890                adb_sleep_ms(1000);
891                do_cmd(ttype, serial, "wait-for-device", 0);
892            } else {
893                return r;
894            }
895        }
896    }
897
898    if(!strcmp(argv[0], "kill-server")) {
899        int fd;
900        fd = _adb_connect("host:kill");
901        if(fd == -1) {
902            fprintf(stderr,"* server not running *\n");
903            return 1;
904        }
905        return 0;
906    }
907
908    if(!strcmp(argv[0], "remount")) {
909        int fd = adb_connect("remount:");
910        if(fd >= 0) {
911            read_and_dump(fd);
912            adb_close(fd);
913            return 0;
914        }
915        fprintf(stderr,"error: %s\n", adb_error());
916        return 1;
917    }
918
919    if(!strcmp(argv[0], "reboot")) {
920        int fd;
921        if (argc > 1)
922            snprintf(buf, sizeof(buf), "reboot:%s", argv[1]);
923        else
924            snprintf(buf, sizeof(buf), "reboot:");
925        fd = adb_connect(buf);
926        if(fd >= 0) {
927            read_and_dump(fd);
928            adb_close(fd);
929            return 0;
930        }
931        fprintf(stderr,"error: %s\n", adb_error());
932        return 1;
933    }
934
935    if(!strcmp(argv[0], "root")) {
936        int fd = adb_connect("root:");
937        if(fd >= 0) {
938            read_and_dump(fd);
939            adb_close(fd);
940            return 0;
941        }
942        fprintf(stderr,"error: %s\n", adb_error());
943        return 1;
944    }
945
946    if(!strcmp(argv[0], "bugreport")) {
947        if (argc != 1) {
948            return 1;
949        }
950        do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
951        return 0;
952    }
953
954    /* adb_command() wrapper commands */
955
956    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
957        char* service = argv[0];
958        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
959            if (ttype == kTransportUsb) {
960                service = "wait-for-usb";
961            } else if (ttype == kTransportLocal) {
962                service = "wait-for-local";
963            } else {
964                service = "wait-for-any";
965            }
966        }
967
968        format_host_command(buf, sizeof buf, service, ttype, serial);
969
970        if (adb_command(buf)) {
971            D("failure: %s *\n",adb_error());
972            fprintf(stderr,"error: %s\n", adb_error());
973            return 1;
974        }
975
976        /* Allow a command to be run after wait-for-device,
977            * e.g. 'adb wait-for-device shell'.
978            */
979        if(argc > 1) {
980            argc--;
981            argv++;
982            goto top;
983        }
984        return 0;
985    }
986
987    if(!strcmp(argv[0], "forward")) {
988        if(argc != 3) return usage();
989        if (serial) {
990            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,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 != 3) return usage();
1015        return do_sync_pull(argv[1], argv[2]);
1016    }
1017
1018    if(!strcmp(argv[0], "install")) {
1019        if (argc < 2) return usage();
1020        return install_app(ttype, serial, argc, argv);
1021    }
1022
1023    if(!strcmp(argv[0], "uninstall")) {
1024        if (argc < 2) return usage();
1025        return uninstall_app(ttype, serial, argc, argv);
1026    }
1027
1028    if(!strcmp(argv[0], "sync")) {
1029        char *srcarg, *android_srcpath, *data_srcpath;
1030        int ret;
1031        if(argc < 2) {
1032            /* No local path was specified. */
1033            srcarg = NULL;
1034        } else if(argc == 2) {
1035            /* A local path or "android"/"data" arg was specified. */
1036            srcarg = argv[1];
1037        } else {
1038            return usage();
1039        }
1040        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1041        if(ret != 0) return usage();
1042
1043        if(android_srcpath != NULL)
1044            ret = do_sync_sync(android_srcpath, "/system");
1045        if(ret == 0 && data_srcpath != NULL)
1046            ret = do_sync_sync(data_srcpath, "/data");
1047
1048        free(android_srcpath);
1049        free(data_srcpath);
1050        return ret;
1051    }
1052
1053    /* passthrough commands */
1054
1055    if(!strcmp(argv[0],"get-state") ||
1056        !strcmp(argv[0],"get-serialno"))
1057    {
1058        char *tmp;
1059
1060        format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1061        tmp = adb_query(buf);
1062        if(tmp) {
1063            printf("%s\n", tmp);
1064            return 0;
1065        } else {
1066            return 1;
1067        }
1068    }
1069
1070    /* other commands */
1071
1072    if(!strcmp(argv[0],"status-window")) {
1073        status_window(ttype, serial);
1074        return 0;
1075    }
1076
1077    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1078        return logcat(ttype, serial, argc, argv);
1079    }
1080
1081    if(!strcmp(argv[0],"ppp")) {
1082        return ppp(argc, argv);
1083    }
1084
1085    if (!strcmp(argv[0], "start-server")) {
1086        return adb_connect("host:start-server");
1087    }
1088
1089    if (!strcmp(argv[0], "jdwp")) {
1090        int  fd = adb_connect("jdwp");
1091        if (fd >= 0) {
1092            read_and_dump(fd);
1093            adb_close(fd);
1094            return 0;
1095        } else {
1096            fprintf(stderr, "error: %s\n", adb_error());
1097            return -1;
1098        }
1099    }
1100
1101    /* "adb /?" is a common idiom under Windows */
1102    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1103        help();
1104        return 0;
1105    }
1106
1107    if(!strcmp(argv[0], "version")) {
1108        version(stdout);
1109        return 0;
1110    }
1111
1112    usage();
1113    return 1;
1114}
1115
1116static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1117{
1118    char *argv[16];
1119    int argc;
1120    va_list ap;
1121
1122    va_start(ap, cmd);
1123    argc = 0;
1124
1125    if (serial) {
1126        argv[argc++] = "-s";
1127        argv[argc++] = serial;
1128    } else if (ttype == kTransportUsb) {
1129        argv[argc++] = "-d";
1130    } else if (ttype == kTransportLocal) {
1131        argv[argc++] = "-e";
1132    }
1133
1134    argv[argc++] = cmd;
1135    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1136    va_end(ap);
1137
1138#if 0
1139    int n;
1140    fprintf(stderr,"argc = %d\n",argc);
1141    for(n = 0; n < argc; n++) {
1142        fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1143    }
1144#endif
1145
1146    return adb_commandline(argc, argv);
1147}
1148
1149int find_sync_dirs(const char *srcarg,
1150        char **android_srcdir_out, char **data_srcdir_out)
1151{
1152    char *android_srcdir, *data_srcdir;
1153
1154    if(srcarg == NULL) {
1155        android_srcdir = product_file("system");
1156        data_srcdir = product_file("data");
1157    } else {
1158        /* srcarg may be "data", "system" or NULL.
1159         * if srcarg is NULL, then both data and system are synced
1160         */
1161        if(strcmp(srcarg, "system") == 0) {
1162            android_srcdir = product_file("system");
1163            data_srcdir = NULL;
1164        } else if(strcmp(srcarg, "data") == 0) {
1165            android_srcdir = NULL;
1166            data_srcdir = product_file("data");
1167        } else {
1168            /* It's not "system" or "data".
1169             */
1170            return 1;
1171        }
1172    }
1173
1174    if(android_srcdir_out != NULL)
1175        *android_srcdir_out = android_srcdir;
1176    else
1177        free(android_srcdir);
1178
1179    if(data_srcdir_out != NULL)
1180        *data_srcdir_out = data_srcdir;
1181    else
1182        free(data_srcdir);
1183
1184    return 0;
1185}
1186
1187static int pm_command(transport_type transport, char* serial,
1188                      int argc, char** argv)
1189{
1190    char buf[4096];
1191
1192    snprintf(buf, sizeof(buf), "shell:pm");
1193
1194    while(argc-- > 0) {
1195        char *quoted;
1196
1197        quoted = dupAndQuote(*argv++);
1198
1199        strncat(buf, " ", sizeof(buf)-1);
1200        strncat(buf, quoted, sizeof(buf)-1);
1201        free(quoted);
1202    }
1203
1204    send_shellcommand(transport, serial, buf);
1205    return 0;
1206}
1207
1208int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1209{
1210    /* if the user choose the -k option, we refuse to do it until devices are
1211       out with the option to uninstall the remaining data somehow (adb/ui) */
1212    if (argc == 3 && strcmp(argv[1], "-k") == 0)
1213    {
1214        printf(
1215            "The -k option uninstalls the application while retaining the data/cache.\n"
1216            "At the moment, there is no way to remove the remaining data.\n"
1217            "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1218            "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1219        return -1;
1220    }
1221
1222    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1223    return pm_command(transport, serial, argc, argv);
1224}
1225
1226static int delete_file(transport_type transport, char* serial, char* filename)
1227{
1228    char buf[4096];
1229    char* quoted;
1230
1231    snprintf(buf, sizeof(buf), "shell:rm ");
1232    quoted = dupAndQuote(filename);
1233    strncat(buf, quoted, sizeof(buf)-1);
1234    free(quoted);
1235
1236    send_shellcommand(transport, serial, buf);
1237    return 0;
1238}
1239
1240int install_app(transport_type transport, char* serial, int argc, char** argv)
1241{
1242    struct stat st;
1243    int err;
1244    const char *const WHERE = "/data/local/tmp/%s";
1245    char to[PATH_MAX];
1246    char* filename = argv[argc - 1];
1247    const char* p;
1248
1249    p = adb_dirstop(filename);
1250    if (p) {
1251        p++;
1252        snprintf(to, sizeof to, WHERE, p);
1253    } else {
1254        snprintf(to, sizeof to, WHERE, filename);
1255    }
1256    if (p[0] == '\0') {
1257    }
1258
1259    err = stat(filename, &st);
1260    if (err != 0) {
1261        fprintf(stderr, "can't find '%s' to install\n", filename);
1262        return 1;
1263    }
1264    if (!S_ISREG(st.st_mode)) {
1265        fprintf(stderr, "can't install '%s' because it's not a file\n",
1266                filename);
1267        return 1;
1268    }
1269
1270    if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) {
1271        /* file in place; tell the Package Manager to install it */
1272        argv[argc - 1] = to;       /* destination name, not source location */
1273        pm_command(transport, serial, argc, argv);
1274        delete_file(transport, serial, to);
1275    }
1276
1277    return err;
1278}
1279