⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generator.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct file_list *dirlist;	char delbuf[MAXPATHLEN];	int dlen, i;	int save_uid_ndx = uid_ndx;	if (!fbuf) {		change_local_filter_dir(NULL, 0, 0);		return;	}	if (verbose > 2)		rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);	if (allowed_lull)		maybe_send_keepalive();	if (io_error && !ignore_errors) {		if (already_warned)			return;		rprintf(FINFO,			"IO error encountered -- skipping file deletion\n");		already_warned = 1;		return;	}	dlen = strlen(fbuf);	change_local_filter_dir(fbuf, dlen, F_DEPTH(file));	if (one_file_system) {		if (file->flags & FLAG_TOP_DIR)			filesystem_dev = *fs_dev;		else if (filesystem_dev != *fs_dev)			return;	}	if (!uid_ndx)		uid_ndx = ++file_extra_cnt;	dirlist = get_dirlist(fbuf, dlen, 0);	/* If an item in dirlist is not found in flist, delete it	 * from the filesystem. */	for (i = dirlist->used; i--; ) {		struct file_struct *fp = dirlist->files[i];		if (!F_IS_ACTIVE(fp))			continue;		if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {			if (verbose > 1)				rprintf(FINFO, "cannot delete mount point: %s\n",					f_name(fp, NULL));			continue;		}		/* Here we want to match regardless of file type.  Replacement		 * of a file with one of another type is handled separately by		 * a delete_item call with a DEL_MAKE_ROOM flag. */		if (flist_find_ignore_dirness(cur_flist, fp) < 0) {			int flags = DEL_RECURSE;			if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)				flags |= DEL_NO_UID_WRITE;			f_name(fp, delbuf);			if (delete_during == 2) {				if (!remember_delete(fp, delbuf, flags))					break;			} else				delete_item(delbuf, fp->mode, flags);		}	}	flist_free(dirlist);	if (!save_uid_ndx) {		--file_extra_cnt;		uid_ndx = 0;	}}/* This deletes any files on the receiving side that are not present on the * sending side.  This is used by --delete-before and --delete-after. */static void do_delete_pass(void){	char fbuf[MAXPATHLEN];	STRUCT_STAT st;	int j;	/* dry_run is incremented when the destination doesn't exist yet. */	if (dry_run > 1 || list_only)		return;	for (j = 0; j < cur_flist->used; j++) {		struct file_struct *file = cur_flist->sorted[j];		f_name(file, fbuf);		if (!(file->flags & FLAG_CONTENT_DIR)) {			change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(file));			continue;		}		if (verbose > 1 && file->flags & FLAG_TOP_DIR)			rprintf(FINFO, "deleting in %s\n", fbuf);		if (link_stat(fbuf, &st, keep_dirlinks) < 0		 || !S_ISDIR(st.st_mode))			continue;		delete_in_dir(fbuf, file, &st.st_dev);	}	delete_in_dir(NULL, NULL, &dev_zero);	if (do_progress && !am_server)		rprintf(FINFO, "                    \r");}int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp){#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES	if (S_ISLNK(file->mode)) {		;	} else#endif	if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)		return 0;	if (preserve_perms) {		if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))			return 0;	} else if (preserve_executability	 && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))		return 0;	if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))		return 0;	if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))		return 0;#ifdef SUPPORT_ACLS	if (preserve_acls && !S_ISLNK(file->mode)) {		if (!ACL_READY(*sxp))			get_acl(fname, sxp);		if (set_acl(NULL, file, sxp) == 0)			return 0;	}#endif#ifdef SUPPORT_XATTRS	if (preserve_xattrs) {		if (!XATTR_READY(*sxp))			get_xattr(fname, sxp);		if (xattr_diff(file, sxp, 0))			return 0;	}#endif	return 1;}void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret,	     stat_x *sxp, int32 iflags, uchar fnamecmp_type,	     const char *xname){	if (statret >= 0) { /* A from-dest-dir statret can == 1! */		int keep_time = !preserve_times ? 0		    : S_ISDIR(file->mode) ? preserve_times > 1 :#if defined HAVE_LUTIMES && defined HAVE_UTIMES		    1;#else		    !S_ISLNK(file->mode);#endif		if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)			iflags |= ITEM_REPORT_SIZE;		if (file->flags & FLAG_TIME_FAILED) { /* symlinks only */			if (iflags & ITEM_LOCAL_CHANGE)				iflags |= symlink_timeset_failed_flags;		} else if (keep_time		 ? cmp_time(file->modtime, sxp->st.st_mtime) != 0		 : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)		  && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))			iflags |= ITEM_REPORT_TIME;#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST		if (S_ISLNK(file->mode)) {			;		} else#endif		if (preserve_perms) {			if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))				iflags |= ITEM_REPORT_PERMS;		} else if (preserve_executability		 && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))			iflags |= ITEM_REPORT_PERMS;		if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)			iflags |= ITEM_REPORT_OWNER;		if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)		    && sxp->st.st_gid != (gid_t)F_GROUP(file))			iflags |= ITEM_REPORT_GROUP;#ifdef SUPPORT_ACLS		if (preserve_acls && !S_ISLNK(file->mode)) {			if (!ACL_READY(*sxp))				get_acl(fnamecmp, sxp);			if (set_acl(NULL, file, sxp) == 0)				iflags |= ITEM_REPORT_ACL;		}#endif#ifdef SUPPORT_XATTRS		if (preserve_xattrs) {			if (!XATTR_READY(*sxp))				get_xattr(fnamecmp, sxp);			if (xattr_diff(file, sxp, 1))				iflags |= ITEM_REPORT_XATTR;		}#endif	} else {#ifdef SUPPORT_XATTRS		if (preserve_xattrs && xattr_diff(file, NULL, 1))			iflags |= ITEM_REPORT_XATTR;#endif		iflags |= ITEM_IS_NEW;	}	iflags &= 0xffff;	if ((iflags & (SIGNIFICANT_ITEM_FLAGS|ITEM_REPORT_XATTR) || verbose > 1	  || stdout_format_has_i > 1 || (xname && *xname)) && !read_batch) {		if (protocol_version >= 29) {			if (ndx >= 0)				write_ndx(sock_f_out, ndx);			write_shortint(sock_f_out, iflags);			if (iflags & ITEM_BASIS_TYPE_FOLLOWS)				write_byte(sock_f_out, fnamecmp_type);			if (iflags & ITEM_XNAME_FOLLOWS)				write_vstring(sock_f_out, xname, strlen(xname));#ifdef SUPPORT_XATTRS			if (preserve_xattrs && !dry_run			 && iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {				send_xattr_request(NULL, file,					iflags & ITEM_REPORT_XATTR ? sock_f_out : -1);			}#endif		} else if (ndx >= 0) {			enum logcode code = logfile_format_has_i ? FINFO : FCLIENT;			log_item(code, file, &stats, iflags, xname);		}	}}/* Perform our quick-check heuristic for determining if a file is unchanged. */int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st){	if (st->st_size != F_LENGTH(file))		return 0;	/* if always checksum is set then we use the checksum instead	   of the file time to determine whether to sync */	if (always_checksum > 0 && S_ISREG(st->st_mode)) {		char sum[MAX_DIGEST_LEN];		file_checksum(fn, sum, st->st_size);		return memcmp(sum, F_SUM(file), checksum_len) == 0;	}	if (size_only > 0)		return 1;	if (ignore_times)		return 0;	return cmp_time(st->st_mtime, file->modtime) == 0;}/* * set (initialize) the size entries in the per-file sum_struct * calculating dynamic block and checksum sizes. * * This is only called from generate_and_send_sums() but is a separate * function to encapsulate the logic. * * The block size is a rounded square root of file length. * * The checksum size is determined according to: *     blocksum_bits = BLOCKSUM_BIAS + 2*log2(file_len) - log2(block_len) * provided by Donovan Baarda which gives a probability of rsync * algorithm corrupting data and falling back using the whole md4 * checksums. * * This might be made one of several selectable heuristics. */static void sum_sizes_sqroot(struct sum_struct *sum, int64 len){	int32 blength;	int s2length;	int64 l;	if (block_size)		blength = block_size;	else if (len <= BLOCK_SIZE * BLOCK_SIZE)		blength = BLOCK_SIZE;	else {		int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;		int32 c;		int cnt;		for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}		if (c < 0 || c >= max_blength)			blength = max_blength;		else {		    blength = 0;		    do {			    blength |= c;			    if (len < (int64)blength * blength)				    blength &= ~c;			    c >>= 1;		    } while (c >= 8);	/* round to multiple of 8 */		    blength = MAX(blength, BLOCK_SIZE);		}	}	if (protocol_version < 27) {		s2length = csum_length;	} else if (csum_length == SUM_LENGTH) {		s2length = SUM_LENGTH;	} else {		int32 c;		int b = BLOCKSUM_BIAS;		for (l = len; l >>= 1; b += 2) {}		for (c = blength; (c >>= 1) && b; b--) {}		/* add a bit, subtract rollsum, round up. */		s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */		s2length = MAX(s2length, csum_length);		s2length = MIN(s2length, SUM_LENGTH);	}	sum->flength	= len;	sum->blength	= blength;	sum->s2length	= s2length;	sum->remainder	= (int32)(len % blength);	sum->count	= (int32)(l = (len / blength) + (sum->remainder != 0));	if ((int64)sum->count != l)		sum->count = -1;	if (sum->count && verbose > 2) {		rprintf(FINFO,			"count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",			(double)sum->count, (long)sum->remainder, (long)sum->blength,			sum->s2length, (double)sum->flength);	}}/* * Generate and send a stream of signatures/checksums that describe a buffer * * Generate approximately one checksum every block_len bytes. */static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy){	int32 i;	struct map_struct *mapbuf;	struct sum_struct sum;	OFF_T offset = 0;	sum_sizes_sqroot(&sum, len);	if (sum.count < 0)		return -1;	write_sum_head(f_out, &sum);	if (append_mode > 0 && f_copy < 0)		return 0;	if (len > 0)		mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);	else		mapbuf = NULL;	for (i = 0; i < sum.count; i++) {		int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);		char *map = map_ptr(mapbuf, offset, n1);		char sum2[SUM_LENGTH];		uint32 sum1;		len -= n1;		offset += n1;		if (f_copy >= 0) {			full_write(f_copy, map, n1);			if (append_mode > 0)				continue;		}		sum1 = get_checksum1(map, n1);		get_checksum2(map, n1, sum2);		if (verbose > 3) {			rprintf(FINFO,				"chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n",				(double)i, (double)offset - n1, (long)n1,				(unsigned long)sum1);		}		write_int(f_out, sum1);		write_buf(f_out, sum2, sum.s2length);	}	if (mapbuf)		unmap_file(mapbuf);	return 0;}/* Try to find a filename in the same dir as "fname" with a similar name. */static int find_fuzzy(struct file_struct *file, struct file_list *dirlist){	int fname_len, fname_suf_len;	const char *fname_suf, *fname = file->basename;	uint32 lowest_dist = 25 << 16; /* ignore a distance greater than 25 */	int j, lowest_j = -1;	fname_len = strlen(fname);	fname_suf = find_filename_suffix(fname, fname_len, &fname_suf_len);	for (j = 0; j < dirlist->used; j++) {		struct file_struct *fp = dirlist->files[j];		const char *suf, *name;		int len, suf_len;		uint32 dist;		if (!S_ISREG(fp->mode) || !F_LENGTH(fp)		 || fp->flags & FLAG_FILE_SENT)			continue;		name = fp->basename;		if (F_LENGTH(fp) == F_LENGTH(file)		    && cmp_time(fp->modtime, file->modtime) == 0) {			if (verbose > 4) {				rprintf(FINFO,					"fuzzy size/modtime match for %s\n",					name);			}			return j;		}		len = strlen(name);		suf = find_filename_suffix(name, len, &suf_len);		dist = fuzzy_distance(name, len, fname, fname_len);		/* Add some extra weight to how well the suffixes match. */		dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len)		      * 10;		if (verbose > 4) {			rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",				name, (int)(dist>>16), (int)(dist&0xFFFF));		}		if (dist <= lowest_dist) {			lowest_dist = dist;			lowest_j = j;		}	}	return lowest_j;}/* Copy a file found in our --copy-dest handling. */static int copy_altdest_file(const char *src, const char *dest, struct file_struct *file){	char buf[MAXPATHLEN];	const char *copy_to, *partialptr;	int save_preserve_xattrs = preserve_xattrs;	int ok, fd_w;	if (inplace) {		/* Let copy_file open the destination in place. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -