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