Loading adb/commandline.cpp +42 −34 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <memory> #include <string> #include <vector> #include <base/logging.h> #include <base/stringprintf.h> Loading Loading @@ -101,11 +102,11 @@ static void help() { " will disconnect from all connected TCP/IP devices.\n" "\n" "device commands:\n" " adb push <local> <remote>\n" " - copy file/dir to device\n" " adb pull [-a] <remote> [<local>]\n" " - copy file/dir from device\n" " ('-a' means copy timestamp and mode)\n" " adb push <local>... <remote>\n" " - copy files/dirs to device\n" " adb pull [-a] <remote>... <local>\n" " - copy files/dirs from device\n" " (-a preserves file timestamp and mode)\n" " adb sync [ <directory> ] - copy host->device only if changed\n" " (-l means list but don't copy)\n" " adb shell [-Ttx] - run remote shell interactively\n" Loading Loading @@ -1066,30 +1067,34 @@ static std::string find_product_out_path(const std::string& hint) { } static void parse_push_pull_args(const char** arg, int narg, char const **path1, char const **path2, int *copy_attrs) { *copy_attrs = 0; std::vector<const char*>* srcs, const char** dst, bool* copy_attrs) { *copy_attrs = false; srcs->clear(); bool ignore_flags = false; while (narg > 0) { if (ignore_flags || *arg[0] != '-') { srcs->push_back(*arg); } else { if (!strcmp(*arg, "-p")) { // Silently ignore for backwards compatibility. } else if (!strcmp(*arg, "-a")) { *copy_attrs = 1; *copy_attrs = true; } else if (!strcmp(*arg, "--")) { ignore_flags = true; } else { break; fprintf(stderr, "adb: unrecognized option '%s'\n", *arg); exit(1); } ++arg; --narg; } if (narg > 0) { *path1 = *arg; ++arg; --narg; } if (narg > 0) { *path2 = *arg; if (srcs->size() > 1) { *dst = srcs->back(); srcs->pop_back(); } } Loading Loading @@ -1561,20 +1566,22 @@ int adb_commandline(int argc, const char **argv) { return do_sync_ls(argv[1]) ? 0 : 1; } else if (!strcmp(argv[0], "push")) { int copy_attrs = 0; const char* lpath = NULL, *rpath = NULL; bool copy_attrs = false; std::vector<const char*> srcs; const char* dst = nullptr; parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, ©_attrs); if (!lpath || !rpath || copy_attrs != 0) return usage(); return do_sync_push(lpath, rpath) ? 0 : 1; parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs); if (srcs.empty() || !dst) return usage(); return do_sync_push(srcs, dst) ? 0 : 1; } else if (!strcmp(argv[0], "pull")) { int copy_attrs = 0; const char* rpath = NULL, *lpath = "."; bool copy_attrs = false; std::vector<const char*> srcs; const char* dst = "."; parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, ©_attrs); if (!rpath) return usage(); return do_sync_pull(rpath, lpath, copy_attrs) ? 0 : 1; parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs); if (srcs.empty()) return usage(); return do_sync_pull(srcs, dst, copy_attrs) ? 0 : 1; } else if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); Loading Loading @@ -1764,8 +1771,9 @@ static int install_app(TransportType transport, const char* serial, int argc, co } int result = -1; const char* apk_file = argv[last_apk]; std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str()); std::vector<const char*> apk_file = {argv[last_apk]}; std::string apk_dest = android::base::StringPrintf( where, adb_basename(argv[last_apk]).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ result = pm_command(transport, serial, argc, argv); Loading adb/file_sync_client.cpp +103 −43 Original line number Diff line number Diff line Loading @@ -625,32 +625,55 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c return true; } bool do_sync_push(const char* lpath, const char* rpath) { bool do_sync_push(const std::vector<const char*>& srcs, const char* dst) { SyncConnection sc; if (!sc.IsValid()) return false; struct stat st; if (stat(lpath, &st)) { sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); bool success = true; unsigned mode; if (!sync_stat(sc, dst, nullptr, &mode, nullptr)) return false; bool dst_isdir = mode != 0 && S_ISDIR(mode); if (!dst_isdir) { if (srcs.size() > 1) { sc.Error("target '%s' is not a directory", dst); return false; } else { size_t dst_len = strlen(dst); if (dst[dst_len - 1] == '/') { sc.Error("failed to access '%s': Not a directory", dst); return false; } } } for (const char* src_path : srcs) { const char* dst_path = dst; struct stat st; if (stat(src_path, &st)) { sc.Error("cannot stat '%s': %s", src_path, strerror(errno)); success = false; continue; } if (S_ISDIR(st.st_mode)) { return copy_local_dir_remote(sc, lpath, rpath, false, false); success &= copy_local_dir_remote(sc, src_path, dst, false, false); continue; } unsigned mode; if (!sync_stat(sc, rpath, nullptr, &mode, nullptr)) return false; std::string path_holder; if (mode != 0 && S_ISDIR(mode)) { // If we're copying a local file to a remote directory, // we really want to copy to remote_dir + "/" + local_filename. path_holder = android::base::StringPrintf("%s/%s", rpath, adb_basename(lpath).c_str()); rpath = path_holder.c_str(); path_holder = android::base::StringPrintf( "%s/%s", dst_path, adb_basename(src_path).c_str()); dst_path = path_holder.c_str(); } bool result = sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode); success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode); } sc.Print("\n"); return result; return success; } struct sync_ls_build_list_cb_args { Loading Loading @@ -733,7 +756,7 @@ static int set_time_and_mode(const char *lpath, time_t time, unsigned int mode) } static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const char* lpath, int copy_attrs) { bool copy_attrs) { // Make sure that both directory paths end in a slash. std::string rpath_clean(rpath); std::string lpath_clean(lpath); Loading Loading @@ -774,43 +797,80 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c return true; } bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs) { bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs) { SyncConnection sc; if (!sc.IsValid()) return false; bool success = true; unsigned mode, time; if (!sync_stat(sc, rpath, &time, &mode, nullptr)) return false; if (mode == 0) { sc.Error("remote object '%s' does not exist", rpath); struct stat st; if (stat(dst, &st)) { // If we're only pulling one file, the destination path might point to // a path that doesn't exist yet. if (srcs.size() != 1 || errno != ENOENT) { sc.Error("cannot stat '%s': %s", dst, strerror(errno)); return false; } } bool dst_isdir = S_ISDIR(st.st_mode); if (!dst_isdir) { if (srcs.size() > 1) { sc.Error("target '%s' is not a directory", dst); return false; } else { size_t dst_len = strlen(dst); if (dst[dst_len - 1] == '/') { sc.Error("failed to access '%s': Not a directory", dst); return false; } } } for (const char* src_path : srcs) { const char* dst_path = dst; if (!sync_stat(sc, src_path, &time, &mode, nullptr)) return false; if (mode == 0) { sc.Error("remote object '%s' does not exist", src_path); success = false; continue; } if (S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) { std::string path_holder; struct stat st; if (stat(lpath, &st) == 0) { if (stat(dst_path, &st) == 0) { if (S_ISDIR(st.st_mode)) { // If we're copying a remote file to a local directory, // we really want to copy to local_dir + "/" + basename(remote). path_holder = android::base::StringPrintf("%s/%s", lpath, adb_basename(rpath).c_str()); lpath = path_holder.c_str(); // we really want to copy to local_dir + "/" + // basename(remote). path_holder = android::base::StringPrintf( "%s/%s", dst_path, adb_basename(src_path).c_str()); dst_path = path_holder.c_str(); } } if (!sync_recv(sc, rpath, lpath)) { return false; if (!sync_recv(sc, src_path, dst_path)) { success = false; continue; } else { if (copy_attrs && set_time_and_mode(lpath, time, mode)) { return false; if (copy_attrs && set_time_and_mode(dst_path, time, mode)) { success = false; continue; } } sc.Print("\n"); return true; } else if (S_ISDIR(mode)) { return copy_remote_dir_local(sc, rpath, lpath, copy_attrs); success &= copy_remote_dir_local(sc, src_path, dst_path, copy_attrs); continue; } else { sc.Error("remote object '%s' not a file or directory", src_path); success = false; continue; } } sc.Error("remote object '%s' not a file or directory", rpath); return false; sc.Print("\n"); return success; } bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) { Loading adb/file_sync_service.h +5 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define _FILE_SYNC_SERVICE_H_ #include <string> #include <vector> #define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) Loading Loading @@ -64,9 +65,11 @@ union syncmsg { void file_sync_service(int fd, void* cookie); bool do_sync_ls(const char* path); bool do_sync_push(const char* lpath, const char* rpath); bool do_sync_push(const std::vector<const char*>& srcs, const char* dst); bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs); bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only); bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs); #define SYNC_DATA_MAX (64*1024) Loading Loading
adb/commandline.cpp +42 −34 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <memory> #include <string> #include <vector> #include <base/logging.h> #include <base/stringprintf.h> Loading Loading @@ -101,11 +102,11 @@ static void help() { " will disconnect from all connected TCP/IP devices.\n" "\n" "device commands:\n" " adb push <local> <remote>\n" " - copy file/dir to device\n" " adb pull [-a] <remote> [<local>]\n" " - copy file/dir from device\n" " ('-a' means copy timestamp and mode)\n" " adb push <local>... <remote>\n" " - copy files/dirs to device\n" " adb pull [-a] <remote>... <local>\n" " - copy files/dirs from device\n" " (-a preserves file timestamp and mode)\n" " adb sync [ <directory> ] - copy host->device only if changed\n" " (-l means list but don't copy)\n" " adb shell [-Ttx] - run remote shell interactively\n" Loading Loading @@ -1066,30 +1067,34 @@ static std::string find_product_out_path(const std::string& hint) { } static void parse_push_pull_args(const char** arg, int narg, char const **path1, char const **path2, int *copy_attrs) { *copy_attrs = 0; std::vector<const char*>* srcs, const char** dst, bool* copy_attrs) { *copy_attrs = false; srcs->clear(); bool ignore_flags = false; while (narg > 0) { if (ignore_flags || *arg[0] != '-') { srcs->push_back(*arg); } else { if (!strcmp(*arg, "-p")) { // Silently ignore for backwards compatibility. } else if (!strcmp(*arg, "-a")) { *copy_attrs = 1; *copy_attrs = true; } else if (!strcmp(*arg, "--")) { ignore_flags = true; } else { break; fprintf(stderr, "adb: unrecognized option '%s'\n", *arg); exit(1); } ++arg; --narg; } if (narg > 0) { *path1 = *arg; ++arg; --narg; } if (narg > 0) { *path2 = *arg; if (srcs->size() > 1) { *dst = srcs->back(); srcs->pop_back(); } } Loading Loading @@ -1561,20 +1566,22 @@ int adb_commandline(int argc, const char **argv) { return do_sync_ls(argv[1]) ? 0 : 1; } else if (!strcmp(argv[0], "push")) { int copy_attrs = 0; const char* lpath = NULL, *rpath = NULL; bool copy_attrs = false; std::vector<const char*> srcs; const char* dst = nullptr; parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, ©_attrs); if (!lpath || !rpath || copy_attrs != 0) return usage(); return do_sync_push(lpath, rpath) ? 0 : 1; parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs); if (srcs.empty() || !dst) return usage(); return do_sync_push(srcs, dst) ? 0 : 1; } else if (!strcmp(argv[0], "pull")) { int copy_attrs = 0; const char* rpath = NULL, *lpath = "."; bool copy_attrs = false; std::vector<const char*> srcs; const char* dst = "."; parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, ©_attrs); if (!rpath) return usage(); return do_sync_pull(rpath, lpath, copy_attrs) ? 0 : 1; parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, ©_attrs); if (srcs.empty()) return usage(); return do_sync_pull(srcs, dst, copy_attrs) ? 0 : 1; } else if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); Loading Loading @@ -1764,8 +1771,9 @@ static int install_app(TransportType transport, const char* serial, int argc, co } int result = -1; const char* apk_file = argv[last_apk]; std::string apk_dest = android::base::StringPrintf(where, adb_basename(apk_file).c_str()); std::vector<const char*> apk_file = {argv[last_apk]}; std::string apk_dest = android::base::StringPrintf( where, adb_basename(argv[last_apk]).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str())) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ result = pm_command(transport, serial, argc, argv); Loading
adb/file_sync_client.cpp +103 −43 Original line number Diff line number Diff line Loading @@ -625,32 +625,55 @@ static bool copy_local_dir_remote(SyncConnection& sc, const char* lpath, const c return true; } bool do_sync_push(const char* lpath, const char* rpath) { bool do_sync_push(const std::vector<const char*>& srcs, const char* dst) { SyncConnection sc; if (!sc.IsValid()) return false; struct stat st; if (stat(lpath, &st)) { sc.Error("cannot stat '%s': %s", lpath, strerror(errno)); bool success = true; unsigned mode; if (!sync_stat(sc, dst, nullptr, &mode, nullptr)) return false; bool dst_isdir = mode != 0 && S_ISDIR(mode); if (!dst_isdir) { if (srcs.size() > 1) { sc.Error("target '%s' is not a directory", dst); return false; } else { size_t dst_len = strlen(dst); if (dst[dst_len - 1] == '/') { sc.Error("failed to access '%s': Not a directory", dst); return false; } } } for (const char* src_path : srcs) { const char* dst_path = dst; struct stat st; if (stat(src_path, &st)) { sc.Error("cannot stat '%s': %s", src_path, strerror(errno)); success = false; continue; } if (S_ISDIR(st.st_mode)) { return copy_local_dir_remote(sc, lpath, rpath, false, false); success &= copy_local_dir_remote(sc, src_path, dst, false, false); continue; } unsigned mode; if (!sync_stat(sc, rpath, nullptr, &mode, nullptr)) return false; std::string path_holder; if (mode != 0 && S_ISDIR(mode)) { // If we're copying a local file to a remote directory, // we really want to copy to remote_dir + "/" + local_filename. path_holder = android::base::StringPrintf("%s/%s", rpath, adb_basename(lpath).c_str()); rpath = path_holder.c_str(); path_holder = android::base::StringPrintf( "%s/%s", dst_path, adb_basename(src_path).c_str()); dst_path = path_holder.c_str(); } bool result = sync_send(sc, lpath, rpath, st.st_mtime, st.st_mode); success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode); } sc.Print("\n"); return result; return success; } struct sync_ls_build_list_cb_args { Loading Loading @@ -733,7 +756,7 @@ static int set_time_and_mode(const char *lpath, time_t time, unsigned int mode) } static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const char* lpath, int copy_attrs) { bool copy_attrs) { // Make sure that both directory paths end in a slash. std::string rpath_clean(rpath); std::string lpath_clean(lpath); Loading Loading @@ -774,43 +797,80 @@ static bool copy_remote_dir_local(SyncConnection& sc, const char* rpath, const c return true; } bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs) { bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs) { SyncConnection sc; if (!sc.IsValid()) return false; bool success = true; unsigned mode, time; if (!sync_stat(sc, rpath, &time, &mode, nullptr)) return false; if (mode == 0) { sc.Error("remote object '%s' does not exist", rpath); struct stat st; if (stat(dst, &st)) { // If we're only pulling one file, the destination path might point to // a path that doesn't exist yet. if (srcs.size() != 1 || errno != ENOENT) { sc.Error("cannot stat '%s': %s", dst, strerror(errno)); return false; } } bool dst_isdir = S_ISDIR(st.st_mode); if (!dst_isdir) { if (srcs.size() > 1) { sc.Error("target '%s' is not a directory", dst); return false; } else { size_t dst_len = strlen(dst); if (dst[dst_len - 1] == '/') { sc.Error("failed to access '%s': Not a directory", dst); return false; } } } for (const char* src_path : srcs) { const char* dst_path = dst; if (!sync_stat(sc, src_path, &time, &mode, nullptr)) return false; if (mode == 0) { sc.Error("remote object '%s' does not exist", src_path); success = false; continue; } if (S_ISREG(mode) || S_ISLNK(mode) || S_ISCHR(mode) || S_ISBLK(mode)) { std::string path_holder; struct stat st; if (stat(lpath, &st) == 0) { if (stat(dst_path, &st) == 0) { if (S_ISDIR(st.st_mode)) { // If we're copying a remote file to a local directory, // we really want to copy to local_dir + "/" + basename(remote). path_holder = android::base::StringPrintf("%s/%s", lpath, adb_basename(rpath).c_str()); lpath = path_holder.c_str(); // we really want to copy to local_dir + "/" + // basename(remote). path_holder = android::base::StringPrintf( "%s/%s", dst_path, adb_basename(src_path).c_str()); dst_path = path_holder.c_str(); } } if (!sync_recv(sc, rpath, lpath)) { return false; if (!sync_recv(sc, src_path, dst_path)) { success = false; continue; } else { if (copy_attrs && set_time_and_mode(lpath, time, mode)) { return false; if (copy_attrs && set_time_and_mode(dst_path, time, mode)) { success = false; continue; } } sc.Print("\n"); return true; } else if (S_ISDIR(mode)) { return copy_remote_dir_local(sc, rpath, lpath, copy_attrs); success &= copy_remote_dir_local(sc, src_path, dst_path, copy_attrs); continue; } else { sc.Error("remote object '%s' not a file or directory", src_path); success = false; continue; } } sc.Error("remote object '%s' not a file or directory", rpath); return false; sc.Print("\n"); return success; } bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) { Loading
adb/file_sync_service.h +5 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define _FILE_SYNC_SERVICE_H_ #include <string> #include <vector> #define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) Loading Loading @@ -64,9 +65,11 @@ union syncmsg { void file_sync_service(int fd, void* cookie); bool do_sync_ls(const char* path); bool do_sync_push(const char* lpath, const char* rpath); bool do_sync_push(const std::vector<const char*>& srcs, const char* dst); bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs); bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only); bool do_sync_pull(const char* rpath, const char* lpath, int copy_attrs); #define SYNC_DATA_MAX (64*1024) Loading