2 * Copyright (C) 2007 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/types.h>
30 #define TRACE_TAG TRACE_SYNC
32 #include "file_sync_service.h"
34 /* The typical default value for the umask is S_IWGRP | S_IWOTH (octal 022).
35 * Before use the DIR_PERMISSION, the process umask value should be set 0 using umask().
37 #define DIR_PERMISSION 0777
39 static int mkdirs(char *name)
44 if(name[0] != '/') return -1;
50 ret = sdb_mkdir(name, DIR_PERMISSION);
51 if((ret < 0) && (errno != EEXIST)) {
52 D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
61 static int do_stat(int s, const char *path)
66 msg.stat.id = ID_STAT;
68 if(lstat(path, &st)) {
73 msg.stat.mode = htoll(st.st_mode);
74 msg.stat.size = htoll(st.st_size);
75 msg.stat.time = htoll(st.st_mtime);
78 return writex(s, &msg.stat, sizeof(msg.stat));
81 static int do_list(int s, const char *path)
89 char tmp[1024 + 256 + 1];
93 memcpy(tmp, path, len);
95 fname = tmp + len + 1;
97 msg.dent.id = ID_DENT;
100 if(d == 0) goto done;
102 while((de = readdir(d))) {
103 int len = strlen(de->d_name);
105 /* not supposed to be possible, but
106 if it does happen, let's not buffer overrun */
107 if(len > 256) continue;
109 strcpy(fname, de->d_name);
110 if(lstat(tmp, &st) == 0) {
111 msg.dent.mode = htoll(st.st_mode);
112 msg.dent.size = htoll(st.st_size);
113 msg.dent.time = htoll(st.st_mtime);
114 msg.dent.namelen = htoll(len);
116 if(writex(s, &msg.dent, sizeof(msg.dent)) ||
117 writex(s, de->d_name, len)) {
126 msg.dent.id = ID_DONE;
130 msg.dent.namelen = 0;
131 return writex(s, &msg.dent, sizeof(msg.dent));
134 static int fail_message(int s, const char *reason)
137 int len = strlen(reason);
139 D("sync: failure: %s\n", reason);
141 msg.data.id = ID_FAIL;
142 msg.data.size = htoll(len);
143 if(writex(s, &msg.data, sizeof(msg.data)) ||
144 writex(s, reason, len)) {
151 static int fail_errno(int s)
153 return fail_message(s, strerror(errno));
156 static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
159 unsigned int timestamp = 0;
162 fd = sdb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
163 if(fd < 0 && errno == ENOENT) {
165 fd = sdb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
167 if(fd < 0 && errno == EEXIST) {
168 fd = sdb_open_mode(path, O_WRONLY, mode);
179 if(readx(s, &msg.data, sizeof(msg.data)))
182 if(msg.data.id != ID_DATA) {
183 if(msg.data.id == ID_DONE) {
184 timestamp = ltohl(msg.data.size);
187 fail_message(s, "invalid data message");
190 len = ltohl(msg.data.size);
191 if(len > SYNC_DATA_MAX) {
192 fail_message(s, "oversize data message");
195 if(readx(s, buffer, len))
200 if(writex(fd, buffer, len)) {
204 if(fail_errno(s)) return -1;
211 u.actime = timestamp;
212 u.modtime = timestamp;
215 msg.status.id = ID_OKAY;
216 msg.status.msglen = 0;
217 if(writex(s, &msg.status, sizeof(msg.status)))
230 static int handle_send_link(int s, char *path, char *buffer)
236 if(readx(s, &msg.data, sizeof(msg.data)))
239 if(msg.data.id != ID_DATA) {
240 fail_message(s, "invalid data message: expected ID_DATA");
244 len = ltohl(msg.data.size);
245 if(len > SYNC_DATA_MAX) {
246 fail_message(s, "oversize data message");
249 if(readx(s, buffer, len))
252 ret = symlink(buffer, path);
253 if(ret && errno == ENOENT) {
255 ret = symlink(buffer, path);
262 if(readx(s, &msg.data, sizeof(msg.data)))
265 if(msg.data.id == ID_DONE) {
266 msg.status.id = ID_OKAY;
267 msg.status.msglen = 0;
268 if(writex(s, &msg.status, sizeof(msg.status)))
271 fail_message(s, "invalid data message: expected ID_DONE");
277 #endif /* HAVE_SYMLINKS */
279 static int do_send(int s, char *path, char *buffer)
285 tmp = strrchr(path,',');
289 mode = strtoul(tmp + 1, NULL, 0);
290 #ifndef HAVE_SYMLINKS
293 is_link = S_ISLNK(mode);
295 // extracts file permission from stat.mode. (ex 100644 & 0777 = 644);
296 mode &= 0777; // combination of (S_IRWXU | S_IRWXG | S_IRWXO)
299 mode = 0644; // set default permission value in most of unix system.
303 // sdb does not allow to check that file exists or not. After deleting old file and creating new file again unconditionally.
309 ret = handle_send_link(s, path, buffer);
314 /* copy user permission bits to "group" and "other" permissions.
315 * ex) 0644 file will be created copied 0666 file.
316 * the following 2 lines should be commented if sdb process has been set to umask 0.
319 //mode |= ((mode >> 3) & 0070);
320 //mode |= ((mode >> 3) & 0007);
322 ret = handle_send_file(s, path, mode, buffer);
328 static int do_recv(int s, const char *path, char *buffer)
333 fd = sdb_open(path, O_RDONLY);
335 if(fail_errno(s)) return -1;
339 msg.data.id = ID_DATA;
341 r = sdb_read(fd, buffer, SYNC_DATA_MAX);
344 if(errno == EINTR) continue;
349 msg.data.size = htoll(r);
350 if(writex(s, &msg.data, sizeof(msg.data)) ||
351 writex(s, buffer, r)) {
359 msg.data.id = ID_DONE;
361 if(writex(s, &msg.data, sizeof(msg.data))) {
368 void file_sync_service(int fd, void *cookie)
374 char *buffer = malloc(SYNC_DATA_MAX);
375 if(buffer == 0) goto fail;
378 D("sync: waiting for command\n");
380 if(readx(fd, &msg.req, sizeof(msg.req))) {
381 fail_message(fd, "command read failure");
384 namelen = ltohl(msg.req.namelen);
386 fail_message(fd, "invalid namelen");
389 if(readx(fd, name, namelen)) {
390 fail_message(fd, "filename read failure");
396 D("sync: '%s' '%s'\n", (char*) &msg.req, name);
400 if(do_stat(fd, name)) goto fail;
403 if(do_list(fd, name)) goto fail;
406 if(do_send(fd, name, buffer)) goto fail;
409 if(do_recv(fd, name, buffer)) goto fail;
414 fail_message(fd, "unknown command");
420 if(buffer != 0) free(buffer);