file_sync_client.cpp revision 379612b1283c7289fbf21e1105b8bec9b0fed7ae
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <dirent.h> 18#include <errno.h> 19#include <inttypes.h> 20#include <limits.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <sys/stat.h> 25#include <sys/time.h> 26#include <sys/types.h> 27#include <time.h> 28#include <unistd.h> 29#include <utime.h> 30 31#include <functional> 32#include <memory> 33#include <vector> 34 35#include "sysdeps.h" 36 37#include "adb.h" 38#include "adb_client.h" 39#include "adb_io.h" 40#include "adb_utils.h" 41#include "file_sync_service.h" 42#include "line_printer.h" 43 44#include <android-base/file.h> 45#include <android-base/strings.h> 46#include <android-base/stringprintf.h> 47 48struct syncsendbuf { 49 unsigned id; 50 unsigned size; 51 char data[SYNC_DATA_MAX]; 52}; 53 54static void ensure_trailing_separators(std::string& local_path, std::string& remote_path) { 55 if (!adb_is_separator(local_path.back())) { 56 local_path.push_back(OS_PATH_SEPARATOR); 57 } 58 if (remote_path.back() != '/') { 59 remote_path.push_back('/'); 60 } 61} 62 63static bool should_pull_file(mode_t mode) { 64 return mode & (S_IFREG | S_IFBLK | S_IFCHR); 65} 66 67static bool should_push_file(mode_t mode) { 68 mode_t mask = S_IFREG; 69#if !defined(_WIN32) 70 mask |= S_IFLNK; 71#endif 72 return mode & mask; 73} 74 75struct copyinfo { 76 std::string lpath; 77 std::string rpath; 78 unsigned int time = 0; 79 unsigned int mode; 80 uint64_t size = 0; 81 bool skip = false; 82 83 copyinfo(const std::string& local_path, 84 const std::string& remote_path, 85 const std::string& name, 86 unsigned int mode) 87 : lpath(local_path), rpath(remote_path), mode(mode) { 88 ensure_trailing_separators(lpath, rpath); 89 lpath.append(name); 90 rpath.append(name); 91 if (S_ISDIR(mode)) { 92 ensure_trailing_separators(lpath, rpath); 93 } 94 } 95}; 96 97class SyncConnection { 98 public: 99 SyncConnection() 100 : total_bytes_(0), 101 start_time_ms_(CurrentTimeMs()), 102 expected_total_bytes_(0), 103 expect_multiple_files_(false), 104 expect_done_(false) { 105 max = SYNC_DATA_MAX; // TODO: decide at runtime. 106 107 std::string error; 108 fd = adb_connect("sync:", &error); 109 if (fd < 0) { 110 Error("connect failed: %s", error.c_str()); 111 } 112 } 113 114 ~SyncConnection() { 115 if (!IsValid()) return; 116 117 if (SendQuit()) { 118 // We sent a quit command, so the server should be doing orderly 119 // shutdown soon. But if we encountered an error while we were using 120 // the connection, the server might still be sending data (before 121 // doing orderly shutdown), in which case we won't wait for all of 122 // the data nor the coming orderly shutdown. In the common success 123 // case, this will wait for the server to do orderly shutdown. 124 ReadOrderlyShutdown(fd); 125 } 126 adb_close(fd); 127 128 line_printer_.KeepInfoLine(); 129 } 130 131 bool IsValid() { return fd >= 0; } 132 133 bool ReceivedError(const char* from, const char* to) { 134 adb_pollfd pfd = {.fd = fd, .events = POLLIN}; 135 int rc = adb_poll(&pfd, 1, 0); 136 if (rc < 0) { 137 Error("failed to poll: %s", strerror(errno)); 138 return true; 139 } 140 return rc != 0; 141 } 142 143 bool SendRequest(int id, const char* path_and_mode) { 144 size_t path_length = strlen(path_and_mode); 145 if (path_length > 1024) { 146 Error("SendRequest failed: path too long: %zu", path_length); 147 errno = ENAMETOOLONG; 148 return false; 149 } 150 151 // Sending header and payload in a single write makes a noticeable 152 // difference to "adb sync" performance. 153 std::vector<char> buf(sizeof(SyncRequest) + path_length); 154 SyncRequest* req = reinterpret_cast<SyncRequest*>(&buf[0]); 155 req->id = id; 156 req->path_length = path_length; 157 char* data = reinterpret_cast<char*>(req + 1); 158 memcpy(data, path_and_mode, path_length); 159 160 return WriteFdExactly(fd, &buf[0], buf.size()); 161 } 162 163 // Sending header, payload, and footer in a single write makes a huge 164 // difference to "adb sync" performance. 165 bool SendSmallFile(const char* path_and_mode, 166 const char* lpath, const char* rpath, 167 unsigned mtime, 168 const char* data, size_t data_length) { 169 size_t path_length = strlen(path_and_mode); 170 if (path_length > 1024) { 171 Error("SendSmallFile failed: path too long: %zu", path_length); 172 errno = ENAMETOOLONG; 173 return false; 174 } 175 176 std::vector<char> buf(sizeof(SyncRequest) + path_length + 177 sizeof(SyncRequest) + data_length + 178 sizeof(SyncRequest)); 179 char* p = &buf[0]; 180 181 SyncRequest* req_send = reinterpret_cast<SyncRequest*>(p); 182 req_send->id = ID_SEND; 183 req_send->path_length = path_length; 184 p += sizeof(SyncRequest); 185 memcpy(p, path_and_mode, path_length); 186 p += path_length; 187 188 SyncRequest* req_data = reinterpret_cast<SyncRequest*>(p); 189 req_data->id = ID_DATA; 190 req_data->path_length = data_length; 191 p += sizeof(SyncRequest); 192 memcpy(p, data, data_length); 193 p += data_length; 194 195 SyncRequest* req_done = reinterpret_cast<SyncRequest*>(p); 196 req_done->id = ID_DONE; 197 req_done->path_length = mtime; 198 p += sizeof(SyncRequest); 199 200 WriteOrDie(lpath, rpath, &buf[0], (p - &buf[0])); 201 expect_done_ = true; 202 total_bytes_ += data_length; 203 ReportProgress(rpath, data_length, data_length); 204 return true; 205 } 206 207 bool SendLargeFile(const char* path_and_mode, 208 const char* lpath, const char* rpath, 209 unsigned mtime) { 210 if (!SendRequest(ID_SEND, path_and_mode)) { 211 Error("failed to send ID_SEND message '%s': %s", path_and_mode, strerror(errno)); 212 return false; 213 } 214 215 struct stat st; 216 if (stat(lpath, &st) == -1) { 217 Error("cannot stat '%s': %s", lpath, strerror(errno)); 218 return false; 219 } 220 221 uint64_t total_size = st.st_size; 222 uint64_t bytes_copied = 0; 223 224 int lfd = adb_open(lpath, O_RDONLY); 225 if (lfd < 0) { 226 Error("opening '%s' locally failed: %s", lpath, strerror(errno)); 227 return false; 228 } 229 230 syncsendbuf sbuf; 231 sbuf.id = ID_DATA; 232 while (true) { 233 int bytes_read = adb_read(lfd, sbuf.data, max); 234 if (bytes_read == -1) { 235 Error("reading '%s' locally failed: %s", lpath, strerror(errno)); 236 adb_close(lfd); 237 return false; 238 } else if (bytes_read == 0) { 239 break; 240 } 241 242 sbuf.size = bytes_read; 243 WriteOrDie(lpath, rpath, &sbuf, sizeof(SyncRequest) + bytes_read); 244 245 total_bytes_ += bytes_read; 246 bytes_copied += bytes_read; 247 248 // Check to see if we've received an error from the other side. 249 if (ReceivedError(lpath, rpath)) { 250 break; 251 } 252 253 ReportProgress(rpath, bytes_copied, total_size); 254 } 255 256 adb_close(lfd); 257 258 syncmsg msg; 259 msg.data.id = ID_DONE; 260 msg.data.size = mtime; 261 expect_done_ = true; 262 return WriteOrDie(lpath, rpath, &msg.data, sizeof(msg.data)); 263 } 264 265 bool CopyDone(const char* from, const char* to) { 266 syncmsg msg; 267 if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) { 268 Error("failed to copy '%s' to '%s': couldn't read from device", from, to); 269 return false; 270 } 271 if (msg.status.id == ID_OKAY) { 272 if (expect_done_) { 273 expect_done_ = false; 274 return true; 275 } else { 276 Error("failed to copy '%s' to '%s': received premature success", from, to); 277 return true; 278 } 279 } 280 if (msg.status.id != ID_FAIL) { 281 Error("failed to copy '%s' to '%s': unknown reason %d", from, to, msg.status.id); 282 return false; 283 } 284 return ReportCopyFailure(from, to, msg); 285 } 286 287 bool ReportCopyFailure(const char* from, const char* to, const syncmsg& msg) { 288 std::vector<char> buf(msg.status.msglen + 1); 289 if (!ReadFdExactly(fd, &buf[0], msg.status.msglen)) { 290 Error("failed to copy '%s' to '%s'; failed to read reason (!): %s", 291 from, to, strerror(errno)); 292 return false; 293 } 294 buf[msg.status.msglen] = 0; 295 Error("failed to copy '%s' to '%s': %s", from, to, &buf[0]); 296 return false; 297 } 298 299 std::string TransferRate() { 300 uint64_t ms = CurrentTimeMs() - start_time_ms_; 301 if (total_bytes_ == 0 || ms == 0) return ""; 302 303 double s = static_cast<double>(ms) / 1000LL; 304 double rate = (static_cast<double>(total_bytes_) / s) / (1024*1024); 305 return android::base::StringPrintf(" %.1f MB/s (%" PRId64 " bytes in %.3fs)", 306 rate, total_bytes_, s); 307 } 308 309 void ReportProgress(const char* file, uint64_t file_copied_bytes, uint64_t file_total_bytes) { 310 char overall_percentage_str[5] = "?"; 311 if (expected_total_bytes_ != 0) { 312 int overall_percentage = static_cast<int>(total_bytes_ * 100 / expected_total_bytes_); 313 // If we're pulling symbolic links, we'll pull the target of the link rather than 314 // just create a local link, and that will cause us to go over 100%. 315 if (overall_percentage <= 100) { 316 snprintf(overall_percentage_str, sizeof(overall_percentage_str), "%d%%", 317 overall_percentage); 318 } 319 } 320 321 if (file_copied_bytes > file_total_bytes || file_total_bytes == 0) { 322 // This case can happen if we're racing against something that wrote to the file 323 // between our stat and our read, or if we're reading a magic file that lies about 324 // its size. Just show how much we've copied. 325 Printf("[%4s] %s: %" PRId64 "/?", overall_percentage_str, file, file_copied_bytes); 326 } else { 327 // If we're transferring multiple files, we want to know how far through the current 328 // file we are, as well as the overall percentage. 329 if (expect_multiple_files_) { 330 int file_percentage = static_cast<int>(file_copied_bytes * 100 / file_total_bytes); 331 Printf("[%4s] %s: %d%%", overall_percentage_str, file, file_percentage); 332 } else { 333 Printf("[%4s] %s", overall_percentage_str, file); 334 } 335 } 336 } 337 338 void Printf(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) { 339 std::string s; 340 341 va_list ap; 342 va_start(ap, fmt); 343 android::base::StringAppendV(&s, fmt, ap); 344 va_end(ap); 345 346 line_printer_.Print(s, LinePrinter::INFO); 347 } 348 349 void Error(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) { 350 std::string s = "adb: error: "; 351 352 va_list ap; 353 va_start(ap, fmt); 354 android::base::StringAppendV(&s, fmt, ap); 355 va_end(ap); 356 357 line_printer_.Print(s, LinePrinter::ERROR); 358 } 359 360 void Warning(const char* fmt, ...) __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 2, 3))) { 361 std::string s = "adb: warning: "; 362 363 va_list ap; 364 va_start(ap, fmt); 365 android::base::StringAppendV(&s, fmt, ap); 366 va_end(ap); 367 368 line_printer_.Print(s, LinePrinter::WARNING); 369 } 370 371 void ComputeExpectedTotalBytes(const std::vector<copyinfo>& file_list) { 372 expected_total_bytes_ = 0; 373 for (const copyinfo& ci : file_list) { 374 // Unfortunately, this doesn't work for symbolic links, because we'll copy the 375 // target of the link rather than just creating a link. (But ci.size is the link size.) 376 if (!ci.skip) expected_total_bytes_ += ci.size; 377 } 378 expect_multiple_files_ = true; 379 } 380 381 void SetExpectedTotalBytes(uint64_t expected_total_bytes) { 382 expected_total_bytes_ = expected_total_bytes; 383 expect_multiple_files_ = false; 384 } 385 386 uint64_t total_bytes_; 387 388 // TODO: add a char[max] buffer here, to replace syncsendbuf... 389 int fd; 390 size_t max; 391 392 private: 393 uint64_t start_time_ms_; 394 395 uint64_t expected_total_bytes_; 396 bool expect_multiple_files_; 397 bool expect_done_; 398 399 LinePrinter line_printer_; 400 401 bool SendQuit() { 402 return SendRequest(ID_QUIT, ""); // TODO: add a SendResponse? 403 } 404 405 bool WriteOrDie(const char* from, const char* to, const void* data, size_t data_length) { 406 if (!WriteFdExactly(fd, data, data_length)) { 407 if (errno == ECONNRESET) { 408 // Assume adbd told us why it was closing the connection, and 409 // try to read failure reason from adbd. 410 syncmsg msg; 411 if (!ReadFdExactly(fd, &msg.status, sizeof(msg.status))) { 412 Error("failed to copy '%s' to '%s': no response: %s", from, to, strerror(errno)); 413 } else if (msg.status.id != ID_FAIL) { 414 Error("failed to copy '%s' to '%s': not ID_FAIL: %d", from, to, msg.status.id); 415 } else { 416 ReportCopyFailure(from, to, msg); 417 } 418 } else { 419 Error("%zu-byte write failed: %s", data_length, strerror(errno)); 420 } 421 _exit(1); 422 } 423 return true; 424 } 425 426 static uint64_t CurrentTimeMs() { 427 struct timeval tv; 428 gettimeofday(&tv, 0); // (Not clock_gettime because of Mac/Windows.) 429 return static_cast<uint64_t>(tv.tv_sec) * 1000 + tv.tv_usec / 1000; 430 } 431}; 432 433typedef void (sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char* name); 434 435static bool sync_ls(SyncConnection& sc, const char* path, 436 std::function<sync_ls_cb> func) { 437 if (!sc.SendRequest(ID_LIST, path)) return false; 438 439 while (true) { 440 syncmsg msg; 441 if (!ReadFdExactly(sc.fd, &msg.dent, sizeof(msg.dent))) return false; 442 443 if (msg.dent.id == ID_DONE) return true; 444 if (msg.dent.id != ID_DENT) return false; 445 446 size_t len = msg.dent.namelen; 447 if (len > 256) return false; // TODO: resize buffer? continue? 448 449 char buf[257]; 450 if (!ReadFdExactly(sc.fd, buf, len)) return false; 451 buf[len] = 0; 452 453 func(msg.dent.mode, msg.dent.size, msg.dent.time, buf); 454 } 455} 456 457static bool sync_finish_stat(SyncConnection& sc, unsigned int* timestamp, 458 unsigned int* mode, unsigned int* size) { 459 syncmsg msg; 460 if (!ReadFdExactly(sc.fd, &msg.stat, sizeof(msg.stat)) || msg.stat.id != ID_STAT) { 461 return false; 462 } 463 464 if (timestamp) *timestamp = msg.stat.time; 465 if (mode) *mode = msg.stat.mode; 466 if (size) *size = msg.stat.size; 467 468 return true; 469} 470 471static bool sync_stat(SyncConnection& sc, const char* path, 472 unsigned int* timestamp, unsigned int* mode, unsigned int* size) { 473 return sc.SendRequest(ID_STAT, path) && sync_finish_stat(sc, timestamp, mode, size); 474} 475 476static bool sync_send(SyncConnection& sc, const char* lpath, const char* rpath, 477 unsigned mtime, mode_t mode) 478{ 479 std::string path_and_mode = android::base::StringPrintf("%s,%d", rpath, mode); 480 481 if (S_ISLNK(mode)) { 482#if !defined(_WIN32) 483 char buf[PATH_MAX]; 484 ssize_t data_length = readlink(lpath, buf, PATH_MAX - 1); 485 if (data_length == -1) { 486 sc.Error("readlink '%s' failed: %s", lpath, strerror(errno)); 487 return false; 488 } 489 buf[data_length++] = '\0'; 490 491 if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime, buf, data_length)) { 492 return false; 493 } 494 return sc.CopyDone(lpath, rpath); 495#endif 496 } 497 498 struct stat st; 499 if (stat(lpath, &st) == -1) { 500 sc.Error("failed to stat local file '%s': %s", lpath, strerror(errno)); 501 return false; 502 } 503 if (st.st_size < SYNC_DATA_MAX) { 504 std::string data; 505 if (!android::base::ReadFileToString(lpath, &data)) { 506 sc.Error("failed to read all of '%s': %s", lpath, strerror(errno)); 507 return false; 508 } 509 if (!sc.SendSmallFile(path_and_mode.c_str(), lpath, rpath, mtime, 510 data.data(), data.size())) { 511 return false; 512 } 513 } else { 514 if (!sc.SendLargeFile(path_and_mode.c_str(), lpath, rpath, mtime)) { 515 return false; 516 } 517 } 518 return sc.CopyDone(lpath, rpath); 519} 520 521static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath) { 522 unsigned size = 0; 523 if (!sync_stat(sc, rpath, nullptr, nullptr, &size)) return false; 524 525 if (!sc.SendRequest(ID_RECV, rpath)) return false; 526 527 adb_unlink(lpath); 528 int lfd = adb_creat(lpath, 0644); 529 if (lfd < 0) { 530 sc.Error("cannot create '%s': %s", lpath, strerror(errno)); 531 return false; 532 } 533 534 uint64_t bytes_copied = 0; 535 while (true) { 536 syncmsg msg; 537 if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) { 538 adb_close(lfd); 539 adb_unlink(lpath); 540 return false; 541 } 542 543 if (msg.data.id == ID_DONE) break; 544 545 if (msg.data.id != ID_DATA) { 546 adb_close(lfd); 547 adb_unlink(lpath); 548 sc.ReportCopyFailure(rpath, lpath, msg); 549 return false; 550 } 551 552 if (msg.data.size > sc.max) { 553 sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max); 554 adb_close(lfd); 555 adb_unlink(lpath); 556 return false; 557 } 558 559 char buffer[SYNC_DATA_MAX]; 560 if (!ReadFdExactly(sc.fd, buffer, msg.data.size)) { 561 adb_close(lfd); 562 adb_unlink(lpath); 563 return false; 564 } 565 566 if (!WriteFdExactly(lfd, buffer, msg.data.size)) { 567 sc.Error("cannot write '%s': %s", lpath, strerror(errno)); 568 adb_close(lfd); 569 adb_unlink(lpath); 570 return false; 571 } 572 573 sc.total_bytes_ += msg.data.size; 574 575 bytes_copied += msg.data.size; 576 577 sc.ReportProgress(rpath, bytes_copied, size); 578 } 579 580 adb_close(lfd); 581 return true; 582} 583 584bool do_sync_ls(const char* path) { 585 SyncConnection sc; 586 if (!sc.IsValid()) return false; 587 588 return sync_ls(sc, path, [](unsigned mode, unsigned size, unsigned time, 589 const char* name) { 590 printf("%08x %08x %08x %s\n", mode, size, time, name); 591 }); 592} 593 594static bool IsDotOrDotDot(const char* name) { 595 return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); 596} 597 598static bool local_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list, 599 const std::string& lpath, 600 const std::string& rpath) { 601 std::vector<copyinfo> dirlist; 602 std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(lpath.c_str()), closedir); 603 if (!dir) { 604 sc.Error("cannot open '%s': %s", lpath.c_str(), strerror(errno)); 605 return false; 606 } 607 608 bool empty_dir = true; 609 dirent* de; 610 while ((de = readdir(dir.get()))) { 611 if (IsDotOrDotDot(de->d_name)) { 612 continue; 613 } 614 615 empty_dir = false; 616 std::string stat_path = lpath + de->d_name; 617 618 struct stat st; 619 if (lstat(stat_path.c_str(), &st) == -1) { 620 sc.Error("cannot lstat '%s': %s", stat_path.c_str(), 621 strerror(errno)); 622 continue; 623 } 624 625 copyinfo ci(lpath, rpath, de->d_name, st.st_mode); 626 if (S_ISDIR(st.st_mode)) { 627 dirlist.push_back(ci); 628 } else { 629 if (!should_push_file(st.st_mode)) { 630 sc.Warning("skipping special file '%s' (mode = 0o%o)", lpath.c_str(), st.st_mode); 631 ci.skip = true; 632 } 633 ci.time = st.st_mtime; 634 ci.size = st.st_size; 635 file_list->push_back(ci); 636 } 637 } 638 639 // Close this directory and recurse. 640 dir.reset(); 641 642 // Add the current directory to the list if it was empty, to ensure that 643 // it gets created. 644 if (empty_dir) { 645 // TODO(b/25566053): Make pushing empty directories work. 646 // TODO(b/25457350): We don't preserve permissions on directories. 647 sc.Warning("skipping empty directory '%s'", lpath.c_str()); 648 copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(lpath), S_IFDIR); 649 ci.skip = true; 650 file_list->push_back(ci); 651 return true; 652 } 653 654 for (const copyinfo& ci : dirlist) { 655 local_build_list(sc, file_list, ci.lpath, ci.rpath); 656 } 657 658 return true; 659} 660 661static bool copy_local_dir_remote(SyncConnection& sc, std::string lpath, 662 std::string rpath, bool check_timestamps, 663 bool list_only) { 664 // Make sure that both directory paths end in a slash. 665 // Both paths are known to be nonempty, so we don't need to check. 666 ensure_trailing_separators(lpath, rpath); 667 668 // Recursively build the list of files to copy. 669 std::vector<copyinfo> file_list; 670 int pushed = 0; 671 int skipped = 0; 672 if (!local_build_list(sc, &file_list, lpath, rpath)) { 673 return false; 674 } 675 676 if (check_timestamps) { 677 for (const copyinfo& ci : file_list) { 678 if (!sc.SendRequest(ID_STAT, ci.rpath.c_str())) { 679 return false; 680 } 681 } 682 for (copyinfo& ci : file_list) { 683 unsigned int timestamp, mode, size; 684 if (!sync_finish_stat(sc, ×tamp, &mode, &size)) { 685 return false; 686 } 687 if (size == ci.size) { 688 // For links, we cannot update the atime/mtime. 689 if ((S_ISREG(ci.mode & mode) && timestamp == ci.time) || 690 (S_ISLNK(ci.mode & mode) && timestamp >= ci.time)) { 691 ci.skip = true; 692 } 693 } 694 } 695 } 696 697 sc.ComputeExpectedTotalBytes(file_list); 698 699 for (const copyinfo& ci : file_list) { 700 if (!ci.skip) { 701 if (list_only) { 702 sc.Error("would push: %s -> %s", ci.lpath.c_str(), ci.rpath.c_str()); 703 } else { 704 if (!sync_send(sc, ci.lpath.c_str(), ci.rpath.c_str(), ci.time, ci.mode)) { 705 return false; 706 } 707 } 708 pushed++; 709 } else { 710 skipped++; 711 } 712 } 713 714 sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s", rpath.c_str(), 715 pushed, (pushed == 1) ? "" : "s", skipped, 716 (skipped == 1) ? "" : "s", sc.TransferRate().c_str()); 717 return true; 718} 719 720bool do_sync_push(const std::vector<const char*>& srcs, const char* dst) { 721 SyncConnection sc; 722 if (!sc.IsValid()) return false; 723 724 bool success = true; 725 unsigned dst_mode; 726 if (!sync_stat(sc, dst, nullptr, &dst_mode, nullptr)) return false; 727 bool dst_exists = (dst_mode != 0); 728 bool dst_isdir = S_ISDIR(dst_mode); 729 730 if (!dst_isdir) { 731 if (srcs.size() > 1) { 732 sc.Error("target '%s' is not a directory", dst); 733 return false; 734 } else { 735 size_t dst_len = strlen(dst); 736 737 // A path that ends with a slash doesn't have to be a directory if 738 // it doesn't exist yet. 739 if (dst[dst_len - 1] == '/' && dst_exists) { 740 sc.Error("failed to access '%s': Not a directory", dst); 741 return false; 742 } 743 } 744 } 745 746 for (const char* src_path : srcs) { 747 const char* dst_path = dst; 748 struct stat st; 749 if (stat(src_path, &st) == -1) { 750 sc.Error("cannot stat '%s': %s", src_path, strerror(errno)); 751 success = false; 752 continue; 753 } 754 755 if (S_ISDIR(st.st_mode)) { 756 std::string dst_dir = dst; 757 758 // If the destination path existed originally, the source directory 759 // should be copied as a child of the destination. 760 if (dst_exists) { 761 if (!dst_isdir) { 762 sc.Error("target '%s' is not a directory", dst); 763 return false; 764 } 765 // dst is a POSIX path, so we don't want to use the sysdeps 766 // helpers here. 767 if (dst_dir.back() != '/') { 768 dst_dir.push_back('/'); 769 } 770 dst_dir.append(adb_basename(src_path)); 771 } 772 773 success &= copy_local_dir_remote(sc, src_path, dst_dir.c_str(), 774 false, false); 775 continue; 776 } else if (!should_push_file(st.st_mode)) { 777 sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, st.st_mode); 778 continue; 779 } 780 781 std::string path_holder; 782 if (dst_isdir) { 783 // If we're copying a local file to a remote directory, 784 // we really want to copy to remote_dir + "/" + local_filename. 785 path_holder = dst_path; 786 if (path_holder.back() != '/') { 787 path_holder.push_back('/'); 788 } 789 path_holder += adb_basename(src_path); 790 dst_path = path_holder.c_str(); 791 } 792 sc.SetExpectedTotalBytes(st.st_size); 793 success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode); 794 } 795 796 return success; 797} 798 799static bool remote_symlink_isdir(SyncConnection& sc, const std::string& rpath) { 800 unsigned mode; 801 std::string dir_path = rpath; 802 dir_path.push_back('/'); 803 if (!sync_stat(sc, dir_path.c_str(), nullptr, &mode, nullptr)) { 804 sc.Error("failed to stat remote symlink '%s'", dir_path.c_str()); 805 return false; 806 } 807 return S_ISDIR(mode); 808} 809 810static bool remote_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list, 811 const std::string& rpath, const std::string& lpath) { 812 std::vector<copyinfo> dirlist; 813 std::vector<copyinfo> linklist; 814 815 // Add an entry for the current directory to ensure it gets created before pulling its contents. 816 copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(lpath), S_IFDIR); 817 file_list->push_back(ci); 818 819 // Put the files/dirs in rpath on the lists. 820 auto callback = [&](unsigned mode, unsigned size, unsigned time, const char* name) { 821 if (IsDotOrDotDot(name)) { 822 return; 823 } 824 825 copyinfo ci(lpath, rpath, name, mode); 826 if (S_ISDIR(mode)) { 827 dirlist.push_back(ci); 828 } else if (S_ISLNK(mode)) { 829 linklist.push_back(ci); 830 } else { 831 if (!should_pull_file(ci.mode)) { 832 sc.Warning("skipping special file '%s' (mode = 0o%o)", ci.rpath.c_str(), ci.mode); 833 ci.skip = true; 834 } 835 ci.time = time; 836 ci.size = size; 837 file_list->push_back(ci); 838 } 839 }; 840 841 if (!sync_ls(sc, rpath.c_str(), callback)) { 842 return false; 843 } 844 845 // Check each symlink we found to see whether it's a file or directory. 846 for (copyinfo& link_ci : linklist) { 847 if (remote_symlink_isdir(sc, link_ci.rpath)) { 848 dirlist.emplace_back(std::move(link_ci)); 849 } else { 850 file_list->emplace_back(std::move(link_ci)); 851 } 852 } 853 854 // Recurse into each directory we found. 855 while (!dirlist.empty()) { 856 copyinfo current = dirlist.back(); 857 dirlist.pop_back(); 858 if (!remote_build_list(sc, file_list, current.rpath, current.lpath)) { 859 return false; 860 } 861 } 862 863 return true; 864} 865 866static int set_time_and_mode(const std::string& lpath, time_t time, 867 unsigned int mode) { 868 struct utimbuf times = { time, time }; 869 int r1 = utime(lpath.c_str(), ×); 870 871 /* use umask for permissions */ 872 mode_t mask = umask(0000); 873 umask(mask); 874 int r2 = chmod(lpath.c_str(), mode & ~mask); 875 876 return r1 ? r1 : r2; 877} 878 879static bool copy_remote_dir_local(SyncConnection& sc, std::string rpath, 880 std::string lpath, bool copy_attrs) { 881 // Make sure that both directory paths end in a slash. 882 // Both paths are known to be nonempty, so we don't need to check. 883 ensure_trailing_separators(lpath, rpath); 884 885 // Recursively build the list of files to copy. 886 sc.Printf("pull: building file list..."); 887 std::vector<copyinfo> file_list; 888 if (!remote_build_list(sc, &file_list, rpath.c_str(), lpath.c_str())) { 889 return false; 890 } 891 892 sc.ComputeExpectedTotalBytes(file_list); 893 894 int pulled = 0; 895 int skipped = 0; 896 for (const copyinfo &ci : file_list) { 897 if (!ci.skip) { 898 if (S_ISDIR(ci.mode)) { 899 // Entry is for an empty directory, create it and continue. 900 // TODO(b/25457350): We don't preserve permissions on directories. 901 if (!mkdirs(ci.lpath)) { 902 sc.Error("failed to create directory '%s': %s", 903 ci.lpath.c_str(), strerror(errno)); 904 return false; 905 } 906 pulled++; 907 continue; 908 } 909 910 if (!sync_recv(sc, ci.rpath.c_str(), ci.lpath.c_str())) { 911 return false; 912 } 913 914 if (copy_attrs && set_time_and_mode(ci.lpath, ci.time, ci.mode)) { 915 return false; 916 } 917 pulled++; 918 } else { 919 skipped++; 920 } 921 } 922 923 sc.Printf("%s: %d file%s pulled. %d file%s skipped.%s", rpath.c_str(), 924 pulled, (pulled == 1) ? "" : "s", skipped, 925 (skipped == 1) ? "" : "s", sc.TransferRate().c_str()); 926 return true; 927} 928 929bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, 930 bool copy_attrs) { 931 SyncConnection sc; 932 if (!sc.IsValid()) return false; 933 934 bool success = true; 935 struct stat st; 936 bool dst_exists = true; 937 938 if (stat(dst, &st) == -1) { 939 dst_exists = false; 940 941 // If we're only pulling one path, the destination path might point to 942 // a path that doesn't exist yet. 943 if (srcs.size() == 1 && errno == ENOENT) { 944 // However, its parent must exist. 945 struct stat parent_st; 946 if (stat(adb_dirname(dst).c_str(), &parent_st) == -1) { 947 sc.Error("cannot create file/directory '%s': %s", dst, strerror(errno)); 948 return false; 949 } 950 } else { 951 sc.Error("failed to access '%s': %s", dst, strerror(errno)); 952 return false; 953 } 954 } 955 956 bool dst_isdir = dst_exists && S_ISDIR(st.st_mode); 957 if (!dst_isdir) { 958 if (srcs.size() > 1) { 959 sc.Error("target '%s' is not a directory", dst); 960 return false; 961 } else { 962 size_t dst_len = strlen(dst); 963 964 // A path that ends with a slash doesn't have to be a directory if 965 // it doesn't exist yet. 966 if (adb_is_separator(dst[dst_len - 1]) && dst_exists) { 967 sc.Error("failed to access '%s': Not a directory", dst); 968 return false; 969 } 970 } 971 } 972 973 for (const char* src_path : srcs) { 974 const char* dst_path = dst; 975 unsigned src_mode, src_time, src_size; 976 if (!sync_stat(sc, src_path, &src_time, &src_mode, &src_size)) { 977 sc.Error("failed to stat remote object '%s'", src_path); 978 return false; 979 } 980 if (src_mode == 0) { 981 sc.Error("remote object '%s' does not exist", src_path); 982 success = false; 983 continue; 984 } 985 986 bool src_isdir = S_ISDIR(src_mode); 987 if (S_ISLNK(src_mode)) { 988 src_isdir = remote_symlink_isdir(sc, src_path); 989 } 990 991 if (src_isdir) { 992 std::string dst_dir = dst; 993 994 // If the destination path existed originally, the source directory 995 // should be copied as a child of the destination. 996 if (dst_exists) { 997 if (!dst_isdir) { 998 sc.Error("target '%s' is not a directory", dst); 999 return false; 1000 } 1001 if (!adb_is_separator(dst_dir.back())) { 1002 dst_dir.push_back(OS_PATH_SEPARATOR); 1003 } 1004 dst_dir.append(adb_basename(src_path)); 1005 } 1006 1007 success &= copy_remote_dir_local(sc, src_path, dst_dir.c_str(), copy_attrs); 1008 continue; 1009 } else if (!should_pull_file(src_mode)) { 1010 sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, src_mode); 1011 continue; 1012 } 1013 1014 std::string path_holder; 1015 if (dst_isdir) { 1016 // If we're copying a remote file to a local directory, we 1017 // really want to copy to local_dir + OS_PATH_SEPARATOR + 1018 // basename(remote). 1019 path_holder = android::base::StringPrintf("%s%c%s", dst_path, OS_PATH_SEPARATOR, 1020 adb_basename(src_path).c_str()); 1021 dst_path = path_holder.c_str(); 1022 } 1023 1024 sc.SetExpectedTotalBytes(src_size); 1025 if (!sync_recv(sc, src_path, dst_path)) { 1026 success = false; 1027 continue; 1028 } 1029 1030 if (copy_attrs && set_time_and_mode(dst_path, src_time, src_mode) != 0) { 1031 success = false; 1032 continue; 1033 } 1034 } 1035 1036 return success; 1037} 1038 1039bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) { 1040 SyncConnection sc; 1041 if (!sc.IsValid()) return false; 1042 1043 return copy_local_dir_remote(sc, lpath, rpath, true, list_only); 1044} 1045