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

📄 exclude.c

📁 Rsync 3.0.5 source code
💻 C
📖 第 1 页 / 共 3 页
字号:
			case 'e':				new_mflags |= MATCHFLG_EXCLUDE_SELF;				break;			case 'n':				new_mflags |= MATCHFLG_NO_INHERIT;				break;			case 'p':				new_mflags |= MATCHFLG_PERISHABLE;				break;			case 'r':				new_mflags |= MATCHFLG_RECEIVER_SIDE;				break;			case 's':				new_mflags |= MATCHFLG_SENDER_SIDE;				break;			case 'w':				new_mflags |= MATCHFLG_WORD_SPLIT;				break;			}		}		if (*s)			s++;	}	if (mflags & MATCHFLG_WORD_SPLIT) {		const uchar *cp = s;		/* Token ends at whitespace or the end of the string. */		while (!isspace(*cp) && *cp != '\0')			cp++;		len = cp - s;	} else		len = strlen((char*)s);	if (new_mflags & MATCHFLG_CLEAR_LIST) {		if (!(mflags & MATCHFLG_NO_PREFIXES)		 && !(xflags & XFLG_OLD_PREFIXES) && len) {			rprintf(FERROR,				"'!' rule has trailing characters: %s\n", p);			exit_cleanup(RERR_SYNTAX);		}		if (len > 1)			new_mflags &= ~MATCHFLG_CLEAR_LIST;	} else if (!len && !(new_mflags & MATCHFLG_CVS_IGNORE)) {		rprintf(FERROR, "unexpected end of filter rule: %s\n", p);		exit_cleanup(RERR_SYNTAX);	}	/* --delete-excluded turns an un-modified include/exclude into a	 * sender-side rule.  We also affect per-dir merge files that take	 * no prefixes as a simple optimization. */	if (delete_excluded	 && !(new_mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE))	 && (!(new_mflags & MATCHFLG_PERDIR_MERGE)	  || new_mflags & MATCHFLG_NO_PREFIXES))		new_mflags |= MATCHFLG_SENDER_SIDE;	*len_ptr = len;	*mflags_ptr = new_mflags;	return (const char *)s;}static char default_cvsignore[] =	/* These default ignored items come from the CVS manual. */	"RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"	" .make.state .nse_depinfo *~ #* .#* ,* _$* *$"	" *.old *.bak *.BAK *.orig *.rej .del-*"	" *.a *.olb *.o *.obj *.so *.exe"	" *.Z *.elc *.ln core"	/* The rest we added to suit ourself. */	" .svn/ .git/ .bzr/";static void get_cvs_excludes(uint32 mflags){	static int initialized = 0;	char *p, fname[MAXPATHLEN];	if (initialized)		return;	initialized = 1;	parse_rule(&cvs_filter_list, default_cvsignore,		   mflags | (protocol_version >= 30 ? MATCHFLG_PERISHABLE : 0),		   0);	p = module_id >= 0 && lp_use_chroot(module_id) ? "/" : getenv("HOME");	if (p && pathjoin(fname, MAXPATHLEN, p, ".cvsignore") < MAXPATHLEN)		parse_filter_file(&cvs_filter_list, fname, mflags, 0);	parse_rule(&cvs_filter_list, getenv("CVSIGNORE"), mflags, 0);}void parse_rule(struct filter_list_struct *listp, const char *pattern,		uint32 mflags, int xflags){	unsigned int pat_len;	uint32 new_mflags;	const char *cp, *p;	if (!pattern)		return;	while (1) {		/* Remember that the returned string is NOT '\0' terminated! */		cp = parse_rule_tok(pattern, mflags, xflags,				    &pat_len, &new_mflags);		if (!cp)			break;		pattern = cp + pat_len;		if (pat_len >= MAXPATHLEN) {			rprintf(FERROR, "discarding over-long filter: %.*s\n",				(int)pat_len, cp);			continue;		}		if (new_mflags & MATCHFLG_CLEAR_LIST) {			if (verbose > 2) {				rprintf(FINFO,					"[%s] clearing filter list%s\n",					who_am_i(), listp->debug_type);			}			clear_filter_list(listp);			continue;		}		if (new_mflags & MATCHFLG_MERGE_FILE) {			unsigned int len;			if (!pat_len) {				cp = ".cvsignore";				pat_len = 10;			}			len = pat_len;			if (new_mflags & MATCHFLG_EXCLUDE_SELF) {				const char *name = cp + len;				while (name > cp && name[-1] != '/') name--;				len -= name - cp;				add_rule(listp, name, len, 0, 0);				new_mflags &= ~MATCHFLG_EXCLUDE_SELF;				len = pat_len;			}			if (new_mflags & MATCHFLG_PERDIR_MERGE) {				if (parent_dirscan) {					if (!(p = parse_merge_name(cp, &len,								module_dirlen)))						continue;					add_rule(listp, p, len, new_mflags, 0);					continue;				}			} else {				if (!(p = parse_merge_name(cp, &len, 0)))					continue;				parse_filter_file(listp, p, new_mflags,						  XFLG_FATAL_ERRORS);				continue;			}		}		add_rule(listp, cp, pat_len, new_mflags, xflags);		if (new_mflags & MATCHFLG_CVS_IGNORE		    && !(new_mflags & MATCHFLG_MERGE_FILE))			get_cvs_excludes(new_mflags);	}}void parse_filter_file(struct filter_list_struct *listp, const char *fname,		       uint32 mflags, int xflags){	FILE *fp;	char line[BIGPATHBUFLEN];	char *eob = line + sizeof line - 1;	int word_split = mflags & MATCHFLG_WORD_SPLIT;	if (!fname || !*fname)		return;	if (*fname != '-' || fname[1] || am_server) {		if (daemon_filter_list.head) {			strlcpy(line, fname, sizeof line);			clean_fname(line, CFN_COLLAPSE_DOT_DOT_DIRS);			if (check_filter(&daemon_filter_list, FLOG, line, 0) < 0)				fp = NULL;			else				fp = fopen(line, "rb");		} else			fp = fopen(fname, "rb");	} else		fp = stdin;	if (verbose > 2) {		rprintf(FINFO, "[%s] parse_filter_file(%s,%x,%x)%s\n",			who_am_i(), fname, mflags, xflags,			fp ? "" : " [not found]");	}	if (!fp) {		if (xflags & XFLG_FATAL_ERRORS) {			rsyserr(FERROR, errno,				"failed to open %sclude file %s",				mflags & MATCHFLG_INCLUDE ? "in" : "ex",				fname);			exit_cleanup(RERR_FILEIO);		}		return;	}	dirbuf[dirbuf_len] = '\0';	while (1) {		char *s = line;		int ch, overflow = 0;		while (1) {			if ((ch = getc(fp)) == EOF) {				if (ferror(fp) && errno == EINTR) {					clearerr(fp);					continue;				}				break;			}			if (word_split && isspace(ch))				break;			if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))				break;			if (s < eob)				*s++ = ch;			else				overflow = 1;		}		if (overflow) {			rprintf(FERROR, "discarding over-long filter: %s...\n", line);			s = line;		}		*s = '\0';		/* Skip an empty token and (when line parsing) comments. */		if (*line && (word_split || (*line != ';' && *line != '#')))			parse_rule(listp, line, mflags, xflags);		if (ch == EOF)			break;	}	fclose(fp);}/* If the "for_xfer" flag is set, the prefix is made compatible with the * current protocol_version (if possible) or a NULL is returned (if not * possible). */char *get_rule_prefix(int match_flags, const char *pat, int for_xfer,		      unsigned int *plen_ptr){	static char buf[MAX_RULE_PREFIX+1];	char *op = buf;	int legal_len = for_xfer && protocol_version < 29 ? 1 : MAX_RULE_PREFIX-1;	if (match_flags & MATCHFLG_PERDIR_MERGE) {		if (legal_len == 1)			return NULL;		*op++ = ':';	} else if (match_flags & MATCHFLG_INCLUDE)		*op++ = '+';	else if (legal_len != 1	    || ((*pat == '-' || *pat == '+') && pat[1] == ' '))		*op++ = '-';	else		legal_len = 0;	if (match_flags & MATCHFLG_NEGATE)		*op++ = '!';	if (match_flags & MATCHFLG_CVS_IGNORE)		*op++ = 'C';	else {		if (match_flags & MATCHFLG_NO_INHERIT)			*op++ = 'n';		if (match_flags & MATCHFLG_WORD_SPLIT)			*op++ = 'w';		if (match_flags & MATCHFLG_NO_PREFIXES) {			if (match_flags & MATCHFLG_INCLUDE)				*op++ = '+';			else				*op++ = '-';		}	}	if (match_flags & MATCHFLG_EXCLUDE_SELF)		*op++ = 'e';	if (match_flags & MATCHFLG_SENDER_SIDE	    && (!for_xfer || protocol_version >= 29))		*op++ = 's';	if (match_flags & MATCHFLG_RECEIVER_SIDE	    && (!for_xfer || protocol_version >= 29	     || (delete_excluded && am_sender)))		*op++ = 'r';	if (match_flags & MATCHFLG_PERISHABLE) {		if (!for_xfer || protocol_version >= 30)			*op++ = 'p';		else if (am_sender)			return NULL;	}	if (op - buf > legal_len)		return NULL;	if (legal_len)		*op++ = ' ';	*op = '\0';	if (plen_ptr)		*plen_ptr = op - buf;	return buf;}static void send_rules(int f_out, struct filter_list_struct *flp){	struct filter_struct *ent, *prev = NULL;	for (ent = flp->head; ent; ent = ent->next) {		unsigned int len, plen, dlen;		int elide = 0;		char *p;		/* Note we need to check delete_excluded here in addition to		 * the code in parse_rule_tok() because some rules may have		 * been added before we found the --delete-excluded option.		 * We must also elide any CVS merge-file rules to avoid a		 * backward compatibility problem, and we elide any no-prefix		 * merge files as an optimization (since they can only have		 * include/exclude rules). */		if (ent->match_flags & MATCHFLG_SENDER_SIDE)			elide = am_sender ? 1 : -1;		if (ent->match_flags & MATCHFLG_RECEIVER_SIDE)			elide = elide ? 0 : am_sender ? -1 : 1;		else if (delete_excluded && !elide		 && (!(ent->match_flags & MATCHFLG_PERDIR_MERGE)		  || ent->match_flags & MATCHFLG_NO_PREFIXES))			elide = am_sender ? 1 : -1;		if (elide < 0) {			if (prev)				prev->next = ent->next;			else				flp->head = ent->next;		} else			prev = ent;		if (elide > 0)			continue;		if (ent->match_flags & MATCHFLG_CVS_IGNORE		    && !(ent->match_flags & MATCHFLG_MERGE_FILE)) {			int f = am_sender || protocol_version < 29 ? f_out : -2;			send_rules(f, &cvs_filter_list);			if (f == f_out)				continue;		}		p = get_rule_prefix(ent->match_flags, ent->pattern, 1, &plen);		if (!p) {			rprintf(FERROR,				"filter rules are too modern for remote rsync.\n");			exit_cleanup(RERR_PROTOCOL);		}		if (f_out < 0)			continue;		len = strlen(ent->pattern);		dlen = ent->match_flags & MATCHFLG_DIRECTORY ? 1 : 0;		if (!(plen + len + dlen))			continue;		write_int(f_out, plen + len + dlen);		if (plen)			write_buf(f_out, p, plen);		write_buf(f_out, ent->pattern, len);		if (dlen)			write_byte(f_out, '/');	}	flp->tail = prev;}/* This is only called by the client. */void send_filter_list(int f_out){	int receiver_wants_list = prune_empty_dirs	    || (delete_mode && (!delete_excluded || protocol_version >= 29));	if (local_server || (am_sender && !receiver_wants_list))		f_out = -1;	if (cvs_exclude && am_sender) {		if (protocol_version >= 29)			parse_rule(&filter_list, ":C", 0, 0);		parse_rule(&filter_list, "-C", 0, 0);	}	send_rules(f_out, &filter_list);	if (f_out >= 0)		write_int(f_out, 0);	if (cvs_exclude) {		if (!am_sender || protocol_version < 29)			parse_rule(&filter_list, ":C", 0, 0);		if (!am_sender)			parse_rule(&filter_list, "-C", 0, 0);	}}/* This is only called by the server. */void recv_filter_list(int f_in){	char line[BIGPATHBUFLEN];	int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;	int receiver_wants_list = prune_empty_dirs	    || (delete_mode	     && (!delete_excluded || protocol_version >= 29));	unsigned int len;	if (!local_server && (am_sender || receiver_wants_list)) {		while ((len = read_int(f_in)) != 0) {			if (len >= sizeof line)				overflow_exit("recv_rules");			read_sbuf(f_in, line, len);			parse_rule(&filter_list, line, 0, xflags);		}	}	if (cvs_exclude) {		if (local_server || am_sender || protocol_version < 29)			parse_rule(&filter_list, ":C", 0, 0);		if (local_server || am_sender)			parse_rule(&filter_list, "-C", 0, 0);	}	if (local_server) /* filter out any rules that aren't for us. */		send_rules(-1, &filter_list);}

⌨️ 快捷键说明

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