summaryrefslogtreecommitdiff
path: root/file_sync_service.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'file_sync_service.cpp')
-rw-r--r--file_sync_service.cpp87
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)) {