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