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