Home | History | Annotate | Download | only in adb
      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 
     48 struct syncsendbuf {
     49     unsigned id;
     50     unsigned size;
     51     char data[SYNC_DATA_MAX];
     52 };
     53 
     54 static 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 
     63 static bool should_pull_file(mode_t mode) {
     64     return mode & (S_IFREG | S_IFBLK | S_IFCHR);
     65 }
     66 
     67 static 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 
     75 struct 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 
     97 class 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 
    433 typedef void (sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char* name);
    434 
    435 static 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 
    457 static 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 
    471 static 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 
    476 static 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 
    521 static bool sync_recv(SyncConnection& sc, const char* rpath, const char* lpath,
    522                       const char* name=nullptr) {
    523     unsigned size = 0;
    524     if (!sync_stat(sc, rpath, nullptr, nullptr, &size)) return false;
    525 
    526     if (!sc.SendRequest(ID_RECV, rpath)) return false;
    527 
    528     adb_unlink(lpath);
    529     int lfd = adb_creat(lpath, 0644);
    530     if (lfd < 0) {
    531         sc.Error("cannot create '%s': %s", lpath, strerror(errno));
    532         return false;
    533     }
    534 
    535     uint64_t bytes_copied = 0;
    536     while (true) {
    537         syncmsg msg;
    538         if (!ReadFdExactly(sc.fd, &msg.data, sizeof(msg.data))) {
    539             adb_close(lfd);
    540             adb_unlink(lpath);
    541             return false;
    542         }
    543 
    544         if (msg.data.id == ID_DONE) break;
    545 
    546         if (msg.data.id != ID_DATA) {
    547             adb_close(lfd);
    548             adb_unlink(lpath);
    549             sc.ReportCopyFailure(rpath, lpath, msg);
    550             return false;
    551         }
    552 
    553         if (msg.data.size > sc.max) {
    554             sc.Error("msg.data.size too large: %u (max %zu)", msg.data.size, sc.max);
    555             adb_close(lfd);
    556             adb_unlink(lpath);
    557             return false;
    558         }
    559 
    560         char buffer[SYNC_DATA_MAX];
    561         if (!ReadFdExactly(sc.fd, buffer, msg.data.size)) {
    562             adb_close(lfd);
    563             adb_unlink(lpath);
    564             return false;
    565         }
    566 
    567         if (!WriteFdExactly(lfd, buffer, msg.data.size)) {
    568             sc.Error("cannot write '%s': %s", lpath, strerror(errno));
    569             adb_close(lfd);
    570             adb_unlink(lpath);
    571             return false;
    572         }
    573 
    574         sc.total_bytes_ += msg.data.size;
    575 
    576         bytes_copied += msg.data.size;
    577 
    578         sc.ReportProgress(name != nullptr ? name : rpath, bytes_copied, size);
    579     }
    580 
    581     adb_close(lfd);
    582     return true;
    583 }
    584 
    585 bool do_sync_ls(const char* path) {
    586     SyncConnection sc;
    587     if (!sc.IsValid()) return false;
    588 
    589     return sync_ls(sc, path, [](unsigned mode, unsigned size, unsigned time,
    590                                 const char* name) {
    591         printf("%08x %08x %08x %s\n", mode, size, time, name);
    592     });
    593 }
    594 
    595 static bool IsDotOrDotDot(const char* name) {
    596     return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
    597 }
    598 
    599 static bool local_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
    600                              const std::string& lpath,
    601                              const std::string& rpath) {
    602     std::vector<copyinfo> dirlist;
    603     std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(lpath.c_str()), closedir);
    604     if (!dir) {
    605         sc.Error("cannot open '%s': %s", lpath.c_str(), strerror(errno));
    606         return false;
    607     }
    608 
    609     bool empty_dir = true;
    610     dirent* de;
    611     while ((de = readdir(dir.get()))) {
    612         if (IsDotOrDotDot(de->d_name)) {
    613             continue;
    614         }
    615 
    616         empty_dir = false;
    617         std::string stat_path = lpath + de->d_name;
    618 
    619         struct stat st;
    620         if (lstat(stat_path.c_str(), &st) == -1) {
    621             sc.Error("cannot lstat '%s': %s", stat_path.c_str(),
    622                      strerror(errno));
    623             continue;
    624         }
    625 
    626         copyinfo ci(lpath, rpath, de->d_name, st.st_mode);
    627         if (S_ISDIR(st.st_mode)) {
    628             dirlist.push_back(ci);
    629         } else {
    630             if (!should_push_file(st.st_mode)) {
    631                 sc.Warning("skipping special file '%s' (mode = 0o%o)", lpath.c_str(), st.st_mode);
    632                 ci.skip = true;
    633             }
    634             ci.time = st.st_mtime;
    635             ci.size = st.st_size;
    636             file_list->push_back(ci);
    637         }
    638     }
    639 
    640     // Close this directory and recurse.
    641     dir.reset();
    642 
    643     // Add the current directory to the list if it was empty, to ensure that
    644     // it gets created.
    645     if (empty_dir) {
    646         // TODO(b/25566053): Make pushing empty directories work.
    647         // TODO(b/25457350): We don't preserve permissions on directories.
    648         sc.Warning("skipping empty directory '%s'", lpath.c_str());
    649         copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(lpath), S_IFDIR);
    650         ci.skip = true;
    651         file_list->push_back(ci);
    652         return true;
    653     }
    654 
    655     for (const copyinfo& ci : dirlist) {
    656         local_build_list(sc, file_list, ci.lpath, ci.rpath);
    657     }
    658 
    659     return true;
    660 }
    661 
    662 static bool copy_local_dir_remote(SyncConnection& sc, std::string lpath,
    663                                   std::string rpath, bool check_timestamps,
    664                                   bool list_only) {
    665     // Make sure that both directory paths end in a slash.
    666     // Both paths are known to be nonempty, so we don't need to check.
    667     ensure_trailing_separators(lpath, rpath);
    668 
    669     // Recursively build the list of files to copy.
    670     std::vector<copyinfo> file_list;
    671     int pushed = 0;
    672     int skipped = 0;
    673     if (!local_build_list(sc, &file_list, lpath, rpath)) {
    674         return false;
    675     }
    676 
    677     if (check_timestamps) {
    678         for (const copyinfo& ci : file_list) {
    679             if (!sc.SendRequest(ID_STAT, ci.rpath.c_str())) {
    680                 return false;
    681             }
    682         }
    683         for (copyinfo& ci : file_list) {
    684             unsigned int timestamp, mode, size;
    685             if (!sync_finish_stat(sc, &timestamp, &mode, &size)) {
    686                 return false;
    687             }
    688             if (size == ci.size) {
    689                 // For links, we cannot update the atime/mtime.
    690                 if ((S_ISREG(ci.mode & mode) && timestamp == ci.time) ||
    691                         (S_ISLNK(ci.mode & mode) && timestamp >= ci.time)) {
    692                     ci.skip = true;
    693                 }
    694             }
    695         }
    696     }
    697 
    698     sc.ComputeExpectedTotalBytes(file_list);
    699 
    700     for (const copyinfo& ci : file_list) {
    701         if (!ci.skip) {
    702             if (list_only) {
    703                 sc.Error("would push: %s -> %s", ci.lpath.c_str(), ci.rpath.c_str());
    704             } else {
    705                 if (!sync_send(sc, ci.lpath.c_str(), ci.rpath.c_str(), ci.time, ci.mode)) {
    706                     return false;
    707                 }
    708             }
    709             pushed++;
    710         } else {
    711             skipped++;
    712         }
    713     }
    714 
    715     sc.Printf("%s: %d file%s pushed. %d file%s skipped.%s", rpath.c_str(),
    716               pushed, (pushed == 1) ? "" : "s", skipped,
    717               (skipped == 1) ? "" : "s", sc.TransferRate().c_str());
    718     return true;
    719 }
    720 
    721 bool do_sync_push(const std::vector<const char*>& srcs, const char* dst) {
    722     SyncConnection sc;
    723     if (!sc.IsValid()) return false;
    724 
    725     bool success = true;
    726     unsigned dst_mode;
    727     if (!sync_stat(sc, dst, nullptr, &dst_mode, nullptr)) return false;
    728     bool dst_exists = (dst_mode != 0);
    729     bool dst_isdir = S_ISDIR(dst_mode);
    730 
    731     if (!dst_isdir) {
    732         if (srcs.size() > 1) {
    733             sc.Error("target '%s' is not a directory", dst);
    734             return false;
    735         } else {
    736             size_t dst_len = strlen(dst);
    737 
    738             // A path that ends with a slash doesn't have to be a directory if
    739             // it doesn't exist yet.
    740             if (dst[dst_len - 1] == '/' && dst_exists) {
    741                 sc.Error("failed to access '%s': Not a directory", dst);
    742                 return false;
    743             }
    744         }
    745     }
    746 
    747     for (const char* src_path : srcs) {
    748         const char* dst_path = dst;
    749         struct stat st;
    750         if (stat(src_path, &st) == -1) {
    751             sc.Error("cannot stat '%s': %s", src_path, strerror(errno));
    752             success = false;
    753             continue;
    754         }
    755 
    756         if (S_ISDIR(st.st_mode)) {
    757             std::string dst_dir = dst;
    758 
    759             // If the destination path existed originally, the source directory
    760             // should be copied as a child of the destination.
    761             if (dst_exists) {
    762                 if (!dst_isdir) {
    763                     sc.Error("target '%s' is not a directory", dst);
    764                     return false;
    765                 }
    766                 // dst is a POSIX path, so we don't want to use the sysdeps
    767                 // helpers here.
    768                 if (dst_dir.back() != '/') {
    769                     dst_dir.push_back('/');
    770                 }
    771                 dst_dir.append(adb_basename(src_path));
    772             }
    773 
    774             success &= copy_local_dir_remote(sc, src_path, dst_dir.c_str(),
    775                                              false, false);
    776             continue;
    777         } else if (!should_push_file(st.st_mode)) {
    778             sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, st.st_mode);
    779             continue;
    780         }
    781 
    782         std::string path_holder;
    783         if (dst_isdir) {
    784             // If we're copying a local file to a remote directory,
    785             // we really want to copy to remote_dir + "/" + local_filename.
    786             path_holder = dst_path;
    787             if (path_holder.back() != '/') {
    788                 path_holder.push_back('/');
    789             }
    790             path_holder += adb_basename(src_path);
    791             dst_path = path_holder.c_str();
    792         }
    793         sc.SetExpectedTotalBytes(st.st_size);
    794         success &= sync_send(sc, src_path, dst_path, st.st_mtime, st.st_mode);
    795     }
    796 
    797     return success;
    798 }
    799 
    800 static bool remote_symlink_isdir(SyncConnection& sc, const std::string& rpath) {
    801     unsigned mode;
    802     std::string dir_path = rpath;
    803     dir_path.push_back('/');
    804     if (!sync_stat(sc, dir_path.c_str(), nullptr, &mode, nullptr)) {
    805         sc.Error("failed to stat remote symlink '%s'", dir_path.c_str());
    806         return false;
    807     }
    808     return S_ISDIR(mode);
    809 }
    810 
    811 static bool remote_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
    812                               const std::string& rpath, const std::string& lpath) {
    813     std::vector<copyinfo> dirlist;
    814     std::vector<copyinfo> linklist;
    815 
    816     // Add an entry for the current directory to ensure it gets created before pulling its contents.
    817     copyinfo ci(adb_dirname(lpath), adb_dirname(rpath), adb_basename(lpath), S_IFDIR);
    818     file_list->push_back(ci);
    819 
    820     // Put the files/dirs in rpath on the lists.
    821     auto callback = [&](unsigned mode, unsigned size, unsigned time, const char* name) {
    822         if (IsDotOrDotDot(name)) {
    823             return;
    824         }
    825 
    826         copyinfo ci(lpath, rpath, name, mode);
    827         if (S_ISDIR(mode)) {
    828             dirlist.push_back(ci);
    829         } else if (S_ISLNK(mode)) {
    830             linklist.push_back(ci);
    831         } else {
    832             if (!should_pull_file(ci.mode)) {
    833                 sc.Warning("skipping special file '%s' (mode = 0o%o)", ci.rpath.c_str(), ci.mode);
    834                 ci.skip = true;
    835             }
    836             ci.time = time;
    837             ci.size = size;
    838             file_list->push_back(ci);
    839         }
    840     };
    841 
    842     if (!sync_ls(sc, rpath.c_str(), callback)) {
    843         return false;
    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 
    867 static 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(), &times);
    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 
    880 static 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 
    930 bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst,
    931                   bool copy_attrs, const char* name) {
    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_isdir) {
    993             std::string dst_dir = dst;
    994 
    995             // If the destination path existed originally, the source directory
    996             // should be copied as a child of the destination.
    997             if (dst_exists) {
    998                 if (!dst_isdir) {
    999                     sc.Error("target '%s' is not a directory", dst);
   1000                     return false;
   1001                 }
   1002                 if (!adb_is_separator(dst_dir.back())) {
   1003                     dst_dir.push_back(OS_PATH_SEPARATOR);
   1004                 }
   1005                 dst_dir.append(adb_basename(src_path));
   1006             }
   1007 
   1008             success &= copy_remote_dir_local(sc, src_path, dst_dir.c_str(), copy_attrs);
   1009             continue;
   1010         } else if (!should_pull_file(src_mode)) {
   1011             sc.Warning("skipping special file '%s' (mode = 0o%o)", src_path, src_mode);
   1012             continue;
   1013         }
   1014 
   1015         std::string path_holder;
   1016         if (dst_isdir) {
   1017             // If we're copying a remote file to a local directory, we
   1018             // really want to copy to local_dir + OS_PATH_SEPARATOR +
   1019             // basename(remote).
   1020             path_holder = android::base::StringPrintf("%s%c%s", dst_path, OS_PATH_SEPARATOR,
   1021                                                       adb_basename(src_path).c_str());
   1022             dst_path = path_holder.c_str();
   1023         }
   1024 
   1025         sc.SetExpectedTotalBytes(src_size);
   1026         if (!sync_recv(sc, src_path, dst_path, name)) {
   1027             success = false;
   1028             continue;
   1029         }
   1030 
   1031         if (copy_attrs && set_time_and_mode(dst_path, src_time, src_mode) != 0) {
   1032             success = false;
   1033             continue;
   1034         }
   1035     }
   1036 
   1037     return success;
   1038 }
   1039 
   1040 bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only) {
   1041     SyncConnection sc;
   1042     if (!sc.IsValid()) return false;
   1043 
   1044     return copy_local_dir_remote(sc, lpath, rpath, true, list_only);
   1045 }
   1046