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