commandline.c revision 8127323f145b2de7e1c30bbb7af0d20d783ac76b
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 Projectstatic int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
423166410a82f43d39201be98a8d35c51baa86cb53Alexey Tarasovvoid get_my_path(char *s, size_t maxLen);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint find_sync_dirs(const char *srcarg,
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char **android_srcdir_out, char **data_srcdir_out);
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint install_app(transport_type transport, char* serial, int argc, char** argv);
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint uninstall_app(transport_type transport, char* serial, int argc, char** argv);
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *gProductOutPath = NULL;
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *product_file(const char *extra)
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *x;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (gProductOutPath == NULL) {
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "adb: Product directory not specified; "
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                "use -p or define ANDROID_PRODUCT_OUT\n");
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(1);
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = strlen(gProductOutPath) + strlen(extra) + 2;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    x = malloc(n);
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (x == 0) {
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "adb: Out of memory (product_file())\n");
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(1);
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return x;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid version(FILE * out) {
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid help()
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    version(stderr);
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " -d                            - directs command to the only connected USB device\n"
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 returns an error if more than one USB device is present.\n"
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " -e                            - directs command to the only running emulator.\n"
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 returns an error if more than one emulator is running.\n"
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " -s <serial number>            - directs command to the USB device or emulator with\n"
88db4492640313be9d3fd65ee5bd7648a9570411bbNick Pelly        "                                 the given serial number. Overrides ANDROID_SERIAL\n"
8931dbed7b60d8237d6d05dc6bf230167a5854b77aElliott Hughes        "                                 environment variable.\n"
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " -p <product name or path>     - simple product name like 'sooner', or\n"
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 a relative/absolute path to a product\n"
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 out directory like 'out/target/product/sooner'.\n"
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 If -p is not specified, the ANDROID_PRODUCT_OUT\n"
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 environment variable is used, which must\n"
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 be an absolute path.\n"
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " devices                       - list all connected devices\n"
97cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        " connect <host>[:<port>]       - connect to a device via TCP/IP\n"
98cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        "                                 Port 5555 is used by default if no port number is specified.\n"
99cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        " disconnect [<host>[:<port>]]  - disconnect from a TCP/IP device.\n"
100cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        "                                 Port 5555 is used by default if no port number is specified.\n"
1016715a4390f482815f51577d25d464537f7e7b823Bernhard Reutner-Fischer        "                                 Using this command with no additional arguments\n"
102cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        "                                 will disconnect from all connected TCP/IP devices.\n"
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "device commands:\n"
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb push <local> <remote>    - copy file/dir to device\n"
10600c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato        "  adb pull <remote> [<local>]  - copy file/dir from device\n"
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
108705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam        "                                 (-l means list but don't copy)\n"
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 (see 'adb help all')\n"
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb shell                    - run remote shell interactively\n"
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb shell <command>          - run remote shell command\n"
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb emu <command>            - run emulator console command\n"
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb logcat [ <filter-spec> ] - View device log\n"
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb forward <local> <remote> - forward socket connections\n"
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 forward specs are one of: \n"
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   tcp:<port>\n"
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   localabstract:<unix domain socket name>\n"
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   localreserved:<unix domain socket name>\n"
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   localfilesystem:<unix domain socket name>\n"
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   dev:<character device name>\n"
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                   jdwp:<process pid> (remote only)\n"
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
1230ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood        "  adb install [-l] [-r] [-s] <file> - push this package file to the device and install it\n"
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 ('-l' means forward-lock the app)\n"
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 ('-r' means reinstall the app, keeping its data)\n"
1260ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood        "                                 ('-s' means install on SD card instead of internal storage)\n"
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb uninstall [-k] <package> - remove this app package from the device\n"
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 ('-k' means keep the data and cache directories)\n"
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb bugreport                - return all information from the device\n"
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "                                 that should be included in a bug report.\n"
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
13256885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "  adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
13356885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                               - write an archive of the device's data to <file>.\n"
13456885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                 If no -f option is supplied then the data is written\n"
13556885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                 to \"backup.ab\" in the current directory.\n"
136d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                 (-apk|-noapk enable/disable backup of the .apks themselves\n"
137de034ec83e2d76db54d1936e706e80853146dcc7Christopher Tate        "                                    in the archive; the default is noapk.)\n"
138d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                 (-shared|-noshared enable/disable backup of the device's\n"
139d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                    shared storage / SD card contents; the default is noshared.)\n"
140d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                 (-all means to back up all installed applications)\n"
14156885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                 (-system|-nosystem toggles whether -all automatically includes\n"
14256885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                    system applications; the default is to include system apps)\n"
143d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                 (<packages...> is the list of applications to be backed up.  If\n"
144d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "                                    the -all or -shared flags are passed, then the package\n"
14556885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                    list is optional.  Applications explicitly given on the\n"
14656885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                    command line will be included even if -nosystem would\n"
14756885094b63af1b0077dec16bc695aa09d8043fcChristopher Tate        "                                    ordinarily cause them to be omitted.)\n"
148d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        "\n"
149de034ec83e2d76db54d1936e706e80853146dcc7Christopher Tate        "  adb restore <file>           - restore device contents from the <file> backup archive\n"
150702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        "\n"
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb help                     - show this help message\n"
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb version                  - show version num\n"
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "scripting:\n"
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb wait-for-device          - block until device is online\n"
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb start-server             - ensure that there is a server running\n"
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb kill-server              - kill the server if it is running\n"
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb get-state                - prints: offline | bootloader | device\n"
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb get-serialno             - prints: <serial-number>\n"
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb status-window            - continuously print device status for a specified device\n"
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb remount                  - remounts the /system partition on the device read-write\n"
162ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
163311add489e4a1712d201c3b83fa364d5569e6788Romain Guy        "  adb reboot-bootloader        - reboots the device into the bootloader\n"
164ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        "  adb root                     - restarts the adbd daemon with root permissions\n"
165311add489e4a1712d201c3b83fa364d5569e6788Romain Guy        "  adb usb                      - restarts the adbd daemon listening on USB\n"
166ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "networking:\n"
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
170c989199ccfbe745a7109f57d2aee2577d2f72b8dKenny Root        " Note: you should not automatically start a PPP connection.\n"
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n"
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n"
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "adb sync notes: adb sync [ <directory> ]\n"
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  <localdir> can be interpreted in several ways:\n"
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  - If <directory> is not specified, both /system and /data partitions will be updated.\n"
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "\n"
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "  - If it is \"system\" or \"data\", only the corresponding partition\n"
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "    is updated.\n"
181cd64315f72537359537c66eebe482495ffefba57Tim        "\n"
182cd64315f72537359537c66eebe482495ffefba57Tim        "environmental variables:\n"
183cd64315f72537359537c66eebe482495ffefba57Tim        "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
184cd64315f72537359537c66eebe482495ffefba57Tim        "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
185cd64315f72537359537c66eebe482495ffefba57Tim        "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
186cd64315f72537359537c66eebe482495ffefba57Tim        "  ANDROID_LOG_TAGS             - When used with the logcat option, only these debug tags are printed.\n"
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        );
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint usage()
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    help();
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 1;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_TERMIO_H
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic struct termios tio_save;
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void stdin_raw_init(int fd)
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct termios tio;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(tcgetattr(fd, &tio)) return;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(tcgetattr(fd, &tio_save)) return;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* no timeout but request at least one character per read */
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tio.c_cc[VTIME] = 0;
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tio.c_cc[VMIN] = 1;
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tcsetattr(fd, TCSANOW, &tio);
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tcflush(fd, TCIFLUSH);
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void stdin_raw_restore(int fd)
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tcsetattr(fd, TCSANOW, &tio_save);
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    tcflush(fd, TCIFLUSH);
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void read_and_dump(int fd)
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int len;
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(fd >= 0) {
229408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        D("read_and_dump(): pre adb_read(fd=%d)\n", fd);
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len = adb_read(fd, buf, 4096);
231408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        D("read_and_dump(): post adb_read(fd=%d): len=%d\n", fd, len);
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len == 0) {
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(len < 0) {
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR) continue;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
240dd6b36e334809e7a99f0bce45353cdd7e4dac4e1Mike Lockwood        fwrite(buf, 1, len, stdout);
241dd6b36e334809e7a99f0bce45353cdd7e4dac4e1Mike Lockwood        fflush(stdout);
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
245d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tatestatic void copy_to_file(int inFd, int outFd) {
2465b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate    const size_t BUFSIZE = 32 * 1024;
2475b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate    char* buf = (char*) malloc(BUFSIZE);
248d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    int len;
249c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate    long total = 0;
250d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
251d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    D("copy_to_file(%d -> %d)\n", inFd, outFd);
252d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    for (;;) {
2535b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate        len = adb_read(inFd, buf, BUFSIZE);
254d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        if (len == 0) {
2555b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate            D("copy_to_file() : read 0 bytes; exiting\n");
256d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate            break;
257d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        }
258d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        if (len < 0) {
2595b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate            if (errno == EINTR) {
2605b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate                D("copy_to_file() : EINTR, retrying\n");
2615b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate                continue;
2625b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate            }
263d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate            D("copy_to_file() : error %d\n", errno);
264d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate            break;
265d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        }
266d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        adb_write(outFd, buf, len);
267c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate        total += len;
268d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
269c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate    D("copy_to_file() finished after %lu bytes\n", total);
2705b811fa5dd00288954f15209a56aea03d5e4a004Christopher Tate    free(buf);
271d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate}
272d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *stdin_read_thread(void *x)
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd, fdi;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char buf[1024];
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int r, n;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int state = 0;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int *fds = (int*) x;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = fds[0];
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdi = fds[1];
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(fds);
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* fdi is really the client's stdin, so use read, not adb_read here */
287408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = unix_read(fdi, buf, 1024);
289408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall        D("stdin_read_thread(): post unix_read(fdi=%d,...)\n", fdi);
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r == 0) break;
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r < 0) {
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(errno == EINTR) continue;
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
29567d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood        for(n = 0; n < r; n++){
29667d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            switch(buf[n]) {
29767d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            case '\n':
29867d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                state = 1;
29967d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                break;
30067d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            case '\r':
30167d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                state = 1;
30267d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                break;
30367d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            case '~':
30467d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                if(state == 1) state++;
30567d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                break;
30667d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            case '.':
30767d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                if(state == 2) {
30867d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                    fprintf(stderr,"\n* disconnect *\n");
30967d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood#ifdef HAVE_TERMIO_H
31067d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                    stdin_raw_restore(fdi);
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
31267d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                    exit(0);
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
31467d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood            default:
31567d5358e2a870f9e9447517bfa49bf5c6b410a50Mike Lockwood                state = 0;
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        r = adb_write(fd, buf, r);
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r <= 0) {
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint interactive_shell(void)
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_thread_t thr;
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fdi, fd;
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int *fds;
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect("shell:");
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdi = 0; //dup(0);
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fds = malloc(sizeof(int) * 2);
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fds[0] = fd;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fds[1] = fdi;
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_TERMIO_H
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stdin_raw_init(fdi);
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_thread_create(&thr, stdin_read_thread, fds);
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    read_and_dump(fd);
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_TERMIO_H
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stdin_raw_restore(fdi);
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void format_host_command(char* buffer, size_t  buflen, const char* command, transport_type ttype, const char* serial)
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (serial) {
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(buffer, buflen, "host-serial:%s:%s", serial, command);
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const char* prefix = "host";
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ttype == kTransportUsb)
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            prefix = "host-usb";
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        else if (ttype == kTransportLocal)
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            prefix = "host-local";
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(buffer, buflen, "%s:%s", prefix, command);
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void status_window(transport_type ttype, const char* serial)
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char command[4096];
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *state = 0;
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *laststate = 0;
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* silence stderr */
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef _WIN32
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* XXX: TODO */
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  fd;
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = unix_open("/dev/null", O_WRONLY);
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dup2(fd, 2);
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_close(fd);
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    format_host_command(command, sizeof command, "get-state", ttype, serial);
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_sleep_ms(250);
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(state) {
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free(state);
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            state = 0;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        state = adb_query(command);
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(state) {
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(laststate && !strcmp(state,laststate)){
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if(laststate) free(laststate);
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                laststate = strdup(state);
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("%c[2J%c[2H", 27, 27);
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("Android Debug Bridge\n");
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("State: %s\n", state ? state : "offline");
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fflush(stdout);
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** duplicate string and quote all \ " ( ) chars + space character. */
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectdupAndQuote(const char *s)
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ts;
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    size_t alloc_len;
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *ret;
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *dest;
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ts = s;
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    alloc_len = 0;
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for( ;*ts != '\0'; ts++) {
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        alloc_len++;
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            alloc_len++;
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = (char *)malloc(alloc_len + 1);
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ts = s;
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dest = ret;
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for ( ;*ts != '\0'; ts++) {
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *dest++ = '\\';
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *dest++ = *ts;
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *dest++ = '\0';
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ret;
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Run ppp in "notty" mode against a resource listed as the first parameter
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * eg:
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ppp dev:/dev/omap_csmi_tty0 <ppp options>
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ppp(int argc, char **argv)
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_WIN32_PROC
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *adb_service_name;
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid_t pid;
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd;
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (argc < 2) {
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n",
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argv[0]);
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_service_name = argv[1];
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd = adb_connect(adb_service_name);
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n",
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                adb_service_name, adb_error());
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pid = fork();
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pid < 0) {
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("from fork()");
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (pid == 0) {
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int err;
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int i;
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const char **ppp_args;
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // copy args
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ppp_args = (const char **) alloca(sizeof(char *) * argc + 1);
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ppp_args[0] = "pppd";
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (i = 2 ; i < argc ; i++) {
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //argv[2] and beyond become ppp_args[1] and beyond
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ppp_args[i - 1] = argv[i];
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ppp_args[i-1] = NULL;
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // child side
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(fd, STDIN_FILENO);
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dup2(fd, STDOUT_FILENO);
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(STDERR_FILENO);
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd);
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        err = execvp("pppd", (char * const *)ppp_args);
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (err < 0) {
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            perror("execing pppd");
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        exit(-1);
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // parent side
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fd);
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* !HAVE_WIN32_PROC */
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int send_shellcommand(transport_type transport, char* serial, char* buf)
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int fd, ret;
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fd = adb_connect(buf);
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fd >= 0)
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"- waiting for device -\n");
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_sleep_ms(1000);
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do_cmd(transport, serial, "wait-for-device", 0);
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    read_and_dump(fd);
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = adb_close(fd);
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret)
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        perror("close");
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return ret;
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int logcat(transport_type transport, char* serial, int argc, char **argv)
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *log_tags;
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *quoted_log_tags;
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    log_tags = getenv("ANDROID_LOG_TAGS");
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(buf, sizeof(buf),
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        quoted_log_tags);
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(quoted_log_tags);
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    argc -= 1;
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    argv += 1;
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc-- > 0) {
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *quoted;
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        quoted = dupAndQuote (*argv++);
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strncat(buf, " ", sizeof(buf)-1);
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strncat(buf, quoted, sizeof(buf)-1);
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(quoted);
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_shellcommand(transport, serial, buf);
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
580b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tatestatic int mkdirs(char *path)
581b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate{
582b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    int ret;
583b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    char *x = path + 1;
584b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate
585b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    for(;;) {
586b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        x = adb_dirstart(x);
587b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        if(x == 0) return 0;
588b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        *x = 0;
589b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        ret = adb_mkdir(path, 0775);
590b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        *x = OS_PATH_SEPARATOR;
591b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        if((ret < 0) && (errno != EEXIST)) {
592b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate            return ret;
593b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        }
594b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate        x++;
595b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    }
596b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    return 0;
597b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate}
598b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate
599d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tatestatic int backup(int argc, char** argv) {
600d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    char buf[4096];
601b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    char default_name[32];
602b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    const char* filename = strcpy(default_name, "./backup.ab");
603d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    int fd, outFd;
604c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate    int i, j;
605d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
606c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate    /* find, extract, and use any -f argument */
607c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate    for (i = 1; i < argc; i++) {
608c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate        if (!strcmp("-f", argv[i])) {
609c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            if (i == argc-1) {
610c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate                fprintf(stderr, "adb: -f passed with no filename\n");
611c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate                return usage();
612c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            }
613c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            filename = argv[i+1];
614c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            for (j = i+2; j <= argc; ) {
615c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate                argv[i++] = argv[j++];
616c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            }
617c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            argc -= 2;
618c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate            argv[argc] = NULL;
619c9cd3b976111d91ede6cd88bd06eb57b10b2f0e7Christopher Tate        }
620d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
621d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
622bb86bc5892374f3a41784135bebc7ada3270c8c1Christopher Tate    /* bare "adb backup" or "adb backup -f filename" are not valid invocations */
623bb86bc5892374f3a41784135bebc7ada3270c8c1Christopher Tate    if (argc < 2) return usage();
624bb86bc5892374f3a41784135bebc7ada3270c8c1Christopher Tate
625b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    adb_unlink(filename);
626b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    mkdirs((char *)filename);
627b1dfffe6bb506313a3bc9146d2f6f8c533213193Christopher Tate    outFd = adb_creat(filename, 0640);
628d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    if (outFd < 0) {
629d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        fprintf(stderr, "adb: unable to open file %s\n", filename);
630d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        return -1;
631d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
632d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
633d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    snprintf(buf, sizeof(buf), "backup");
634d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    for (argc--, argv++; argc; argc--, argv++) {
635d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
636d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
637d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
638d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
639d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    D("backup. filename=%s buf=%s\n", filename, buf);
640d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    fd = adb_connect(buf);
641d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    if (fd < 0) {
642d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        fprintf(stderr, "adb: unable to connect for backup\n");
643d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        adb_close(outFd);
644d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        return -1;
645d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
646d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
647d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    copy_to_file(fd, outFd);
648d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
649d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    adb_close(fd);
650d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    adb_close(outFd);
651d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    return 0;
652d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate}
653d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
654702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tatestatic int restore(int argc, char** argv) {
655702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    const char* filename;
656702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    int fd, tarFd;
657702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
658702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    if (argc != 2) return usage();
659702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
660702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    filename = argv[1];
661702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    tarFd = adb_open(filename, O_RDONLY);
662702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    if (tarFd < 0) {
663702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        fprintf(stderr, "adb: unable to open file %s\n", filename);
664702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        return -1;
665702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    }
666702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
667702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    fd = adb_connect("restore:");
668702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    if (fd < 0) {
669702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        fprintf(stderr, "adb: unable to connect for backup\n");
670702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        adb_close(tarFd);
671702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        return -1;
672702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    }
673702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
674702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    copy_to_file(tarFd, fd);
675702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
676702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    adb_close(fd);
677702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    adb_close(tarFd);
678702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    return 0;
679702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate}
680702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make"
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int top_works(const char *top)
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (top != NULL && adb_is_absolute_host_path(top)) {
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char path_buf[PATH_MAX];
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(path_buf, sizeof(path_buf),
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top);
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return access(path_buf, F_OK) == 0;
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *find_top_from(const char *indir, char path_buf[PATH_MAX])
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strcpy(path_buf, indir);
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (1) {
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (top_works(path_buf)) {
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return path_buf;
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *s = adb_dirstop(path_buf);
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (s != NULL) {
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *s = '\0';
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            path_buf[0] = '\0';
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *find_top(char path_buf[PATH_MAX])
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *top = getenv("ANDROID_BUILD_TOP");
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (top != NULL && top[0] != '\0') {
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!top_works(top)) {
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top);
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        top = getenv("TOP");
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (top != NULL && top[0] != '\0') {
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (!top_works(top)) {
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "adb: bad TOP value \"%s\"\n", top);
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return NULL;
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            top = NULL;
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (top != NULL) {
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* The environment pointed to a top directory that works.
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcpy(path_buf, top);
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return path_buf;
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* The environment didn't help.  Walk up the tree from the CWD
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * to see if we can find the top.
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     */
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char dir[PATH_MAX];
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    top = find_top_from(getcwd(dir, sizeof(dir)), path_buf);
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (top == NULL) {
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* If the CWD isn't under a good-looking top, see if the
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * executable is.
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
7463166410a82f43d39201be98a8d35c51baa86cb53Alexey Tarasov        get_my_path(dir, PATH_MAX);
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        top = find_top_from(dir, path_buf);
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return top;
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* <hint> may be:
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * - A simple product name
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   e.g., "sooner"
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectTODO: debug?  sooner-debug, sooner:debug?
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   e.g., "out/target/product/sooner"
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * - An absolute path to the PRODUCT_OUT dir
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   e.g., "/src/device/out/target/product/sooner"
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Given <hint>, try to construct an absolute path to the
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANDROID_PRODUCT_OUT dir.
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *find_product_out_path(const char *hint)
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    static char path_buf[PATH_MAX];
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hint == NULL || hint[0] == '\0') {
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* If it's already absolute, don't bother doing any work.
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     */
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (adb_is_absolute_host_path(hint)) {
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcpy(path_buf, hint);
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return path_buf;
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* If there are any slashes in it, assume it's a relative path;
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * make it absolute.
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     */
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (adb_dirstart(hint) != NULL) {
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "adb: Couldn't assemble path\n");
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return NULL;
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcat(path_buf, OS_PATH_SEPARATOR_STR);
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcat(path_buf, hint);
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return path_buf;
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* It's a string without any slashes.  Try to do something with it.
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     *
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * Try to find the root of the build tree, and build a PRODUCT_OUT
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     * path from there.
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     */
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char top_buf[PATH_MAX];
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *top = find_top(top_buf);
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (top == NULL) {
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "adb: Couldn't find top of build tree\n");
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//TODO: if we have a way to indicate debug, look in out/debug/target/...
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(path_buf, sizeof(path_buf),
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "%s" OS_PATH_SEPARATOR_STR
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "out" OS_PATH_SEPARATOR_STR
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "target" OS_PATH_SEPARATOR_STR
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "product" OS_PATH_SEPARATOR_STR
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "%s", top_buf, hint);
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (access(path_buf, F_OK) < 0) {
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr, "adb: Couldn't find a product dir "
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return path_buf;
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint adb_commandline(int argc, char **argv)
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int no_daemon = 0;
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int is_daemon = 0;
827305b4b0f6069d733d3023a57fdc8a6d9cf7de2a6David 'Digit' Turner    int is_server = 0;
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int persist = 0;
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int r;
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int quote;
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    transport_type ttype = kTransportAny;
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* serial = NULL;
833a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    char* server_port_str = NULL;
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* If defined, this should be an absolute path to
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * the directory containing all of the various system images
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * for a particular product.  If not defined, and the adb
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * command requires this information, then the user must
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * specify the path using "-p".
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gProductOutPath = NULL;
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
847db4492640313be9d3fd65ee5bd7648a9570411bbNick Pelly    serial = getenv("ANDROID_SERIAL");
848db4492640313be9d3fd65ee5bd7648a9570411bbNick Pelly
849a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    /* Validate and assign the server port */
850a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    server_port_str = getenv("ANDROID_ADB_SERVER_PORT");
851a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    int server_port = DEFAULT_ADB_PORT;
852a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    if (server_port_str && strlen(server_port_str) > 0) {
853a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger        server_port = (int) strtol(server_port_str, NULL, 0);
854a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger        if (server_port <= 0) {
855a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger            fprintf(stderr,
856a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger                    "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n",
857a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger                    server_port_str);
858a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger            return usage();
859a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger        }
860a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    }
861a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger
862a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    /* modifiers and flags */
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc > 0) {
864305b4b0f6069d733d3023a57fdc8a6d9cf7de2a6David 'Digit' Turner        if(!strcmp(argv[0],"server")) {
865305b4b0f6069d733d3023a57fdc8a6d9cf7de2a6David 'Digit' Turner            is_server = 1;
866305b4b0f6069d733d3023a57fdc8a6d9cf7de2a6David 'Digit' Turner        } else if(!strcmp(argv[0],"nodaemon")) {
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            no_daemon = 1;
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strcmp(argv[0], "fork-server")) {
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* this is a special flag used only when the ADB client launches the ADB Server */
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            is_daemon = 1;
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(!strcmp(argv[0],"persist")) {
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            persist = 1;
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(!strncmp(argv[0], "-p", 2)) {
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const char *product = NULL;
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (argv[0][2] == '\0') {
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if (argc < 2) return usage();
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                product = argv[1];
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argc--;
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argv++;
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
8818127323f145b2de7e1c30bbb7af0d20d783ac76bVairavan Srinivasan                product = argv[0] + 2;
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            gProductOutPath = find_product_out_path(product);
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (gProductOutPath == NULL) {
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        product);
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return usage();
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (argv[0][0]=='-' && argv[0][1]=='s') {
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (isdigit(argv[0][2])) {
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                serial = argv[0] + 2;
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
893a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger                if(argc < 2 || argv[0][2] != '\0') return usage();
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                serial = argv[1];
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argc--;
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argv++;
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strcmp(argv[0],"-d")) {
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ttype = kTransportUsb;
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if (!strcmp(argv[0],"-e")) {
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ttype = kTransportLocal;
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* out of recognized modifiers and flags */
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argc--;
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv++;
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_set_transport(ttype, serial);
911a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger    adb_set_tcp_specifics(server_port);
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
913305b4b0f6069d733d3023a57fdc8a6d9cf7de2a6David 'Digit' Turner    if (is_server) {
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (no_daemon || is_daemon) {
915a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger            r = adb_main(is_daemon, server_port);
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
917a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger            r = launch_server(server_port);
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(r) {
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"* could not start server *\n");
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return r;
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttop:
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(argc == 0) {
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return usage();
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* adb_connect() commands */
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "devices")) {
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp;
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(buf, sizeof buf, "host:%s", argv[0]);
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp = adb_query(buf);
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp) {
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            printf("List of devices attached \n");
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            printf("%s\n", tmp);
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
945cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood    if(!strcmp(argv[0], "connect")) {
946ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        char *tmp;
947ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        if (argc != 2) {
948cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
949ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            return 1;
950ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        }
951cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
952cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        tmp = adb_query(buf);
953cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        if(tmp) {
954cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            printf("%s\n", tmp);
955cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            return 0;
956cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        } else {
957cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            return 1;
958cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        }
959cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood    }
960cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood
961cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood    if(!strcmp(argv[0], "disconnect")) {
962cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        char *tmp;
963cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        if (argc > 2) {
964cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
965cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            return 1;
966cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        }
967cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        if (argc == 2) {
968cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            snprintf(buf, sizeof buf, "host:disconnect:%s", argv[1]);
969cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        } else {
970cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood            snprintf(buf, sizeof buf, "host:disconnect:");
971cbbe79add1410b53ec65936cfb1b74cac68467f0Mike Lockwood        }
972ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        tmp = adb_query(buf);
973ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        if(tmp) {
974ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            printf("%s\n", tmp);
975ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            return 0;
976ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        } else {
977ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            return 1;
978ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        }
979ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    }
980ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(argv[0], "emu")) {
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return adb_send_emulator_command(argc, argv);
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
985ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler    if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int r;
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fd;
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
989ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler        char h = (argv[0][0] == 'h');
990ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler
991ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler        if (h) {
992ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            printf("\x1b[41;33m");
993ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            fflush(stdout);
994ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler        }
995ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc < 2) {
997408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            D("starting interactive shell\n");
998ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            r = interactive_shell();
999ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            if (h) {
1000ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                printf("\x1b[0m");
1001ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                fflush(stdout);
1002ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            }
1003ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler            return r;
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argc -= 2;
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv += 2;
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while(argc-- > 0) {
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            strcat(buf, " ");
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* quote empty strings and strings with spaces */
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            quote = (**argv == 0 || strchr(*argv, ' '));
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (quote)
1015a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger                strcat(buf, "\"");
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            strcat(buf, *argv++);
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (quote)
1018a84a42eb20d43ffa2695a69d583a6e09532b49d9Stefan Hilzinger                strcat(buf, "\"");
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for(;;) {
1022408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall            D("interactive shell loop. buff=%s\n", buf);
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fd = adb_connect(buf);
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(fd >= 0) {
1025408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("about to read_and_dump(fd=%d)\n", fd);
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                read_and_dump(fd);
1027408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("read_and_dump() done.\n");
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                adb_close(fd);
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                r = 0;
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr,"error: %s\n", adb_error());
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                r = -1;
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(persist) {
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                fprintf(stderr,"\n- waiting for device -\n");
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                adb_sleep_ms(1000);
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                do_cmd(ttype, serial, "wait-for-device", 0);
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
1040ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                if (h) {
1041ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                    printf("\x1b[0m");
1042ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                    fflush(stdout);
1043ff91ab855b84cdcf110f1a899320d3920e7c55a5Daniel Sandler                }
1044408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall                D("interactive shell loop. return r=%d\n", r);
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return r;
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "kill-server")) {
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int fd;
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fd = _adb_connect("host:kill");
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fd == -1) {
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"* server not running *\n");
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1060ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood    if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
1061311add489e4a1712d201c3b83fa364d5569e6788Romain Guy            || !strcmp(argv[0], "reboot-bootloader")
1062ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
1063f56d1b5a76c6cb282a7689fc93f85de63bd205f6Mike Lockwood            || !strcmp(argv[0], "root")) {
1064ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        char command[100];
1065311add489e4a1712d201c3b83fa364d5569e6788Romain Guy        if (!strcmp(argv[0], "reboot-bootloader"))
1066311add489e4a1712d201c3b83fa364d5569e6788Romain Guy            snprintf(command, sizeof(command), "reboot:bootloader");
1067311add489e4a1712d201c3b83fa364d5569e6788Romain Guy        else if (argc > 1)
1068ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
1069ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood        else
1070ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood            snprintf(command, sizeof(command), "%s:", argv[0]);
1071ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood        int fd = adb_connect(command);
1072e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        if(fd >= 0) {
1073e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            read_and_dump(fd);
1074e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            adb_close(fd);
1075e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project            return 0;
1076e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        }
1077e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        fprintf(stderr,"error: %s\n", adb_error());
1078e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project        return 1;
1079e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project    }
1080e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project
1081f56d1b5a76c6cb282a7689fc93f85de63bd205f6Mike Lockwood    if(!strcmp(argv[0], "bugreport")) {
1082c130ea7c29b0149939c8fd6b8da2c981944636f9Dan Egnor        if (argc != 1) return usage();
1083c130ea7c29b0149939c8fd6b8da2c981944636f9Dan Egnor        do_cmd(ttype, serial, "shell", "bugreport", 0);
1084f56d1b5a76c6cb282a7689fc93f85de63bd205f6Mike Lockwood        return 0;
1085f56d1b5a76c6cb282a7689fc93f85de63bd205f6Mike Lockwood    }
1086f56d1b5a76c6cb282a7689fc93f85de63bd205f6Mike Lockwood
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* adb_command() wrapper commands */
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char* service = argv[0];
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (ttype == kTransportUsb) {
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                service = "wait-for-usb";
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else if (ttype == kTransportLocal) {
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                service = "wait-for-local";
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                service = "wait-for-any";
1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        format_host_command(buf, sizeof buf, service, ttype, serial);
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (adb_command(buf)) {
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D("failure: %s *\n",adb_error());
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"error: %s\n", adb_error());
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* Allow a command to be run after wait-for-device,
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            * e.g. 'adb wait-for-device shell'.
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            */
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc > 1) {
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            argc--;
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            argv++;
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto top;
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "forward")) {
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc != 3) return usage();
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (serial) {
112364e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood            snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial, argv[1], argv[2]);
112464e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood        } else if (ttype == kTransportUsb) {
112564e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood            snprintf(buf, sizeof buf, "host-usb:forward:%s;%s", argv[1], argv[2]);
112664e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood        } else if (ttype == kTransportLocal) {
112764e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood            snprintf(buf, sizeof buf, "host-local:forward:%s;%s", argv[1], argv[2]);
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
112964e99545d4b5600bb5ca044fcad636ae8389b381Mike Lockwood            snprintf(buf, sizeof buf, "host:forward:%s;%s", argv[1], argv[2]);
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(adb_command(buf)) {
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr,"error: %s\n", adb_error());
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* do_sync_*() commands */
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "ls")) {
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc != 2) return usage();
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return do_sync_ls(argv[1]);
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "push")) {
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc != 3) return usage();
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return do_sync_push(argv[1], argv[2], 0 /* no verify APK */);
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "pull")) {
115100c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato        if (argc == 2) {
115200c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato            return do_sync_pull(argv[1], ".");
115300c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato        } else if (argc == 3) {
115400c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato            return do_sync_pull(argv[1], argv[2]);
115500c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato        } else {
115600c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato            return usage();
115700c0eeac6be1597ce24fccf8e2afaaffab223cb3Joe Onorato        }
1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "install")) {
1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (argc < 2) return usage();
1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return install_app(ttype, serial, argc, argv);
1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "uninstall")) {
1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (argc < 2) return usage();
1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return uninstall_app(ttype, serial, argc, argv);
1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "sync")) {
1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *srcarg, *android_srcpath, *data_srcpath;
1172705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam        int listonly = 0;
1173705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam
1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(argc < 2) {
1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* No local path was specified. */
1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            srcarg = NULL;
1178705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam        } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
1179705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            listonly = 1;
1180705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            if (argc == 3) {
1181705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam                srcarg = argv[2];
1182705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            } else {
1183705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam                srcarg = NULL;
1184705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            }
1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(argc == 2) {
1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* A local path or "android"/"data" arg was specified. */
1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            srcarg = argv[1];
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return usage();
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ret != 0) return usage();
1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(android_srcpath != NULL)
1195705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            ret = do_sync_sync(android_srcpath, "/system", listonly);
1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(ret == 0 && data_srcpath != NULL)
1197705c944c0e2a50150ffb41707b6b3daebb45cf79Anthony Newnam            ret = do_sync_sync(data_srcpath, "/data", listonly);
1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(android_srcpath);
1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(data_srcpath);
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return ret;
1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* passthrough commands */
1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0],"get-state") ||
1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        !strcmp(argv[0],"get-serialno"))
1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *tmp;
1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        format_host_command(buf, sizeof buf, argv[0], ttype, serial);
1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        tmp = adb_query(buf);
1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(tmp) {
1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            printf("%s\n", tmp);
1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* other commands */
1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0],"status-window")) {
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        status_window(ttype, serial);
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) {
1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return logcat(ttype, serial, argc, argv);
1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0],"ppp")) {
1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return ppp(argc, argv);
1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(argv[0], "start-server")) {
1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return adb_connect("host:start-server");
1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1240d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    if (!strcmp(argv[0], "backup")) {
1241d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate        return backup(argc, argv);
1242d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate    }
1243d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate
1244702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    if (!strcmp(argv[0], "restore")) {
1245702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate        return restore(argc, argv);
1246702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate    }
1247702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate
1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!strcmp(argv[0], "jdwp")) {
1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  fd = adb_connect("jdwp");
1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (fd >= 0) {
1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            read_and_dump(fd);
1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            adb_close(fd);
1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fprintf(stderr, "error: %s\n", adb_error());
1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* "adb /?" is a common idiom under Windows */
1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        help();
1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!strcmp(argv[0], "version")) {
1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        version(stdout);
1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    usage();
1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 1;
1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *argv[16];
1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int argc;
1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_list ap;
1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_start(ap, cmd);
1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    argc = 0;
1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (serial) {
1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv[argc++] = "-s";
1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv[argc++] = serial;
1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (ttype == kTransportUsb) {
1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv[argc++] = "-d";
1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (ttype == kTransportLocal) {
1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv[argc++] = "-e";
1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    argv[argc++] = cmd;
1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    va_end(ap);
1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"argc = %d\n",argc);
1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(n = 0; n < argc; n++) {
1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]);
1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return adb_commandline(argc, argv);
1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint find_sync_dirs(const char *srcarg,
1309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char **android_srcdir_out, char **data_srcdir_out)
1310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *android_srcdir, *data_srcdir;
1312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(srcarg == NULL) {
1314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        android_srcdir = product_file("system");
1315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        data_srcdir = product_file("data");
1316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
1317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* srcarg may be "data", "system" or NULL.
1318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         * if srcarg is NULL, then both data and system are synced
1319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project         */
1320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(strcmp(srcarg, "system") == 0) {
1321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            android_srcdir = product_file("system");
1322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            data_srcdir = NULL;
1323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(strcmp(srcarg, "data") == 0) {
1324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            android_srcdir = NULL;
1325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            data_srcdir = product_file("data");
1326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
1327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* It's not "system" or "data".
1328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project             */
1329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 1;
1330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(android_srcdir_out != NULL)
1334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *android_srcdir_out = android_srcdir;
1335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(android_srcdir);
1337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(data_srcdir_out != NULL)
1339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *data_srcdir_out = data_srcdir;
1340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(data_srcdir);
1342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int pm_command(transport_type transport, char* serial,
1347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                      int argc, char** argv)
1348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
1350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(buf, sizeof(buf), "shell:pm");
1352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc-- > 0) {
1354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char *quoted;
1355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        quoted = dupAndQuote(*argv++);
1357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strncat(buf, " ", sizeof(buf)-1);
1359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strncat(buf, quoted, sizeof(buf)-1);
1360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        free(quoted);
1361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_shellcommand(transport, serial, buf);
1364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint uninstall_app(transport_type transport, char* serial, int argc, char** argv)
1368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* if the user choose the -k option, we refuse to do it until devices are
1370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       out with the option to uninstall the remaining data somehow (adb/ui) */
1371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (argc == 3 && strcmp(argv[1], "-k") == 0)
1372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
1373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf(
1374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "The -k option uninstalls the application while retaining the data/cache.\n"
1375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "At the moment, there is no way to remove the remaining data.\n"
1376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "You will have to reinstall the application with the same signature, and fully uninstall it.\n"
1377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]);
1378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */
1382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return pm_command(transport, serial, argc, argv);
1383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int delete_file(transport_type transport, char* serial, char* filename)
1386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char buf[4096];
1388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char* quoted;
1389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(buf, sizeof(buf), "shell:rm ");
1391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    quoted = dupAndQuote(filename);
1392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    strncat(buf, quoted, sizeof(buf)-1);
1393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    free(quoted);
1394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    send_shellcommand(transport, serial, buf);
1396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1399597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Rootstatic const char* get_basename(const char* filename)
1400597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root{
1401597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    const char* basename = adb_dirstop(filename);
1402597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (basename) {
1403597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        basename++;
1404597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return basename;
1405597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    } else {
1406597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return filename;
1407597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1408597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root}
1409597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1410597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Rootstatic int check_file(const char* filename)
1411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat st;
1413597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1414597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (filename == NULL) {
1415597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return 0;
1416597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1417597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1418597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (stat(filename, &st) != 0) {
1419597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        fprintf(stderr, "can't find '%s' to install\n", filename);
1420597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return 1;
1421597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1422597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1423597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (!S_ISREG(st.st_mode)) {
1424597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        fprintf(stderr, "can't install '%s' because it's not a file\n", filename);
1425597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return 1;
1426597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1427597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1428597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    return 0;
1429597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root}
1430597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1431597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Rootint install_app(transport_type transport, char* serial, int argc, char** argv)
1432597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root{
1433597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    static const char *const DATA_DEST = "/data/local/tmp/%s";
1434597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    static const char *const SD_DEST = "/sdcard/tmp/%s";
14350ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood    const char* where = DATA_DEST;
1436597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    char apk_dest[PATH_MAX];
1437597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    char verification_dest[PATH_MAX];
1438597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    char* apk_file;
1439597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    char* verification_file = NULL;
1440597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    int file_arg = -1;
1441597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    int err;
14420ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood    int i;
14430ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood
1444597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    for (i = 1; i < argc; i++) {
1445597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        if (*argv[i] != '-') {
1446597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            file_arg = i;
1447597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            break;
1448a031a91b9518af9a38290713b0c2126d9b8f6cdeKenny Root        } else if (!strcmp(argv[i], "-i")) {
1449a031a91b9518af9a38290713b0c2126d9b8f6cdeKenny Root            // Skip the installer package name.
1450a031a91b9518af9a38290713b0c2126d9b8f6cdeKenny Root            i++;
1451597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        } else if (!strcmp(argv[i], "-s")) {
14520ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood            where = SD_DEST;
1453597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        }
14540ef3fd048aeaeb59467e43e543f66b96e4e6c7f5Mike Lockwood    }
1455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1456597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (file_arg < 0) {
1457a031a91b9518af9a38290713b0c2126d9b8f6cdeKenny Root        fprintf(stderr, "can't find filename in arguments\n");
1458597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return 1;
1459597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    } else if (file_arg + 2 < argc) {
1460a031a91b9518af9a38290713b0c2126d9b8f6cdeKenny Root        fprintf(stderr, "too many files specified; only takes APK file and verifier file\n");
1461597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return 1;
1462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1463597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1464597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    apk_file = argv[file_arg];
1465597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1466597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (file_arg != argc - 1) {
1467597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        verification_file = argv[file_arg + 1];
1468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1470597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (check_file(apk_file) || check_file(verification_file)) {
1471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 1;
1472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1473597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1474597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
1475597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (verification_file != NULL) {
1476597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        snprintf(verification_dest, sizeof(verification_dest), where, get_basename(verification_file));
1477597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1478597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        if (!strcmp(apk_dest, verification_dest)) {
1479597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            fprintf(stderr, "APK and verification file can't have the same name\n");
1480597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            return 1;
1481597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        }
1482597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1483597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1484597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    err = do_sync_push(apk_file, apk_dest, 1 /* verify APK */);
1485597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (err) {
1486597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        return err;
1487597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    } else {
1488597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        argv[file_arg] = apk_dest; /* destination name, not source location */
1489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1491597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (verification_file != NULL) {
1492597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        err = do_sync_push(verification_file, verification_dest, 0 /* no verify APK */);
1493597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        if (err) {
1494597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            goto cleanup_apk;
1495597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        } else {
1496597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root            argv[file_arg + 1] = verification_dest; /* destination name, not source location */
1497597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        }
1498597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    }
1499597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1500597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    pm_command(transport, serial, argc, argv);
1501597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1502597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    if (verification_file != NULL) {
1503597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root        delete_file(transport, serial, verification_dest);
1504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1506597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Rootcleanup_apk:
1507597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root    delete_file(transport, serial, apk_dest);
1508597ea5b63f764b4403fd0d34400ab37cf944b479Kenny Root
1509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return err;
1510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1511