file_sync_service.c revision 20d33f4d99c26afdd0aebf23786958ef34e261e3
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; 4620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int uid, gid; 4720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode = 0775; 4820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 4920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uid = getuid(); 5020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng gid = getgid(); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name[0] != '/') return -1; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project x = adb_dirstart(x); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(x == 0) return 0; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = 0; 5820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (is_on_system(name)) { 5920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fs_config(name, 1, &uid, &gid, &mode, &cap); 6020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 6120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = adb_mkdir(name, mode); 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((ret < 0) && (errno != EEXIST)) { 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x = '/'; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 6620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else if(ret == 0) { 6720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng ret = chown(name, uid, gid); 6820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if (ret < 0) { 6920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng *x = '/'; 7020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return ret; 7120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 7220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng selinux_android_restorecon(name); 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *x++ = '/'; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_stat(int s, const char *path) 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.id = ID_STAT; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(path, &st)) { 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = 0; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = 0; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = 0; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.mode = htoll(st.st_mode); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.size = htoll(st.st_size); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.stat.time = htoll(st.st_mtime); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.stat, sizeof(msg.stat)); 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_list(int s, const char *path) 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat st; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[1024 + 256 + 1]; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *fname; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(path); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(tmp, path, len); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp[len] = '/'; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fname = tmp + len + 1; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DENT; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir(path); 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) goto done; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d))) { 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(de->d_name); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* not supposed to be possible, but 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if it does happen, let's not buffer overrun */ 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 256) continue; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(fname, de->d_name); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(tmp, &st) == 0) { 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = htoll(st.st_mode); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = htoll(st.st_size); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = htoll(st.st_mtime); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = htoll(len); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.dent, sizeof(msg.dent)) || 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, de->d_name, len)) { 13614e28d39f7f094225c1ddae8fa43bd792c621a8fElliott Hughes closedir(d); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone: 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.id = ID_DONE; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.mode = 0; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.size = 0; 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.time = 0; 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.dent.namelen = 0; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return writex(s, &msg.dent, sizeof(msg.dent)); 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_message(int s, const char *reason) 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len = strlen(reason); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("sync: failure: %s\n", reason); 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.id = ID_FAIL; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.data.size = htoll(len); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.data, sizeof(msg.data)) || 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, reason, len)) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int fail_errno(int s) 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fail_message(s, strerror(errno)); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Chengstatic int handle_send_file(int s, char *path, unsigned int uid, 17620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int gid, mode_t mode, char *buffer) 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int timestamp = 0; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == ENOENT) { 18420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 18520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fail_errno(s)) 18620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 18720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fd = -1; 18820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 18920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 19020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0 && errno == EEXIST) { 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_open_mode(path, O_WRONLY, mode); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 19920d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } else { 20020d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fchown(fd, uid, gid) != 0) { 20120d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 20220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng errno = 0; 20320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 20420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng /* fchown clears the setuid bit - restore it if present */ 20520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(fchmod(fd, mode) != 0) { 20620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 20720d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng errno = 0; 20820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project timestamp = ltohl(msg.data.size); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message"); 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto fail; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(fd, buffer, len)) { 236408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int saved_errno = errno; 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = -1; 240408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall errno = saved_errno; 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fail_errno(s)) return -1; 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) { 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct utimbuf u; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 24820d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng selinux_android_restorecon(path); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.actime = timestamp; 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project u.modtime = timestamp; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project utime(path, &u); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfail: 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd >= 0) 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int handle_send_link(int s, char *path, char *buffer) 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project syncmsg msg; 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned int len; 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id != ID_DATA) { 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DATA"); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = ltohl(msg.data.size); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > SYNC_DATA_MAX) { 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "oversize data message"); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buffer, len)) 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret && errno == ENOENT) { 29220d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng if(mkdirs(path) != 0) { 29320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng fail_errno(s); 29420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng return -1; 29520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng } 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = symlink(buffer, path); 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ret) { 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_errno(s); 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, &msg.data, sizeof(msg.data))) 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(msg.data.id == ID_DONE) { 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.id = ID_OKAY; 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project msg.status.msglen = 0; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(s, &msg.status, sizeof(msg.status))) 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fail_message(s, "invalid data message: expected ID_DONE"); 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* HAVE_SYMLINKS */ 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int do_send(int s, char *path, char *buffer) 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *tmp; 32320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int mode; 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int is_link, ret; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project tmp = strrchr(path,','); 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(tmp) { 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *tmp = 0; 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project errno = 0; 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = strtoul(tmp + 1, NULL, 0); 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_SYMLINKS 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 33420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng is_link = S_ISLNK((mode_t) mode); 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode &= 0777; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!tmp || errno) { 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = 0644; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project is_link = 0; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_unlink(path); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef HAVE_SYMLINKS 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(is_link) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = handle_send_link(s, path, buffer); 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 35320d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng unsigned int uid, gid; 35420d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uint64_t cap = 0; 35520d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng uid = getuid(); 35620d33f4d99c26afdd0aebf23786958ef34e261e3Liang Cheng gid = getgid(); 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