file_sync_service.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  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
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  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.
  15. */
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <sys/stat.h>
  20. #include <sys/types.h>
  21. #include <dirent.h>
  22. #include <utime.h>
  23. #include <errno.h>
  24. #include "sysdeps.h"
  25. #define TRACE_TAG TRACE_SYNC
  26. #include "adb.h"
  27. #include "file_sync_service.h"
  28. static int mkdirs(char *name)
  29. {
  30. int ret;
  31. char *x = name + 1;
  32. if(name[0] != '/') return -1;
  33. for(;;) {
  34. x = adb_dirstart(x);
  35. if(x == 0) return 0;
  36. *x = 0;
  37. ret = adb_mkdir(name, 0775);
  38. if((ret < 0) && (errno != EEXIST)) {
  39. D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
  40. *x = '/';
  41. return ret;
  42. }
  43. *x++ = '/';
  44. }
  45. return 0;
  46. }
  47. static int do_stat(int s, const char *path)
  48. {
  49. syncmsg msg;
  50. struct stat st;
  51. msg.stat.id = ID_STAT;
  52. if(lstat(path, &st)) {
  53. msg.stat.mode = 0;
  54. msg.stat.size = 0;
  55. msg.stat.time = 0;
  56. } else {
  57. msg.stat.mode = htoll(st.st_mode);
  58. msg.stat.size = htoll(st.st_size);
  59. msg.stat.time = htoll(st.st_mtime);
  60. }
  61. return writex(s, &msg.stat, sizeof(msg.stat));
  62. }
  63. static int do_list(int s, const char *path)
  64. {
  65. DIR *d;
  66. struct dirent *de;
  67. struct stat st;
  68. syncmsg msg;
  69. int len;
  70. char tmp[1024 + 256 + 1];
  71. char *fname;
  72. len = strlen(path);
  73. memcpy(tmp, path, len);
  74. tmp[len] = '/';
  75. fname = tmp + len + 1;
  76. msg.dent.id = ID_DENT;
  77. d = opendir(path);
  78. if(d == 0) goto done;
  79. while((de = readdir(d))) {
  80. int len = strlen(de->d_name);
  81. /* not supposed to be possible, but
  82. if it does happen, let's not buffer overrun */
  83. if(len > 256) continue;
  84. strcpy(fname, de->d_name);
  85. if(lstat(tmp, &st) == 0) {
  86. msg.dent.mode = htoll(st.st_mode);
  87. msg.dent.size = htoll(st.st_size);
  88. msg.dent.time = htoll(st.st_mtime);
  89. msg.dent.namelen = htoll(len);
  90. if(writex(s, &msg.dent, sizeof(msg.dent)) ||
  91. writex(s, de->d_name, len)) {
  92. closedir(d);
  93. return -1;
  94. }
  95. }
  96. }
  97. closedir(d);
  98. done:
  99. msg.dent.id = ID_DONE;
  100. msg.dent.mode = 0;
  101. msg.dent.size = 0;
  102. msg.dent.time = 0;
  103. msg.dent.namelen = 0;
  104. return writex(s, &msg.dent, sizeof(msg.dent));
  105. }
  106. static int fail_message(int s, const char *reason)
  107. {
  108. syncmsg msg;
  109. int len = strlen(reason);
  110. D("sync: failure: %s\n", reason);
  111. msg.data.id = ID_FAIL;
  112. msg.data.size = htoll(len);
  113. if(writex(s, &msg.data, sizeof(msg.data)) ||
  114. writex(s, reason, len)) {
  115. return -1;
  116. } else {
  117. return 0;
  118. }
  119. }
  120. static int fail_errno(int s)
  121. {
  122. return fail_message(s, strerror(errno));
  123. }
  124. static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
  125. {
  126. syncmsg msg;
  127. unsigned int timestamp = 0;
  128. int fd;
  129. fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
  130. if(fd < 0 && errno == ENOENT) {
  131. mkdirs(path);
  132. fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
  133. }
  134. if(fd < 0 && errno == EEXIST) {
  135. fd = adb_open_mode(path, O_WRONLY, mode);
  136. }
  137. if(fd < 0) {
  138. if(fail_errno(s))
  139. return -1;
  140. fd = -1;
  141. }
  142. for(;;) {
  143. unsigned int len;
  144. if(readx(s, &msg.data, sizeof(msg.data)))
  145. goto fail;
  146. if(msg.data.id != ID_DATA) {
  147. if(msg.data.id == ID_DONE) {
  148. timestamp = ltohl(msg.data.size);
  149. break;
  150. }
  151. fail_message(s, "invalid data message");
  152. goto fail;
  153. }
  154. len = ltohl(msg.data.size);
  155. if(len > SYNC_DATA_MAX) {
  156. fail_message(s, "oversize data message");
  157. goto fail;
  158. }
  159. if(readx(s, buffer, len))
  160. goto fail;
  161. if(fd < 0)
  162. continue;
  163. if(writex(fd, buffer, len)) {
  164. int saved_errno = errno;
  165. adb_close(fd);
  166. adb_unlink(path);
  167. fd = -1;
  168. errno = saved_errno;
  169. if(fail_errno(s)) return -1;
  170. }
  171. }
  172. if(fd >= 0) {
  173. struct utimbuf u;
  174. adb_close(fd);
  175. u.actime = timestamp;
  176. u.modtime = timestamp;
  177. utime(path, &u);
  178. msg.status.id = ID_OKAY;
  179. msg.status.msglen = 0;
  180. if(writex(s, &msg.status, sizeof(msg.status)))
  181. return -1;
  182. }
  183. return 0;
  184. fail:
  185. if(fd >= 0)
  186. adb_close(fd);
  187. adb_unlink(path);
  188. return -1;
  189. }
  190. #ifdef HAVE_SYMLINKS
  191. static int handle_send_link(int s, char *path, char *buffer)
  192. {
  193. syncmsg msg;
  194. unsigned int len;
  195. int ret;
  196. if(readx(s, &msg.data, sizeof(msg.data)))
  197. return -1;
  198. if(msg.data.id != ID_DATA) {
  199. fail_message(s, "invalid data message: expected ID_DATA");
  200. return -1;
  201. }
  202. len = ltohl(msg.data.size);
  203. if(len > SYNC_DATA_MAX) {
  204. fail_message(s, "oversize data message");
  205. return -1;
  206. }
  207. if(readx(s, buffer, len))
  208. return -1;
  209. ret = symlink(buffer, path);
  210. if(ret && errno == ENOENT) {
  211. mkdirs(path);
  212. ret = symlink(buffer, path);
  213. }
  214. if(ret) {
  215. fail_errno(s);
  216. return -1;
  217. }
  218. if(readx(s, &msg.data, sizeof(msg.data)))
  219. return -1;
  220. if(msg.data.id == ID_DONE) {
  221. msg.status.id = ID_OKAY;
  222. msg.status.msglen = 0;
  223. if(writex(s, &msg.status, sizeof(msg.status)))
  224. return -1;
  225. } else {
  226. fail_message(s, "invalid data message: expected ID_DONE");
  227. return -1;
  228. }
  229. return 0;
  230. }
  231. #endif /* HAVE_SYMLINKS */
  232. static int do_send(int s, char *path, char *buffer)
  233. {
  234. char *tmp;
  235. mode_t mode;
  236. int is_link, ret;
  237. tmp = strrchr(path,',');
  238. if(tmp) {
  239. *tmp = 0;
  240. errno = 0;
  241. mode = strtoul(tmp + 1, NULL, 0);
  242. #ifndef HAVE_SYMLINKS
  243. is_link = 0;
  244. #else
  245. is_link = S_ISLNK(mode);
  246. #endif
  247. mode &= 0777;
  248. }
  249. if(!tmp || errno) {
  250. mode = 0644;
  251. is_link = 0;
  252. }
  253. adb_unlink(path);
  254. #ifdef HAVE_SYMLINKS
  255. if(is_link)
  256. ret = handle_send_link(s, path, buffer);
  257. else {
  258. #else
  259. {
  260. #endif
  261. /* copy user permission bits to "group" and "other" permissions */
  262. mode |= ((mode >> 3) & 0070);
  263. mode |= ((mode >> 3) & 0007);
  264. ret = handle_send_file(s, path, mode, buffer);
  265. }
  266. return ret;
  267. }
  268. static int do_recv(int s, const char *path, char *buffer)
  269. {
  270. syncmsg msg;
  271. int fd, r;
  272. fd = adb_open(path, O_RDONLY);
  273. if(fd < 0) {
  274. if(fail_errno(s)) return -1;
  275. return 0;
  276. }
  277. msg.data.id = ID_DATA;
  278. for(;;) {
  279. r = adb_read(fd, buffer, SYNC_DATA_MAX);
  280. if(r <= 0) {
  281. if(r == 0) break;
  282. if(errno == EINTR) continue;
  283. r = fail_errno(s);
  284. adb_close(fd);
  285. return r;
  286. }
  287. msg.data.size = htoll(r);
  288. if(writex(s, &msg.data, sizeof(msg.data)) ||
  289. writex(s, buffer, r)) {
  290. adb_close(fd);
  291. return -1;
  292. }
  293. }
  294. adb_close(fd);
  295. msg.data.id = ID_DONE;
  296. msg.data.size = 0;
  297. if(writex(s, &msg.data, sizeof(msg.data))) {
  298. return -1;
  299. }
  300. return 0;
  301. }
  302. void file_sync_service(int fd, void *cookie)
  303. {
  304. syncmsg msg;
  305. char name[1025];
  306. unsigned namelen;
  307. char *buffer = malloc(SYNC_DATA_MAX);
  308. if(buffer == 0) goto fail;
  309. for(;;) {
  310. D("sync: waiting for command\n");
  311. if(readx(fd, &msg.req, sizeof(msg.req))) {
  312. fail_message(fd, "command read failure");
  313. break;
  314. }
  315. namelen = ltohl(msg.req.namelen);
  316. if(namelen > 1024) {
  317. fail_message(fd, "invalid namelen");
  318. break;
  319. }
  320. if(readx(fd, name, namelen)) {
  321. fail_message(fd, "filename read failure");
  322. break;
  323. }
  324. name[namelen] = 0;
  325. msg.req.namelen = 0;
  326. D("sync: '%s' '%s'\n", (char*) &msg.req, name);
  327. switch(msg.req.id) {
  328. case ID_STAT:
  329. if(do_stat(fd, name)) goto fail;
  330. break;
  331. case ID_LIST:
  332. if(do_list(fd, name)) goto fail;
  333. break;
  334. case ID_SEND:
  335. if(do_send(fd, name, buffer)) goto fail;
  336. break;
  337. case ID_RECV:
  338. if(do_recv(fd, name, buffer)) goto fail;
  339. break;
  340. case ID_QUIT:
  341. goto fail;
  342. default:
  343. fail_message(fd, "unknown command");
  344. goto fail;
  345. }
  346. }
  347. fail:
  348. if(buffer != 0) free(buffer);
  349. D("sync: done\n");
  350. adb_close(fd);
  351. }