commandline.c revision 2f38b699713dc2587a771bd5d4c6a47329728f5e
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], "reboot")) {
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    if(!strcmp(argv[0], "bugreport")) {
949        if (argc != 1) {
950            return 1;
951        }
952        do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
953        return 0;
954    }
955
956    /* adb_command() wrapper commands */
957
958    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
959        char* service = argv[0];
960        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
961            if (ttype == kTransportUsb) {
962                service = "wait-for-usb";
963            } else if (ttype == kTransportLocal) {
964                service = "wait-for-local";
965            } else {
966                service = "wait-for-any";
967            }
968        }
969
970        format_host_command(buf, sizeof buf, service, ttype, serial);
971
972        if (adb_command(buf)) {
973            D("failure: %s *\n",adb_error());
974            fprintf(stderr,"error: %s\n", adb_error());
975            return 1;
976        }
977
978        /* Allow a command to be run after wait-for-device,
979            * e.g. 'adb wait-for-device shell'.
980            */
981        if(argc > 1) {
982            argc--;
983            argv++;
984            goto top;
985        }
986        return 0;
987    }
988
989    if(!strcmp(argv[0], "forward")) {
990        if(argc != 3) return usage();
991        if (serial) {
992            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,argv[1],argv[2]);
993        } else {
994            snprintf(buf, sizeof buf, "host:forward:%s;%s",argv[1],argv[2]);
995        }
996        if(adb_command(buf)) {
997            fprintf(stderr,"error: %s\n", adb_error());
998            return 1;
999        }
1000        return 0;
1001    }
1002
1003    /* do_sync_*() commands */
1004
1005    if(!strcmp(argv[0], "ls")) {
1006        if(argc != 2) return usage();
1007        return do_sync_ls(argv[1]);
1008    }
1009
1010    if(!strcmp(argv[0], "push")) {
1011        if(argc != 3) return usage();
1012        return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1013    }
1014
1015    if(!strcmp(argv[0], "pull")) {
1016        if(argc != 3) return usage();
1017        return do_sync_pull(argv[1], argv[2]);
1018    }
1019
1020    if(!strcmp(argv[0], "install")) {
1021        if (argc < 2) return usage();
1022        return install_app(ttype, serial, argc, argv);
1023    }
1024
1025    if(!strcmp(argv[0], "uninstall")) {
1026        if (argc < 2) return usage();
1027        return uninstall_app(ttype, serial, argc, argv);
1028    }
1029
1030    if(!strcmp(argv[0], "sync")) {
1031        char *srcarg, *android_srcpath, *data_srcpath;
1032        int ret;
1033        if(argc < 2) {
1034            /* No local path was specified. */
1035            srcarg = NULL;
1036        } else if(argc == 2) {
1037            /* A local path or "android"/"data" arg was specified. */
1038            srcarg = argv[1];
1039        } else {
1040            return usage();
1041        }
1042        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1043        if(ret != 0) return usage();
1044
1045        if(android_srcpath != NULL)
1046            ret = do_sync_sync(android_srcpath, "/system");
1047        if(ret == 0 && data_srcpath != NULL)
1048            ret = do_sync_sync(data_srcpath, "/data");
1049
1050        free(android_srcpath);
1051        free(data_srcpath);
1052        return ret;
1053    }
1054
1055    /* passthrough commands */
1056
1057    if(!strcmp(argv[0],"get-state") ||
1058        !strcmp(argv[0],"get-serialno"))
1059    {
1060        char *tmp;
1061
1062        format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1063        tmp = adb_query(buf);
1064        if(tmp) {
1065            printf("%s\n", tmp);
1066            return 0;
1067        } else {
1068            return 1;
1069        }
1070    }
1071
1072    /* other commands */
1073
1074    if(!strcmp(argv[0],"status-window")) {
1075        status_window(ttype, serial);
1076        return 0;
1077    }
1078
1079    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1080        return logcat(ttype, serial, argc, argv);
1081    }
1082
1083    if(!strcmp(argv[0],"ppp")) {
1084        return ppp(argc, argv);
1085    }
1086
1087    if (!strcmp(argv[0], "start-server")) {
1088        return adb_connect("host:start-server");
1089    }
1090
1091    if (!strcmp(argv[0], "jdwp")) {
1092        int  fd = adb_connect("jdwp");
1093        if (fd >= 0) {
1094            read_and_dump(fd);
1095            adb_close(fd);
1096            return 0;
1097        } else {
1098            fprintf(stderr, "error: %s\n", adb_error());
1099            return -1;
1100        }
1101    }
1102
1103    /* "adb /?" is a common idiom under Windows */
1104    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1105        help();
1106        return 0;
1107    }
1108
1109    if(!strcmp(argv[0], "version")) {
1110        version(stdout);
1111        return 0;
1112    }
1113
1114    usage();
1115    return 1;
1116}
1117
1118static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1119{
1120    char *argv[16];
1121    int argc;
1122    va_list ap;
1123
1124    va_start(ap, cmd);
1125    argc = 0;
1126
1127    if (serial) {
1128        argv[argc++] = "-s";
1129        argv[argc++] = serial;
1130    } else if (ttype == kTransportUsb) {
1131        argv[argc++] = "-d";
1132    } else if (ttype == kTransportLocal) {
1133        argv[argc++] = "-e";
1134    }
1135
1136    argv[argc++] = cmd;
1137    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1138    va_end(ap);
1139
1140#if 0
1141    int n;
1142    fprintf(stderr,"argc = %d\n",argc);
1143    for(n = 0; n < argc; n++) {
1144        fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1145    }
1146#endif
1147
1148    return adb_commandline(argc, argv);
1149}
1150
1151int find_sync_dirs(const char *srcarg,
1152        char **android_srcdir_out, char **data_srcdir_out)
1153{
1154    char *android_srcdir, *data_srcdir;
1155
1156    if(srcarg == NULL) {
1157        android_srcdir = product_file("system");
1158        data_srcdir = product_file("data");
1159    } else {
1160        /* srcarg may be "data", "system" or NULL.
1161         * if srcarg is NULL, then both data and system are synced
1162         */
1163        if(strcmp(srcarg, "system") == 0) {
1164            android_srcdir = product_file("system");
1165            data_srcdir = NULL;
1166        } else if(strcmp(srcarg, "data") == 0) {
1167            android_srcdir = NULL;
1168            data_srcdir = product_file("data");
1169        } else {
1170            /* It's not "system" or "data".
1171             */
1172            return 1;
1173        }
1174    }
1175
1176    if(android_srcdir_out != NULL)
1177        *android_srcdir_out = android_srcdir;
1178    else
1179        free(android_srcdir);
1180
1181    if(data_srcdir_out != NULL)
1182        *data_srcdir_out = data_srcdir;
1183    else
1184        free(data_srcdir);
1185
1186    return 0;
1187}
1188
1189static int pm_command(transport_type transport, char* serial,
1190                      int argc, char** argv)
1191{
1192    char buf[4096];
1193
1194    snprintf(buf, sizeof(buf), "shell:pm");
1195
1196    while(argc-- > 0) {
1197        char *quoted;
1198
1199        quoted = dupAndQuote(*argv++);
1200
1201        strncat(buf, " ", sizeof(buf)-1);
1202        strncat(buf, quoted, sizeof(buf)-1);
1203        free(quoted);
1204    }
1205
1206    send_shellcommand(transport, serial, buf);
1207    return 0;
1208}
1209
1210int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1211{
1212    /* if the user choose the -k option, we refuse to do it until devices are
1213       out with the option to uninstall the remaining data somehow (adb/ui) */
1214    if (argc == 3 && strcmp(argv[1], "-k") == 0)
1215    {
1216        printf(
1217            "The -k option uninstalls the application while retaining the data/cache.\n"
1218            "At the moment, there is no way to remove the remaining data.\n"
1219            "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1220            "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1221        return -1;
1222    }
1223
1224    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1225    return pm_command(transport, serial, argc, argv);
1226}
1227
1228static int delete_file(transport_type transport, char* serial, char* filename)
1229{
1230    char buf[4096];
1231    char* quoted;
1232
1233    snprintf(buf, sizeof(buf), "shell:rm ");
1234    quoted = dupAndQuote(filename);
1235    strncat(buf, quoted, sizeof(buf)-1);
1236    free(quoted);
1237
1238    send_shellcommand(transport, serial, buf);
1239    return 0;
1240}
1241
1242int install_app(transport_type transport, char* serial, int argc, char** argv)
1243{
1244    struct stat st;
1245    int err;
1246    const char *const WHERE = "/data/local/tmp/%s";
1247    char to[PATH_MAX];
1248    char* filename = argv[argc - 1];
1249    const char* p;
1250
1251    p = adb_dirstop(filename);
1252    if (p) {
1253        p++;
1254        snprintf(to, sizeof to, WHERE, p);
1255    } else {
1256        snprintf(to, sizeof to, WHERE, filename);
1257    }
1258    if (p[0] == '\0') {
1259    }
1260
1261    err = stat(filename, &st);
1262    if (err != 0) {
1263        fprintf(stderr, "can't find '%s' to install\n", filename);
1264        return 1;
1265    }
1266    if (!S_ISREG(st.st_mode)) {
1267        fprintf(stderr, "can't install '%s' because it's not a file\n",
1268                filename);
1269        return 1;
1270    }
1271
1272    if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) {
1273        /* file in place; tell the Package Manager to install it */
1274        argv[argc - 1] = to;       /* destination name, not source location */
1275        pm_command(transport, serial, argc, argv);
1276        delete_file(transport, serial, to);
1277    }
1278
1279    return err;
1280}
1281