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