Commit | Line | Data |
---|---|---|
c627d613 AT |
1 | /* |
2 | Copyright (C) Andrew Tridgell 1996 | |
3 | Copyright (C) Paul Mackerras 1996 | |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
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. | |
18 | */ | |
19 | ||
20 | /* | |
21 | a lot of this stuff was derived from GNU tar | |
22 | */ | |
23 | ||
24 | #include "rsync.h" | |
25 | ||
26 | extern int verbose; | |
27 | ||
3a6a366f | 28 | static char **exclude_list; |
c627d613 AT |
29 | |
30 | static int is_regex(char *str) | |
31 | { | |
32 | return strchr(str, '*') || strchr(str, '[') || strchr(str, '?'); | |
33 | } | |
34 | ||
35 | ||
36 | static int check_one_exclude(char *name,char *pattern) | |
37 | { | |
c627d613 AT |
38 | char *p; |
39 | ||
40 | if (!strchr(pattern,'/') && (p=strrchr(name,'/'))) | |
41 | name = p+1; | |
42 | ||
43 | if (!name[0]) return 0; | |
44 | ||
0944563e AT |
45 | if (*pattern == '/' && *name != '/') pattern++; |
46 | ||
c627d613 AT |
47 | if (is_regex(pattern)) { |
48 | if (fnmatch(pattern, name, 0) == 0) | |
49 | return 1; | |
50 | } else { | |
51 | int l1 = strlen(name); | |
52 | int l2 = strlen(pattern); | |
53 | if (l2 <= l1 && | |
54 | strcmp(name+(l1-l2),pattern) == 0 && | |
55 | (l1==l2 || name[l1-(l2+1)] == '/')) | |
56 | return 1; | |
57 | } | |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | ||
63 | int check_exclude(char *name,char **local_exclude_list) | |
64 | { | |
65 | int n; | |
66 | ||
67 | if (exclude_list) { | |
68 | for (n=0; exclude_list[n]; n++) | |
69 | if (check_one_exclude(name,exclude_list[n])) | |
70 | return 1; | |
71 | } | |
72 | ||
73 | if (local_exclude_list) { | |
74 | for (n=0; local_exclude_list[n]; n++) | |
75 | if (check_one_exclude(name,local_exclude_list[n])) | |
76 | return 1; | |
77 | } | |
78 | ||
79 | return 0; | |
80 | } | |
81 | ||
82 | ||
83 | void add_exclude_list(char *pattern,char ***list) | |
84 | { | |
85 | int len=0; | |
86 | if (list && *list) | |
87 | for (; (*list)[len]; len++) ; | |
88 | ||
89 | if (strcmp(pattern,"!") == 0) { | |
90 | if (verbose > 2) | |
9486289c | 91 | rprintf(FINFO,"clearing exclude list\n"); |
c627d613 AT |
92 | while ((len)--) |
93 | free((*list)[len]); | |
94 | free((*list)); | |
95 | *list = NULL; | |
96 | return; | |
97 | } | |
98 | ||
99 | if (!*list) { | |
100 | *list = (char **)malloc(sizeof(char *)*2); | |
101 | } else { | |
102 | *list = (char **)realloc(*list,sizeof(char *)*(len+2)); | |
103 | } | |
104 | ||
105 | if (!*list || !((*list)[len] = strdup(pattern))) | |
106 | out_of_memory("add_exclude"); | |
107 | ||
108 | if (verbose > 2) | |
9486289c | 109 | rprintf(FINFO,"add_exclude(%s)\n",pattern); |
c627d613 AT |
110 | |
111 | (*list)[len+1] = NULL; | |
112 | } | |
113 | ||
114 | void add_exclude(char *pattern) | |
115 | { | |
116 | add_exclude_list(pattern,&exclude_list); | |
117 | } | |
118 | ||
119 | char **make_exclude_list(char *fname,char **list1,int fatal) | |
120 | { | |
121 | char **list=list1; | |
122 | FILE *f = fopen(fname,"r"); | |
123 | char line[MAXPATHLEN]; | |
124 | if (!f) { | |
125 | if (fatal) { | |
9486289c | 126 | rprintf(FERROR,"%s : %s\n",fname,strerror(errno)); |
34ccb63e | 127 | exit_cleanup(1); |
c627d613 AT |
128 | } |
129 | return list; | |
130 | } | |
131 | ||
132 | while (fgets(line,MAXPATHLEN,f)) { | |
133 | int l = strlen(line); | |
134 | if (l && line[l-1] == '\n') l--; | |
135 | line[l] = 0; | |
136 | if (line[0]) add_exclude_list(line,&list); | |
137 | } | |
138 | fclose(f); | |
139 | return list; | |
140 | } | |
141 | ||
142 | ||
143 | void add_exclude_file(char *fname,int fatal) | |
144 | { | |
8f3a2d54 AT |
145 | if (!fname || !*fname) return; |
146 | ||
147 | exclude_list = make_exclude_list(fname,exclude_list,fatal); | |
c627d613 AT |
148 | } |
149 | ||
150 | ||
151 | void send_exclude_list(int f) | |
152 | { | |
153 | int i; | |
154 | if (exclude_list) | |
155 | for (i=0;exclude_list[i];i++) { | |
156 | int l = strlen(exclude_list[i]); | |
157 | if (l == 0) continue; | |
158 | write_int(f,l); | |
159 | write_buf(f,exclude_list[i],l); | |
160 | } | |
161 | write_int(f,0); | |
162 | } | |
163 | ||
164 | ||
165 | void recv_exclude_list(int f) | |
166 | { | |
167 | char line[MAXPATHLEN]; | |
168 | int l; | |
169 | while ((l=read_int(f))) { | |
575f2fca AT |
170 | if (l >= MAXPATHLEN) overflow("recv_exclude_list"); |
171 | read_sbuf(f,line,l); | |
172 | add_exclude(line); | |
c627d613 AT |
173 | } |
174 | } | |
175 | ||
176 | ||
8f3a2d54 AT |
177 | void add_exclude_line(char *p) |
178 | { | |
179 | char *tok; | |
180 | if (!p || !*p) return; | |
181 | p = strdup(p); | |
182 | if (!p) out_of_memory("add_exclude_line"); | |
183 | for (tok=strtok(p," "); tok; tok=strtok(NULL," ")) | |
184 | add_exclude(tok); | |
185 | free(p); | |
186 | } | |
187 | ||
188 | ||
c627d613 AT |
189 | static char *cvs_ignore_list[] = { |
190 | "RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*", | |
191 | "tags","TAGS",".make.state",".nse_depinfo", | |
192 | "*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig", | |
193 | "*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln", | |
194 | "core",NULL}; | |
195 | ||
196 | ||
197 | ||
198 | void add_cvs_excludes(void) | |
199 | { | |
200 | char fname[MAXPATHLEN]; | |
201 | char *p; | |
202 | int i; | |
203 | ||
204 | for (i=0; cvs_ignore_list[i]; i++) | |
205 | add_exclude(cvs_ignore_list[i]); | |
206 | ||
13a1f792 | 207 | if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) { |
e42c9458 AT |
208 | slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p); |
209 | add_exclude_file(fname,0); | |
c627d613 AT |
210 | } |
211 | ||
8f3a2d54 | 212 | add_exclude_line(getenv("CVSIGNORE")); |
c627d613 | 213 | } |