]>
git.ipfire.org Git - thirdparty/rsync.git/blob - exclude.c
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* a lot of this stuff was originally derived from GNU tar, although
21 it has now changed so much that it is hard to tell :) */
27 static struct exclude_struct
**exclude_list
;
29 /* build an exclude structure given a exclude pattern */
30 static struct exclude_struct
*make_exclude(char *pattern
, int include
)
32 struct exclude_struct
*ret
;
34 ret
= (struct exclude_struct
*)malloc(sizeof(*ret
));
35 if (!ret
) out_of_memory("make_exclude");
37 memset(ret
, 0, sizeof(*ret
));
39 ret
->orig
= strdup(pattern
);
41 if (strncmp(pattern
,"- ",2) == 0) {
43 } else if (strncmp(pattern
,"+ ",2) == 0) {
47 ret
->include
= include
;
50 ret
->pattern
= strdup(pattern
);
52 if (!ret
->orig
|| !ret
->pattern
) out_of_memory("make_exclude");
54 if (strpbrk(pattern
, "*[?")) ret
->regular_exp
= 1;
56 if (strlen(pattern
) > 1 && pattern
[strlen(pattern
)-1] == '/') {
57 ret
->pattern
[strlen(pattern
)-1] = 0;
61 if (!strchr(ret
->pattern
,'/')) {
68 static void free_exclude(struct exclude_struct
*ex
)
72 memset(ex
,0,sizeof(*ex
));
76 static int check_one_exclude(char *name
,struct exclude_struct
*ex
,
81 char *pattern
= ex
->pattern
;
83 if (ex
->local
&& (p
=strrchr(name
,'/')))
86 if (!name
[0]) return 0;
88 if (ex
->directory
&& !S_ISDIR(st
->st_mode
)) return 0;
90 if (*pattern
== '/' && *name
!= '/') {
95 if (ex
->regular_exp
) {
96 if (fnmatch(ex
->pattern
, name
, 0) == 0)
99 int l1
= strlen(name
);
100 int l2
= strlen(ex
->pattern
);
102 strcmp(name
+(l1
-l2
),ex
->pattern
) == 0 &&
103 (l1
==l2
|| (!match_start
&& name
[l1
-(l2
+1)] == '/')))
111 int check_exclude(char *name
,struct exclude_struct
**local_exclude_list
,
117 for (n
=0; exclude_list
[n
]; n
++)
118 if (check_one_exclude(name
,exclude_list
[n
],st
))
119 return !exclude_list
[n
]->include
;
122 if (local_exclude_list
) {
123 for (n
=0; local_exclude_list
[n
]; n
++)
124 if (check_one_exclude(name
,local_exclude_list
[n
],st
))
125 return !local_exclude_list
[n
]->include
;
132 void add_exclude_list(char *pattern
,struct exclude_struct
***list
, int include
)
136 for (; (*list
)[len
]; len
++) ;
138 if (strcmp(pattern
,"!") == 0) {
140 rprintf(FINFO
,"clearing exclude list\n");
142 free_exclude((*list
)[len
]);
150 *list
= (struct exclude_struct
**)malloc(sizeof(struct exclude_struct
*)*2);
152 *list
= (struct exclude_struct
**)realloc(*list
,sizeof(struct exclude_struct
*)*(len
+2));
155 if (!*list
|| !((*list
)[len
] = make_exclude(pattern
, include
)))
156 out_of_memory("add_exclude");
159 rprintf(FINFO
,"add_exclude(%s)\n",pattern
);
161 (*list
)[len
+1] = NULL
;
164 void add_exclude(char *pattern
, int include
)
166 add_exclude_list(pattern
,&exclude_list
, include
);
169 struct exclude_struct
**make_exclude_list(char *fname
,
170 struct exclude_struct
**list1
,
171 int fatal
, int include
)
173 struct exclude_struct
**list
=list1
;
174 FILE *f
= fopen(fname
,"r");
175 char line
[MAXPATHLEN
];
178 rprintf(FERROR
,"%s : %s\n",fname
,strerror(errno
));
184 while (fgets(line
,MAXPATHLEN
,f
)) {
185 int l
= strlen(line
);
186 if (l
&& line
[l
-1] == '\n') l
--;
188 if (line
[0]) add_exclude_list(line
,&list
,include
);
195 void add_exclude_file(char *fname
,int fatal
,int include
)
197 if (!fname
|| !*fname
) return;
199 exclude_list
= make_exclude_list(fname
,exclude_list
,fatal
,include
);
203 void send_exclude_list(int f
)
206 extern int remote_version
;
213 for (i
=0;exclude_list
[i
];i
++) {
214 char *pattern
= exclude_list
[i
]->orig
;
217 if (remote_version
< 19) {
218 if (strncmp(pattern
,"+ ", 2)==0) {
219 rprintf(FERROR
,"remote rsync does not support include syntax - aborting\n");
223 if (strncmp(pattern
,"- ", 2) == 0) {
229 if (l
== 0) continue;
231 write_buf(f
,pattern
,l
);
238 void recv_exclude_list(int f
)
240 char line
[MAXPATHLEN
];
242 while ((l
=read_int(f
))) {
243 if (l
>= MAXPATHLEN
) overflow("recv_exclude_list");
250 void add_exclude_line(char *p
)
253 if (!p
|| !*p
) return;
255 if (!p
) out_of_memory("add_exclude_line");
256 for (tok
=strtok(p
," "); tok
; tok
=strtok(NULL
," "))
262 static char *cvs_ignore_list
[] = {
263 "RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
264 "tags","TAGS",".make.state",".nse_depinfo",
265 "*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig",
266 "*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln",
271 void add_cvs_excludes(void)
273 char fname
[MAXPATHLEN
];
277 for (i
=0; cvs_ignore_list
[i
]; i
++)
278 add_exclude(cvs_ignore_list
[i
], 0);
280 if ((p
=getenv("HOME")) && strlen(p
) < (MAXPATHLEN
-12)) {
281 slprintf(fname
,sizeof(fname
)-1, "%s/.cvsignore",p
);
282 add_exclude_file(fname
,0,0);
285 add_exclude_line(getenv("CVSIGNORE"));