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