1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2007 The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 1749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <stdlib.h> 18f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdio.h> 1949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <string.h> 2049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 2149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <sys/stat.h> 2249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <sys/types.h> 2349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <dirent.h> 2449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <utime.h> 2549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 2649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat#include <errno.h> 27a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 28a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "sysdeps.h" 29a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 30a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#define TRACE_TAG TRACE_SYNC 31a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "adb.h" 32a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "file_sync_service.h" 332a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat 34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int mkdirs(char *name) 35f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat{ 36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int ret; 37f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat char *x = name + 1; 38f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 39f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if(name[0] != '/') return -1; 40a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 41a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat for(;;) { 42bf04185c88161f13118b9975cdff7967d49a4fa0San Mehat x = adb_dirstart(x); 43586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat if(x == 0) return 0; 44f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *x = 0; 45a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat ret = adb_mkdir(name, 0775); 46a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if((ret < 0) && (errno != EEXIST)) { 4749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); 483bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat *x = '/'; 493bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat return ret; 503bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 513bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat *x++ = '/'; 523bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 533bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat return 0; 543bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat} 553bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 563bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehatstatic int do_stat(int s, const char *path) 573bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat{ 583bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat syncmsg msg; 593bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat struct stat st; 603bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 613bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.id = ID_STAT; 623bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 633bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(lstat(path, &st)) { 6452c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat msg.stat.mode = 0; 653bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.size = 0; 663bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.time = 0; 673bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } else { 683bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.mode = htoll(st.st_mode); 693bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.size = htoll(st.st_size); 703bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.stat.time = htoll(st.st_mtime); 713bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 723bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 733bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat return writex(s, &msg.stat, sizeof(msg.stat)); 743bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat} 753bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 76a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatic int do_list(int s, const char *path) 77a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat{ 78a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat DIR *d; 79a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat struct dirent *de; 80a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat struct stat st; 81a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat syncmsg msg; 82a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int len; 83a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 84a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char tmp[1024 + 256 + 1]; 85a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char *fname; 86a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 87a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat len = strlen(path); 88a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat memcpy(tmp, path, len); 89a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat tmp[len] = '/'; 90a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fname = tmp + len + 1; 91a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 92a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg.dent.id = ID_DENT; 93a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 94a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat d = opendir(path); 95a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(d == 0) goto done; 96a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 97a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat while((de = readdir(d))) { 98a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int len = strlen(de->d_name); 99a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 10049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat /* not supposed to be possible, but 101a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if it does happen, let's not buffer overrun */ 102a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(len > 256) continue; 103d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 104f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat strcpy(fname, de->d_name); 105f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if(lstat(tmp, &st) == 0) { 106f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg.dent.mode = htoll(st.st_mode); 107a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg.dent.size = htoll(st.st_size); 108f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg.dent.time = htoll(st.st_mtime); 109f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat msg.dent.namelen = htoll(len); 110f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 111f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if(writex(s, &msg.dent, sizeof(msg.dent)) || 112f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat writex(s, de->d_name, len)) { 113f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return -1; 114f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 115cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat } 116cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat } 117cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat 118cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat closedir(d); 119cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat 12097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatdone: 121cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.dent.id = ID_DONE; 122cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.dent.mode = 0; 123cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.dent.size = 0; 124cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.dent.time = 0; 125cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.dent.namelen = 0; 126cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat return writex(s, &msg.dent, sizeof(msg.dent)); 127cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat} 128cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat 12997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatstatic int fail_message(int s, const char *reason) 130cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat{ 131cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat syncmsg msg; 132cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat int len = strlen(reason); 133cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat 134d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat D("sync: failure: %s\n", reason); 135d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 136d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat msg.data.id = ID_FAIL; 137d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat msg.data.size = htoll(len); 138a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(writex(s, &msg.data, sizeof(msg.data)) || 139a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat writex(s, reason, len)) { 140a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 141a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 142a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 143a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 144a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 145a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 146a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatic int fail_errno(int s) 147a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat{ 148fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat return fail_message(s, strerror(errno)); 149f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 150f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 151f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int handle_send_file(int s, char *path, mode_t mode, char *buffer) 152f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat{ 153f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat syncmsg msg; 154a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat unsigned int timestamp = 0; 155a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int fd; 156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 157a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 15897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat if(fd < 0 && errno == ENOENT) { 159a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mkdirs(path); 160a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); 161a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 162f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if(fd < 0 && errno == EEXIST) { 163a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fd = adb_open_mode(path, O_WRONLY, mode); 16497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 165a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fd < 0) { 166a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fail_errno(s)) 167a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 168a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fd = -1; 169a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 170a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 171a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat for(;;) { 172a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat unsigned int len; 173f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if(readx(s, &msg.data, sizeof(msg.data))) 175dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat goto fail; 176dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 177dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if(msg.data.id != ID_DATA) { 178dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if(msg.data.id == ID_DONE) { 179dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat timestamp = ltohl(msg.data.size); 180dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat break; 181dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 182dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat fail_message(s, "invalid data message"); 183dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat goto fail; 184dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 185dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat len = ltohl(msg.data.size); 186a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(len > SYNC_DATA_MAX) { 18749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat fail_message(s, "oversize data message"); 188a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat goto fail; 189a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 19049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if(readx(s, buffer, len)) 191a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat goto fail; 192a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 193a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fd < 0) 194a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat continue; 195a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(writex(fd, buffer, len)) { 196a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat adb_close(fd); 19797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat adb_unlink(path); 198a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fd = -1; 199a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fail_errno(s)) return -1; 200a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 201a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 202a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 203a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fd >= 0) { 204a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat struct utimbuf u; 205a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat adb_close(fd); 206a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat u.actime = timestamp; 207a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat u.modtime = timestamp; 208a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat utime(path, &u); 209a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 210a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg.status.id = ID_OKAY; 211d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat msg.status.msglen = 0; 21297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat if(writex(s, &msg.status, sizeof(msg.status))) 213d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 2142a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat } 215a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 216a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 21797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatfail: 218a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fd >= 0) 219a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat adb_close(fd); 220a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat adb_unlink(path); 221a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 222a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 223a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 224fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat#ifdef HAVE_SYMLINKS 22597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatstatic int handle_send_link(int s, char *path, char *buffer) 226a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat{ 227a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat syncmsg msg; 228a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat unsigned int len; 2292a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat int ret; 230a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 231a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(readx(s, &msg.data, sizeof(msg.data))) 232a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 233a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 234a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(msg.data.id != ID_DATA) { 235a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fail_message(s, "invalid data message: expected ID_DATA"); 236a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 237a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 238a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 239a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat len = ltohl(msg.data.size); 240a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(len > SYNC_DATA_MAX) { 241a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fail_message(s, "oversize data message"); 242a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 24397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 244a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(readx(s, buffer, len)) 24549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return -1; 24649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 247a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat ret = symlink(buffer, path); 248a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(ret && errno == ENOENT) { 249a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mkdirs(path); 250a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat ret = symlink(buffer, path); 251a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 252a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(ret) { 253a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fail_errno(s); 254dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return -1; 255a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 256dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 257a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(readx(s, &msg.data, sizeof(msg.data))) 258a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 259a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 260a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(msg.data.id == ID_DONE) { 261a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg.status.id = ID_OKAY; 262a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg.status.msglen = 0; 263a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(writex(s, &msg.status, sizeof(msg.status))) 264a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 265a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 266a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat fail_message(s, "invalid data message: expected ID_DONE"); 267a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 268a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 269a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 270a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 271a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 272a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif /* HAVE_SYMLINKS */ 273a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 274a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatic int do_send(int s, char *path, char *buffer) 275a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat{ 276a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char *tmp; 27749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat mode_t mode; 27849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat int is_link, ret; 27949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 280a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat tmp = strrchr(path,','); 28197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat if(tmp) { 282a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat *tmp = 0; 283a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = 0; 284a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mode = strtoul(tmp + 1, NULL, 0); 285a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifndef HAVE_SYMLINKS 286a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat is_link = 0; 287a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#else 288a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat is_link = S_ISLNK(mode); 28997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat#endif 29049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat mode &= 0777; 29149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 29249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if(!tmp || errno) { 293a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mode = 0644; 294a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat is_link = 0; 295dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 296a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 297a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat adb_unlink(path); 298a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 29997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat 300a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef HAVE_SYMLINKS 301a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(is_link) 302bf04185c88161f13118b9975cdff7967d49a4fa0San Mehat ret = handle_send_link(s, path, buffer); 303bf04185c88161f13118b9975cdff7967d49a4fa0San Mehat else { 3043bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat#else 305a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat { 30697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat#endif 307a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat /* copy user permission bits to "group" and "other" permissions */ 308a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mode |= ((mode >> 3) & 0070); 309eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat mode |= ((mode >> 3) & 0007); 310eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 31197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat ret = handle_send_file(s, path, mode, buffer); 312eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat } 313eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 314a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return ret; 315a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 3163bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 3173bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehatstatic int do_recv(int s, const char *path, char *buffer) 3183bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat{ 3193bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat syncmsg msg; 320a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int fd, r; 3213bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 32297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat fd = adb_open(path, O_RDONLY); 3233bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(fd < 0) { 324a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(fail_errno(s)) return -1; 325a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 32697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 3273bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 328cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat msg.data.id = ID_DATA; 329cb4dac8a5243f6673b0590019b5b28a01bd3e343San Mehat for(;;) { 3303bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat r = adb_read(fd, buffer, SYNC_DATA_MAX); 33197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat if(r <= 0) { 3323bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(r == 0) break; 3333bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(errno == EINTR) continue; 3343bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat r = fail_errno(s); 3353bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat adb_close(fd); 3363bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat return r; 3373bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 3383bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.data.size = htoll(r); 3393bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(writex(s, &msg.data, sizeof(msg.data)) || 3403bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat writex(s, buffer, r)) { 3413bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat adb_close(fd); 34297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat return -1; 3433bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 3443bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 3453bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 3463bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat adb_close(fd); 3473bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 3483bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.data.id = ID_DONE; 3493bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.data.size = 0; 350a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if(writex(s, &msg.data, sizeof(msg.data))) { 351a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 35297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 35349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 354a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 355eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat} 356a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 357a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid file_sync_service(int fd, void *cookie) 3583bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat{ 3593bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat syncmsg msg; 3603bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat char name[1025]; 3613bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat unsigned namelen; 36252c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat 36352c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat char *buffer = malloc(SYNC_DATA_MAX); 36452c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat if(buffer == 0) goto fail; 36552c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat 36652c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat for(;;) { 36797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat D("sync: waiting for command\n"); 36852c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat 36952c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat if(readx(fd, &msg.req, sizeof(msg.req))) { 37052c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat fail_message(fd, "command read failure"); 37152c2ccb6d25b94b96685efd4803226727710fbaeSan Mehat break; 3723bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat } 3733bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat namelen = ltohl(msg.req.namelen); 3743bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(namelen > 1024) { 3753bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat fail_message(fd, "invalid namelen"); 3763bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 37797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 3783bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(readx(fd, name, namelen)) { 3793bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat fail_message(fd, "filename read failure"); 3803bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 38197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat } 3823bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat name[namelen] = 0; 3833bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat 3843bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat msg.req.namelen = 0; 3853bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat D("sync: '%s' '%s'\n", (char*) &msg.req, name); 386a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 3873bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat switch(msg.req.id) { 38897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat case ID_STAT: 3893bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(do_stat(fd, name)) goto fail; 3903bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 3913bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat case ID_LIST: 39297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat if(do_list(fd, name)) goto fail; 3933bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 3943bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat case ID_SEND: 3953bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(do_send(fd, name, buffer)) goto fail; 3963bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 3973bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat case ID_RECV: 3983bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(do_recv(fd, name, buffer)) goto fail; 3993bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat break; 4003bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat case ID_QUIT: 4013bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat goto fail; 4023bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat default: 40397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat fail_message(fd, "unknown command"); 4043bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat goto fail; 405a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 406a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 407a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 4083bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehatfail: 4093bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat if(buffer != 0) free(buffer); 4103bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat D("sync: done\n"); 4113bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat adb_close(fd); 4123bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat} 41397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat