Fix more buffer overruns.
Also add some tests. Bug: 20323050 Change-Id: I9eaf3dc04efd85206663c4cca4f8c1208620a89a
This commit is contained in:
parent
3538b40942
commit
5830577bd8
6 changed files with 230 additions and 221 deletions
|
@ -21,6 +21,7 @@ LIBADB_SRC_FILES := \
|
|||
adb_auth.cpp \
|
||||
adb_io.cpp \
|
||||
adb_listeners.cpp \
|
||||
adb_utils.cpp \
|
||||
sockets.cpp \
|
||||
transport.cpp \
|
||||
transport_local.cpp \
|
||||
|
@ -82,6 +83,7 @@ include $(BUILD_HOST_STATIC_LIBRARY)
|
|||
|
||||
LIBADB_TEST_SRCS := \
|
||||
adb_io_test.cpp \
|
||||
adb_utils_test.cpp \
|
||||
transport_test.cpp \
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
43
adb/adb_utils.cpp
Normal file
43
adb/adb_utils.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "adb_utils.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool directory_exists(const std::string& path) {
|
||||
struct stat sb;
|
||||
return lstat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
|
||||
}
|
||||
|
||||
static bool should_escape(const char c) {
|
||||
return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
|
||||
}
|
||||
|
||||
std::string escape_arg(const std::string& s) {
|
||||
// Preserve empty arguments.
|
||||
if (s.empty()) return "\"\"";
|
||||
|
||||
std::string result(s);
|
||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
||||
if (should_escape(*it)) {
|
||||
it = result.insert(it, '\\') + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
26
adb/adb_utils.h
Normal file
26
adb/adb_utils.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ADB_UTILS_H_
|
||||
#define _ADB_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
bool directory_exists(const std::string& path);
|
||||
|
||||
std::string escape_arg(const std::string& s);
|
||||
|
||||
#endif
|
52
adb/adb_utils_test.cpp
Normal file
52
adb/adb_utils_test.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "adb_utils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(adb_utils, directory_exists) {
|
||||
ASSERT_TRUE(directory_exists("/proc"));
|
||||
ASSERT_FALSE(directory_exists("/proc/self")); // Symbolic link.
|
||||
ASSERT_FALSE(directory_exists("/proc/does-not-exist"));
|
||||
}
|
||||
|
||||
TEST(adb_utils, escape_arg) {
|
||||
ASSERT_EQ(R"("")", escape_arg(""));
|
||||
|
||||
ASSERT_EQ(R"(abc)", escape_arg("abc"));
|
||||
|
||||
ASSERT_EQ(R"(\ abc)", escape_arg(" abc"));
|
||||
ASSERT_EQ(R"(\'abc)", escape_arg("'abc"));
|
||||
ASSERT_EQ(R"(\"abc)", escape_arg("\"abc"));
|
||||
ASSERT_EQ(R"(\\abc)", escape_arg("\\abc"));
|
||||
ASSERT_EQ(R"(\(abc)", escape_arg("(abc"));
|
||||
ASSERT_EQ(R"(\)abc)", escape_arg(")abc"));
|
||||
|
||||
ASSERT_EQ(R"(abc\ abc)", escape_arg("abc abc"));
|
||||
ASSERT_EQ(R"(abc\'abc)", escape_arg("abc'abc"));
|
||||
ASSERT_EQ(R"(abc\"abc)", escape_arg("abc\"abc"));
|
||||
ASSERT_EQ(R"(abc\\abc)", escape_arg("abc\\abc"));
|
||||
ASSERT_EQ(R"(abc\(abc)", escape_arg("abc(abc"));
|
||||
ASSERT_EQ(R"(abc\)abc)", escape_arg("abc)abc"));
|
||||
|
||||
ASSERT_EQ(R"(abc\ )", escape_arg("abc "));
|
||||
ASSERT_EQ(R"(abc\')", escape_arg("abc'"));
|
||||
ASSERT_EQ(R"(abc\")", escape_arg("abc\""));
|
||||
ASSERT_EQ(R"(abc\\)", escape_arg("abc\\"));
|
||||
ASSERT_EQ(R"(abc\()", escape_arg("abc("));
|
||||
ASSERT_EQ(R"(abc\))", escape_arg("abc)"));
|
||||
}
|
|
@ -43,49 +43,38 @@
|
|||
#include "adb_auth.h"
|
||||
#include "adb_client.h"
|
||||
#include "adb_io.h"
|
||||
#include "adb_utils.h"
|
||||
#include "file_sync_service.h"
|
||||
|
||||
static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...);
|
||||
|
||||
int find_sync_dirs(const char *srcarg,
|
||||
char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
|
||||
char **oem_srcdir_out);
|
||||
int install_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv);
|
||||
int install_multiple_app(transport_type transport, const char* serial, int argc,
|
||||
static int install_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv);
|
||||
static int install_multiple_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv);
|
||||
static int uninstall_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv);
|
||||
int uninstall_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv);
|
||||
|
||||
static const char *gProductOutPath = NULL;
|
||||
static std::string gProductOutPath;
|
||||
extern int gListenAll;
|
||||
|
||||
static char *product_file(const char *extra)
|
||||
{
|
||||
if (gProductOutPath == NULL) {
|
||||
static std::string product_file(const char *extra) {
|
||||
if (gProductOutPath.empty()) {
|
||||
fprintf(stderr, "adb: Product directory not specified; "
|
||||
"use -p or define ANDROID_PRODUCT_OUT\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int n = strlen(gProductOutPath) + strlen(extra) + 2;
|
||||
char* x = reinterpret_cast<char*>(malloc(n));
|
||||
if (x == 0) {
|
||||
fprintf(stderr, "adb: Out of memory (product_file())\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra);
|
||||
return x;
|
||||
return android::base::StringPrintf("%s%s%s",
|
||||
gProductOutPath.c_str(), OS_PATH_SEPARATOR_STR, extra);
|
||||
}
|
||||
|
||||
void version(FILE * out) {
|
||||
static void version(FILE* out) {
|
||||
fprintf(out, "Android Debug Bridge version %d.%d.%d\n",
|
||||
ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
|
||||
ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION);
|
||||
}
|
||||
|
||||
void help()
|
||||
{
|
||||
static void help() {
|
||||
version(stderr);
|
||||
|
||||
fprintf(stderr,
|
||||
|
@ -245,8 +234,7 @@ void help()
|
|||
);
|
||||
}
|
||||
|
||||
int usage()
|
||||
{
|
||||
static int usage() {
|
||||
help();
|
||||
return 1;
|
||||
}
|
||||
|
@ -418,8 +406,7 @@ static void *stdin_read_thread(void *x)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int interactive_shell(void)
|
||||
{
|
||||
static int interactive_shell() {
|
||||
adb_thread_t thr;
|
||||
int fdi, fd;
|
||||
|
||||
|
@ -457,8 +444,8 @@ static void format_host_command(char* buffer, size_t buflen, const char* comman
|
|||
}
|
||||
}
|
||||
|
||||
int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
|
||||
unsigned progress)
|
||||
static int adb_download_buffer(const char *service, const char *fn, const void* data, int sz,
|
||||
unsigned progress)
|
||||
{
|
||||
char buf[4096];
|
||||
unsigned total;
|
||||
|
@ -516,23 +503,6 @@ int adb_download_buffer(const char *service, const char *fn, const void* data, i
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int adb_download(const char *service, const char *fn, unsigned progress)
|
||||
{
|
||||
void *data;
|
||||
unsigned sz;
|
||||
|
||||
data = load_file(fn, &sz);
|
||||
if(data == 0) {
|
||||
fprintf(stderr,"* cannot read '%s' *\n", fn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int status = adb_download_buffer(service, fn, data, sz, progress);
|
||||
free(data);
|
||||
return status;
|
||||
}
|
||||
|
||||
#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
|
||||
|
||||
/*
|
||||
|
@ -554,7 +524,7 @@ int adb_download(const char *service, const char *fn, unsigned progress)
|
|||
* - When the other side sends "DONEDONE" instead of a block number,
|
||||
* we hang up.
|
||||
*/
|
||||
int adb_sideload_host(const char* fn) {
|
||||
static int adb_sideload_host(const char* fn) {
|
||||
unsigned sz;
|
||||
size_t xfer = 0;
|
||||
int status;
|
||||
|
@ -685,24 +655,6 @@ static void status_window(transport_type ttype, const char* serial)
|
|||
}
|
||||
}
|
||||
|
||||
static int should_escape(const char c)
|
||||
{
|
||||
return (c == ' ' || c == '\'' || c == '"' || c == '\\' || c == '(' || c == ')');
|
||||
}
|
||||
|
||||
static std::string escape_arg(const std::string& s) {
|
||||
// Preserve empty arguments.
|
||||
if (s.empty()) return "\"\"";
|
||||
|
||||
std::string result(s);
|
||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
||||
if (should_escape(*it)) {
|
||||
it = result.insert(it, '\\') + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run ppp in "notty" mode against a resource listed as the first parameter
|
||||
* eg:
|
||||
|
@ -710,8 +662,7 @@ static std::string escape_arg(const std::string& s) {
|
|||
* ppp dev:/dev/omap_csmi_tty0 <ppp options>
|
||||
*
|
||||
*/
|
||||
int ppp(int argc, const char **argv)
|
||||
{
|
||||
static int ppp(int argc, const char** argv) {
|
||||
#if defined(_WIN32)
|
||||
fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
|
||||
return -1;
|
||||
|
@ -1003,62 +954,52 @@ TODO: debug? sooner-debug, sooner:debug?
|
|||
* Given <hint>, try to construct an absolute path to the
|
||||
* ANDROID_PRODUCT_OUT dir.
|
||||
*/
|
||||
static const char *find_product_out_path(const char *hint)
|
||||
{
|
||||
static char path_buf[PATH_MAX];
|
||||
|
||||
static std::string find_product_out_path(const char* hint) {
|
||||
if (hint == NULL || hint[0] == '\0') {
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
|
||||
/* If it's already absolute, don't bother doing any work.
|
||||
*/
|
||||
// If it's already absolute, don't bother doing any work.
|
||||
if (adb_is_absolute_host_path(hint)) {
|
||||
strcpy(path_buf, hint);
|
||||
return path_buf;
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* If there are any slashes in it, assume it's a relative path;
|
||||
* make it absolute.
|
||||
*/
|
||||
// If there are any slashes in it, assume it's a relative path;
|
||||
// make it absolute.
|
||||
if (adb_dirstart(hint) != NULL) {
|
||||
if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
return "";
|
||||
}
|
||||
if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
|
||||
fprintf(stderr, "adb: Couldn't assemble path\n");
|
||||
return NULL;
|
||||
}
|
||||
strcat(path_buf, OS_PATH_SEPARATOR_STR);
|
||||
strcat(path_buf, hint);
|
||||
return path_buf;
|
||||
return android::base::StringPrintf("%s%s%s", cwd, OS_PATH_SEPARATOR_STR, hint);
|
||||
}
|
||||
|
||||
/* It's a string without any slashes. Try to do something with it.
|
||||
*
|
||||
* Try to find the root of the build tree, and build a PRODUCT_OUT
|
||||
* path from there.
|
||||
*/
|
||||
// It's a string without any slashes. Try to do something with it.
|
||||
//
|
||||
// Try to find the root of the build tree, and build a PRODUCT_OUT
|
||||
// path from there.
|
||||
char top_buf[PATH_MAX];
|
||||
const char *top = find_top(top_buf);
|
||||
if (top == NULL) {
|
||||
const char* top = find_top(top_buf);
|
||||
if (top == nullptr) {
|
||||
fprintf(stderr, "adb: Couldn't find top of build tree\n");
|
||||
return "";
|
||||
}
|
||||
std::string path = top_buf;
|
||||
path += OS_PATH_SEPARATOR_STR;
|
||||
path += "out";
|
||||
path += OS_PATH_SEPARATOR_STR;
|
||||
path += "target";
|
||||
path += OS_PATH_SEPARATOR_STR;
|
||||
path += "product";
|
||||
path += OS_PATH_SEPARATOR_STR;
|
||||
path += hint;
|
||||
if (!directory_exists(path)) {
|
||||
fprintf(stderr, "adb: Couldn't find a product dir based on -p %s; "
|
||||
"\"%s\" doesn't exist\n", hint, path.c_str());
|
||||
return NULL;
|
||||
}
|
||||
//TODO: if we have a way to indicate debug, look in out/debug/target/...
|
||||
snprintf(path_buf, sizeof(path_buf),
|
||||
"%s" OS_PATH_SEPARATOR_STR
|
||||
"out" OS_PATH_SEPARATOR_STR
|
||||
"target" OS_PATH_SEPARATOR_STR
|
||||
"product" OS_PATH_SEPARATOR_STR
|
||||
"%s", top_buf, hint);
|
||||
if (access(path_buf, F_OK) < 0) {
|
||||
fprintf(stderr, "adb: Couldn't find a product dir "
|
||||
"based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf);
|
||||
return NULL;
|
||||
}
|
||||
return path_buf;
|
||||
return path;
|
||||
}
|
||||
|
||||
static void parse_push_pull_args(const char **arg, int narg, char const **path1,
|
||||
|
@ -1113,15 +1054,14 @@ int adb_commandline(int argc, const char **argv)
|
|||
const char* serial = NULL;
|
||||
const char* server_port_str = NULL;
|
||||
|
||||
/* If defined, this should be an absolute path to
|
||||
* the directory containing all of the various system images
|
||||
* for a particular product. If not defined, and the adb
|
||||
* command requires this information, then the user must
|
||||
* specify the path using "-p".
|
||||
*/
|
||||
gProductOutPath = getenv("ANDROID_PRODUCT_OUT");
|
||||
if (gProductOutPath == NULL || gProductOutPath[0] == '\0') {
|
||||
gProductOutPath = NULL;
|
||||
// If defined, this should be an absolute path to
|
||||
// the directory containing all of the various system images
|
||||
// for a particular product. If not defined, and the adb
|
||||
// command requires this information, then the user must
|
||||
// specify the path using "-p".
|
||||
char* ANDROID_PRODUCT_OUT = getenv("ANDROID_PRODUCT_OUT");
|
||||
if (ANDROID_PRODUCT_OUT != nullptr) {
|
||||
gProductOutPath = ANDROID_PRODUCT_OUT;
|
||||
}
|
||||
// TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint
|
||||
|
||||
|
@ -1162,9 +1102,8 @@ int adb_commandline(int argc, const char **argv)
|
|||
product = argv[0] + 2;
|
||||
}
|
||||
gProductOutPath = find_product_out_path(product);
|
||||
if (gProductOutPath == NULL) {
|
||||
fprintf(stderr, "adb: could not resolve \"-p %s\"\n",
|
||||
product);
|
||||
if (gProductOutPath.empty()) {
|
||||
fprintf(stderr, "adb: could not resolve \"-p %s\"\n", product);
|
||||
return usage();
|
||||
}
|
||||
} else if (argv[0][0]=='-' && argv[0][1]=='s') {
|
||||
|
@ -1595,46 +1534,55 @@ int adb_commandline(int argc, const char **argv)
|
|||
return uninstall_app(ttype, serial, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "sync")) {
|
||||
const char* srcarg;
|
||||
char *system_srcpath, *data_srcpath, *vendor_srcpath, *oem_srcpath;
|
||||
|
||||
int listonly = 0;
|
||||
|
||||
int ret;
|
||||
std::string src_arg;
|
||||
bool list_only = false;
|
||||
if (argc < 2) {
|
||||
/* No local path was specified. */
|
||||
srcarg = NULL;
|
||||
// No local path was specified.
|
||||
src_arg = "";
|
||||
} else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
|
||||
listonly = 1;
|
||||
list_only = 1;
|
||||
if (argc == 3) {
|
||||
srcarg = argv[2];
|
||||
src_arg = argv[2];
|
||||
} else {
|
||||
srcarg = NULL;
|
||||
src_arg = "";
|
||||
}
|
||||
} else if (argc == 2) {
|
||||
/* A local path or "android"/"data" arg was specified. */
|
||||
srcarg = argv[1];
|
||||
// A local path or "android"/"data" arg was specified.
|
||||
src_arg = argv[1];
|
||||
} else {
|
||||
return usage();
|
||||
}
|
||||
ret = find_sync_dirs(srcarg, &system_srcpath, &data_srcpath, &vendor_srcpath,
|
||||
&oem_srcpath);
|
||||
if (ret != 0) return usage();
|
||||
|
||||
if (system_srcpath != NULL)
|
||||
ret = do_sync_sync(system_srcpath, "/system", listonly);
|
||||
if (ret == 0 && vendor_srcpath != NULL)
|
||||
ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
|
||||
if(ret == 0 && oem_srcpath != NULL)
|
||||
ret = do_sync_sync(oem_srcpath, "/oem", listonly);
|
||||
if (ret == 0 && data_srcpath != NULL)
|
||||
ret = do_sync_sync(data_srcpath, "/data", listonly);
|
||||
if (src_arg != "" &&
|
||||
src_arg != "system" && src_arg != "data" && src_arg != "vendor" && src_arg != "oem") {
|
||||
return usage();
|
||||
}
|
||||
|
||||
free(system_srcpath);
|
||||
free(vendor_srcpath);
|
||||
free(oem_srcpath);
|
||||
free(data_srcpath);
|
||||
return ret;
|
||||
std::string system_src_path = product_file("system");
|
||||
std::string data_src_path = product_file("data");
|
||||
std::string vendor_src_path = product_file("vendor");
|
||||
std::string oem_src_path = product_file("oem");
|
||||
if (!directory_exists(vendor_src_path)) {
|
||||
vendor_src_path = "";
|
||||
}
|
||||
if (!directory_exists(oem_src_path)) {
|
||||
oem_src_path = "";
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
if (rc == 0 && (src_arg.empty() || src_arg == "system")) {
|
||||
rc = do_sync_sync(system_src_path.c_str(), "/system", list_only);
|
||||
}
|
||||
if (rc == 0 && (src_arg.empty() || src_arg == "vendor")) {
|
||||
rc = do_sync_sync(vendor_src_path.c_str(), "/vendor", list_only);
|
||||
}
|
||||
if(rc == 0 && (src_arg.empty() || src_arg == "oem")) {
|
||||
rc = do_sync_sync(oem_src_path.c_str(), "/oem", list_only);
|
||||
}
|
||||
if (rc == 0 && (src_arg.empty() || src_arg == "data")) {
|
||||
rc = do_sync_sync(data_src_path.c_str(), "/data", list_only);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
/* passthrough commands */
|
||||
else if (!strcmp(argv[0],"get-state") ||
|
||||
|
@ -1729,64 +1677,6 @@ static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...
|
|||
return adb_commandline(argc, argv);
|
||||
}
|
||||
|
||||
int find_sync_dirs(const char *srcarg,
|
||||
char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
|
||||
char **oem_srcdir_out)
|
||||
{
|
||||
char *system_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL, *oem_srcdir = NULL;
|
||||
struct stat st;
|
||||
|
||||
if(srcarg == NULL) {
|
||||
system_srcdir = product_file("system");
|
||||
data_srcdir = product_file("data");
|
||||
vendor_srcdir = product_file("vendor");
|
||||
oem_srcdir = product_file("oem");
|
||||
// Check if vendor partition exists.
|
||||
if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
|
||||
vendor_srcdir = NULL;
|
||||
// Check if oem partition exists.
|
||||
if (lstat(oem_srcdir, &st) || !S_ISDIR(st.st_mode))
|
||||
oem_srcdir = NULL;
|
||||
} else {
|
||||
// srcarg may be "data", "system", "vendor", "oem" or NULL.
|
||||
// If srcarg is NULL, then all partitions are synced.
|
||||
if(strcmp(srcarg, "system") == 0) {
|
||||
system_srcdir = product_file("system");
|
||||
} else if(strcmp(srcarg, "data") == 0) {
|
||||
data_srcdir = product_file("data");
|
||||
} else if(strcmp(srcarg, "vendor") == 0) {
|
||||
vendor_srcdir = product_file("vendor");
|
||||
} else if(strcmp(srcarg, "oem") == 0) {
|
||||
oem_srcdir = product_file("oem");
|
||||
} else {
|
||||
// It's not "system", "data", "vendor", or "oem".
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(system_srcdir_out != NULL)
|
||||
*system_srcdir_out = system_srcdir;
|
||||
else
|
||||
free(system_srcdir);
|
||||
|
||||
if(vendor_srcdir_out != NULL)
|
||||
*vendor_srcdir_out = vendor_srcdir;
|
||||
else
|
||||
free(vendor_srcdir);
|
||||
|
||||
if(oem_srcdir_out != NULL)
|
||||
*oem_srcdir_out = oem_srcdir;
|
||||
else
|
||||
free(oem_srcdir);
|
||||
|
||||
if(data_srcdir_out != NULL)
|
||||
*data_srcdir_out = data_srcdir;
|
||||
else
|
||||
free(data_srcdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pm_command(transport_type transport, const char* serial,
|
||||
int argc, const char** argv)
|
||||
{
|
||||
|
@ -1801,8 +1691,8 @@ static int pm_command(transport_type transport, const char* serial,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int uninstall_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
static int uninstall_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
{
|
||||
/* if the user choose the -k option, we refuse to do it until devices are
|
||||
out with the option to uninstall the remaining data somehow (adb/ui) */
|
||||
|
@ -1838,8 +1728,8 @@ static const char* get_basename(const char* filename)
|
|||
}
|
||||
}
|
||||
|
||||
int install_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
static int install_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
{
|
||||
static const char *const DATA_DEST = "/data/local/tmp/%s";
|
||||
static const char *const SD_DEST = "/sdcard/tmp/%s";
|
||||
|
@ -1892,8 +1782,8 @@ cleanup_apk:
|
|||
return err;
|
||||
}
|
||||
|
||||
int install_multiple_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
static int install_multiple_app(transport_type transport, const char* serial, int argc,
|
||||
const char** argv)
|
||||
{
|
||||
int i;
|
||||
struct stat sb;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "adb.h"
|
||||
#include "adb_io.h"
|
||||
#include "adb_utils.h"
|
||||
#include "cutils/properties.h"
|
||||
|
||||
static int system_ro = 1;
|
||||
|
@ -56,11 +57,6 @@ static std::string find_mount(const char *dir) {
|
|||
return device;
|
||||
}
|
||||
|
||||
static bool has_partition(const char* path) {
|
||||
struct stat sb;
|
||||
return (lstat(path, &sb) == 0 && S_ISDIR(sb.st_mode));
|
||||
}
|
||||
|
||||
int make_block_device_writable(const std::string& dev) {
|
||||
int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
|
@ -90,7 +86,7 @@ static int remount(const char* dir, int* dir_ro) {
|
|||
}
|
||||
|
||||
static bool remount_partition(int fd, const char* partition, int* ro) {
|
||||
if (!has_partition(partition)) {
|
||||
if (!directory_exists(partition)) {
|
||||
return true;
|
||||
}
|
||||
if (remount(partition, ro)) {
|
||||
|
|
Loading…
Reference in a new issue