1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <utime.h> 2520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng#include <unistd.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 2820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng#include <private/android_filesystem_config.h> 2920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng#include <selinux/android.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_SYNC 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h" 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng/* TODO: use fs_config to configure permissions on /data */ 3720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Chengstatic bool is_on_system(const char *name) { 3820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng const char *SYSTEM = "/system/"; 3920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0); 4020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng} 4120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng 42686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenbergstatic bool is_on_vendor(const char *name) { 43686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg const char *VENDOR = "/vendor/"; 44686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg return (strncmp(VENDOR, name, strlen(VENDOR)) == 0); 45686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg} 46686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int mkdirs(char *name) 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x = name + 1; 5172917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich uid_t uid = -1; 5272917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich gid_t gid = -1; 5320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode = 0775; 5420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name[0] != '/') return -1; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = adb_dirstart(x); 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(x == 0) return 0; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 62686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg if (is_on_system(name) || is_on_vendor(name)) { 6320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fs_config(name, 1, &uid, &gid, &mode, &cap); 6420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 6520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = adb_mkdir(name, mode); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((ret < 0) && (errno != EEXIST)) { 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = '/'; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 7020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else if(ret == 0) { 7120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = chown(name, uid, gid); 7220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (ret < 0) { 7320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng *x = '/'; 7420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return ret; 7520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 7627a93650c0df02e4cd3c48bbec8acee8b817a012Stephen Smalley selinux_android_restorecon(name, 0); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x++ = '/'; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_stat(int s, const char *path) 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.id = ID_STAT; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(path, &st)) { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = 0; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = 0; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = 0; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = htoll(st.st_mode); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = htoll(st.st_size); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = htoll(st.st_mtime); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.stat, sizeof(msg.stat)); 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_list(int s, const char *path) 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[1024 + 256 + 1]; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(path); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(tmp, path, len); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp[len] = '/'; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = tmp + len + 1; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DENT; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir(path); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) goto done; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d))) { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(de->d_name); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* not supposed to be possible, but 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if it does happen, let's not buffer overrun */ 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 256) continue; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(fname, de->d_name); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(tmp, &st) == 0) { 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = htoll(st.st_mode); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = htoll(st.st_size); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = htoll(st.st_mtime); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = htoll(len); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.dent, sizeof(msg.dent)) || 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, de->d_name, len)) { 14014e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes closedir(d); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone: 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DONE; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = 0; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = 0; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = 0; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = 0; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.dent, sizeof(msg.dent)); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_message(int s, const char *reason) 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(reason); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: failure: %s\n", reason); 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_FAIL; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = htoll(len); 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data)) || 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, reason, len)) { 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_errno(int s) 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fail_message(s, strerror(errno)); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17972917837e6a1163bd389cf535eb404501a118cf2Nick Kralevichstatic int handle_send_file(int s, char *path, uid_t uid, 18055b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall gid_t gid, mode_t mode, char *buffer, bool do_unlink) 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int timestamp = 0; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode); 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == ENOENT) { 18820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 18920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fail_errno(s)) 19020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 19120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fd = -1; 19220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 193fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode); 19420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == EEXIST) { 197fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich fd = adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode); 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 20320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 20420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fchown(fd, uid, gid) != 0) { 20520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 20620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng errno = 0; 20720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 20872917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich 20972917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich /* 21072917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * fchown clears the setuid bit - restore it if present. 21172917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * Ignore the result of calling fchmod. It's not supported 21272917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * by all filesystems. b/12441485 21372917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich */ 21472917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich fchmod(fd, mode); 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timestamp = ltohl(msg.data.size); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message"); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(fd, buffer, len)) { 242408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 24455b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall if (do_unlink) adb_unlink(path); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 246408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = saved_errno; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) return -1; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) { 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct utimbuf u; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 25427a93650c0df02e4cd3c48bbec8acee8b817a012Stephen Smalley selinux_android_restorecon(path, 0); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.actime = timestamp; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.modtime = timestamp; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project utime(path, &u); 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 26955b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall if (do_unlink) adb_unlink(path); 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int handle_send_link(int s, char *path, char *buffer) 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DATA"); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret && errno == ENOENT) { 29820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 29920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 30020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 30120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret) { 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_errno(s); 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DONE"); 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* HAVE_SYMLINKS */ 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_send(int s, char *path, char *buffer) 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tmp; 32920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int is_link, ret; 33155b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall bool do_unlink; 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = strrchr(path,','); 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tmp) { 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *tmp = 0; 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = 0; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = strtoul(tmp + 1, NULL, 0); 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_SYMLINKS 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 34120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng is_link = S_ISLNK((mode_t) mode); 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode &= 0777; 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!tmp || errno) { 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = 0644; 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 34855b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall do_unlink = true; 3494ce2f838e78592d0b93776b73ca4de855a423ddeJP Abgrall } else { 3504ce2f838e78592d0b93776b73ca4de855a423ddeJP Abgrall struct stat st; 3514ce2f838e78592d0b93776b73ca4de855a423ddeJP Abgrall /* Don't delete files before copying if they are not "regular" */ 35255b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall do_unlink = lstat(path, &st) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode); 35355b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall if (do_unlink) { 3544ce2f838e78592d0b93776b73ca4de855a423ddeJP Abgrall adb_unlink(path); 3554ce2f838e78592d0b93776b73ca4de855a423ddeJP Abgrall } 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(is_link) 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = handle_send_link(s, path, buffer); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 36572917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich uid_t uid = -1; 36672917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich gid_t gid = -1; 36720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 36820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* copy user permission bits to "group" and "other" permissions */ 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= ((mode >> 3) & 0070); 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= ((mode >> 3) & 0007); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 37320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng tmp = path; 37420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(*tmp == '/') { 37520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng tmp++; 37620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 377686bce6390db802bfd2cb4e78f9270596b6decb2Daniel Rosenberg if (is_on_system(path) || is_on_vendor(path)) { 37820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fs_config(tmp, 0, &uid, &gid, &mode, &cap); 37920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 38055b6c843a6166fbbf57aa4afba8b2c2b3e87cfeaJP Abgrall ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink); 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_recv(int s, const char *path, char *buffer) 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, r; 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 391fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich fd = adb_open(path, O_RDONLY | O_CLOEXEC); 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) return -1; 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_DATA; 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, buffer, SYNC_DATA_MAX); 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r <= 0) { 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r == 0) break; 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) continue; 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = fail_errno(s); 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return r; 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = htoll(r); 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data)) || 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, buffer, r)) { 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_DONE; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = 0; 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data))) { 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid file_sync_service(int fd, void *cookie) 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[1025]; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned namelen; 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *buffer = malloc(SYNC_DATA_MAX); 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(buffer == 0) goto fail; 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: waiting for command\n"); 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(fd, &msg.req, sizeof(msg.req))) { 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "command read failure"); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = ltohl(msg.req.namelen); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(namelen > 1024) { 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "invalid namelen"); 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(fd, name, namelen)) { 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "filename read failure"); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name[namelen] = 0; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.req.namelen = 0; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: '%s' '%s'\n", (char*) &msg.req, name); 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(msg.req.id) { 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_STAT: 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_stat(fd, name)) goto fail; 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_LIST: 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_list(fd, name)) goto fail; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_SEND: 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_send(fd, name, buffer)) goto fail; 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_RECV: 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_recv(fd, name, buffer)) goto fail; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_QUIT: 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "unknown command"); 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(buffer != 0) free(buffer); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: done\n"); 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 482