diff options
Diffstat (limited to 'adb/file_sync_service.c')
-rw-r--r-- | adb/file_sync_service.c | 412 |
1 files changed, 0 insertions, 412 deletions
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c deleted file mode 100644 index a231e93d6..000000000 --- a/adb/file_sync_service.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <utime.h> - -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_SYNC -#include "adb.h" -#include "file_sync_service.h" - -static int mkdirs(char *name) -{ - int ret; - char *x = name + 1; - - if(name[0] != '/') return -1; - - for(;;) { - x = adb_dirstart(x); - if(x == 0) return 0; - *x = 0; - ret = adb_mkdir(name, 0775); - if((ret < 0) && (errno != EEXIST)) { - D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); - *x = '/'; - return ret; - } - *x++ = '/'; - } - return 0; -} - -static int do_stat(int s, const char *path) -{ - syncmsg msg; - struct stat st; - - msg.stat.id = ID_STAT; - - if(lstat(path, &st)) { - msg.stat.mode = 0; - msg.stat.size = 0; - msg.stat.time = 0; - } else { - msg.stat.mode = htoll(st.st_mode); - msg.stat.size = htoll(st.st_size); - msg.stat.time = htoll(st.st_mtime); - } - - return writex(s, &msg.stat, sizeof(msg.stat)); -} - -static int do_list(int s, const char *path) -{ - DIR *d; - struct dirent *de; - struct stat st; - syncmsg msg; - int len; - - char tmp[1024 + 256 + 1]; - char *fname; - - len = strlen(path); - memcpy(tmp, path, len); - tmp[len] = '/'; - fname = tmp + len + 1; - - msg.dent.id = ID_DENT; - - d = opendir(path); - if(d == 0) goto done; - - while((de = readdir(d))) { - int len = strlen(de->d_name); - - /* not supposed to be possible, but - if it does happen, let's not buffer overrun */ - if(len > 256) continue; - - strcpy(fname, de->d_name); - if(lstat(tmp, &st) == 0) { - msg.dent.mode = htoll(st.st_mode); - msg.dent.size = htoll(st.st_size); - msg.dent.time = htoll(st.st_mtime); - msg.dent.namelen = htoll(len); - - if(writex(s, &msg.dent, sizeof(msg.dent)) || - writex(s, de->d_name, len)) { - return -1; - } - } - } - - closedir(d); - -done: - msg.dent.id = ID_DONE; - msg.dent.mode = 0; - msg.dent.size = 0; - msg.dent.time = 0; - msg.dent.namelen = 0; - return writex(s, &msg.dent, sizeof(msg.dent)); -} - -static int fail_message(int s, const char *reason) -{ - syncmsg msg; - int len = strlen(reason); - - D("sync: failure: %s\n", reason); - - msg.data.id = ID_FAIL; - msg.data.size = htoll(len); - if(writex(s, &msg.data, sizeof(msg.data)) || - writex(s, reason, len)) { - return -1; - } else { - return 0; - } -} - -static int fail_errno(int s) -{ - return fail_message(s, strerror(errno)); -} - -static int handle_send_file(int s, char *path, mode_t mode, char *buffer) -{ - syncmsg msg; - unsigned int timestamp = 0; - int fd; - - fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); - if(fd < 0 && errno == ENOENT) { - mkdirs(path); - fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); - } - if(fd < 0 && errno == EEXIST) { - fd = adb_open_mode(path, O_WRONLY, mode); - } - if(fd < 0) { - if(fail_errno(s)) - return -1; - fd = -1; - } - - for(;;) { - unsigned int len; - - if(readx(s, &msg.data, sizeof(msg.data))) - goto fail; - - if(msg.data.id != ID_DATA) { - if(msg.data.id == ID_DONE) { - timestamp = ltohl(msg.data.size); - break; - } - fail_message(s, "invalid data message"); - goto fail; - } - len = ltohl(msg.data.size); - if(len > SYNC_DATA_MAX) { - fail_message(s, "oversize data message"); - goto fail; - } - if(readx(s, buffer, len)) - goto fail; - - if(fd < 0) - continue; - if(writex(fd, buffer, len)) { - adb_close(fd); - adb_unlink(path); - fd = -1; - if(fail_errno(s)) return -1; - } - } - - if(fd >= 0) { - struct utimbuf u; - adb_close(fd); - u.actime = timestamp; - u.modtime = timestamp; - utime(path, &u); - - msg.status.id = ID_OKAY; - msg.status.msglen = 0; - if(writex(s, &msg.status, sizeof(msg.status))) - return -1; - } - return 0; - -fail: - if(fd >= 0) - adb_close(fd); - adb_unlink(path); - return -1; -} - -#ifdef HAVE_SYMLINKS -static int handle_send_link(int s, char *path, char *buffer) -{ - syncmsg msg; - unsigned int len; - int ret; - - if(readx(s, &msg.data, sizeof(msg.data))) - return -1; - - if(msg.data.id != ID_DATA) { - fail_message(s, "invalid data message: expected ID_DATA"); - return -1; - } - - len = ltohl(msg.data.size); - if(len > SYNC_DATA_MAX) { - fail_message(s, "oversize data message"); - return -1; - } - if(readx(s, buffer, len)) - return -1; - - ret = symlink(buffer, path); - if(ret && errno == ENOENT) { - mkdirs(path); - ret = symlink(buffer, path); - } - if(ret) { - fail_errno(s); - return -1; - } - - if(readx(s, &msg.data, sizeof(msg.data))) - return -1; - - if(msg.data.id == ID_DONE) { - msg.status.id = ID_OKAY; - msg.status.msglen = 0; - if(writex(s, &msg.status, sizeof(msg.status))) - return -1; - } else { - fail_message(s, "invalid data message: expected ID_DONE"); - return -1; - } - - return 0; -} -#endif /* HAVE_SYMLINKS */ - -static int do_send(int s, char *path, char *buffer) -{ - char *tmp; - mode_t mode; - int is_link, ret; - - tmp = strrchr(path,','); - if(tmp) { - *tmp = 0; - errno = 0; - mode = strtoul(tmp + 1, NULL, 0); -#ifndef HAVE_SYMLINKS - is_link = 0; -#else - is_link = S_ISLNK(mode); -#endif - mode &= 0777; - } - if(!tmp || errno) { - mode = 0644; - is_link = 0; - } - - adb_unlink(path); - - -#ifdef HAVE_SYMLINKS - if(is_link) - ret = handle_send_link(s, path, buffer); - else { -#else - { -#endif - /* copy user permission bits to "group" and "other" permissions */ - mode |= ((mode >> 3) & 0070); - mode |= ((mode >> 3) & 0007); - - ret = handle_send_file(s, path, mode, buffer); - } - - return ret; -} - -static int do_recv(int s, const char *path, char *buffer) -{ - syncmsg msg; - int fd, r; - - fd = adb_open(path, O_RDONLY); - if(fd < 0) { - if(fail_errno(s)) return -1; - return 0; - } - - msg.data.id = ID_DATA; - for(;;) { - r = adb_read(fd, buffer, SYNC_DATA_MAX); - if(r <= 0) { - if(r == 0) break; - if(errno == EINTR) continue; - r = fail_errno(s); - adb_close(fd); - return r; - } - msg.data.size = htoll(r); - if(writex(s, &msg.data, sizeof(msg.data)) || - writex(s, buffer, r)) { - adb_close(fd); - return -1; - } - } - - adb_close(fd); - - msg.data.id = ID_DONE; - msg.data.size = 0; - if(writex(s, &msg.data, sizeof(msg.data))) { - return -1; - } - - return 0; -} - -void file_sync_service(int fd, void *cookie) -{ - syncmsg msg; - char name[1025]; - unsigned namelen; - - char *buffer = malloc(SYNC_DATA_MAX); - if(buffer == 0) goto fail; - - for(;;) { - D("sync: waiting for command\n"); - - if(readx(fd, &msg.req, sizeof(msg.req))) { - fail_message(fd, "command read failure"); - break; - } - namelen = ltohl(msg.req.namelen); - if(namelen > 1024) { - fail_message(fd, "invalid namelen"); - break; - } - if(readx(fd, name, namelen)) { - fail_message(fd, "filename read failure"); - break; - } - name[namelen] = 0; - - msg.req.namelen = 0; - D("sync: '%s' '%s'\n", (char*) &msg.req, name); - - switch(msg.req.id) { - case ID_STAT: - if(do_stat(fd, name)) goto fail; - break; - case ID_LIST: - if(do_list(fd, name)) goto fail; - break; - case ID_SEND: - if(do_send(fd, name, buffer)) goto fail; - break; - case ID_RECV: - if(do_recv(fd, name, buffer)) goto fail; - break; - case ID_QUIT: - goto fail; - default: - fail_message(fd, "unknown command"); - goto fail; - } - } - -fail: - if(buffer != 0) free(buffer); - D("sync: done\n"); - adb_close(fd); -} |