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