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