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 | ||
28 | static char **exclude_list = NULL; | |
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 | ||
45 | if (is_regex(pattern)) { | |
46 | if (fnmatch(pattern, name, 0) == 0) | |
47 | return 1; | |
48 | } else { | |
49 | int l1 = strlen(name); | |
50 | int l2 = strlen(pattern); | |
51 | if (l2 <= l1 && | |
52 | strcmp(name+(l1-l2),pattern) == 0 && | |
53 | (l1==l2 || name[l1-(l2+1)] == '/')) | |
54 | return 1; | |
55 | } | |
56 | ||
57 | return 0; | |
58 | } | |
59 | ||
60 | ||
61 | int check_exclude(char *name,char **local_exclude_list) | |
62 | { | |
63 | int n; | |
64 | ||
65 | if (exclude_list) { | |
66 | for (n=0; exclude_list[n]; n++) | |
67 | if (check_one_exclude(name,exclude_list[n])) | |
68 | return 1; | |
69 | } | |
70 | ||
71 | if (local_exclude_list) { | |
72 | for (n=0; local_exclude_list[n]; n++) | |
73 | if (check_one_exclude(name,local_exclude_list[n])) | |
74 | return 1; | |
75 | } | |
76 | ||
77 | return 0; | |
78 | } | |
79 | ||
80 | ||
81 | void add_exclude_list(char *pattern,char ***list) | |
82 | { | |
83 | int len=0; | |
84 | if (list && *list) | |
85 | for (; (*list)[len]; len++) ; | |
86 | ||
87 | if (strcmp(pattern,"!") == 0) { | |
88 | if (verbose > 2) | |
dc5ddbcc | 89 | fprintf(FERROR,"clearing exclude list\n"); |
c627d613 AT |
90 | while ((len)--) |
91 | free((*list)[len]); | |
92 | free((*list)); | |
93 | *list = NULL; | |
94 | return; | |
95 | } | |
96 | ||
97 | if (!*list) { | |
98 | *list = (char **)malloc(sizeof(char *)*2); | |
99 | } else { | |
100 | *list = (char **)realloc(*list,sizeof(char *)*(len+2)); | |
101 | } | |
102 | ||
103 | if (!*list || !((*list)[len] = strdup(pattern))) | |
104 | out_of_memory("add_exclude"); | |
105 | ||
106 | if (verbose > 2) | |
dc5ddbcc | 107 | fprintf(FERROR,"add_exclude(%s)\n",pattern); |
c627d613 AT |
108 | |
109 | (*list)[len+1] = NULL; | |
110 | } | |
111 | ||
112 | void add_exclude(char *pattern) | |
113 | { | |
114 | add_exclude_list(pattern,&exclude_list); | |
115 | } | |
116 | ||
117 | char **make_exclude_list(char *fname,char **list1,int fatal) | |
118 | { | |
119 | char **list=list1; | |
120 | FILE *f = fopen(fname,"r"); | |
121 | char line[MAXPATHLEN]; | |
122 | if (!f) { | |
123 | if (fatal) { | |
dc5ddbcc | 124 | fprintf(FERROR,"%s : %s\n",fname,strerror(errno)); |
34ccb63e | 125 | exit_cleanup(1); |
c627d613 AT |
126 | } |
127 | return list; | |
128 | } | |
129 | ||
130 | while (fgets(line,MAXPATHLEN,f)) { | |
131 | int l = strlen(line); | |
132 | if (l && line[l-1] == '\n') l--; | |
133 | line[l] = 0; | |
134 | if (line[0]) add_exclude_list(line,&list); | |
135 | } | |
136 | fclose(f); | |
137 | return list; | |
138 | } | |
139 | ||
140 | ||
141 | void add_exclude_file(char *fname,int fatal) | |
142 | { | |
143 | exclude_list = make_exclude_list(fname,exclude_list,fatal); | |
144 | } | |
145 | ||
146 | ||
147 | void send_exclude_list(int f) | |
148 | { | |
149 | int i; | |
150 | if (exclude_list) | |
151 | for (i=0;exclude_list[i];i++) { | |
152 | int l = strlen(exclude_list[i]); | |
153 | if (l == 0) continue; | |
154 | write_int(f,l); | |
155 | write_buf(f,exclude_list[i],l); | |
156 | } | |
157 | write_int(f,0); | |
158 | } | |
159 | ||
160 | ||
161 | void recv_exclude_list(int f) | |
162 | { | |
163 | char line[MAXPATHLEN]; | |
164 | int l; | |
165 | while ((l=read_int(f))) { | |
166 | read_buf(f,line,l); | |
167 | line[l] = 0; | |
168 | add_exclude(line); | |
169 | } | |
170 | } | |
171 | ||
172 | ||
173 | static char *cvs_ignore_list[] = { | |
174 | "RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*", | |
175 | "tags","TAGS",".make.state",".nse_depinfo", | |
176 | "*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig", | |
177 | "*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln", | |
178 | "core",NULL}; | |
179 | ||
180 | ||
181 | ||
182 | void add_cvs_excludes(void) | |
183 | { | |
184 | char fname[MAXPATHLEN]; | |
185 | char *p; | |
186 | int i; | |
187 | ||
188 | for (i=0; cvs_ignore_list[i]; i++) | |
189 | add_exclude(cvs_ignore_list[i]); | |
190 | ||
191 | if ((p=getenv("HOME"))) { | |
192 | sprintf(fname,"%s/.cvsignore",p); | |
193 | add_exclude_file(fname,0); | |
194 | } | |
195 | ||
196 | if ((p=getenv("CVSIGNORE"))) { | |
197 | char *tok; | |
198 | for (tok=strtok(p," "); tok; tok=strtok(NULL," ")) | |
199 | add_exclude(tok); | |
200 | } | |
201 | } |