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

📄 flist.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* Read the symlink data into the end of our double-sized				 * buffer and then convert it into the right spot. */				INIT_XBUF(inbuf, bp + alloc_len - linkname_len,					  linkname_len - 1, (size_t)-1);				read_sbuf(f, inbuf.buf, inbuf.len);				INIT_XBUF(outbuf, bp, 0, alloc_len);				if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {					io_error |= IOERR_GENERAL;					rprintf(FERROR_XFER,					    "[%s] cannot convert symlink data for: %s (%s)\n",					    who_am_i(), full_fname(thisname), strerror(errno));					bp = (char*)file->basename;					*bp++ = '\0';					outbuf.len = 0;				}				bp[outbuf.len] = '\0';			} else#endif				read_sbuf(f, bp, linkname_len - 1);			if (sanitize_paths && !munge_symlinks && *bp)				sanitize_path(bp, bp, "", lastdir_depth, SP_DEFAULT);		}	}#endif#ifdef SUPPORT_HARD_LINKS	if (preserve_hard_links && xflags & XMIT_HLINKED) {		if (protocol_version >= 30) {			if (xflags & XMIT_HLINK_FIRST) {				F_HL_GNUM(file) = flist->ndx_start + flist->used;			} else				F_HL_GNUM(file) = first_hlink_ndx;		} else {			static int32 cnt = 0;			struct ht_int64_node *np;			int64 ino;			int32 ndx;			if (protocol_version < 26) {				dev = read_int(f);				ino = read_int(f);			} else {				if (!(xflags & XMIT_SAME_DEV_pre30))					dev = read_longint(f);				ino = read_longint(f);			}			np = idev_find(dev, ino);			ndx = (int32)(long)np->data - 1;			if (ndx < 0) {				ndx = cnt++;				np->data = (void*)(long)cnt;			}			F_HL_GNUM(file) = ndx;		}	}#endif	if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) {		if (S_ISREG(mode))			bp = F_SUM(file);		else {			/* Prior to 28, we get a useless set of nulls. */			bp = tmp_sum;		}		if (first_hlink_ndx >= flist->ndx_start) {			struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];			memcpy(bp, F_SUM(first), checksum_len);		} else			read_buf(f, bp, checksum_len);	}#ifdef SUPPORT_ACLS	if (preserve_acls && !S_ISLNK(mode))		receive_acl(file, f);#endif#ifdef SUPPORT_XATTRS	if (preserve_xattrs)		receive_xattr(file, f );#endif	if (S_ISREG(mode) || S_ISLNK(mode))		stats.total_size += file_length;	return file;}/* Create a file_struct for a named file by reading its stat() information * and performing extensive checks against global options. * * Returns a pointer to the new file struct, or NULL if there was an error * or this file should be excluded. * * Note: Any error (here or in send_file_name) that results in the omission of * an existent source file from the file list should set * "io_error |= IOERR_GENERAL" to avoid deletion of the file from the * destination if --delete is on. */struct file_struct *make_file(const char *fname, struct file_list *flist,			      STRUCT_STAT *stp, int flags, int filter_level){	static char *lastdir;	static int lastdir_len = -1;	struct file_struct *file;	char thisname[MAXPATHLEN];	char linkname[MAXPATHLEN];	int alloc_len, basename_len, linkname_len;	int extra_len = file_extra_cnt * EXTRA_LEN;	const char *basename;	alloc_pool_t *pool;	STRUCT_STAT st;	char *bp;	if (strlcpy(thisname, fname, sizeof thisname) >= sizeof thisname) {		io_error |= IOERR_GENERAL;		rprintf(FERROR_XFER, "skipping overly long name: %s\n", fname);		return NULL;	}	clean_fname(thisname, 0);	if (sanitize_paths)		sanitize_path(thisname, thisname, "", 0, SP_DEFAULT);	if (stp && S_ISDIR(stp->st_mode)) {		st = *stp; /* Needed for "symlink/." with --relative. */		*linkname = '\0'; /* make IBM code checker happy */	} else if (readlink_stat(thisname, &st, linkname) != 0) {		int save_errno = errno;		/* See if file is excluded before reporting an error. */		if (filter_level != NO_FILTERS		 && (is_excluded(thisname, 0, filter_level)		  || is_excluded(thisname, 1, filter_level))) {			if (ignore_perishable && save_errno != ENOENT)				non_perishable_cnt++;			return NULL;		}		if (save_errno == ENOENT) {#ifdef SUPPORT_LINKS			/* When our options tell us to follow a symlink that			 * points nowhere, tell the user about the symlink			 * instead of giving a "vanished" message.  We only			 * dereference a symlink if one of the --copy*links			 * options was specified, so there's no need for the			 * extra lstat() if one of these options isn't on. */			if ((copy_links || copy_unsafe_links || copy_dirlinks)			 && x_lstat(thisname, &st, NULL) == 0			 && S_ISLNK(st.st_mode)) {				io_error |= IOERR_GENERAL;				rprintf(FERROR_XFER, "symlink has no referent: %s\n",					full_fname(thisname));			} else#endif			{				enum logcode c = am_daemon && protocol_version < 28					       ? FERROR : FWARNING;				io_error |= IOERR_VANISHED;				rprintf(c, "file has vanished: %s\n",					full_fname(thisname));			}		} else {			io_error |= IOERR_GENERAL;			rsyserr(FERROR_XFER, save_errno, "readlink_stat(%s) failed",				full_fname(thisname));		}		return NULL;	}	if (filter_level == NO_FILTERS)		goto skip_filters;	if (S_ISDIR(st.st_mode)) {		if (!xfer_dirs) {			rprintf(FINFO, "skipping directory %s\n", thisname);			return NULL;		}		/* -x only affects dirs because we need to avoid recursing		 * into a mount-point directory, not to avoid copying a		 * symlinked file if -L (or similar) was specified. */		if (one_file_system && st.st_dev != filesystem_dev		 && BITS_SETnUNSET(flags, FLAG_CONTENT_DIR, FLAG_TOP_DIR)) {			if (one_file_system > 1) {				if (verbose > 1) {					rprintf(FINFO,					    "[%s] skipping mount-point dir %s\n",					    who_am_i(), thisname);				}				return NULL;			}			flags |= FLAG_MOUNT_DIR;			flags &= ~FLAG_CONTENT_DIR;		}	} else		flags &= ~FLAG_CONTENT_DIR;	if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) {		if (ignore_perishable)			non_perishable_cnt++;		return NULL;	}	if (lp_ignore_nonreadable(module_id)) {#ifdef SUPPORT_LINKS		if (!S_ISLNK(st.st_mode))#endif			if (access(thisname, R_OK) != 0)				return NULL;	}  skip_filters:	/* Only divert a directory in the main transfer. */	if (flist) {		if (flist->prev && S_ISDIR(st.st_mode)		 && flags & FLAG_DIVERT_DIRS) {			/* Room for parent/sibling/next-child info. */			extra_len += DIRNODE_EXTRA_CNT * EXTRA_LEN;			if (relative_paths)				extra_len += PTR_EXTRA_CNT * EXTRA_LEN;			pool = dir_flist->file_pool;		} else			pool = flist->file_pool;	} else {#ifdef SUPPORT_ACLS		/* Directories need an extra int32 for the default ACL. */		if (preserve_acls && S_ISDIR(st.st_mode))			extra_len += EXTRA_LEN;#endif		pool = NULL;	}	if (verbose > 2) {		rprintf(FINFO, "[%s] make_file(%s,*,%d)\n",			who_am_i(), thisname, filter_level);	}	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;		}	} else		basename = thisname;	basename_len = strlen(basename) + 1; /* count the '\0' */#ifdef SUPPORT_LINKS	linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0;#else	linkname_len = 0;#endif#if SIZEOF_CAPITAL_OFF_T >= 8	if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode))		extra_len += EXTRA_LEN;#endif#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;	if (pool)		bp = pool_alloc(pool, alloc_len, "make_file");	else {		if (!(bp = new_array(char, alloc_len)))			out_of_memory("make_file");	}	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 (preserve_hard_links && flist && flist->prev) {		if (protocol_version >= 28		 ? (!S_ISDIR(st.st_mode) && st.st_nlink > 1)		 : S_ISREG(st.st_mode)) {			tmp_dev = (int64)st.st_dev + 1;			tmp_ino = (int64)st.st_ino;		} else			tmp_dev = 0;	}#endif#ifdef HAVE_STRUCT_STAT_ST_RDEV	if (IS_DEVICE(st.st_mode) || IS_SPECIAL(st.st_mode)) {		tmp_rdev = st.st_rdev;		st.st_size = 0;	}#endif	file->flags = flags;	file->modtime = st.st_mtime;	file->len32 = (uint32)st.st_size;#if SIZEOF_CAPITAL_OFF_T >= 8	if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) {		file->flags |= FLAG_LENGTH64;		OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);	}#endif	file->mode = st.st_mode;	if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */		F_OWNER(file) = st.st_uid;	if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */		F_GROUP(file) = st.st_gid;	if (basename != thisname)		file->dirname = lastdir;#ifdef SUPPORT_LINKS	if (linkname_len)		memcpy(bp + basename_len, linkname, linkname_len);#endif	if (always_checksum && am_sender && S_ISREG(st.st_mode))		file_checksum(thisname, tmp_sum, st.st_size);	if (am_sender)		F_PATHNAME(file) = pathname;	else if (!pool)		F_DEPTH(file) = extra_len / EXTRA_LEN;	if (basename_len == 0+1) {		if (!pool)			unmake_file(file);		return NULL;	}	if (unsort_ndx)		F_NDX(file) = dir_count;	return file;}/* Only called for temporary file_struct entries created by make_file(). */void unmake_file(struct file_struct *file){	free(REQ_EXTRA(file, F_DEPTH(file)));}static struct file_struct *send_file_name(int f, struct file_list *flist,					  const char *fname, STRUCT_STAT *stp,					  int flags, int filter_level){	struct file_struct *file;	file = make_file(fname, flist, stp, flags, filter_level);	if (!file)		return NULL;	if (chmod_modes && !S_ISLNK(file->mode))		file->mode = tweak_mode(file->mode, chmod_modes);	if (f >= 0) {		char fbuf[MAXPATHLEN];#ifdef SUPPORT_LINKS		const char *symlink_name;		int symlink_len;#ifdef ICONV_OPTION		char symlink_buf[MAXPATHLEN];#endif#endif#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS		stat_x sx;#endif#ifdef SUPPORT_LINKS		if (preserve_links && S_ISLNK(file->mode)) {			symlink_name = F_SYMLINK(file);			symlink_len = strlen(symlink_name);		} else {			symlink_name = NULL;			symlink_len = 0;		}#endif#ifdef ICONV_OPTION		if (ic_send != (iconv_t)-1) {			xbuf outbuf, inbuf;			INIT_CONST_XBUF(outbuf, fbuf);			if (file->dirname) {				INIT_XBUF_STRLEN(inbuf, (char*)file->dirname);				outbuf.size -= 2; /* Reserve room for '/' & 1 more char. */				if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0)					goto convert_error;				outbuf.size += 2;				fbuf[outbuf.len++] = '/';			}			INIT_XBUF_STRLEN(inbuf, (char*)file->basename);			if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {			  convert_error:				io_error |= IOERR_GENERAL;				rprintf(FERROR_XFER,				    "[%s] cannot convert filename: %s (%s)\n",				    who_am_i(), f_name(file, fbuf), strerror(errno));				return NULL;			}			fbuf[outbuf.len] = '\0';#ifdef SUPPORT_LINKS			if (symlink_len && sender_symlink_iconv) {				INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1);				INIT_CONST_XBUF(outbuf, symlink_buf);				if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {					io_error |= IOERR_GENERAL;					f_name(file, fbuf);					rprintf(FERROR_XFER,					    "[%s] cannot convert symlink data for: %s (%s)\n",					    who_am_i(), full_fname(fbuf), strerror(errno));					return NULL;				}				symlink_buf[outbuf.len] = '\0';				symlink_name = symlink_buf;				symlink_len = outbuf.len;			}#endif		} else#endif			f_name(file, fbuf);#ifdef SUPPORT_ACLS		if (preserve_acls && !S_ISLNK(file->mode)) {			sx.st.st_mode = file->mode;			sx.acc_acl = sx.def_acl = NULL;			if (get_acl(fname, &sx) < 0) {				io_error |= IOERR_GENERAL;				return NULL;			}		}#endif#ifdef SUPPORT_XATTRS		if (preserve_xattrs) {			sx.xattr = NULL;			if (get_xattr(fname, &sx) < 0) {				io_error |= IOERR_GENERAL;				return NULL;			}		}#endif		send_file_entry(f, fbuf, file,#ifdef SUPPORT_LINKS				symlink_name, symlink_len,#endif				flist->used, flist->ndx_start);#ifdef SUPPORT_ACLS		if (preserve_acls && !S_ISLNK(file->mode)) {			send_acl(&sx, f);			free_acl(&sx);		}#endif#ifdef SUPPORT_XATTRS		if (preserve_xattrs) {			F_XATTR(file) = send_xattr(&sx, f);			free_xattr(&sx);		}#endif	}	maybe_emit_filelist_progress(flist->used + flist_count_offset);	flist_expand(flist, 1);	flist->files[flist->used++] = file;	return file;}static void send_if_directory(int f, struct file_list *flist,			      struct file_struct *file,			      char *fbuf, unsigned int ol,			      int flags){	char is_dot_dir = fbuf[ol-1] == '.' && (ol == 1 || fbuf[ol-2] == '/');	if (S_ISDIR(file->mode)	    && !(file->flags & FLAG_MOUNT_DIR) && f_name(file, fbuf)) {

⌨️ 快捷键说明

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