diff options
Diffstat (limited to 'file_sync_service.cpp')
-rw-r--r-- | file_sync_service.cpp | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/file_sync_service.cpp b/file_sync_service.cpp index 7a92d2e..57a8a45 100644 --- a/file_sync_service.cpp +++ b/file_sync_service.cpp @@ -98,18 +98,47 @@ static bool secure_mkdirs(const std::string& path) { return true; } -static bool do_stat(int s, const char* path) { - syncmsg msg; - msg.stat.id = ID_STAT; +static bool do_lstat_v1(int s, const char* path) { + syncmsg msg = {}; + msg.stat_v1.id = ID_LSTAT_V1; struct stat st = {}; - // TODO: add a way to report that the stat failed! lstat(path, &st); - msg.stat.mode = st.st_mode; - msg.stat.size = st.st_size; - msg.stat.time = st.st_mtime; + msg.stat_v1.mode = st.st_mode; + msg.stat_v1.size = st.st_size; + msg.stat_v1.time = st.st_mtime; + return WriteFdExactly(s, &msg.stat_v1, sizeof(msg.stat_v1)); +} + +static bool do_stat_v2(int s, uint32_t id, const char* path) { + syncmsg msg = {}; + msg.stat_v2.id = id; + + decltype(&stat) stat_fn; + if (id == ID_STAT_V2) { + stat_fn = stat; + } else { + stat_fn = lstat; + } + + struct stat st = {}; + int rc = stat_fn(path, &st); + if (rc == -1) { + msg.stat_v2.error = errno; + } else { + msg.stat_v2.dev = st.st_dev; + msg.stat_v2.ino = st.st_ino; + msg.stat_v2.mode = st.st_mode; + msg.stat_v2.nlink = st.st_nlink; + msg.stat_v2.uid = st.st_uid; + msg.stat_v2.gid = st.st_gid; + msg.stat_v2.size = st.st_size; + msg.stat_v2.atime = st.st_atime; + msg.stat_v2.mtime = st.st_mtime; + msg.stat_v2.ctime = st.st_ctime; + } - return WriteFdExactly(s, &msg.stat, sizeof(msg.stat)); + return WriteFdExactly(s, &msg.stat_v2, sizeof(msg.stat_v2)); } static bool do_list(int s, const char* path) { @@ -427,30 +456,34 @@ static bool handle_sync_command(int fd, std::vector<char>& buffer) { D("sync: '%.4s' '%s'", id, name); switch (request.id) { - case ID_STAT: - if (!do_stat(fd, name)) return false; - break; - case ID_LIST: - if (!do_list(fd, name)) return false; - break; - case ID_SEND: - if (!do_send(fd, name, buffer)) return false; - break; - case ID_RECV: - if (!do_recv(fd, name, buffer)) return false; - break; - case ID_QUIT: - return false; - default: - SendSyncFail(fd, android::base::StringPrintf("unknown command '%.4s' (%08x)", - id, request.id)); - return false; + case ID_LSTAT_V1: + if (!do_lstat_v1(fd, name)) return false; + break; + case ID_LSTAT_V2: + case ID_STAT_V2: + if (!do_stat_v2(fd, request.id, name)) return false; + break; + case ID_LIST: + if (!do_list(fd, name)) return false; + break; + case ID_SEND: + if (!do_send(fd, name, buffer)) return false; + break; + case ID_RECV: + if (!do_recv(fd, name, buffer)) return false; + break; + case ID_QUIT: + return false; + default: + SendSyncFail( + fd, android::base::StringPrintf("unknown command '%.4s' (%08x)", id, request.id)); + return false; } return true; } -void file_sync_service(int fd, void* cookie) { +void file_sync_service(int fd, void*) { std::vector<char> buffer(SYNC_DATA_MAX); while (handle_sync_command(fd, buffer)) { |