Support --sparse combined with --preallocate or --inplace.
[rsync.git] / syscall.c
1 /*
2  * Syscall wrappers to ensure that nothing gets done in dry_run mode
3  * and to handle system peculiarities.
4  *
5  * Copyright (C) 1998 Andrew Tridgell
6  * Copyright (C) 2002 Martin Pool
7  * Copyright (C) 2003-2015 Wayne Davison
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, visit the http://fsf.org website.
21  */
22
23 #include "rsync.h"
24
25 #if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
26 #include <sys/un.h>
27 #endif
28 #ifdef HAVE_SYS_ATTR_H
29 #include <sys/attr.h>
30 #endif
31
32 #if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE
33 #include <sys/syscall.h>
34 #endif
35
36 extern int dry_run;
37 extern int am_root;
38 extern int am_sender;
39 extern int read_only;
40 extern int list_only;
41 extern int inplace;
42 extern int preallocate_files;
43 extern int preserve_perms;
44 extern int preserve_executability;
45
46 #define RETURN_ERROR_IF(x,e) \
47         do { \
48                 if (x) { \
49                         errno = (e); \
50                         return -1; \
51                 } \
52         } while (0)
53
54 #define RETURN_ERROR_IF_RO_OR_LO RETURN_ERROR_IF(read_only || list_only, EROFS)
55
56 int do_unlink(const char *fname)
57 {
58         if (dry_run) return 0;
59         RETURN_ERROR_IF_RO_OR_LO;
60         return unlink(fname);
61 }
62
63 #ifdef SUPPORT_LINKS
64 int do_symlink(const char *lnk, const char *fname)
65 {
66         if (dry_run) return 0;
67         RETURN_ERROR_IF_RO_OR_LO;
68
69 #if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
70         /* For --fake-super, we create a normal file with mode 0600
71          * and write the lnk into it. */
72         if (am_root < 0) {
73                 int ok, len = strlen(lnk);
74                 int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
75                 if (fd < 0)
76                         return -1;
77                 ok = write(fd, lnk, len) == len;
78                 if (close(fd) < 0)
79                         ok = 0;
80                 return ok ? 0 : -1;
81         }
82 #endif
83
84         return symlink(lnk, fname);
85 }
86
87 #if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
88 ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
89 {
90         /* For --fake-super, we read the link from the file. */
91         if (am_root < 0) {
92                 int fd = do_open_nofollow(path, O_RDONLY);
93                 if (fd >= 0) {
94                         int len = read(fd, buf, bufsiz);
95                         close(fd);
96                         return len;
97                 }
98                 if (errno != ELOOP)
99                         return -1;
100                 /* A real symlink needs to be turned into a fake one on the receiving
101                  * side, so tell the generator that the link has no length. */
102                 if (!am_sender)
103                         return 0;
104                 /* Otherwise fall through and let the sender report the real length. */
105         }
106
107         return readlink(path, buf, bufsiz);
108 }
109 #endif
110 #endif
111
112 #ifdef HAVE_LINK
113 int do_link(const char *fname1, const char *fname2)
114 {
115         if (dry_run) return 0;
116         RETURN_ERROR_IF_RO_OR_LO;
117         return link(fname1, fname2);
118 }
119 #endif
120
121 int do_lchown(const char *path, uid_t owner, gid_t group)
122 {
123         if (dry_run) return 0;
124         RETURN_ERROR_IF_RO_OR_LO;
125 #ifndef HAVE_LCHOWN
126 #define lchown chown
127 #endif
128         return lchown(path, owner, group);
129 }
130
131 int do_mknod(const char *pathname, mode_t mode, dev_t dev)
132 {
133         if (dry_run) return 0;
134         RETURN_ERROR_IF_RO_OR_LO;
135
136         /* For --fake-super, we create a normal file with mode 0600. */
137         if (am_root < 0) {
138                 int fd = open(pathname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
139                 if (fd < 0 || close(fd) < 0)
140                         return -1;
141                 return 0;
142         }
143
144 #if !defined MKNOD_CREATES_FIFOS && defined HAVE_MKFIFO
145         if (S_ISFIFO(mode))
146                 return mkfifo(pathname, mode);
147 #endif
148 #if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
149         if (S_ISSOCK(mode)) {
150                 int sock;
151                 struct sockaddr_un saddr;
152                 unsigned int len = strlcpy(saddr.sun_path, pathname, sizeof saddr.sun_path);
153                 if (len >= sizeof saddr.sun_path) {
154                         errno = ENAMETOOLONG;
155                         return -1;
156                 }
157 #ifdef HAVE_SOCKADDR_UN_LEN
158                 saddr.sun_len = len + 1;
159 #endif
160                 saddr.sun_family = AF_UNIX;
161
162                 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0
163                     || (unlink(pathname) < 0 && errno != ENOENT)
164                     || (bind(sock, (struct sockaddr*)&saddr, sizeof saddr)) < 0)
165                         return -1;
166                 close(sock);
167 #ifdef HAVE_CHMOD
168                 return do_chmod(pathname, mode);
169 #else
170                 return 0;
171 #endif
172         }
173 #endif
174 #ifdef HAVE_MKNOD
175         return mknod(pathname, mode, dev);
176 #else
177         return -1;
178 #endif
179 }
180
181 int do_rmdir(const char *pathname)
182 {
183         if (dry_run) return 0;
184         RETURN_ERROR_IF_RO_OR_LO;
185         return rmdir(pathname);
186 }
187
188 int do_open(const char *pathname, int flags, mode_t mode)
189 {
190         if (flags != O_RDONLY) {
191                 RETURN_ERROR_IF(dry_run, 0);
192                 RETURN_ERROR_IF_RO_OR_LO;
193         }
194
195         return open(pathname, flags | O_BINARY, mode);
196 }
197
198 #ifdef HAVE_CHMOD
199 int do_chmod(const char *path, mode_t mode)
200 {
201         int code;
202         if (dry_run) return 0;
203         RETURN_ERROR_IF_RO_OR_LO;
204 #ifdef HAVE_LCHMOD
205         code = lchmod(path, mode & CHMOD_BITS);
206 #else
207         if (S_ISLNK(mode)) {
208 # if defined HAVE_SETATTRLIST
209                 struct attrlist attrList;
210                 uint32_t m = mode & CHMOD_BITS; /* manpage is wrong: not mode_t! */
211
212                 memset(&attrList, 0, sizeof attrList);
213                 attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
214                 attrList.commonattr = ATTR_CMN_ACCESSMASK;
215                 code = setattrlist(path, &attrList, &m, sizeof m, FSOPT_NOFOLLOW);
216 # else
217                 code = 1;
218 # endif
219         } else
220                 code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
221 #endif /* !HAVE_LCHMOD */
222         if (code != 0 && (preserve_perms || preserve_executability))
223                 return code;
224         return 0;
225 }
226 #endif
227
228 int do_rename(const char *fname1, const char *fname2)
229 {
230         if (dry_run) return 0;
231         RETURN_ERROR_IF_RO_OR_LO;
232         return rename(fname1, fname2);
233 }
234
235 #ifdef HAVE_FTRUNCATE
236 int do_ftruncate(int fd, OFF_T size)
237 {
238         int ret;
239
240         if (dry_run) return 0;
241         RETURN_ERROR_IF_RO_OR_LO;
242
243         do {
244                 ret = ftruncate(fd, size);
245         } while (ret < 0 && errno == EINTR);
246
247         return ret;
248 }
249 #endif
250
251 void trim_trailing_slashes(char *name)
252 {
253         int l;
254         /* Some BSD systems cannot make a directory if the name
255          * contains a trailing slash.
256          * <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
257
258         /* Don't change empty string; and also we can't improve on
259          * "/" */
260
261         l = strlen(name);
262         while (l > 1) {
263                 if (name[--l] != '/')
264                         break;
265                 name[l] = '\0';
266         }
267 }
268
269 int do_mkdir(char *fname, mode_t mode)
270 {
271         if (dry_run) return 0;
272         RETURN_ERROR_IF_RO_OR_LO;
273         trim_trailing_slashes(fname);
274         return mkdir(fname, mode);
275 }
276
277 /* like mkstemp but forces permissions */
278 int do_mkstemp(char *template, mode_t perms)
279 {
280         RETURN_ERROR_IF(dry_run, 0);
281         RETURN_ERROR_IF(read_only, EROFS);
282         perms |= S_IWUSR;
283
284 #if defined HAVE_SECURE_MKSTEMP && defined HAVE_FCHMOD && (!defined HAVE_OPEN64 || defined HAVE_MKSTEMP64)
285         {
286                 int fd = mkstemp(template);
287                 if (fd == -1)
288                         return -1;
289                 if (fchmod(fd, perms) != 0 && preserve_perms) {
290                         int errno_save = errno;
291                         close(fd);
292                         unlink(template);
293                         errno = errno_save;
294                         return -1;
295                 }
296 #if defined HAVE_SETMODE && O_BINARY
297                 setmode(fd, O_BINARY);
298 #endif
299                 return fd;
300         }
301 #else
302         if (!mktemp(template))
303                 return -1;
304         return do_open(template, O_RDWR|O_EXCL|O_CREAT, perms);
305 #endif
306 }
307
308 int do_stat(const char *fname, STRUCT_STAT *st)
309 {
310 #ifdef USE_STAT64_FUNCS
311         return stat64(fname, st);
312 #else
313         return stat(fname, st);
314 #endif
315 }
316
317 int do_lstat(const char *fname, STRUCT_STAT *st)
318 {
319 #ifdef SUPPORT_LINKS
320 # ifdef USE_STAT64_FUNCS
321         return lstat64(fname, st);
322 # else
323         return lstat(fname, st);
324 # endif
325 #else
326         return do_stat(fname, st);
327 #endif
328 }
329
330 int do_fstat(int fd, STRUCT_STAT *st)
331 {
332 #ifdef USE_STAT64_FUNCS
333         return fstat64(fd, st);
334 #else
335         return fstat(fd, st);
336 #endif
337 }
338
339 OFF_T do_lseek(int fd, OFF_T offset, int whence)
340 {
341 #ifdef HAVE_LSEEK64
342 #if !SIZEOF_OFF64_T
343         OFF_T lseek64();
344 #else
345         off64_t lseek64();
346 #endif
347         return lseek64(fd, offset, whence);
348 #else
349         return lseek(fd, offset, whence);
350 #endif
351 }
352
353 #ifdef HAVE_UTIMENSAT
354 int do_utimensat(const char *fname, time_t modtime, uint32 mod_nsec)
355 {
356         struct timespec t[2];
357
358         if (dry_run) return 0;
359         RETURN_ERROR_IF_RO_OR_LO;
360
361         t[0].tv_sec = 0;
362         t[0].tv_nsec = UTIME_NOW;
363         t[1].tv_sec = modtime;
364         t[1].tv_nsec = mod_nsec;
365         return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
366 }
367 #endif
368
369 #ifdef HAVE_LUTIMES
370 int do_lutimes(const char *fname, time_t modtime, uint32 mod_nsec)
371 {
372         struct timeval t[2];
373
374         if (dry_run) return 0;
375         RETURN_ERROR_IF_RO_OR_LO;
376
377         t[0].tv_sec = time(NULL);
378         t[0].tv_usec = 0;
379         t[1].tv_sec = modtime;
380         t[1].tv_usec = mod_nsec / 1000;
381         return lutimes(fname, t);
382 }
383 #endif
384
385 #ifdef HAVE_UTIMES
386 int do_utimes(const char *fname, time_t modtime, uint32 mod_nsec)
387 {
388         struct timeval t[2];
389
390         if (dry_run) return 0;
391         RETURN_ERROR_IF_RO_OR_LO;
392
393         t[0].tv_sec = time(NULL);
394         t[0].tv_usec = 0;
395         t[1].tv_sec = modtime;
396         t[1].tv_usec = mod_nsec / 1000;
397         return utimes(fname, t);
398 }
399
400 #elif defined HAVE_UTIME
401 int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec))
402 {
403 #ifdef HAVE_STRUCT_UTIMBUF
404         struct utimbuf tbuf;
405 #else
406         time_t t[2];
407 #endif
408
409         if (dry_run) return 0;
410         RETURN_ERROR_IF_RO_OR_LO;
411
412 # ifdef HAVE_STRUCT_UTIMBUF
413         tbuf.actime = time(NULL);
414         tbuf.modtime = modtime;
415         return utime(fname, &tbuf);
416 # else
417         t[0] = time(NULL);
418         t[1] = modtime;
419         return utime(fname, t);
420 # endif
421 }
422
423 #else
424 #error Need utimes or utime function.
425 #endif
426
427 #ifdef SUPPORT_PREALLOCATION
428 #ifdef FALLOC_FL_KEEP_SIZE
429 #define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE
430 #else
431 #define DO_FALLOC_OPTIONS 0
432 #endif
433
434 OFF_T do_fallocate(int fd, OFF_T offset, OFF_T length)
435 {
436         int opts = inplace || preallocate_files ? 0 : DO_FALLOC_OPTIONS;
437         int ret;
438         RETURN_ERROR_IF(dry_run, 0);
439         RETURN_ERROR_IF_RO_OR_LO;
440         if (length & 1) /* make the length not match the desired length */
441                 length++;
442         else
443                 length--;
444 #if defined HAVE_FALLOCATE
445         ret = fallocate(fd, opts, offset, length);
446 #elif defined HAVE_SYS_FALLOCATE
447         ret = syscall(SYS_fallocate, fd, opts, (loff_t)offset, (loff_t)length);
448 #elif defined HAVE_EFFICIENT_POSIX_FALLOCATE
449         ret = posix_fallocate(fd, offset, length);
450 #else
451 #error Coding error in SUPPORT_PREALLOCATION logic.
452 #endif
453         if (ret < 0)
454                 return ret;
455         if (opts == 0) {
456                 STRUCT_STAT st;
457                 if (do_fstat(fd, &st) < 0)
458                         return length;
459                 return st.st_blocks * 512;
460         }
461         return 0;
462 }
463 #endif
464
465 /* Punch a hole at pos for len bytes. The current file position must be at pos and will be
466  * changed to be at pos + len. */
467 int do_punch_hole(int fd, UNUSED(OFF_T pos), int len)
468 {
469 #ifdef HAVE_FALLOCATE
470 # ifdef HAVE_FALLOC_FL_PUNCH_HOLE
471         if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, pos, len) == 0) {
472                 if (do_lseek(fd, len, SEEK_CUR) != pos + len)
473                         return -1;
474                 return 0;
475         }
476 # endif
477 # ifdef HAVE_FALLOC_FL_ZERO_RANGE
478         if (fallocate(fd, FALLOC_FL_ZERO_RANGE, pos, len) == 0) {
479                 if (do_lseek(fd, len, SEEK_CUR) != pos + len)
480                         return -1;
481                 return 0;
482         }
483 # endif
484 #endif
485         {
486                 char zeros[4096];
487                 memset(zeros, 0, sizeof zeros);
488                 while (len > 0) {
489                         int chunk = len > (int)sizeof zeros ? (int)sizeof zeros : len;
490                         int wrote = write(fd, zeros, chunk);
491                         if (wrote <= 0) {
492                                 if (wrote < 0 && errno == EINTR)
493                                         continue;
494                                 return -1;
495                         }
496                         len -= wrote;
497                 }
498         }
499         return 0;
500 }
501
502 int do_open_nofollow(const char *pathname, int flags)
503 {
504 #ifndef O_NOFOLLOW
505         STRUCT_STAT f_st, l_st;
506 #endif
507         int fd;
508
509         if (flags != O_RDONLY) {
510                 RETURN_ERROR_IF(dry_run, 0);
511                 RETURN_ERROR_IF_RO_OR_LO;
512 #ifndef O_NOFOLLOW
513                 /* This function doesn't support write attempts w/o O_NOFOLLOW. */
514                 errno = EINVAL;
515                 return -1;
516 #endif
517         }
518
519 #ifdef O_NOFOLLOW
520         fd = open(pathname, flags|O_NOFOLLOW);
521 #else
522         if (do_lstat(pathname, &l_st) < 0)
523                 return -1;
524         if (S_ISLNK(l_st.st_mode)) {
525                 errno = ELOOP;
526                 return -1;
527         }
528         if ((fd = open(pathname, flags)) < 0)
529                 return fd;
530         if (do_fstat(fd, &f_st) < 0) {
531           close_and_return_error:
532                 {
533                         int save_errno = errno;
534                         close(fd);
535                         errno = save_errno;
536                 }
537                 return -1;
538         }
539         if (l_st.st_dev != f_st.st_dev || l_st.st_ino != f_st.st_ino) {
540                 errno = EINVAL;
541                 goto close_and_return_error;
542         }
543 #endif
544
545         return fd;
546 }