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