file_sync_service.c revision 72917837e6a1163bd389cf535eb404501a118cf2
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 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int mkdirs(char *name) 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *x = name + 1; 4672917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich uid_t uid = -1; 4772917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich gid_t gid = -1; 4820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode = 0775; 4920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name[0] != '/') return -1; 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = adb_dirstart(x); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(x == 0) return 0; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 5720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (is_on_system(name)) { 5820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fs_config(name, 1, &uid, &gid, &mode, &cap); 5920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 6020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = adb_mkdir(name, mode); 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((ret < 0) && (errno != EEXIST)) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = '/'; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 6520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else if(ret == 0) { 6620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = chown(name, uid, gid); 6720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (ret < 0) { 6820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng *x = '/'; 6920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return ret; 7020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 7120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng selinux_android_restorecon(name); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x++ = '/'; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_stat(int s, const char *path) 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.id = ID_STAT; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(path, &st)) { 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = 0; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = 0; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = 0; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = htoll(st.st_mode); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = htoll(st.st_size); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = htoll(st.st_mtime); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.stat, sizeof(msg.stat)); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_list(int s, const char *path) 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[1024 + 256 + 1]; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(path); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(tmp, path, len); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp[len] = '/'; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = tmp + len + 1; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DENT; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir(path); 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) goto done; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d))) { 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(de->d_name); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* not supposed to be possible, but 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if it does happen, let's not buffer overrun */ 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 256) continue; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(fname, de->d_name); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(tmp, &st) == 0) { 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = htoll(st.st_mode); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = htoll(st.st_size); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = htoll(st.st_mtime); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = htoll(len); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.dent, sizeof(msg.dent)) || 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, de->d_name, len)) { 13514e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes closedir(d); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone: 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DONE; 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = 0; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = 0; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = 0; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = 0; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.dent, sizeof(msg.dent)); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_message(int s, const char *reason) 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(reason); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: failure: %s\n", reason); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_FAIL; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = htoll(len); 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data)) || 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, reason, len)) { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_errno(int s) 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fail_message(s, strerror(errno)); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17472917837e6a1163bd389cf535eb404501a118cf2Nick Kralevichstatic int handle_send_file(int s, char *path, uid_t uid, 17572917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich gid_t gid, mode_t mode, char *buffer) 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int timestamp = 0; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == ENOENT) { 18320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 18420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fail_errno(s)) 18520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 18620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fd = -1; 18720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 18820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 18920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == EEXIST) { 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_open_mode(path, O_WRONLY, mode); 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 19820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 19920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fchown(fd, uid, gid) != 0) { 20020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 20120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng errno = 0; 20220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 20372917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich 20472917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich /* 20572917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * fchown clears the setuid bit - restore it if present. 20672917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * Ignore the result of calling fchmod. It's not supported 20772917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich * by all filesystems. b/12441485 20872917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich */ 20972917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich fchmod(fd, mode); 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timestamp = ltohl(msg.data.size); 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message"); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(fd, buffer, len)) { 237408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 241408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = saved_errno; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) return -1; 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) { 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct utimbuf u; 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 24920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng selinux_android_restorecon(path); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.actime = timestamp; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.modtime = timestamp; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project utime(path, &u); 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int handle_send_link(int s, char *path, char *buffer) 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DATA"); 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret && errno == ENOENT) { 29320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 29420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 29520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 29620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret) { 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_errno(s); 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DONE"); 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* HAVE_SYMLINKS */ 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_send(int s, char *path, char *buffer) 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tmp; 32420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int is_link, ret; 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = strrchr(path,','); 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tmp) { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *tmp = 0; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = 0; 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = strtoul(tmp + 1, NULL, 0); 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_SYMLINKS 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 33520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng is_link = S_ISLNK((mode_t) mode); 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode &= 0777; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!tmp || errno) { 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = 0644; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(is_link) 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = handle_send_link(s, path, buffer); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 35472917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich uid_t uid = -1; 35572917837e6a1163bd389cf535eb404501a118cf2Nick Kralevich gid_t gid = -1; 35620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 35720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* copy user permission bits to "group" and "other" permissions */ 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= ((mode >> 3) & 0070); 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= ((mode >> 3) & 0007); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 36220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng tmp = path; 36320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(*tmp == '/') { 36420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng tmp++; 36520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 36620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (is_on_system(path)) { 36720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fs_config(tmp, 0, &uid, &gid, &mode, &cap); 36820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 36920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = handle_send_file(s, path, uid, gid, mode, buffer); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_recv(int s, const char *path, char *buffer) 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd, r; 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_open(path, O_RDONLY); 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) return -1; 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_DATA; 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = adb_read(fd, buffer, SYNC_DATA_MAX); 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r <= 0) { 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r == 0) break; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) continue; 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = fail_errno(s); 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return r; 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = htoll(r); 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data)) || 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, buffer, r)) { 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_DONE; 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = 0; 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data))) { 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid file_sync_service(int fd, void *cookie) 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char name[1025]; 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned namelen; 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *buffer = malloc(SYNC_DATA_MAX); 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(buffer == 0) goto fail; 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: waiting for command\n"); 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(fd, &msg.req, sizeof(msg.req))) { 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "command read failure"); 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project namelen = ltohl(msg.req.namelen); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(namelen > 1024) { 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "invalid namelen"); 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(fd, name, namelen)) { 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "filename read failure"); 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name[namelen] = 0; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.req.namelen = 0; 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: '%s' '%s'\n", (char*) &msg.req, name); 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(msg.req.id) { 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_STAT: 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_stat(fd, name)) goto fail; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_LIST: 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_list(fd, name)) goto fail; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_SEND: 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_send(fd, name, buffer)) goto fail; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_RECV: 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(do_recv(fd, name, buffer)) goto fail; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case ID_QUIT: 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(fd, "unknown command"); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(buffer != 0) free(buffer); 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: done\n"); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 471