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