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

📄 flist.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		xflags |= XMIT_HLINKED;	}#endif	for (l1 = 0;	    lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);	    l1++) {}	l2 = strlen(fname+l1);	if (l1 > 0)		xflags |= XMIT_SAME_NAME;	if (l2 > 255)		xflags |= XMIT_LONG_NAME;	/* We must make sure we don't send a zero flag byte or the	 * other end will terminate the flist transfer.  Note that	 * the use of XMIT_TOP_DIR on a non-dir has no meaning, so	 * it's harmless way to add a bit to the first flag byte. */	if (protocol_version >= 28) {		if (!xflags && !S_ISDIR(mode))			xflags |= XMIT_TOP_DIR;		if ((xflags & 0xFF00) || !xflags) {			xflags |= XMIT_EXTENDED_FLAGS;			write_shortint(f, xflags);		} else			write_byte(f, xflags);	} else {		if (!(xflags & 0xFF))			xflags |= S_ISDIR(mode) ? XMIT_LONG_NAME : XMIT_TOP_DIR;		write_byte(f, xflags);	}	if (xflags & XMIT_SAME_NAME)		write_byte(f, l1);	if (xflags & XMIT_LONG_NAME)		write_varint30(f, l2);	else		write_byte(f, l2);	write_buf(f, fname + l1, l2);	if (first_hlink_ndx >= 0) {		write_varint(f, first_hlink_ndx);		if (first_hlink_ndx >= first_ndx)			goto the_end;	}	write_varlong30(f, F_LENGTH(file), 3);	if (!(xflags & XMIT_SAME_TIME)) {		if (protocol_version >= 30)			write_varlong(f, modtime, 4);		else			write_int(f, modtime);	}	if (!(xflags & XMIT_SAME_MODE))		write_int(f, to_wire_mode(mode));	if (preserve_uid && !(xflags & XMIT_SAME_UID)) {		if (protocol_version < 30)			write_int(f, uid);		else {			write_varint(f, uid);			if (xflags & XMIT_USER_NAME_FOLLOWS) {				int len = strlen(user_name);				write_byte(f, len);				write_buf(f, user_name, len);			}		}	}	if (preserve_gid && !(xflags & XMIT_SAME_GID)) {		if (protocol_version < 30)			write_int(f, gid);		else {			write_varint(f, gid);			if (xflags & XMIT_GROUP_NAME_FOLLOWS) {				int len = strlen(group_name);				write_byte(f, len);				write_buf(f, group_name, len);			}		}	}	if ((preserve_devices && IS_DEVICE(mode))	 || (preserve_specials && IS_SPECIAL(mode))) {		if (protocol_version < 28) {			if (!(xflags & XMIT_SAME_RDEV_pre28))				write_int(f, (int)rdev);		} else {			if (!(xflags & XMIT_SAME_RDEV_MAJOR))				write_varint30(f, major(rdev));			if (protocol_version >= 30)				write_varint(f, minor(rdev));			else if (xflags & XMIT_RDEV_MINOR_8_pre30)				write_byte(f, minor(rdev));			else				write_int(f, minor(rdev));		}	}#ifdef SUPPORT_LINKS	if (symlink_len) {		write_varint30(f, symlink_len);		write_buf(f, symlink_name, symlink_len);	}#endif#ifdef SUPPORT_HARD_LINKS	if (tmp_dev != 0 && protocol_version < 30) {		if (protocol_version < 26) {			/* 32-bit dev_t and ino_t */			write_int(f, (int32)dev);			write_int(f, (int32)tmp_ino);		} else {			/* 64-bit dev_t and ino_t */			if (!(xflags & XMIT_SAME_DEV_pre30))				write_longint(f, dev);			write_longint(f, tmp_ino);		}	}#endif	if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) {		const char *sum;		if (S_ISREG(mode))			sum = tmp_sum;		else {			/* Prior to 28, we sent a useless set of nulls. */			sum = empty_sum;		}		write_buf(f, sum, checksum_len);	}  the_end:	strlcpy(lastname, fname, MAXPATHLEN);	if (S_ISREG(mode) || S_ISLNK(mode))		stats.total_size += F_LENGTH(file);}static struct file_struct *recv_file_entry(struct file_list *flist,					   int xflags, int f){	static int64 modtime;	static mode_t mode;#ifdef SUPPORT_HARD_LINKS	static int64 dev;#endif	static dev_t rdev;	static uint32 rdev_major;	static uid_t uid;	static gid_t gid;	static uint16 gid_flags;	static char lastname[MAXPATHLEN], *lastdir;	static int lastdir_depth, lastdir_len = -1;	static unsigned int del_hier_name_len = 0;	static int in_del_hier = 0;	char thisname[MAXPATHLEN];	unsigned int l1 = 0, l2 = 0;	int alloc_len, basename_len, linkname_len;	int extra_len = file_extra_cnt * EXTRA_LEN;	int first_hlink_ndx = -1;	int64 file_length;	const char *basename;	struct file_struct *file;	alloc_pool_t *pool;	char *bp;	if (xflags & XMIT_SAME_NAME)		l1 = read_byte(f);	if (xflags & XMIT_LONG_NAME)		l2 = read_varint30(f);	else		l2 = read_byte(f);	if (l2 >= MAXPATHLEN - l1) {		rprintf(FERROR,			"overflow: xflags=0x%x l1=%d l2=%d lastname=%s [%s]\n",			xflags, l1, l2, lastname, who_am_i());		overflow_exit("recv_file_entry");	}	strlcpy(thisname, lastname, l1 + 1);	read_sbuf(f, &thisname[l1], l2);	thisname[l1 + l2] = 0;	/* Abuse basename_len for a moment... */	basename_len = strlcpy(lastname, thisname, MAXPATHLEN);#ifdef ICONV_OPTION	if (ic_recv != (iconv_t)-1) {		xbuf outbuf, inbuf;		INIT_CONST_XBUF(outbuf, thisname);		INIT_XBUF(inbuf, lastname, basename_len, -1);		if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {			io_error |= IOERR_GENERAL;			rprintf(FERROR_UTF8,			    "[%s] cannot convert filename: %s (%s)\n",			    who_am_i(), lastname, strerror(errno));			outbuf.len = 0;		}		thisname[outbuf.len] = '\0';	}#endif	if (*thisname)		clean_fname(thisname, 0);	if (sanitize_paths)		sanitize_path(thisname, thisname, "", 0, SP_DEFAULT);	if ((basename = strrchr(thisname, '/')) != NULL) {		int len = basename++ - thisname;		if (len != lastdir_len || memcmp(thisname, lastdir, len) != 0) {			lastdir = new_array(char, len + 1);			memcpy(lastdir, thisname, len);			lastdir[len] = '\0';			lastdir_len = len;			lastdir_depth = count_dir_elements(lastdir);		}	} else		basename = thisname;	basename_len = strlen(basename) + 1; /* count the '\0' */#ifdef SUPPORT_HARD_LINKS	if (protocol_version >= 30	 && BITS_SETnUNSET(xflags, XMIT_HLINKED, XMIT_HLINK_FIRST)) {		first_hlink_ndx = read_varint(f);		if (first_hlink_ndx < 0 || first_hlink_ndx >= flist->ndx_start + flist->used) {			rprintf(FERROR,				"hard-link reference out of range: %d (%d)\n",				first_hlink_ndx, flist->ndx_start + flist->used);			exit_cleanup(RERR_PROTOCOL);		}		if (first_hlink_ndx >= flist->ndx_start) {			struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];			file_length = F_LENGTH(first);			modtime = first->modtime;			mode = first->mode;			if (preserve_uid)				uid = F_OWNER(first);			if (preserve_gid)				gid = F_GROUP(first);			if ((preserve_devices && IS_DEVICE(mode))			 || (preserve_specials && IS_SPECIAL(mode))) {				uint32 *devp = F_RDEV_P(first);				rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));				extra_len += DEV_EXTRA_CNT * EXTRA_LEN;			}			if (preserve_links && S_ISLNK(mode))				linkname_len = strlen(F_SYMLINK(first)) + 1;			else				linkname_len = 0;			goto create_object;		}	}#endif	file_length = read_varlong30(f, 3);	if (!(xflags & XMIT_SAME_TIME)) {		if (protocol_version >= 30) {			modtime = read_varlong(f, 4);#if SIZEOF_TIME_T < SIZEOF_INT64			if (!am_generator && (int64)(time_t)modtime != modtime) {				rprintf(FERROR_XFER,				    "Time value of %s truncated on receiver.\n",				    lastname);			}#endif		} else			modtime = read_int(f);	}	if (!(xflags & XMIT_SAME_MODE))		mode = from_wire_mode(read_int(f));	if (chmod_modes && !S_ISLNK(mode))		mode = tweak_mode(mode, chmod_modes);	if (preserve_uid && !(xflags & XMIT_SAME_UID)) {		if (protocol_version < 30)			uid = (uid_t)read_int(f);		else {			uid = (uid_t)read_varint(f);			if (xflags & XMIT_USER_NAME_FOLLOWS)				uid = recv_user_name(f, uid);			else if (inc_recurse && am_root && !numeric_ids)				uid = match_uid(uid);		}	}	if (preserve_gid && !(xflags & XMIT_SAME_GID)) {		if (protocol_version < 30)			gid = (gid_t)read_int(f);		else {			gid = (gid_t)read_varint(f);			gid_flags = 0;			if (xflags & XMIT_GROUP_NAME_FOLLOWS)				gid = recv_group_name(f, gid, &gid_flags);			else if (inc_recurse && (!am_root || !numeric_ids))				gid = match_gid(gid, &gid_flags);		}	}	if ((preserve_devices && IS_DEVICE(mode))	 || (preserve_specials && IS_SPECIAL(mode))) {		if (protocol_version < 28) {			if (!(xflags & XMIT_SAME_RDEV_pre28))				rdev = (dev_t)read_int(f);		} else {			uint32 rdev_minor;			if (!(xflags & XMIT_SAME_RDEV_MAJOR))				rdev_major = read_varint30(f);			if (protocol_version >= 30)				rdev_minor = read_varint(f);			else if (xflags & XMIT_RDEV_MINOR_8_pre30)				rdev_minor = read_byte(f);			else				rdev_minor = read_int(f);			rdev = MAKEDEV(rdev_major, rdev_minor);		}		extra_len += DEV_EXTRA_CNT * EXTRA_LEN;		file_length = 0;	} else if (protocol_version < 28)		rdev = MAKEDEV(0, 0);#ifdef SUPPORT_LINKS	if (preserve_links && S_ISLNK(mode)) {		linkname_len = read_varint30(f) + 1; /* count the '\0' */		if (linkname_len <= 0 || linkname_len > MAXPATHLEN) {			rprintf(FERROR, "overflow: linkname_len=%d\n",				linkname_len - 1);			overflow_exit("recv_file_entry");		}#ifdef ICONV_OPTION		/* We don't know how much extra room we need to convert		 * the as-yet-unread symlink data, so let's hope that a		 * double-size buffer is plenty. */		if (sender_symlink_iconv)			linkname_len *= 2;#endif		if (munge_symlinks)			linkname_len += SYMLINK_PREFIX_LEN;	}	else#endif		linkname_len = 0;#ifdef SUPPORT_HARD_LINKS  create_object:	if (preserve_hard_links) {		if (protocol_version < 28 && S_ISREG(mode))			xflags |= XMIT_HLINKED;		if (xflags & XMIT_HLINKED)			extra_len += (inc_recurse+1) * EXTRA_LEN;	}#endif#ifdef SUPPORT_ACLS	/* Directories need an extra int32 for the default ACL. */	if (preserve_acls && S_ISDIR(mode))		extra_len += EXTRA_LEN;#endif	if (always_checksum && S_ISREG(mode))		extra_len += SUM_EXTRA_CNT * EXTRA_LEN;#if SIZEOF_INT64 >= 8	if (file_length > 0xFFFFFFFFu && S_ISREG(mode))		extra_len += EXTRA_LEN;#endif	if (file_length < 0) {		rprintf(FERROR, "Offset underflow: file-length is negative\n");		exit_cleanup(RERR_UNSUPPORTED);	}	if (inc_recurse && S_ISDIR(mode)) {		if (one_file_system) {			/* Room to save the dir's device for -x */			extra_len += DEV_EXTRA_CNT * EXTRA_LEN;		}		pool = dir_flist->file_pool;	} else		pool = flist->file_pool;#if EXTRA_ROUNDING > 0	if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))		extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;#endif	alloc_len = FILE_STRUCT_LEN + extra_len + basename_len		  + linkname_len;	bp = pool_alloc(pool, alloc_len, "recv_file_entry");	memset(bp, 0, extra_len + FILE_STRUCT_LEN);	bp += extra_len;	file = (struct file_struct *)bp;	bp += FILE_STRUCT_LEN;	memcpy(bp, basename, basename_len);#ifdef SUPPORT_HARD_LINKS	if (xflags & XMIT_HLINKED)		file->flags |= FLAG_HLINKED;#endif	file->modtime = (time_t)modtime;	file->len32 = (uint32)file_length;#if SIZEOF_INT64 >= 8	if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) {#if SIZEOF_CAPITAL_OFF_T < 8		rprintf(FERROR, "Offset overflow: attempted 64-bit file-length\n");		exit_cleanup(RERR_UNSUPPORTED);#else		file->flags |= FLAG_LENGTH64;		OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);#endif	}#endif	file->mode = mode;	if (preserve_uid)		F_OWNER(file) = uid;	if (preserve_gid) {		F_GROUP(file) = gid;		file->flags |= gid_flags;	}	if (unsort_ndx)		F_NDX(file) = flist->used + flist->ndx_start;	if (basename != thisname) {		file->dirname = lastdir;		F_DEPTH(file) = lastdir_depth + 1;	} else		F_DEPTH(file) = 1;	if (S_ISDIR(mode)) {		if (basename_len == 1+1 && *basename == '.') /* +1 for '\0' */			F_DEPTH(file)--;		if (protocol_version >= 30) {			if (!(xflags & XMIT_NO_CONTENT_DIR)) {				if (xflags & XMIT_TOP_DIR)					file->flags |= FLAG_TOP_DIR;				file->flags |= FLAG_CONTENT_DIR;			} else if (xflags & XMIT_TOP_DIR)				file->flags |= FLAG_IMPLIED_DIR;		} else if (xflags & XMIT_TOP_DIR) {			in_del_hier = recurse;			del_hier_name_len = F_DEPTH(file) == 0 ? 0 : l1 + l2;			if (relative_paths && del_hier_name_len > 2			    && lastname[del_hier_name_len-1] == '.'			    && lastname[del_hier_name_len-2] == '/')				del_hier_name_len -= 2;			file->flags |= FLAG_TOP_DIR | FLAG_CONTENT_DIR;		} else if (in_del_hier) {			if (!relative_paths || !del_hier_name_len			 || (l1 >= del_hier_name_len			  && lastname[del_hier_name_len] == '/'))				file->flags |= FLAG_CONTENT_DIR;			else				in_del_hier = 0;		}	}	if ((preserve_devices && IS_DEVICE(mode))	 || (preserve_specials && IS_SPECIAL(mode))) {		uint32 *devp = F_RDEV_P(file);		DEV_MAJOR(devp) = major(rdev);		DEV_MINOR(devp) = minor(rdev);	}#ifdef SUPPORT_LINKS	if (linkname_len) {		bp += basename_len;		if (first_hlink_ndx >= flist->ndx_start) {			struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];			memcpy(bp, F_SYMLINK(first), linkname_len);		} else {			if (munge_symlinks) {				strlcpy(bp, SYMLINK_PREFIX, linkname_len);				bp += SYMLINK_PREFIX_LEN;				linkname_len -= SYMLINK_PREFIX_LEN;			}#ifdef ICONV_OPTION			if (sender_symlink_iconv) {				xbuf outbuf, inbuf;				alloc_len = linkname_len;				linkname_len /= 2;

⌨️ 快捷键说明

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