backup.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * Backup handling code.
  3. *
  4. * Copyright (C) 1999 Andrew Tridgell
  5. * Copyright (C) 2003-2009 Wayne Davison
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, visit the http://fsf.org website.
  19. */
  20. #include "rsync.h"
  21. extern int verbose;
  22. extern int am_root;
  23. extern int preserve_acls;
  24. extern int preserve_xattrs;
  25. extern int preserve_devices;
  26. extern int preserve_specials;
  27. extern int preserve_links;
  28. extern int safe_symlinks;
  29. extern int backup_dir_len;
  30. extern unsigned int backup_dir_remainder;
  31. extern char backup_dir_buf[MAXPATHLEN];
  32. extern char *backup_suffix;
  33. extern char *backup_dir;
  34. /* make a complete pathname for backup file */
  35. char *get_backup_name(const char *fname)
  36. {
  37. if (backup_dir) {
  38. if (stringjoin(backup_dir_buf + backup_dir_len, backup_dir_remainder,
  39. fname, backup_suffix, NULL) < backup_dir_remainder)
  40. return backup_dir_buf;
  41. } else {
  42. if (stringjoin(backup_dir_buf, MAXPATHLEN,
  43. fname, backup_suffix, NULL) < MAXPATHLEN)
  44. return backup_dir_buf;
  45. }
  46. rprintf(FERROR, "backup filename too long\n");
  47. return NULL;
  48. }
  49. /* simple backup creates a backup with a suffix in the same directory */
  50. static int make_simple_backup(const char *fname)
  51. {
  52. int rename_errno;
  53. const char *fnamebak = get_backup_name(fname);
  54. if (!fnamebak)
  55. return 0;
  56. while (1) {
  57. if (do_rename(fname, fnamebak) == 0) {
  58. if (verbose > 1) {
  59. rprintf(FINFO, "backed up %s to %s\n",
  60. fname, fnamebak);
  61. }
  62. break;
  63. }
  64. /* cygwin (at least version b19) reports EINVAL */
  65. if (errno == ENOENT || errno == EINVAL)
  66. break;
  67. rename_errno = errno;
  68. if (errno == EISDIR && do_rmdir(fnamebak) == 0)
  69. continue;
  70. if (errno == ENOTDIR && do_unlink(fnamebak) == 0)
  71. continue;
  72. rsyserr(FERROR, rename_errno, "rename %s to backup %s",
  73. fname, fnamebak);
  74. errno = rename_errno;
  75. return 0;
  76. }
  77. return 1;
  78. }
  79. /****************************************************************************
  80. Create a directory given an absolute path, perms based upon another directory
  81. path
  82. ****************************************************************************/
  83. int make_bak_dir(const char *fullpath)
  84. {
  85. char fbuf[MAXPATHLEN], *rel, *end, *p;
  86. struct file_struct *file;
  87. int len = backup_dir_len;
  88. stat_x sx;
  89. while (*fullpath == '.' && fullpath[1] == '/') {
  90. fullpath += 2;
  91. len -= 2;
  92. }
  93. if (strlcpy(fbuf, fullpath, sizeof fbuf) >= sizeof fbuf)
  94. return -1;
  95. rel = fbuf + len;
  96. end = p = rel + strlen(rel);
  97. /* Try to find an existing dir, starting from the deepest dir. */
  98. while (1) {
  99. if (--p == fbuf)
  100. return -1;
  101. if (*p == '/') {
  102. *p = '\0';
  103. if (mkdir_defmode(fbuf) == 0)
  104. break;
  105. if (errno != ENOENT) {
  106. rsyserr(FERROR, errno,
  107. "make_bak_dir mkdir %s failed",
  108. full_fname(fbuf));
  109. return -1;
  110. }
  111. }
  112. }
  113. /* Make all the dirs that we didn't find on the way here. */
  114. while (1) {
  115. if (p >= rel) {
  116. /* Try to transfer the directory settings of the
  117. * actual dir that the files are coming from. */
  118. if (x_stat(rel, &sx.st, NULL) < 0) {
  119. rsyserr(FERROR, errno,
  120. "make_bak_dir stat %s failed",
  121. full_fname(rel));
  122. } else {
  123. #ifdef SUPPORT_ACLS
  124. sx.acc_acl = sx.def_acl = NULL;
  125. #endif
  126. #ifdef SUPPORT_XATTRS
  127. sx.xattr = NULL;
  128. #endif
  129. if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
  130. continue;
  131. #ifdef SUPPORT_ACLS
  132. if (preserve_acls && !S_ISLNK(file->mode)) {
  133. get_acl(rel, &sx);
  134. cache_tmp_acl(file, &sx);
  135. free_acl(&sx);
  136. }
  137. #endif
  138. #ifdef SUPPORT_XATTRS
  139. if (preserve_xattrs) {
  140. get_xattr(rel, &sx);
  141. cache_tmp_xattr(file, &sx);
  142. free_xattr(&sx);
  143. }
  144. #endif
  145. set_file_attrs(fbuf, file, NULL, NULL, 0);
  146. unmake_file(file);
  147. #ifdef SUPPORT_ACLS
  148. uncache_tmp_acls();
  149. #endif
  150. #ifdef SUPPORT_XATTRS
  151. uncache_tmp_xattrs();
  152. #endif
  153. }
  154. }
  155. *p = '/';
  156. p += strlen(p);
  157. if (p == end)
  158. break;
  159. if (mkdir_defmode(fbuf) < 0) {
  160. rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
  161. full_fname(fbuf));
  162. return -1;
  163. }
  164. }
  165. return 0;
  166. }
  167. /* robustly move a file, creating new directory structures if necessary */
  168. static int robust_move(const char *src, char *dst)
  169. {
  170. if (robust_rename(src, dst, NULL, 0755) < 0) {
  171. int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
  172. if (errno == ENOENT && make_bak_dir(dst) == 0) {
  173. if (robust_rename(src, dst, NULL, 0755) < 0)
  174. save_errno = errno ? errno : save_errno;
  175. else
  176. save_errno = 0;
  177. }
  178. if (save_errno) {
  179. errno = save_errno;
  180. return -1;
  181. }
  182. }
  183. return 0;
  184. }
  185. /* If we have a --backup-dir, then we get here from make_backup().
  186. * We will move the file to be deleted into a parallel directory tree. */
  187. static int keep_backup(const char *fname)
  188. {
  189. stat_x sx;
  190. struct file_struct *file;
  191. char *buf;
  192. int save_preserve_xattrs = preserve_xattrs;
  193. int kept = 0;
  194. int ret_code;
  195. /* return if no file to keep */
  196. if (x_lstat(fname, &sx.st, NULL) < 0)
  197. return 1;
  198. #ifdef SUPPORT_ACLS
  199. sx.acc_acl = sx.def_acl = NULL;
  200. #endif
  201. #ifdef SUPPORT_XATTRS
  202. sx.xattr = NULL;
  203. #endif
  204. if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
  205. return 1; /* the file could have disappeared */
  206. if (!(buf = get_backup_name(fname))) {
  207. unmake_file(file);
  208. #ifdef SUPPORT_ACLS
  209. uncache_tmp_acls();
  210. #endif
  211. #ifdef SUPPORT_XATTRS
  212. uncache_tmp_xattrs();
  213. #endif
  214. return 0;
  215. }
  216. #ifdef SUPPORT_ACLS
  217. if (preserve_acls && !S_ISLNK(file->mode)) {
  218. get_acl(fname, &sx);
  219. cache_tmp_acl(file, &sx);
  220. free_acl(&sx);
  221. }
  222. #endif
  223. #ifdef SUPPORT_XATTRS
  224. if (preserve_xattrs) {
  225. get_xattr(fname, &sx);
  226. cache_tmp_xattr(file, &sx);
  227. free_xattr(&sx);
  228. }
  229. #endif
  230. /* Check to see if this is a device file, or link */
  231. if ((am_root && preserve_devices && IS_DEVICE(file->mode))
  232. || (preserve_specials && IS_SPECIAL(file->mode))) {
  233. int save_errno;
  234. do_unlink(buf);
  235. if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) {
  236. save_errno = errno ? errno : EINVAL; /* 0 paranoia */
  237. if (errno == ENOENT && make_bak_dir(buf) == 0) {
  238. if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
  239. save_errno = errno ? errno : save_errno;
  240. else
  241. save_errno = 0;
  242. }
  243. if (save_errno) {
  244. rsyserr(FERROR, save_errno, "mknod %s failed",
  245. full_fname(buf));
  246. }
  247. } else
  248. save_errno = 0;
  249. if (verbose > 2 && save_errno == 0) {
  250. rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
  251. fname);
  252. }
  253. kept = 1;
  254. do_unlink(fname);
  255. }
  256. if (!kept && S_ISDIR(file->mode)) {
  257. /* make an empty directory */
  258. if (do_mkdir(buf, file->mode) < 0) {
  259. int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
  260. if (errno == ENOENT && make_bak_dir(buf) == 0) {
  261. if (do_mkdir(buf, file->mode) < 0)
  262. save_errno = errno ? errno : save_errno;
  263. else
  264. save_errno = 0;
  265. }
  266. if (save_errno) {
  267. rsyserr(FINFO, save_errno, "mkdir %s failed",
  268. full_fname(buf));
  269. }
  270. }
  271. ret_code = do_rmdir(fname);
  272. if (verbose > 2) {
  273. rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
  274. full_fname(fname), ret_code);
  275. }
  276. kept = 1;
  277. }
  278. #ifdef SUPPORT_LINKS
  279. if (!kept && preserve_links && S_ISLNK(file->mode)) {
  280. const char *sl = F_SYMLINK(file);
  281. if (safe_symlinks && unsafe_symlink(sl, fname)) {
  282. if (verbose) {
  283. rprintf(FINFO, "not backing up unsafe symlink \"%s\" -> \"%s\"\n",
  284. fname, sl);
  285. }
  286. kept = 1;
  287. } else {
  288. do_unlink(buf);
  289. if (do_symlink(sl, buf) < 0) {
  290. int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
  291. if (errno == ENOENT && make_bak_dir(buf) == 0) {
  292. if (do_symlink(sl, buf) < 0)
  293. save_errno = errno ? errno : save_errno;
  294. else
  295. save_errno = 0;
  296. }
  297. if (save_errno) {
  298. rsyserr(FERROR, save_errno, "link %s -> \"%s\"",
  299. full_fname(buf), sl);
  300. }
  301. }
  302. do_unlink(fname);
  303. kept = 1;
  304. }
  305. }
  306. #endif
  307. if (!kept && !S_ISREG(file->mode)) {
  308. rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
  309. fname);
  310. unmake_file(file);
  311. #ifdef SUPPORT_ACLS
  312. uncache_tmp_acls();
  313. #endif
  314. #ifdef SUPPORT_XATTRS
  315. uncache_tmp_xattrs();
  316. #endif
  317. return 1;
  318. }
  319. /* move to keep tree if a file */
  320. if (!kept) {
  321. if (robust_move(fname, buf) != 0) {
  322. rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
  323. full_fname(fname), buf);
  324. } else if (sx.st.st_nlink > 1) {
  325. /* If someone has hard-linked the file into the backup
  326. * dir, rename() might return success but do nothing! */
  327. robust_unlink(fname); /* Just in case... */
  328. }
  329. }
  330. preserve_xattrs = 0;
  331. set_file_attrs(buf, file, NULL, fname, 0);
  332. preserve_xattrs = save_preserve_xattrs;
  333. unmake_file(file);
  334. #ifdef SUPPORT_ACLS
  335. uncache_tmp_acls();
  336. #endif
  337. #ifdef SUPPORT_XATTRS
  338. uncache_tmp_xattrs();
  339. #endif
  340. if (verbose > 1) {
  341. rprintf(FINFO, "backed up %s to %s\n",
  342. fname, buf);
  343. }
  344. return 1;
  345. }
  346. /* main backup switch routine */
  347. int make_backup(const char *fname)
  348. {
  349. if (backup_dir)
  350. return keep_backup(fname);
  351. return make_simple_backup(fname);
  352. }