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

(-)rsync-c31e3fd/flist.c (-3 / +27 lines)
Lines 63-68 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 216-222 Link Here
216
#endif
217
#endif
217
}
218
}
218
219
219
int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
220
static int link_stat2(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
220
{
221
{
221
#ifdef SUPPORT_LINKS
222
#ifdef SUPPORT_LINKS
222
	if (copy_links)
223
	if (copy_links)
Lines 234-239 Link Here
234
#endif
235
#endif
235
}
236
}
236
237
238
int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
239
{
240
       if (link_stat2(path, stp, follow_dirlinks) != 0)
241
               return -1;
242
       if (rw_devices && S_ISBLK(stp->st_mode) && stp->st_size == 0) {
243
               /* On Linux systems (at least), st_size is typically 0 for devices.
244
                * If so, try to determine the actual device size. */
245
               int fdx = do_open(path, O_RDONLY, 0);
246
               if (fdx == -1)
247
                       rsyserr(FERROR, errno, "failed to open device %s to determine size", path);
248
               else {
249
                       OFF_T off = lseek(fdx, 0, SEEK_END);
250
                       if (off == (OFF_T)-1)
251
                               rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", path);
252
                       else
253
                               stp->st_size = off;
254
                       close(fdx);
255
               }
256
       }
257
       return 0;
258
}
259
237
static inline int is_daemon_excluded(const char *fname, int is_dir)
260
static inline int is_daemon_excluded(const char *fname, int is_dir)
238
{
261
{
239
	if (daemon_filter_list.head
262
	if (daemon_filter_list.head
Lines 626-632 Link Here
626
  the_end:
649
  the_end:
627
	strlcpy(lastname, fname, MAXPATHLEN);
650
	strlcpy(lastname, fname, MAXPATHLEN);
628
651
629
	if (S_ISREG(mode) || S_ISLNK(mode))
652
	if (S_ISREG(mode) || S_ISLNK(mode) || (rw_devices && S_ISBLK(mode)))
630
		stats.total_size += F_LENGTH(file);
653
		stats.total_size += F_LENGTH(file);
631
}
654
}
632
655
Lines 1269-1275 Link Here
1269
#ifdef HAVE_STRUCT_STAT_ST_RDEV
1292
#ifdef HAVE_STRUCT_STAT_ST_RDEV
1270
	if (IS_DEVICE(st.st_mode)) {
1293
	if (IS_DEVICE(st.st_mode)) {
1271
		tmp_rdev = st.st_rdev;
1294
		tmp_rdev = st.st_rdev;
1272
		st.st_size = 0;
1295
		if (!rw_devices || !S_ISBLK(st.st_mode))
1296
			st.st_size = 0;
1273
	} else if (IS_SPECIAL(st.st_mode))
1297
	} else if (IS_SPECIAL(st.st_mode))
1274
		st.st_size = 0;
1298
		st.st_size = 0;
1275
#endif
1299
#endif
(-)rsync-c31e3fd/generator.c (-2 / +20 lines)
Lines 39-44 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 1367-1372 Link Here
1367
1368
1368
		statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
1369
		statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
1369
		stat_errno = errno;
1370
		stat_errno = errno;
1371
1372
		if (statret == 0 && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) {
1373
			/* On Linux systems (at least), st_size is typically 0 for devices.
1374
			* If so, try to determine the actual device size. */
1375
			int fdx = do_open(fname, O_RDONLY, 0);
1376
			if ( fdx == -1 ) {
1377
				rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
1378
			}
1379
			else {
1380
				OFF_T off = lseek(fdx, 0, SEEK_END);
1381
				if (off == (OFF_T)-1)
1382
					rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
1383
				else
1384
					sx.st.st_size = off;
1385
				close(fdx);
1386
			}
1387
		}
1370
	}
1388
	}
1371
1389
1372
	if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) {
1390
	if (ignore_non_existing > 0 && statret == -1 && stat_errno == ENOENT) {
Lines 1695-1701 Link Here
1695
		goto cleanup;
1713
		goto cleanup;
1696
	}
1714
	}
1697
1715
1698
	if (!S_ISREG(file->mode)) {
1716
	if (!(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) {
1699
		if (solo_file)
1717
		if (solo_file)
1700
			fname = f_name(file, NULL);
1718
			fname = f_name(file, NULL);
1701
		rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
1719
		rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
Lines 1733-1739 Link Here
1733
	fnamecmp = fname;
1751
	fnamecmp = fname;
1734
	fnamecmp_type = FNAMECMP_FNAME;
1752
	fnamecmp_type = FNAMECMP_FNAME;
1735
1753
1736
	if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
1754
	if (statret == 0 && !(S_ISREG(sx.st.st_mode) || (rw_devices && IS_DEVICE(sx.st.st_mode)))) {
1737
		if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
1755
		if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
1738
			goto cleanup;
1756
			goto cleanup;
1739
		statret = -1;
1757
		statret = -1;
(-)rsync-c31e3fd/options.c (+11 lines)
Lines 48-53 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 351-356 Link Here
351
  rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
352
  rprintf(F," -o, --owner                 preserve owner (super-user only)\n");
352
  rprintf(F," -g, --group                 preserve group\n");
353
  rprintf(F," -g, --group                 preserve group\n");
353
  rprintf(F,"     --devices               preserve device files (super-user only)\n");
354
  rprintf(F,"     --devices               preserve device files (super-user only)\n");
355
  rprintf(F,"     --rw-devices            read/write device contents as regular file (implies --inplace)\n");
354
  rprintf(F,"     --specials              preserve special files\n");
356
  rprintf(F,"     --specials              preserve special files\n");
355
  rprintf(F," -D                          same as --devices --specials\n");
357
  rprintf(F," -D                          same as --devices --specials\n");
356
  rprintf(F," -t, --times                 preserve modification times\n");
358
  rprintf(F," -t, --times                 preserve modification times\n");
Lines 509-514 Link Here
509
  {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
511
  {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
510
  {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
512
  {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
511
  {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
513
  {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
514
  {"rw-devices",       0,  POPT_ARG_NONE,   &rw_devices, 0, 0, 0 },
512
  {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
515
  {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
513
  {"no-specials",      0,  POPT_ARG_VAL,    &preserve_specials, 0, 0, 0 },
516
  {"no-specials",      0,  POPT_ARG_VAL,    &preserve_specials, 0, 0, 0 },
514
  {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
517
  {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
Lines 1284-1289 Link Here
1284
		exit_cleanup(0);
1287
		exit_cleanup(0);
1285
	}
1288
	}
1286
1289
1290
	if (rw_devices) {
1291
		inplace = 1;
1292
		ignore_times = 1;
1293
	}
1294
1287
#ifdef ICONV_OPTION
1295
#ifdef ICONV_OPTION
1288
	if (iconv_opt && protect_args != 2) {
1296
	if (iconv_opt && protect_args != 2) {
1289
		if (!am_server && strcmp(iconv_opt, "-") == 0)
1297
		if (!am_server && strcmp(iconv_opt, "-") == 0)
Lines 2072-2077 Link Here
2072
	else if (remove_source_files)
2080
	else if (remove_source_files)
2073
		args[ac++] = "--remove-sent-files";
2081
		args[ac++] = "--remove-sent-files";
2074
2082
2083
	if (rw_devices)
2084
		args[ac++] = "--rw-devices";
2085
2075
	if (ac > MAX_SERVER_ARGS) { /* Not possible... */
2086
	if (ac > MAX_SERVER_ARGS) { /* Not possible... */
2076
		rprintf(FERROR, "argc overflow in server_options().\n");
2087
		rprintf(FERROR, "argc overflow in server_options().\n");
2077
		exit_cleanup(RERR_MALLOC);
2088
		exit_cleanup(RERR_MALLOC);
(-)rsync-c31e3fd/receiver.c (-5 / +25 lines)
Lines 38-43 Link Here
38
extern int relative_paths;
38
extern int relative_paths;
39
extern int preserve_hard_links;
39
extern int preserve_hard_links;
40
extern int preserve_perms;
40
extern int preserve_perms;
41
extern int rw_devices;
41
extern int preserve_xattrs;
42
extern int preserve_xattrs;
42
extern int basis_dir_cnt;
43
extern int basis_dir_cnt;
43
extern int make_backups;
44
extern int make_backups;
Lines 166-171 Link Here
166
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
167
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
167
			const char *fname, int fd, OFF_T total_size)
168
			const char *fname, int fd, OFF_T total_size)
168
{
169
{
170
	STRUCT_STAT st;
169
	static char file_sum1[MAX_DIGEST_LEN];
171
	static char file_sum1[MAX_DIGEST_LEN];
170
	static char file_sum2[MAX_DIGEST_LEN];
172
	static char file_sum2[MAX_DIGEST_LEN];
171
	struct map_struct *mapbuf;
173
	struct map_struct *mapbuf;
Lines 286-295 Link Here
286
		goto report_write_error;
288
		goto report_write_error;
287
289
288
#ifdef HAVE_FTRUNCATE
290
#ifdef HAVE_FTRUNCATE
289
	if (inplace && fd != -1
291
	(void)do_fstat(fd,&st);
290
	 && ftruncate(fd, offset) < 0) {
292
	/* Makes no sense to attempt to ftruncate() a block device: */
291
		rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
293
	if (!(IS_DEVICE(st.st_mode))) {
292
			full_fname(fname));
294
		if (inplace && fd != -1
295
		&& ftruncate(fd, offset) < 0) {
296
			rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
297
				full_fname(fname));
298
		}
293
	}
299
	}
294
#endif
300
#endif
295
301
Lines 669-679 Link Here
669
			continue;
675
			continue;
670
		}
676
		}
671
677
672
		if (fd1 != -1 && !S_ISREG(st.st_mode)) {
678
		if (fd1 != -1 && !(S_ISREG(st.st_mode) || (rw_devices && IS_DEVICE(st.st_mode)))) {
673
			close(fd1);
679
			close(fd1);
674
			fd1 = -1;
680
			fd1 = -1;
675
		}
681
		}
676
682
683
		/* On Linux systems (at least), st_size is typically 0 for devices.
684
		* If so, try to determine the actual device size. */
685
		if (fd1 != -1 && IS_DEVICE(st.st_mode) && st.st_size == 0) {
686
			OFF_T off = lseek(fd1, 0, SEEK_END);
687
			if (off == (OFF_T) -1)
688
				rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
689
			else {
690
				st.st_size = off;
691
				off = lseek(fd1, 0, SEEK_SET);
692
				if (off != 0)
693
					rsyserr(FERROR, errno, "failed to seek back to beginning of %s to read it", fname);
694
			}
695
		}
696
677
		/* If we're not preserving permissions, change the file-list's
697
		/* If we're not preserving permissions, change the file-list's
678
		 * mode based on the local permissions and some heuristics. */
698
		 * mode based on the local permissions and some heuristics. */
679
		if (!preserve_perms) {
699
		if (!preserve_perms) {
(-)rsync-c31e3fd/rsync.c (-1 / +3 lines)
Lines 34-39 Link Here
34
extern int preserve_perms;
34
extern int preserve_perms;
35
extern int preserve_executability;
35
extern int preserve_executability;
36
extern int preserve_times;
36
extern int preserve_times;
37
extern int rw_devices;
37
extern int am_root;
38
extern int am_root;
38
extern int am_server;
39
extern int am_server;
39
extern int am_sender;
40
extern int am_sender;
Lines 328-334 Link Here
328
329
329
	if (iflags & ITEM_TRANSFER) {
330
	if (iflags & ITEM_TRANSFER) {
330
		int i = ndx - cur_flist->ndx_start;
331
		int i = ndx - cur_flist->ndx_start;
331
		if (i < 0 || !S_ISREG(cur_flist->files[i]->mode)) {
332
		struct file_struct *file = cur_flist->files[i];
333
		if (i < 0 || !(S_ISREG(file->mode) || (rw_devices && IS_DEVICE(file->mode)))) {
332
			rprintf(FERROR,
334
			rprintf(FERROR,
333
				"received request to transfer non-regular file: %d [%s]\n",
335
				"received request to transfer non-regular file: %d [%s]\n",
334
				ndx, who_am_i());
336
				ndx, who_am_i());
(-)rsync-c31e3fd/syscall.c (-6 / +63 lines)
Lines 35-40 Link Here
35
extern int list_only;
35
extern int list_only;
36
extern int preserve_perms;
36
extern int preserve_perms;
37
extern int preserve_executability;
37
extern int preserve_executability;
38
extern int rw_devices;
38
39
39
#define RETURN_ERROR_IF(x,e) \
40
#define RETURN_ERROR_IF(x,e) \
40
	do { \
41
	do { \
Lines 241-260 Link Here
241
int do_stat(const char *fname, STRUCT_STAT *st)
242
int do_stat(const char *fname, STRUCT_STAT *st)
242
{
243
{
243
#ifdef USE_STAT64_FUNCS
244
#ifdef USE_STAT64_FUNCS
244
	return stat64(fname, st);
245
	if (stat64(fname, st) != 0)
246
		return -1;
245
#else
247
#else
246
	return stat(fname, st);
248
	if (stat(fname, st) != 0)
249
		return -1;
247
#endif
250
#endif
251
	if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
252
		/* On Linux systems (at least), st_size is typically 0 for devices.
253
		* If so, try to determine the actual device size. */
254
		int fdx = do_open(fname, O_RDONLY, 0);
255
		if (fdx == -1)
256
			rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
257
		else {
258
			OFF_T off = lseek(fdx, 0, SEEK_END);
259
			if (off == (OFF_T)-1)
260
				rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
261
			else
262
				st->st_size = off;
263
			close(fdx);
264
		}
265
	}
266
	return 0;
248
}
267
}
249
268
250
int do_lstat(const char *fname, STRUCT_STAT *st)
269
int do_lstat(const char *fname, STRUCT_STAT *st)
251
{
270
{
252
#ifdef SUPPORT_LINKS
271
#ifdef SUPPORT_LINKS
253
# ifdef USE_STAT64_FUNCS
272
# ifdef USE_STAT64_FUNCS
254
	return lstat64(fname, st);
273
	if (lstat64(fname, st) != 0)
274
		return -1;
255
# else
275
# else
256
	return lstat(fname, st);
276
	if (lstat(fname, st) != 0)
277
		return -1;
257
# endif
278
# endif
279
	if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
280
		/* On Linux systems (at least), st_size is typically 0 for devices.
281
		* If so, try to determine the actual device size. */
282
		int fdx = do_open(fname, O_RDONLY, 0);
283
		if (fdx == -1)
284
			rsyserr(FERROR, errno, "failed to open device %s to determine size", fname);
285
		else {
286
			OFF_T off = lseek(fdx, 0, SEEK_END);
287
			if (off == (OFF_T)-1)
288
				rsyserr(FERROR, errno, "failed to seek to end of %s to determine size", fname);
289
			else
290
				st->st_size = off;
291
			close(fdx);
292
		}
293
	}
294
	return 0;
258
#else
295
#else
259
	return do_stat(fname, st);
296
	return do_stat(fname, st);
260
#endif
297
#endif
Lines 263-272 Link Here
263
int do_fstat(int fd, STRUCT_STAT *st)
300
int do_fstat(int fd, STRUCT_STAT *st)
264
{
301
{
265
#ifdef USE_STAT64_FUNCS
302
#ifdef USE_STAT64_FUNCS
266
	return fstat64(fd, st);
303
	if (fstat64(fd, st) != 0)
304
		return -1;
267
#else
305
#else
268
	return fstat(fd, st);
306
	if (fstat(fd, st) != 0)
307
		return -1;
269
#endif
308
#endif
309
	if (rw_devices && S_ISBLK(st->st_mode) && st->st_size == 0) {
310
		/* On Linux systems (at least), st_size is typically 0 for devices.
311
		* If so, try to determine the actual device size. */
312
		OFF_T off_save = lseek(fd, 0, SEEK_CUR);
313
		if (off_save == (OFF_T)-1)
314
			rsyserr(FERROR, errno, "failed to seek on device inode %lld to read current position", (long long int)(st->st_ino));
315
		else {
316
			OFF_T off = lseek(fd, 0, SEEK_END);
317
			if (off == (OFF_T)-1)
318
				rsyserr(FERROR, errno, "failed to seek to end on device inode %lld to determine size", (long long int)(st->st_ino));
319
			else
320
				st->st_size = off;
321
			off = lseek(fd, off_save, SEEK_SET);
322
			if (off == (OFF_T)-1)
323
				rsyserr(FERROR, errno, "failed to seek to origin position on device inode %lld", (long long int)(st->st_ino));
324
		}
325
	}
326
	return 0;
270
}
327
}
271
328
272
OFF_T do_lseek(int fd, OFF_T offset, int whence)
329
OFF_T do_lseek(int fd, OFF_T offset, int whence)

Return to bug 24497