Deleted Added
full compact
mkctm.c (15773) mkctm.c (19813)
1/* Still missing:
2 *
1/* Still missing:
2 *
3 * Damage counter
4 * Change counter
5 * Time stamp
6 * prefix
7 * cmd-line args
8 * %100 deltas
9 * delta and Add are different. delta -> Equ.
10 *
11 * mkctm
12 * -B regex Bogus
13 * -I regex Ignore
14 * -D int Damage
15 * -q decrease verbosity
16 * -v increase verbosity
3 * mkctm
4 * -B regex Bogus
5 * -I regex Ignore
6 * -D int Damage
7 * -q decrease verbosity
8 * -v increase verbosity
17 * (-l str control logging.)
9 * -l file logfile
18 * name cvs-cur
19 * prefix src/secure
20 * dir1 "Soll"
21 * dir2 "Ist"
22 *
23 */
24
25#include <sys/types.h>

--- 7 unchanged lines hidden (view full) ---

33#include <string.h>
34#include <stdlib.h>
35#include <unistd.h>
36#include <md5.h>
37#include <err.h>
38#include <signal.h>
39
40#define DEFAULT_IGNORE "/CVS$|/\\.#|00_TRANS\\.TBL$"
10 * name cvs-cur
11 * prefix src/secure
12 * dir1 "Soll"
13 * dir2 "Ist"
14 *
15 */
16
17#include <sys/types.h>

--- 7 unchanged lines hidden (view full) ---

25#include <string.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <md5.h>
29#include <err.h>
30#include <signal.h>
31
32#define DEFAULT_IGNORE "/CVS$|/\\.#|00_TRANS\\.TBL$"
41#define DEFAULT_BOGUS "\\.core$|\\.orig$|\\.rej$"
33#define DEFAULT_BOGUS "\\.core$|\\.orig$|\\.rej$|\\.o$"
42regex_t reg_ignore, reg_bogus;
43int flag_ignore, flag_bogus;
44
45int verbose;
46int damage, damage_limit;
47int change;
48
34regex_t reg_ignore, reg_bogus;
35int flag_ignore, flag_bogus;
36
37int verbose;
38int damage, damage_limit;
39int change;
40
41FILE *logf;
42
49u_long s1_ignored, s2_ignored;
50u_long s1_bogus, s2_bogus;
51u_long s1_wrong, s2_wrong;
52u_long s_new_dirs, s_new_files, s_new_bytes;
53u_long s_del_dirs, s_del_files, s_del_bytes;
54u_long s_files_chg, s_bytes_add, s_bytes_del;
55u_long s_same_dirs, s_same_files, s_same_bytes;
56u_long s_edit_files, s_edit_bytes, s_edit_saves;

--- 11 unchanged lines hidden (view full) ---

68 fprintf(stderr, "\t\t-I ignore_regexp\n");
69 fprintf(stderr, "\t\t-q\n");
70 fprintf(stderr, "\t\t-v\n");
71}
72
73void
74print_stat(FILE *fd, char *pre)
75{
43u_long s1_ignored, s2_ignored;
44u_long s1_bogus, s2_bogus;
45u_long s1_wrong, s2_wrong;
46u_long s_new_dirs, s_new_files, s_new_bytes;
47u_long s_del_dirs, s_del_files, s_del_bytes;
48u_long s_files_chg, s_bytes_add, s_bytes_del;
49u_long s_same_dirs, s_same_files, s_same_bytes;
50u_long s_edit_files, s_edit_bytes, s_edit_saves;

--- 11 unchanged lines hidden (view full) ---

62 fprintf(stderr, "\t\t-I ignore_regexp\n");
63 fprintf(stderr, "\t\t-q\n");
64 fprintf(stderr, "\t\t-v\n");
65}
66
67void
68print_stat(FILE *fd, char *pre)
69{
76 fprintf(fd,"%sAvoided:\n",pre);
77 fprintf(fd,"%s ignore: %5lu old %5lu new\n",
70 fprintf(fd, "%sNames:\n", pre);
71 fprintf(fd, "%s ignore: %5lu ref %5lu target\n",
78 pre, s1_ignored, s2_ignored);
72 pre, s1_ignored, s2_ignored);
79 fprintf(fd,"%s bogus: %5lu old %5lu new\n",
73 fprintf(fd, "%s bogus: %5lu ref %5lu target\n",
80 pre, s1_bogus, s2_bogus);
74 pre, s1_bogus, s2_bogus);
81 fprintf(fd,"%s wrong: %5lu old %5lu new\n",
75 fprintf(fd, "%s wrong: %5lu ref %5lu target\n",
82 pre, s1_wrong, s2_wrong);
76 pre, s1_wrong, s2_wrong);
83 fprintf(fd,"%sDelta:\n",pre);
84 fprintf(fd,"%s new: %5lu dirs %5lu files %9lu plus\n",
77 fprintf(fd, "%sDelta:\n", pre);
78 fprintf(fd, "%s new: %5lu dirs %5lu files %9lu plus\n",
85 pre, s_new_dirs, s_new_files, s_new_bytes);
79 pre, s_new_dirs, s_new_files, s_new_bytes);
86 fprintf(fd,"%s del: %5lu dirs %5lu files %9lu minus\n",
80 fprintf(fd, "%s del: %5lu dirs %5lu files %9lu minus\n",
87 pre, s_del_dirs, s_del_files, s_del_bytes);
81 pre, s_del_dirs, s_del_files, s_del_bytes);
88 fprintf(fd,"%s chg: %5lu files %9lu plus %9lu minus\n",
82 fprintf(fd, "%s chg: %5lu files %9lu plus %9lu minus\n",
89 pre, s_files_chg, s_bytes_add, s_bytes_del);
83 pre, s_files_chg, s_bytes_add, s_bytes_del);
90 fprintf(fd,"%s same: %5lu dirs %5lu files %9lu bytes\n",
84 fprintf(fd, "%s same: %5lu dirs %5lu files %9lu bytes\n",
91 pre, s_same_dirs, s_same_files, s_same_bytes);
85 pre, s_same_dirs, s_same_files, s_same_bytes);
92 fprintf(fd,"%sMethod:\n",pre);
93 fprintf(fd,"%s edit: %5lu files %9lu bytes %9lu saved\n",
86 fprintf(fd, "%sMethod:\n", pre);
87 fprintf(fd, "%s edit: %5lu files %9lu bytes %9lu saved\n",
94 pre, s_edit_files, s_edit_bytes, s_edit_saves);
88 pre, s_edit_files, s_edit_bytes, s_edit_saves);
95 fprintf(fd,"%s sub: %5lu files %9lu bytes\n",
89 fprintf(fd, "%s sub: %5lu files %9lu bytes\n",
96 pre, s_sub_files, s_sub_bytes);
90 pre, s_sub_files, s_sub_bytes);
91
97}
98
99void
100stat_info(int foo)
101{
92}
93
94void
95stat_info(int foo)
96{
102 signal(SIGINFO,stat_info);
103 print_stat(stderr,"INFO: ");
97 signal(SIGINFO, stat_info);
98 print_stat(stderr, "INFO: ");
104}
105
106void DoDir(const char *dir1, const char *dir2, const char *name);
107
108static struct stat st;
109static __inline struct stat *
110StatFile(char *name)
111{
99}
100
101void DoDir(const char *dir1, const char *dir2, const char *name);
102
103static struct stat st;
104static __inline struct stat *
105StatFile(char *name)
106{
112 if (lstat(name,&st) < 0)
113 err(1,"Couldn't stat %s\n",name);
107 if (lstat(name, &st) < 0)
108 err(1, "Couldn't stat %s\n", name);
114 return &st;
115}
116
117int
118dirselect(struct dirent *de)
119{
109 return &st;
110}
111
112int
113dirselect(struct dirent *de)
114{
120 if (!strcmp(de->d_name,".")) return 0;
121 if (!strcmp(de->d_name,"..")) return 0;
115 if (!strcmp(de->d_name, ".")) return 0;
116 if (!strcmp(de->d_name, "..")) return 0;
122 return 1;
123}
124
125void
126name_stat(const char *pfx, const char *dir, const char *name, struct dirent *de)
127{
128 char *buf = alloca(strlen(dir) + strlen(name) +
129 strlen(de->d_name) + 3);
130 struct stat *st;
131
117 return 1;
118}
119
120void
121name_stat(const char *pfx, const char *dir, const char *name, struct dirent *de)
122{
123 char *buf = alloca(strlen(dir) + strlen(name) +
124 strlen(de->d_name) + 3);
125 struct stat *st;
126
132 strcpy(buf,dir);
133 strcat(buf,"/"); strcat(buf,name);
134 strcat(buf,"/"); strcat(buf,de->d_name);
127 strcpy(buf, dir);
128 strcat(buf, "/"); strcat(buf, name);
129 strcat(buf, "/"); strcat(buf, de->d_name);
135 st = StatFile(buf);
130 st = StatFile(buf);
136 printf("%s %s%s %lu %lu %o",
131 printf("%s %s%s %u %u %o",
137 pfx, name, de->d_name,
138 st->st_uid, st->st_gid, st->st_mode & ~S_IFMT);
132 pfx, name, de->d_name,
133 st->st_uid, st->st_gid, st->st_mode & ~S_IFMT);
134 fprintf(logf, "%s %s%s\n", pfx, name, de->d_name);
139 if (verbose > 1) {
135 if (verbose > 1) {
140 fprintf(stderr,"%s %s%s\n", pfx, name, de->d_name);
136 fprintf(stderr, "%s %s%s\n", pfx, name, de->d_name);
141 }
142}
143
144void
145Equ(const char *dir1, const char *dir2, const char *name, struct dirent *de)
146{
147 if (de->d_type == DT_DIR) {
148 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
149
137 }
138}
139
140void
141Equ(const char *dir1, const char *dir2, const char *name, struct dirent *de)
142{
143 if (de->d_type == DT_DIR) {
144 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
145
150 strcpy(p,name); strcat(p,de->d_name); strcat(p, "/");
151 DoDir(dir1,dir2,p);
146 strcpy(p, name); strcat(p, de->d_name); strcat(p, "/");
147 DoDir(dir1, dir2, p);
152 s_same_dirs++;
153 } else {
154 char *buf1 = alloca(strlen(dir1) + strlen(name) +
155 strlen(de->d_name) + 3);
156 char *buf2 = alloca(strlen(dir2) + strlen(name) +
157 strlen(de->d_name) + 3);
148 s_same_dirs++;
149 } else {
150 char *buf1 = alloca(strlen(dir1) + strlen(name) +
151 strlen(de->d_name) + 3);
152 char *buf2 = alloca(strlen(dir2) + strlen(name) +
153 strlen(de->d_name) + 3);
158 char *m1,md5_1[33],*m2, md5_2[33];
159 u_char *p1,*p2;
160 int fd1,fd2;
161 struct stat s1,s2;
154 char *m1, md5_1[33], *m2, md5_2[33];
155 u_char *p1, *p2;
156 int fd1, fd2;
157 struct stat s1, s2;
162
158
163 strcpy(buf1,dir1);
164 strcat(buf1,"/"); strcat(buf1,name);
165 strcat(buf1,"/"); strcat(buf1,de->d_name);
166 fd1 = open(buf1,O_RDONLY);
159 strcpy(buf1, dir1);
160 strcat(buf1, "/"); strcat(buf1, name);
161 strcat(buf1, "/"); strcat(buf1, de->d_name);
162 fd1 = open(buf1, O_RDONLY);
167 if(fd1 < 0) { perror(buf1); exit(3); }
163 if(fd1 < 0) { perror(buf1); exit(3); }
168 fstat(fd1,&s1);
169 strcpy(buf2,dir2);
170 strcat(buf2,"/"); strcat(buf2,name);
171 strcat(buf2,"/"); strcat(buf2,de->d_name);
172 fd2 = open(buf2,O_RDONLY);
164 fstat(fd1, &s1);
165 strcpy(buf2, dir2);
166 strcat(buf2, "/"); strcat(buf2, name);
167 strcat(buf2, "/"); strcat(buf2, de->d_name);
168 fd2 = open(buf2, O_RDONLY);
173 if(fd2 < 0) { perror(buf2); exit(3); }
169 if(fd2 < 0) { perror(buf2); exit(3); }
174 fstat(fd2,&s2);
170 fstat(fd2, &s2);
175#if 0
176 /* XXX if we could just trust the size to change... */
177 if (s1.st_size == s2.st_size) {
178 s_same_files++;
179 s_same_bytes += s1.st_size;
180 close(fd1);
181 close(fd2);
182 goto finish;
183 }
184#endif
171#if 0
172 /* XXX if we could just trust the size to change... */
173 if (s1.st_size == s2.st_size) {
174 s_same_files++;
175 s_same_bytes += s1.st_size;
176 close(fd1);
177 close(fd2);
178 goto finish;
179 }
180#endif
185 p1=mmap(0,s1.st_size,PROT_READ,MAP_PRIVATE,fd1,0);
181 p1=mmap(0, s1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
186 if ((int)p1 == -1) { perror(buf1); exit(3); }
187 close(fd1);
188
182 if ((int)p1 == -1) { perror(buf1); exit(3); }
183 close(fd1);
184
189 p2=mmap(0,s2.st_size,PROT_READ,MAP_PRIVATE,fd2,0);
185 p2=mmap(0, s2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
190 if ((int)p2 == -1) { perror(buf2); exit(3); }
191 close(fd2);
192
193 /* If identical, we're done. */
186 if ((int)p2 == -1) { perror(buf2); exit(3); }
187 close(fd2);
188
189 /* If identical, we're done. */
194 if((s1.st_size == s2.st_size) && !memcmp(p1,p2,s1.st_size)) {
190 if((s1.st_size == s2.st_size) && !memcmp(p1, p2, s1.st_size)) {
195 s_same_files++;
196 s_same_bytes += s1.st_size;
197 goto finish;
198 }
199
200 s_files_chg++;
191 s_same_files++;
192 s_same_bytes += s1.st_size;
193 goto finish;
194 }
195
196 s_files_chg++;
201 damage++;
202 change++;
203 if (s1.st_size > s2.st_size)
204 s_bytes_del += (s1.st_size - s2.st_size);
205 else
206 s_bytes_add += (s2.st_size - s1.st_size);
207
208 m1 = MD5Data(p1, s1.st_size, md5_1);
209 m2 = MD5Data(p2, s2.st_size, md5_2);
210
211 /* Just a curiosity... */
197 change++;
198 if (s1.st_size > s2.st_size)
199 s_bytes_del += (s1.st_size - s2.st_size);
200 else
201 s_bytes_add += (s2.st_size - s1.st_size);
202
203 m1 = MD5Data(p1, s1.st_size, md5_1);
204 m2 = MD5Data(p2, s2.st_size, md5_2);
205
206 /* Just a curiosity... */
212 if(!strcmp(m1,m2)) {
207 if(!strcmp(m1, m2)) {
213 if (s1.st_size != s2.st_size)
214 fprintf(stderr,
215 "Notice: MD5 same for files of diffent size:\n\t%s\n\t%s\n",
208 if (s1.st_size != s2.st_size)
209 fprintf(stderr,
210 "Notice: MD5 same for files of diffent size:\n\t%s\n\t%s\n",
216 buf1,buf2);
211 buf1, buf2);
217 goto finish;
218 }
219
220 {
221 u_long l = s2.st_size + 2;
222 u_char *cmd = alloca(strlen(buf1)+strlen(buf2)+100);
223 u_char *ob = alloca(l), *p;
224 int j;

--- 32 unchanged lines hidden (view full) ---

257 buf2);
258 goto subst;
259 }
260
261 strcpy(cmd, "diff -n ");
262 strcat(cmd, buf1);
263 strcat(cmd, " ");
264 strcat(cmd, buf2);
212 goto finish;
213 }
214
215 {
216 u_long l = s2.st_size + 2;
217 u_char *cmd = alloca(strlen(buf1)+strlen(buf2)+100);
218 u_char *ob = alloca(l), *p;
219 int j;

--- 32 unchanged lines hidden (view full) ---

252 buf2);
253 goto subst;
254 }
255
256 strcpy(cmd, "diff -n ");
257 strcat(cmd, buf1);
258 strcat(cmd, " ");
259 strcat(cmd, buf2);
265 F = popen(cmd,"r");
260 F = popen(cmd, "r");
266 for (j = 1, l = 0; l < s2.st_size; ) {
267 j = fread(ob+l, 1, s2.st_size - l, F);
268 if (j < 1)
269 break;
270 l += j;
271 continue;
272 }
273 if (j) {
274 l = 0;
275 while (EOF != fgetc(F))
276 continue;
277 }
278 pclose(F);
279
280 if (l && l < s2.st_size) {
261 for (j = 1, l = 0; l < s2.st_size; ) {
262 j = fread(ob+l, 1, s2.st_size - l, F);
263 if (j < 1)
264 break;
265 l += j;
266 continue;
267 }
268 if (j) {
269 l = 0;
270 while (EOF != fgetc(F))
271 continue;
272 }
273 pclose(F);
274
275 if (l && l < s2.st_size) {
281 name_stat("CTMFN",dir2,name,de);
282 printf(" %s %s %d\n",m1,m2,(unsigned)l);
283 fwrite(ob,1,l,stdout);
276 name_stat("CTMFN", dir2, name, de);
277 printf(" %s %s %d\n", m1, m2, (unsigned)l);
278 fwrite(ob, 1, l, stdout);
284 putchar('\n');
285 s_edit_files++;
286 s_edit_bytes += l;
287 s_edit_saves += (s2.st_size - l);
288 } else {
289 subst:
279 putchar('\n');
280 s_edit_files++;
281 s_edit_bytes += l;
282 s_edit_saves += (s2.st_size - l);
283 } else {
284 subst:
290 name_stat("CTMFS",dir2,name,de);
291 printf(" %s %s %u\n",m1,m2,(unsigned)s2.st_size);
292 fwrite(p2,1,s2.st_size,stdout);
285 name_stat("CTMFS", dir2, name, de);
286 printf(" %s %s %u\n", m1, m2, (unsigned)s2.st_size);
287 fwrite(p2, 1, s2.st_size, stdout);
293 putchar('\n');
294 s_sub_files++;
295 s_sub_bytes += s2.st_size;
296 }
297 }
298 finish:
288 putchar('\n');
289 s_sub_files++;
290 s_sub_bytes += s2.st_size;
291 }
292 }
293 finish:
299 munmap(p1,s1.st_size);
300 munmap(p2,s2.st_size);
294 munmap(p1, s1.st_size);
295 munmap(p2, s2.st_size);
301 }
302}
303
304void
305Add(const char *dir1, const char *dir2, const char *name, struct dirent *de)
306{
307 change++;
308 if (de->d_type == DT_DIR) {
309 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
296 }
297}
298
299void
300Add(const char *dir1, const char *dir2, const char *name, struct dirent *de)
301{
302 change++;
303 if (de->d_type == DT_DIR) {
304 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
310 strcpy(p,name); strcat(p,de->d_name); strcat(p, "/");
311 name_stat("CTMDM",dir2,name,de);
305 strcpy(p, name); strcat(p, de->d_name); strcat(p, "/");
306 name_stat("CTMDM", dir2, name, de);
312 putchar('\n');
313 s_new_dirs++;
307 putchar('\n');
308 s_new_dirs++;
314 DoDir(dir1,dir2,p);
309 DoDir(dir1, dir2, p);
315 } else if (de->d_type == DT_REG) {
316 char *buf2 = alloca(strlen(dir2) + strlen(name) +
317 strlen(de->d_name) + 3);
318 char *m2, md5_2[33];
319 u_char *p1;
320 struct stat st;
321 int fd1;
322
310 } else if (de->d_type == DT_REG) {
311 char *buf2 = alloca(strlen(dir2) + strlen(name) +
312 strlen(de->d_name) + 3);
313 char *m2, md5_2[33];
314 u_char *p1;
315 struct stat st;
316 int fd1;
317
323 strcpy(buf2,dir2);
324 strcat(buf2,"/"); strcat(buf2,name);
325 strcat(buf2,"/"); strcat(buf2,de->d_name);
326 fd1 = open(buf2,O_RDONLY);
318 strcpy(buf2, dir2);
319 strcat(buf2, "/"); strcat(buf2, name);
320 strcat(buf2, "/"); strcat(buf2, de->d_name);
321 fd1 = open(buf2, O_RDONLY);
327 if (fd1 < 0) {perror(buf2); exit (3); }
322 if (fd1 < 0) {perror(buf2); exit (3); }
328 fstat(fd1,&st);
329 p1=mmap(0,st.st_size,PROT_READ,MAP_PRIVATE,fd1,0);
323 fstat(fd1, &st);
324 p1=mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
330 if ((int)p1 == -1) { perror(buf2); exit(3); }
331 close(fd1);
332 m2 = MD5Data(p1, st.st_size, md5_2);
325 if ((int)p1 == -1) { perror(buf2); exit(3); }
326 close(fd1);
327 m2 = MD5Data(p1, st.st_size, md5_2);
333 name_stat("CTMFM",dir2,name,de);
334 printf(" %s %u\n",m2,(unsigned)st.st_size);
335 fwrite(p1,1,st.st_size,stdout);
328 name_stat("CTMFM", dir2, name, de);
329 printf(" %s %u\n", m2, (unsigned)st.st_size);
330 fwrite(p1, 1, st.st_size, stdout);
336 putchar('\n');
331 putchar('\n');
337 munmap(p1,st.st_size);
332 munmap(p1, st.st_size);
338 s_new_files++;
339 s_new_bytes += st.st_size;
340 }
341}
342
343void
344Del (const char *dir1, const char *dir2, const char *name, struct dirent *de)
345{
346 damage++;
347 change++;
348 if (de->d_type == DT_DIR) {
349 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
333 s_new_files++;
334 s_new_bytes += st.st_size;
335 }
336}
337
338void
339Del (const char *dir1, const char *dir2, const char *name, struct dirent *de)
340{
341 damage++;
342 change++;
343 if (de->d_type == DT_DIR) {
344 char *p = alloca(strlen(name)+strlen(de->d_name)+2);
350 strcpy(p,name); strcat(p,de->d_name); strcat(p, "/");
351 DoDir(dir1,dir2,p);
352 printf("CTMDR %s%s\n",name,de->d_name);
345 strcpy(p, name); strcat(p, de->d_name); strcat(p, "/");
346 DoDir(dir1, dir2, p);
347 printf("CTMDR %s%s\n", name, de->d_name);
348 fprintf(logf, "CTMDR %s%s\n", name, de->d_name);
349 if (verbose > 1) {
350 fprintf(stderr, "CTMDR %s%s\n", name, de->d_name);
351 }
353 s_del_dirs++;
354 } else if (de->d_type == DT_REG) {
355 char *buf1 = alloca(strlen(dir1) + strlen(name) +
356 strlen(de->d_name) + 3);
357 char *m1, md5_1[33];
352 s_del_dirs++;
353 } else if (de->d_type == DT_REG) {
354 char *buf1 = alloca(strlen(dir1) + strlen(name) +
355 strlen(de->d_name) + 3);
356 char *m1, md5_1[33];
358 strcpy(buf1,dir1);
359 strcat(buf1,"/"); strcat(buf1,name);
360 strcat(buf1,"/"); strcat(buf1,de->d_name);
357 strcpy(buf1, dir1);
358 strcat(buf1, "/"); strcat(buf1, name);
359 strcat(buf1, "/"); strcat(buf1, de->d_name);
361 m1 = MD5File(buf1, md5_1);
360 m1 = MD5File(buf1, md5_1);
362 printf("CTMFR %s%s %s\n",name,de->d_name,m1);
361 printf("CTMFR %s%s %s\n", name, de->d_name, m1);
362 fprintf(logf, "CTMFR %s%s %s\n", name, de->d_name, m1);
363 if (verbose > 1) {
364 fprintf(stderr, "CTMFR %s%s\n", name, de->d_name);
365 }
363 s_del_files++;
364 s_del_bytes += StatFile(buf1)->st_size;
365 }
366}
367
368void
369GetNext(int *i, int *n, struct dirent **nl, const char *dir, const char *name, u_long *ignored, u_long *bogus, u_long *wrong)
370{
371 char buf[BUFSIZ];
372
373 for (;;) {
374 for (;;) {
375 (*i)++;
376 if (*i >= *n)
377 return;
378 *buf = 0;
379 if (*dir != '/')
366 s_del_files++;
367 s_del_bytes += StatFile(buf1)->st_size;
368 }
369}
370
371void
372GetNext(int *i, int *n, struct dirent **nl, const char *dir, const char *name, u_long *ignored, u_long *bogus, u_long *wrong)
373{
374 char buf[BUFSIZ];
375
376 for (;;) {
377 for (;;) {
378 (*i)++;
379 if (*i >= *n)
380 return;
381 *buf = 0;
382 if (*dir != '/')
380 strcat(buf,"/");
381 strcat(buf,dir);
383 strcat(buf, "/");
384 strcat(buf, dir);
382 if (buf[strlen(buf)-1] != '/')
385 if (buf[strlen(buf)-1] != '/')
383 strcat(buf,"/");
384 strcat(buf,name);
386 strcat(buf, "/");
387 strcat(buf, name);
385 if (buf[strlen(buf)-1] != '/')
388 if (buf[strlen(buf)-1] != '/')
386 strcat(buf,"/");
387 strcat(buf,nl[*i]->d_name);
389 strcat(buf, "/");
390 strcat(buf, nl[*i]->d_name);
388 if (flag_ignore &&
391 if (flag_ignore &&
389 !regexec(&reg_ignore,buf,0,0,0)) {
392 !regexec(&reg_ignore, buf, 0, 0, 0)) {
390 (*ignored)++;
393 (*ignored)++;
394 fprintf(logf, "Ignore %s\n", buf);
391 if (verbose > 2) {
395 if (verbose > 2) {
392 fprintf(stderr,"Ignore %s\n",buf);
396 fprintf(stderr, "Ignore %s\n", buf);
393 }
394 } else if (flag_bogus &&
397 }
398 } else if (flag_bogus &&
395 !regexec(&reg_bogus,buf,0,0,0)) {
399 !regexec(&reg_bogus, buf, 0, 0, 0)) {
396 (*bogus)++;
400 (*bogus)++;
397 if (verbose > 0) {
398 fprintf(stderr,"Bogus %s\n",buf);
399 }
401 fprintf(logf, "Bogus %s\n", buf);
402 fprintf(stderr, "Bogus %s\n", buf);
403 damage++;
400 } else {
401 break;
402 }
403 free(nl[*i]); nl[*i] = 0;
404 }
405 /* If the filesystem didn't tell us, find type */
406 if (nl[*i]->d_type == DT_UNKNOWN)
407 nl[*i]->d_type = IFTODT(StatFile(buf)->st_mode);
408 if (nl[*i]->d_type == DT_REG || nl[*i]->d_type == DT_DIR)
409 break;
410 (*wrong)++;
411 if (verbose > 0)
404 } else {
405 break;
406 }
407 free(nl[*i]); nl[*i] = 0;
408 }
409 /* If the filesystem didn't tell us, find type */
410 if (nl[*i]->d_type == DT_UNKNOWN)
411 nl[*i]->d_type = IFTODT(StatFile(buf)->st_mode);
412 if (nl[*i]->d_type == DT_REG || nl[*i]->d_type == DT_DIR)
413 break;
414 (*wrong)++;
415 if (verbose > 0)
412 fprintf(stderr,"Wrong %s\n",buf);
416 fprintf(stderr, "Wrong %s\n", buf);
413 free(nl[*i]); nl[*i] = 0;
414 }
415}
416
417void
418DoDir(const char *dir1, const char *dir2, const char *name)
419{
417 free(nl[*i]); nl[*i] = 0;
418 }
419}
420
421void
422DoDir(const char *dir1, const char *dir2, const char *name)
423{
420 int i1,i2,n1,n2,i;
421 struct dirent **nl1,**nl2;
424 int i1, i2, n1, n2, i;
425 struct dirent **nl1, **nl2;
422 char *buf1 = alloca(strlen(dir1) + strlen(name) + 4);
423 char *buf2 = alloca(strlen(dir2) + strlen(name) + 4);
424
426 char *buf1 = alloca(strlen(dir1) + strlen(name) + 4);
427 char *buf2 = alloca(strlen(dir2) + strlen(name) + 4);
428
425 strcpy(buf1,dir1); strcat(buf1,"/"); strcat(buf1,name);
426 strcpy(buf2,dir2); strcat(buf2,"/"); strcat(buf2,name);
429 strcpy(buf1, dir1); strcat(buf1, "/"); strcat(buf1, name);
430 strcpy(buf2, dir2); strcat(buf2, "/"); strcat(buf2, name);
427 n1 = scandir(buf1, &nl1, dirselect, alphasort);
428 n2 = scandir(buf2, &nl2, dirselect, alphasort);
429 i1 = i2 = -1;
430 GetNext(&i1, &n1, nl1, dir1, name, &s1_ignored, &s1_bogus, &s1_wrong);
431 GetNext(&i2, &n2, nl2, dir2, name, &s2_ignored, &s2_bogus, &s2_wrong);
432 for (;i1 < n1 || i2 < n2;) {
433
434 if (damage_limit && damage > damage_limit)

--- 9 unchanged lines hidden (view full) ---

444 GetNext(&i2, &n2, nl2, dir2, name,
445 &s2_ignored, &s2_bogus, &s2_wrong);
446
447 if (i1 >= n1 && i2 >= n2) {
448 /* Done */
449 break;
450 } else if (i1 >= n1 && i2 < n2) {
451 /* end of list 1, add anything left on list 2 */
431 n1 = scandir(buf1, &nl1, dirselect, alphasort);
432 n2 = scandir(buf2, &nl2, dirselect, alphasort);
433 i1 = i2 = -1;
434 GetNext(&i1, &n1, nl1, dir1, name, &s1_ignored, &s1_bogus, &s1_wrong);
435 GetNext(&i2, &n2, nl2, dir2, name, &s2_ignored, &s2_bogus, &s2_wrong);
436 for (;i1 < n1 || i2 < n2;) {
437
438 if (damage_limit && damage > damage_limit)

--- 9 unchanged lines hidden (view full) ---

448 GetNext(&i2, &n2, nl2, dir2, name,
449 &s2_ignored, &s2_bogus, &s2_wrong);
450
451 if (i1 >= n1 && i2 >= n2) {
452 /* Done */
453 break;
454 } else if (i1 >= n1 && i2 < n2) {
455 /* end of list 1, add anything left on list 2 */
452 Add(dir1,dir2,name,nl2[i2]);
456 Add(dir1, dir2, name, nl2[i2]);
453 free(nl2[i2]); nl2[i2] = 0;
454 } else if (i1 < n1 && i2 >= n2) {
455 /* end of list 2, delete anything left on list 1 */
457 free(nl2[i2]); nl2[i2] = 0;
458 } else if (i1 < n1 && i2 >= n2) {
459 /* end of list 2, delete anything left on list 1 */
456 Del(dir1,dir2,name,nl1[i1]);
460 Del(dir1, dir2, name, nl1[i1]);
457 free(nl1[i1]); nl1[i1] = 0;
458 } else if (!(i = strcmp(nl1[i1]->d_name, nl2[i2]->d_name))) {
459 /* Identical names */
460 if (nl1[i1]->d_type == nl2[i2]->d_type) {
461 /* same type */
461 free(nl1[i1]); nl1[i1] = 0;
462 } else if (!(i = strcmp(nl1[i1]->d_name, nl2[i2]->d_name))) {
463 /* Identical names */
464 if (nl1[i1]->d_type == nl2[i2]->d_type) {
465 /* same type */
462 Equ(dir1,dir2,name,nl1[i1]);
466 Equ(dir1, dir2, name, nl1[i1]);
463 } else {
464 /* different types */
467 } else {
468 /* different types */
465 Del(dir1,dir2,name,nl1[i1]);
466 Add(dir1,dir2,name,nl2[i2]);
469 Del(dir1, dir2, name, nl1[i1]);
470 Add(dir1, dir2, name, nl2[i2]);
467 }
468 free(nl1[i1]); nl1[i1] = 0;
469 free(nl2[i2]); nl2[i2] = 0;
470 } else if (i < 0) {
471 /* Something extra in list 1, delete it */
471 }
472 free(nl1[i1]); nl1[i1] = 0;
473 free(nl2[i2]); nl2[i2] = 0;
474 } else if (i < 0) {
475 /* Something extra in list 1, delete it */
472 Del(dir1,dir2,name,nl1[i1]);
476 Del(dir1, dir2, name, nl1[i1]);
473 free(nl1[i1]); nl1[i1] = 0;
474 } else {
475 /* Something extra in list 2, add it */
477 free(nl1[i1]); nl1[i1] = 0;
478 } else {
479 /* Something extra in list 2, add it */
476 Add(dir1,dir2,name,nl2[i2]);
480 Add(dir1, dir2, name, nl2[i2]);
477 free(nl2[i2]); nl2[i2] = 0;
478 }
479 }
480 if (n1 >= 0)
481 free(nl1);
482 if (n2 >= 0)
483 free(nl2);
484}
485
486int
487main(int argc, char **argv)
488{
489 int i;
490 extern char *optarg;
491 extern int optind;
492
493 setbuf(stderr, NULL);
494
481 free(nl2[i2]); nl2[i2] = 0;
482 }
483 }
484 if (n1 >= 0)
485 free(nl1);
486 if (n2 >= 0)
487 free(nl2);
488}
489
490int
491main(int argc, char **argv)
492{
493 int i;
494 extern char *optarg;
495 extern int optind;
496
497 setbuf(stderr, NULL);
498
495 if (regcomp(&reg_bogus,DEFAULT_BOGUS, REG_EXTENDED | REG_NEWLINE))
499#if 0
500 if (regcomp(&reg_bogus, DEFAULT_BOGUS, REG_EXTENDED | REG_NEWLINE))
496 /* XXX use regerror to explain it */
501 /* XXX use regerror to explain it */
497 err(1,"Default regular expression argument to -B is botched");
502 errx(1, "Default regular expression argument to -B is botched");
498 flag_bogus = 1;
499
503 flag_bogus = 1;
504
500 if (regcomp(®_ignore,DEFAULT_IGNORE, REG_EXTENDED | REG_NEWLINE))
505 if (regcomp(&reg_ignore, DEFAULT_IGNORE, REG_EXTENDED | REG_NEWLINE))
501 /* XXX use regerror to explain it */
506 /* XXX use regerror to explain it */
502 err(1,"Default regular expression argument to -I is botched");
507 errx(1, "Default regular expression argument to -I is botched");
503 flag_ignore = 1;
508 flag_ignore = 1;
509#endif
504
510
505 while ((i = getopt(argc,argv,"D:I:B:qv")) != EOF)
511 while ((i = getopt(argc, argv, "D:I:B:l:qv")) != EOF)
506 switch (i) {
507 case 'D':
512 switch (i) {
513 case 'D':
508 damage_limit = strtol(optarg,0,0);
514 damage_limit = strtol(optarg, 0, 0);
509 if (damage_limit < 0)
515 if (damage_limit < 0)
510 err(1,"Damage limit must be positive");
516 errx(1, "Damage limit must be positive");
511 break;
512 case 'I':
513 if (flag_ignore)
514 regfree(&reg_ignore);
515 flag_ignore = 0;
516 if (!*optarg)
517 break;
517 break;
518 case 'I':
519 if (flag_ignore)
520 regfree(&reg_ignore);
521 flag_ignore = 0;
522 if (!*optarg)
523 break;
518 if (regcomp(®_ignore,optarg,
524 if (regcomp(&reg_ignore, optarg,
519 REG_EXTENDED | REG_NEWLINE))
520 /* XXX use regerror to explain it */
525 REG_EXTENDED | REG_NEWLINE))
526 /* XXX use regerror to explain it */
521 err(1,"Regular expression argument to -I is botched");
527 errx(1, "Regular expression argument to -I is botched");
522 flag_ignore = 1;
523 break;
524 case 'B':
525 if (flag_bogus)
526 regfree(&reg_bogus);
527 flag_bogus = 0;
528 if (!*optarg)
529 break;
528 flag_ignore = 1;
529 break;
530 case 'B':
531 if (flag_bogus)
532 regfree(&reg_bogus);
533 flag_bogus = 0;
534 if (!*optarg)
535 break;
530 if (regcomp(®_bogus,optarg,
536 if (regcomp(&reg_bogus, optarg,
531 REG_EXTENDED | REG_NEWLINE))
532 /* XXX use regerror to explain it */
537 REG_EXTENDED | REG_NEWLINE))
538 /* XXX use regerror to explain it */
533 err(1,"Regular expression argument to -B is botched");
539 errx(1, "Regular expression argument to -B is botched");
534 flag_bogus = 1;
535 break;
540 flag_bogus = 1;
541 break;
542 case 'l':
543 logf = fopen(optarg, "w");
544 if (!logf)
545 err(1, optarg);
546 break;
536 case 'q':
537 verbose--;
538 break;
539 case 'v':
540 verbose++;
541 break;
542 case '?':
543 default:
544 Usage();
545 return (1);
546 }
547 argc -= optind;
548 argv += optind;
549
547 case 'q':
548 verbose--;
549 break;
550 case 'v':
551 verbose++;
552 break;
553 case '?':
554 default:
555 Usage();
556 return (1);
557 }
558 argc -= optind;
559 argv += optind;
560
550 setbuf(stdout,0);
561 if (!logf)
562 logf = fopen("/dev/null", "w");
551
563
564 setbuf(stdout, 0);
565
552 if (argc != 6) {
553 Usage();
554 return (1);
555 }
556
566 if (argc != 6) {
567 Usage();
568 return (1);
569 }
570
557 signal(SIGINFO,stat_info);
571 signal(SIGINFO, stat_info);
558
572
573 fprintf(stderr, "CTM_BEGIN 2.0 %s %s %s %s\n",
574 argv[0], argv[1], argv[2], argv[3]);
575 fprintf(logf, "CTM_BEGIN 2.0 %s %s %s %s\n",
576 argv[0], argv[1], argv[2], argv[3]);
559 printf("CTM_BEGIN 2.0 %s %s %s %s\n",
560 argv[0], argv[1], argv[2], argv[3]);
577 printf("CTM_BEGIN 2.0 %s %s %s %s\n",
578 argv[0], argv[1], argv[2], argv[3]);
561 DoDir(argv[4],argv[5],"");
579 DoDir(argv[4], argv[5], "");
562 if (damage_limit && damage > damage_limit) {
580 if (damage_limit && damage > damage_limit) {
563 print_stat(stderr,"");
564 err(1,"Damage would exceede %d files", damage_limit);
565 } else if (!change) {
566 err(1,"No changes");
581 print_stat(stderr, "DAMAGE: ");
582 errx(1, "Damage of %d would exceed %d files",
583 damage, damage_limit);
584 } else if (change < 2) {
585 errx(1, "No changes");
567 } else {
568 printf("CTM_END ");
586 } else {
587 printf("CTM_END ");
569 print_stat(stderr,"");
588 fprintf(logf, "CTM_END\n");
589 print_stat(stderr, "END: ");
570 }
571 exit(0);
572}
590 }
591 exit(0);
592}