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