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

📄 generator.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
			rsyserr(FERROR_XFER, errno, "unlink %s",				full_fname(backupptr));			unmake_file(back_file);			back_file = NULL;			close(fd);			goto cleanup;		}		if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {			int save_errno = errno ? errno : EINVAL; /* 0 paranoia */			if (errno == ENOENT && make_bak_dir(backupptr) == 0) {				if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0)					save_errno = errno ? errno : save_errno;				else					save_errno = 0;			}			if (save_errno) {				rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(backupptr));				unmake_file(back_file);				back_file = NULL;				close(fd);				goto cleanup;			}		}		fnamecmp_type = FNAMECMP_BACKUP;	}	if (verbose > 3) {		rprintf(FINFO, "gen mapped %s of size %.0f\n",			fnamecmp, (double)sx.st.st_size);	}	if (verbose > 2)		rprintf(FINFO, "generating and sending sums for %d\n", ndx);  notify_others:	if (remove_source_files && !delay_updates && !phase && !dry_run)		increment_active_files(ndx, itemizing, code);	if (inc_recurse && !dry_run)		cur_flist->in_progress++;#ifdef SUPPORT_HARD_LINKS	if (preserve_hard_links && F_IS_HLINKED(file))		file->flags |= FLAG_FILE_SENT;#endif	write_ndx(f_out, ndx);	if (itemizing) {		int iflags = ITEM_TRANSFER;		if (always_checksum > 0)			iflags |= ITEM_REPORT_CHANGE;		if (fnamecmp_type != FNAMECMP_FNAME)			iflags |= ITEM_BASIS_TYPE_FOLLOWS;		if (fnamecmp_type == FNAMECMP_FUZZY)			iflags |= ITEM_XNAME_FOLLOWS;		itemize(fnamecmp, file, -1, real_ret, &real_sx, iflags, fnamecmp_type,			fuzzy_file ? fuzzy_file->basename : NULL);#ifdef SUPPORT_ACLS		if (preserve_acls)			free_acl(&real_sx);#endif#ifdef SUPPORT_XATTRS		if (preserve_xattrs)			free_xattr(&real_sx);#endif	}	if (!do_xfers) {#ifdef SUPPORT_HARD_LINKS		if (preserve_hard_links && F_IS_HLINKED(file))			finish_hard_link(file, fname, ndx, &sx.st, itemizing, code, -1);#endif		goto cleanup;	}	if (read_batch)		goto cleanup;	if (statret != 0 || whole_file)		write_sum_head(f_out, NULL);	else if (sx.st.st_size <= 0) {		write_sum_head(f_out, NULL);		close(fd);	} else {		if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {			rprintf(FWARNING,			    "WARNING: file is too large for checksum sending: %s\n",			    fnamecmp);			write_sum_head(f_out, NULL);		}		close(fd);	}  cleanup:	if (back_file) {		int save_preserve_xattrs = preserve_xattrs;		if (f_copy >= 0)			close(f_copy);#ifdef SUPPORT_XATTRS		if (preserve_xattrs) {			copy_xattrs(fname, backupptr);			preserve_xattrs = 0;		}#endif		set_file_attrs(backupptr, back_file, NULL, NULL, 0);		preserve_xattrs = save_preserve_xattrs;		if (verbose > 1) {			rprintf(FINFO, "backed up %s to %s\n",				fname, backupptr);		}		unmake_file(back_file);	}#ifdef SUPPORT_ACLS	if (preserve_acls)		free_acl(&sx);#endif#ifdef SUPPORT_XATTRS	if (preserve_xattrs)		free_xattr(&sx);#endif	return;}#ifdef SUPPORT_HARD_LINKSstatic void handle_skipped_hlink(struct file_struct *file, int itemizing,				 enum logcode code, int f_out){	char fbuf[MAXPATHLEN];	int new_last_ndx;	struct file_list *save_flist = cur_flist;	/* If we skip the last item in a chain of links and there was a	 * prior non-skipped hard-link waiting to finish, finish it now. */	if ((new_last_ndx = skip_hard_link(file, &cur_flist)) < 0)		return;	file = cur_flist->files[new_last_ndx - cur_flist->ndx_start];	cur_flist->in_progress--; /* undo prior increment */	f_name(file, fbuf);	recv_generator(fbuf, file, new_last_ndx, itemizing, code, f_out);	cur_flist = save_flist;}#endifstatic void touch_up_dirs(struct file_list *flist, int ndx){	static int counter = 0;	struct file_struct *file;	char *fname;	int i, start, end;	if (ndx < 0) {		start = 0;		end = flist->used - 1;	} else		start = end = ndx;	/* Fix any directory permissions that were modified during the	 * transfer and/or re-set any tweaked modified-time values. */	for (i = start; i <= end; i++, counter++) {		file = flist->files[i];		if (!S_ISDIR(file->mode)		 || (!implied_dirs && file->flags & FLAG_IMPLIED_DIR))			continue;		if (verbose > 3) {			fname = f_name(file, NULL);			rprintf(FINFO, "touch_up_dirs: %s (%d)\n",				NS(fname), i);		}		if (!F_IS_ACTIVE(file) || file->flags & FLAG_MISSING_DIR		 || (!need_retouch_dir_times && file->mode & S_IWUSR))			continue;		fname = f_name(file, NULL);		if (!(file->mode & S_IWUSR))			do_chmod(fname, file->mode);		if (need_retouch_dir_times) {			STRUCT_STAT st;			if (link_stat(fname, &st, 0) == 0			 && cmp_time(st.st_mtime, file->modtime) != 0)				set_modtime(fname, file->modtime, file->mode);		}		if (counter >= loopchk_limit) {			if (allowed_lull)				maybe_send_keepalive();			else				maybe_flush_socket(0);			counter = 0;		}	}}void check_for_finished_files(int itemizing, enum logcode code, int check_redo){	struct file_struct *file;	struct file_list *flist;	char fbuf[MAXPATHLEN];	int ndx;	while (1) {#ifdef SUPPORT_HARD_LINKS		if (preserve_hard_links && (ndx = get_hlink_num()) != -1) {			flist = flist_for_ndx(ndx, "check_for_finished_files.1");			file = flist->files[ndx - flist->ndx_start];			assert(file->flags & FLAG_HLINKED);			finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1);			flist->in_progress--;			continue;		}#endif		if (check_redo && (ndx = get_redo_num()) != -1) {			csum_length = SUM_LENGTH;			max_size = -max_size;			min_size = -min_size;			ignore_existing = -ignore_existing;			ignore_non_existing = -ignore_non_existing;			update_only = -update_only;			always_checksum = -always_checksum;			size_only = -size_only;			append_mode = -append_mode;			make_backups = -make_backups; /* avoid dup backup w/inplace */			ignore_times++;			flist = cur_flist;			cur_flist = flist_for_ndx(ndx, "check_for_finished_files.2");			file = cur_flist->files[ndx - cur_flist->ndx_start];			if (solo_file)				strlcpy(fbuf, solo_file, sizeof fbuf);			else				f_name(file, fbuf);			recv_generator(fbuf, file, ndx, itemizing, code, sock_f_out);			cur_flist->to_redo--;			cur_flist = flist;			csum_length = SHORT_SUM_LENGTH;			max_size = -max_size;			min_size = -min_size;			ignore_existing = -ignore_existing;			ignore_non_existing = -ignore_non_existing;			update_only = -update_only;			always_checksum = -always_checksum;			size_only = -size_only;			append_mode = -append_mode;			make_backups = -make_backups;			ignore_times--;			continue;		}		if (cur_flist == first_flist)			break;		/* We only get here if inc_recurse is enabled. */		if (first_flist->in_progress || first_flist->to_redo)			break;		if (!read_batch) {			write_ndx(sock_f_out, NDX_DONE);			maybe_flush_socket(1);		}		if (delete_during == 2 || !dir_tweaking) {			/* Skip directory touch-up. */		} else if (first_flist->parent_ndx >= 0)			touch_up_dirs(dir_flist, first_flist->parent_ndx);		flist_free(first_flist); /* updates first_flist */	}}void generate_files(int f_out, const char *local_name){	int i, ndx, next_loopchk = 0;	char fbuf[MAXPATHLEN];	int itemizing;	enum logcode code;	int save_do_progress = do_progress;	if (protocol_version >= 29) {		itemizing = 1;		maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;		code = logfile_format_has_i ? FNONE : FLOG;	} else if (am_daemon) {		itemizing = logfile_format_has_i && do_xfers;		maybe_ATTRS_REPORT = ATTRS_REPORT;		code = itemizing || !do_xfers ? FCLIENT : FINFO;	} else if (!am_server) {		itemizing = stdout_format_has_i;		maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;		code = itemizing ? FNONE : FINFO;	} else {		itemizing = 0;		maybe_ATTRS_REPORT = ATTRS_REPORT;		code = FINFO;	}	solo_file = local_name;	dir_tweaking = !(list_only || solo_file || dry_run);	need_retouch_dir_times = preserve_times > 1;	loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;	symlink_timeset_failed_flags = ITEM_REPORT_TIME	    | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);	implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30;	if (verbose > 2)		rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());	if (delete_before && !solo_file && cur_flist->used > 0)		do_delete_pass();	if (delete_during == 2) {		deldelay_size = BIGPATHBUFLEN * 4;		deldelay_buf = new_array(char, deldelay_size);		if (!deldelay_buf)			out_of_memory("delete-delay");	}	do_progress = 0;	if (append_mode > 0 || whole_file < 0)		whole_file = 0;	if (verbose >= 2) {		rprintf(FINFO, "delta-transmission %s\n",			whole_file			? "disabled for local transfer or --whole-file"			: "enabled");	}	/* Since we often fill up the outgoing socket and then just sit around	 * waiting for the other 2 processes to do their thing, we don't want	 * to exit on a timeout.  If the data stops flowing, the receiver will	 * notice that and let us know via the redo pipe (or its closing). */	ignore_timeout = 1;	dflt_perms = (ACCESSPERMS & ~orig_umask);	do {#ifdef SUPPORT_HARD_LINKS		if (preserve_hard_links && inc_recurse) {			while (!flist_eof && file_total < FILECNT_LOOKAHEAD/2)				wait_for_receiver();		}#endif		if (inc_recurse && cur_flist->parent_ndx >= 0) {			struct file_struct *fp = dir_flist->files[cur_flist->parent_ndx];			if (solo_file)				strlcpy(fbuf, solo_file, sizeof fbuf);			else				f_name(fp, fbuf);			ndx = cur_flist->ndx_start - 1;			recv_generator(fbuf, fp, ndx, itemizing, code, f_out);			if (delete_during && dry_run < 2 && !list_only			 && !(fp->flags & FLAG_MISSING_DIR)) {				if (fp->flags & FLAG_CONTENT_DIR) {					dev_t dirdev;					if (one_file_system) {						uint32 *devp = F_DIR_DEV_P(fp);						dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));					} else						dirdev = MAKEDEV(0, 0);					delete_in_dir(fbuf, fp, &dirdev);				} else					change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));			}		}		for (i = cur_flist->low; i <= cur_flist->high; i++) {			struct file_struct *file = cur_flist->sorted[i];			if (!F_IS_ACTIVE(file))				continue;			if (unsort_ndx)				ndx = F_NDX(file);			else				ndx = i + cur_flist->ndx_start;			if (solo_file)				strlcpy(fbuf, solo_file, sizeof fbuf);			else				f_name(file, fbuf);			recv_generator(fbuf, file, ndx, itemizing, code, f_out);			check_for_finished_files(itemizing, code, 0);			if (i + cur_flist->ndx_start >= next_loopchk) {				if (allowed_lull)					maybe_send_keepalive();				else					maybe_flush_socket(0);				next_loopchk += loopchk_limit;			}		}		if (!inc_recurse) {			write_ndx(f_out, NDX_DONE);			break;		}		while (1) {			check_for_finished_files(itemizing, code, 1);			if (cur_flist->next || flist_eof)				break;			wait_for_receiver();		}	} while ((cur_flist = cur_flist->next) != NULL);	if (read_batch && inc_recurse)		write_ndx(f_out, NDX_DONE);	if (delete_during)		delete_in_dir(NULL, NULL, &dev_zero);	phase++;	if (verbose > 2)		rprintf(FINFO, "generate_files phase=%d\n", phase);	while (1) {		check_for_finished_files(itemizing, code, 1);		if (msgdone_cnt)			break;		wait_for_receiver();	}	phase++;	if (verbose > 2)		rprintf(FINFO, "generate_files phase=%d\n", phase);	write_ndx(f_out, NDX_DONE);	/* Reduce round-trip lag-time for a useless delay-updates phase. */	if (protocol_version >= 29 && !delay_updates)		write_ndx(f_out, NDX_DONE);	/* Read MSG_DONE for the redo phase (and any prior messages). */	while (1) {		check_for_finished_files(itemizing, code, 0);		if (msgdone_cnt > 1)			break;		wait_for_receiver();	}	if (protocol_version >= 29) {		phase++;		if (verbose > 2)			rprintf(FINFO, "generate_files phase=%d\n", phase);		if (delay_updates)			write_ndx(f_out, NDX_DONE);		/* Read MSG_DONE for delay-updates phase & prior messages. */		while (msgdone_cnt == 2)			wait_for_receiver();	}	do_progress = save_do_progress;	if (delete_during == 2)		do_delayed_deletions(fbuf);	if (delete_after && !solo_file && file_total > 0)		do_delete_pass();	if ((need_retouch_dir_perms || need_retouch_dir_times)	 && dir_tweaking && (!inc_recurse || delete_during == 2))		touch_up_dirs(dir_flist, -1);	if (max_delete >= 0 && deletion_count > max_delete) {		rprintf(FWARNING,			"Deletions stopped due to --max-delete limit (%d skipped)\n",			deletion_count - max_delete);		io_error |= IOERR_DEL_LIMIT;	}	if (verbose > 2)		rprintf(FINFO, "generate_files finished\n");}

⌨️ 快捷键说明

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