View | Details | Raw Unified | Return to bug 24497
Collapse All | Expand All

(-)a/flist.c (-3 / +27 lines)
Lines 63-68 extern int non_perishable_cnt; Link Here
63
extern int prune_empty_dirs;
63
extern int prune_empty_dirs;
64
extern int copy_links;
64
extern int copy_links;
65
extern int copy_unsafe_links;
65
extern int copy_unsafe_links;
66
extern int rw_devices;
66
extern int protocol_version;
67
extern int protocol_version;
67
extern int sanitize_paths;
68
extern int sanitize_paths;
68
extern int munge_symlinks;
69
extern int munge_symlinks;
Lines 228-234 static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf) Link Here
228
#endif
229
#endif
229
}
230
}
230
int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
231
static int link_stat2(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
231
{
232
{
232
#ifdef SUPPORT_LINKS
233
#ifdef SUPPORT_LINKS
233
       if (copy_links)
234
       if (copy_links)
Lines 246-251 int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks) Link Here
246
#endif
247
#endif
247
}
248
}
249
int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
250
{
251
       if (link_stat2(path, stp, follow_dirlinks) != 0)
252
               return -1;
253
       if (rw_devices && S_ISBLK(stp->st_mode) && stp->st_size == 0) {
254
               /* On Linux systems (at least), st_size is typically 0 for devices.
255
                * If so, try to determine the actual device size. */
256
               int fdx = do_open(path, O_RDONLY, 0);
257
               if (fdx == -1)
258
                       rsyserr(FERROR, errno, "failed to open device %s to determine size", path);
259
               else {
260
                       OFF_T off = lseek(fdx, 0, SEEK_END);
261
                       if (off == (OFF_T)-1)
262
                               rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", path);
263
                       else
264
                               stp->st_size = off;
265
                       close(fdx);
266
               }
267
       }
268
       return 0;
269
}
270
248
static inline int is_daemon_excluded(const char *fname, int is_dir)
271
static inline int is_daemon_excluded(const char *fname, int is_dir)
249
{
272
{
250
       if (daemon_filter_list.head
273
       if (daemon_filter_list.head
Lines 671-677 static void send_file_entry(int f, const char *fname, struct file_struct *file, Link Here
671
#endif
694
#endif
672
       strlcpy(lastname, fname, MAXPATHLEN);
695
       strlcpy(lastname, fname, MAXPATHLEN);
673
       if (S_ISREG(mode) || S_ISLNK(mode))
696
       if (S_ISREG(mode) || S_ISLNK(mode) || (rw_devices && S_ISBLK(mode)))
674
               stats.total_size += F_LENGTH(file);
697
               stats.total_size += F_LENGTH(file);
675
}
698
}
Lines 1351-1357 struct file_struct *make_file(const char *fname, struct file_list *flist, Link Here
1351
#ifdef HAVE_STRUCT_STAT_ST_RDEV
1374
#ifdef HAVE_STRUCT_STAT_ST_RDEV
1352
       if (IS_DEVICE(st.st_mode)) {
1375
       if (IS_DEVICE(st.st_mode)) {
1353
               tmp_rdev = st.st_rdev;
1376
               tmp_rdev = st.st_rdev;
1354
               st.st_size = 0;
1377
               if (!rw_devices || !S_ISBLK(st.st_mode))
1378
                       st.st_size = 0;
1355
       } else if (IS_SPECIAL(st.st_mode))
1379
       } else if (IS_SPECIAL(st.st_mode))
1356
               st.st_size = 0;
1380
               st.st_size = 0;
1357
#endif
1381
#endif
(-)a/generator.c (-2 / +20 lines)
Lines 39-44 extern int preserve_acls; Link Here
39
extern int preserve_xattrs;
39
extern int preserve_xattrs;
40
extern int preserve_links;
40
extern int preserve_links;
41
extern int preserve_devices;
41
extern int preserve_devices;
42
extern int rw_devices;
42
extern int preserve_specials;
43
extern int preserve_specials;
43
extern int preserve_hard_links;
44
extern int preserve_hard_links;
44
extern int preserve_executability;
45
extern int preserve_executability;
Lines 1181-1186 static void recv_generator(char *fname, struct file_struct *file, int ndx, Link Here
1181
               statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
1182
               statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
1182
               stat_errno = errno;
1183
               stat_errno = errno;
1184
1185
               if (statret == 0 && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) {
1186
                       /* On Linux systems (at least), st_size is typically 0 for devices.
1187
                        * If so, try to determine the actual device size. */
1188
                       int fdx = do_open(fname, O_RDONLY, 0);
1189
                       if ( fdx == -1 ) {
1190
                               rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
1191
                       }
1192
                       else {
1193
                               OFF_T off = lseek(fdx, 0, SEEK_END);
1194
                               if (off == (OFF_T)-1)
1195
                                       rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
1196
                               else
1197
                                       sx.st.st_size = off;
1198
                               close(fdx);
1199
                       }
1200
               }
1183
       }
1201
       }
1184
       if (missing_args == 2 && file->mode == 0) {
1202
       if (missing_args == 2 && file->mode == 0) {
Lines 1494-1500 static void recv_generator(char *fname, struct file_struct *file, int ndx, Link Here
1494
               goto cleanup;
1512
               goto cleanup;
1495
       }
1513
       }
1496
       if (!S_ISREG(file->mode)) {
1514
       if (!(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) {
1497
               if (solo_file)
1515
               if (solo_file)
1498
                       fname = f_name(file, NULL);
1516
                       fname = f_name(file, NULL);
1499
               rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
1517
               rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
Lines 1532-1538 static void recv_generator(char *fname, struct file_struct *file, int ndx, Link Here
1532
       fnamecmp = fname;
1550
       fnamecmp = fname;
1533
       fnamecmp_type = FNAMECMP_FNAME;
1551
       fnamecmp_type = FNAMECMP_FNAME;
1534
       if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
1552
       if (statret == 0 && !(S_ISREG(sx.st.st_mode) || (rw_devices && IS_DEVICE(sx.st.st_mode)))) {
1535
               if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
1553
               if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
1536
                       goto cleanup;
1554
                       goto cleanup;
1537
               statret = -1;
1555
               statret = -1;
(-)a/options.c (+11 lines)
Lines 48-53 int append_mode = 0; Link Here
48
int keep_dirlinks = 0;
48
int keep_dirlinks = 0;
49
int copy_dirlinks = 0;
49
int copy_dirlinks = 0;
50
int copy_links = 0;
50
int copy_links = 0;
51
int rw_devices = 0;
51
int preserve_links = 0;
52
int preserve_links = 0;
52
int preserve_hard_links = 0;
53
int preserve_hard_links = 0;
53
int preserve_acls = 0;
54
int preserve_acls = 0;
Lines 695-700 void usage(enum logcode F) Link Here
695
  rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
696
  rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
696
  rprintf(F," -g, --group                 preserve group\n");
697
  rprintf(F," -g, --group                 preserve group\n");
697
  rprintf(F,"     --devices               preserve device files (super-user only)\n");
698
  rprintf(F,"     --devices               preserve device files (super-user only)\n");
699
  rprintf(F,"     --rw-devices            read/write device contents as regular file (implies --inplace)\n");
698
  rprintf(F,"     --specials              preserve special files\n");
700
  rprintf(F,"     --specials              preserve special files\n");
699
  rprintf(F," -D                          same as --devices --specials\n");
701
  rprintf(F," -D                          same as --devices --specials\n");
700
  rprintf(F," -t, --times                 preserve modification times\n");
702
  rprintf(F," -t, --times                 preserve modification times\n");
Lines 863-868 static struct poptOption long_options[] = { Link Here
863
  {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
865
  {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
864
  {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
866
  {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
865
  {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
867
  {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
868
  {"rw-devices",       0,  POPT_ARG_NONE,   &rw_devices, 0, 0, 0 },
866
  {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
869
  {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
867
  {"no-specials",      0,  POPT_ARG_VAL,    &preserve_specials, 0, 0, 0 },
870
  {"no-specials",      0,  POPT_ARG_VAL,    &preserve_specials, 0, 0, 0 },
868
  {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
871
  {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
Lines 1801-1806 int parse_arguments(int *argc_p, const char ***argv_p) Link Here
1801
       set_output_verbosity(verbose, DEFAULT_PRIORITY);
1804
       set_output_verbosity(verbose, DEFAULT_PRIORITY);
1805
       if (rw_devices) {
1806
               inplace = 1;
1807
               ignore_times = 1;
1808
       }
1809
1802
       if (do_stats) {
1810
       if (do_stats) {
1803
               parse_output_words(info_words, info_levels,
1811
               parse_output_words(info_words, info_levels,
1804
                       verbose > 1 ? "stats3" : "stats2", DEFAULT_PRIORITY);
1812
                       verbose > 1 ? "stats3" : "stats2", DEFAULT_PRIORITY);
Lines 2661-2666 void server_options(char **args, int *argc_p) Link Here
2661
       else if (remove_source_files)
2669
       else if (remove_source_files)
2662
               args[ac++] = "--remove-sent-files";
2670
               args[ac++] = "--remove-sent-files";
2671
       if (rw_devices)
2672
               args[ac++] = "--rw-devices";
2673
2663
       if (ac > MAX_SERVER_ARGS) { /* Not possible... */
2674
       if (ac > MAX_SERVER_ARGS) { /* Not possible... */
2664
               rprintf(FERROR, "argc overflow in server_options().\n");
2675
               rprintf(FERROR, "argc overflow in server_options().\n");
2665
               exit_cleanup(RERR_MALLOC);
2676
               exit_cleanup(RERR_MALLOC);
(-)a/receiver.c (-5 / +25 lines)
Lines 37-42 extern int protocol_version; Link Here
37
extern int relative_paths;
37
extern int relative_paths;
38
extern int preserve_hard_links;
38
extern int preserve_hard_links;
39
extern int preserve_perms;
39
extern int preserve_perms;
40
extern int rw_devices;
40
extern int preserve_xattrs;
41
extern int preserve_xattrs;
41
extern int basis_dir_cnt;
42
extern int basis_dir_cnt;
42
extern int make_backups;
43
extern int make_backups;
Lines 199-204 int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file) Link Here
199
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
200
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
200
                       const char *fname, int fd, OFF_T total_size)
201
                       const char *fname, int fd, OFF_T total_size)
201
{
202
{
203
       STRUCT_STAT st;
202
       static char file_sum1[MAX_DIGEST_LEN];
204
       static char file_sum1[MAX_DIGEST_LEN];
203
       struct map_struct *mapbuf;
205
       struct map_struct *mapbuf;
204
       struct sum_struct sum;
206
       struct sum_struct sum;
Lines 321-330 static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r, Link Here
321
               goto report_write_error;
323
               goto report_write_error;
322
#ifdef HAVE_FTRUNCATE
324
#ifdef HAVE_FTRUNCATE
323
       if (inplace && fd != -1
325
       (void)do_fstat(fd,&st);
324
        && ftruncate(fd, offset) < 0) {
326
       /* Makes no sense to attempt to ftruncate() a block device: */
325
               rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
327
       if (!(IS_DEVICE(st.st_mode))) {
326
                       full_fname(fname));
328
               if (inplace && fd != -1
329
                && ftruncate(fd, offset) < 0) {
330
                       rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
331
                               full_fname(fname));
332
               }
327
       }
333
       }
328
#endif
334
#endif
Lines 732-742 int recv_files(int f_in, int f_out, char *local_name) Link Here
732
                       continue;
738
                       continue;
733
               }
739
               }
734
               if (fd1 != -1 && !S_ISREG(st.st_mode)) {
740
               if (fd1 != -1 && !(S_ISREG(st.st_mode) || (rw_devices && IS_DEVICE(st.st_mode)))) {
735
                       close(fd1);
741
                       close(fd1);
736
                       fd1 = -1;
742
                       fd1 = -1;
737
               }
743
               }
744
               /* On Linux systems (at least), st_size is typically 0 for devices.
745
                * If so, try to determine the actual device size. */
746
               if (fd1 != -1 && IS_DEVICE(st.st_mode) && st.st_size == 0) {
747
                       OFF_T off = lseek(fd1, 0, SEEK_END);
748
                       if (off == (OFF_T) -1)
749
                               rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
750
                       else {
751
                               st.st_size = off;
752
                               off = lseek(fd1, 0, SEEK_SET);
753
                               if (off != 0)
754
                                       rsyserr(FERROR, errno, "failed to seek back to beginning of %s to read it", fname);
755
                       }
756
               }
757
738
               /* If we're not preserving permissions, change the file-list's
758
               /* If we're not preserving permissions, change the file-list's
739
                * mode based on the local permissions and some heuristics. */
759
                * mode based on the local permissions and some heuristics. */
740
               if (!preserve_perms) {
760
               if (!preserve_perms) {
(-)a/rsync.c (-1 / +3 lines)
Lines 33-38 extern int preserve_xattrs; Link Here
33
extern int preserve_perms;
33
extern int preserve_perms;
34
extern int preserve_executability;
34
extern int preserve_executability;
35
extern int preserve_times;
35
extern int preserve_times;
36
extern int rw_devices;
36
extern int am_root;
37
extern int am_root;
37
extern int am_server;
38
extern int am_server;
38
extern int am_sender;
39
extern int am_sender;
Lines 397-403 int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr, Link Here
397
       if (iflags & ITEM_TRANSFER) {
398
       if (iflags & ITEM_TRANSFER) {
398
               int i = ndx - cur_flist->ndx_start;
399
               int i = ndx - cur_flist->ndx_start;
399
               if (i < 0 || !S_ISREG(cur_flist->files[i]->mode)) {
400
               struct file_struct *file = cur_flist->files[i];
401
               if (i < 0 || !(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) {
400
                       rprintf(FERROR,
402
                       rprintf(FERROR,
401
                               "received request to transfer non-regular file: %d [%s]\n",
403
                               "received request to transfer non-regular file: %d [%s]\n",
402
                               ndx, who_am_i());
404
                               ndx, who_am_i());
(-)a/syscall.c (-6 / +63 lines)
Lines 36-41 extern int read_only; Link Here
36
extern int list_only;
36
extern int list_only;
37
extern int preserve_perms;
37
extern int preserve_perms;
38
extern int preserve_executability;
38
extern int preserve_executability;
39
extern int rw_devices;
39
#define RETURN_ERROR_IF(x,e) \
40
#define RETURN_ERROR_IF(x,e) \
40
       do { \
41
       do { \
Lines 286-305 int do_mkstemp(char *template, mode_t perms) Link Here
286
int do_stat(const char *fname, STRUCT_STAT *st)
287
int do_stat(const char *fname, STRUCT_STAT *st)
287
{
288
{
288
#ifdef USE_STAT64_FUNCS
289
#ifdef USE_STAT64_FUNCS
289
       return stat64(fname, st);
290
       if (stat64(fname, st) != 0)
291
               return -1;
290
#else
292
#else
291
       return stat(fname, st);
293
       if (stat(fname, st) != 0)
294
               return -1;
292
#endif
295
#endif
296
       if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
297
               /* On Linux systems (at least), st_size is typically 0 for devices.
298
                * If so, try to determine the actual device size. */
299
               int fdx = do_open(fname, O_RDONLY, 0);
300
               if (fdx == -1)
301
                       rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
302
               else {
303
                       OFF_T off = lseek(fdx, 0, SEEK_END);
304
                       if (off == (OFF_T)-1)
305
                               rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
306
                       else
307
                               st->st_size = off;
308
                       close(fdx);
309
               }
310
       }
311
       return 0;
293
}
312
}
294
int do_lstat(const char *fname, STRUCT_STAT *st)
313
int do_lstat(const char *fname, STRUCT_STAT *st)
295
{
314
{
296
#ifdef SUPPORT_LINKS
315
#ifdef SUPPORT_LINKS
297
# ifdef USE_STAT64_FUNCS
316
# ifdef USE_STAT64_FUNCS
298
       return lstat64(fname, st);
317
       if (lstat64(fname, st) != 0)
318
               return -1;
299
# else
319
# else
300
       return lstat(fname, st);
320
       if (lstat(fname, st) != 0)
321
               return -1;
301
# endif
322
# endif
323
       if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
324
               /* On Linux systems (at least), st_size is typically 0 for devices.
325
                * If so, try to determine the actual device size. */
326
               int fdx = do_open(fname, O_RDONLY, 0);
327
               if (fdx == -1)
328
                       rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
329
               else {
330
                       OFF_T off = lseek(fdx, 0, SEEK_END);
331
                       if (off == (OFF_T)-1)
332
                               rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
333
                       else
334
                               st->st_size = off;
335
                       close(fdx);
336
               }
337
       }
338
       return 0;
302
#else
339
#else
303
       return do_stat(fname, st);
340
       return do_stat(fname, st);
304
#endif
341
#endif
Lines 308-317 int do_lstat(const char *fname, STRUCT_STAT *st) Link Here
308
int do_fstat(int fd, STRUCT_STAT *st)
345
int do_fstat(int fd, STRUCT_STAT *st)
309
{
346
{
310
#ifdef USE_STAT64_FUNCS
347
#ifdef USE_STAT64_FUNCS
311
       return fstat64(fd, st);
348
       if (fstat64(fd, st) != 0)
349
               return -1;
312
#else
350
#else
313
       return fstat(fd, st);
351
       if (fstat(fd, st) != 0)
352
               return -1;
314
#endif
353
#endif
354
       if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
355
               /* On Linux systems (at least), st_size is typically 0 for devices.
356
                * If so, try to determine the actual device size. */
357
               OFF_T off_save = lseek(fd, 0, SEEK_CUR);
358
               if (off_save == (OFF_T)-1)
359
                       rsyserr(FERROR, errno, "failed to seek on device inode %lld to read current position", (long long int)(st->st_ino));
360
               else {
361
                       OFF_T off = lseek(fd, 0, SEEK_END);
362
                       if (off == (OFF_T)-1)
363
                               rsyserr(FERROR, errno, "failed to seek to end on device inode %lld to determine size", (long long int)(st->st_ino));
364
                       else
365
                               st->st_size = off;
366
                       off = lseek(fd, off_save, SEEK_SET);
367
                       if (off == (OFF_T)-1)
368
                               rsyserr(FERROR, errno, "failed to seek to origin position on device inode %lld", (long long int)(st->st_ino));
369
               }
370
       }
371
       return 0;
315
}
372
}
316
OFF_T do_lseek(int fd, OFF_T offset, int whence)
373
OFF_T do_lseek(int fd, OFF_T offset, int whence)

Return to bug 24497