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