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