This source file includes following definitions.
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26
27 #if HAVE_ACL_GET_FILE || HAVE_FACL || HAVE_GETACL || HAVE_ACLX_GET || HAVE_STATACL || HAVE_ACLSORT
28 # include <sys/types.h>
29 # include <sys/acl.h>
30 #endif
31 #if HAVE_ACLV_H
32 # include <sys/types.h>
33 # include <aclv.h>
34 #endif
35
36 #include "read-file.h"
37 #include "xalloc.h"
38 #include "macros.h"
39
40 int
41 main (int argc, char *argv[])
42 {
43 const char *file1;
44 const char *file2;
45
46 ASSERT (argc == 3);
47
48 file1 = argv[1];
49 file2 = argv[2];
50
51
52 {
53 size_t size1;
54 char *contents1;
55 size_t size2;
56 char *contents2;
57
58 contents1 = read_file (file1, 0, &size1);
59 if (contents1 == NULL)
60 {
61 fprintf (stderr, "error reading file %s: errno = %d\n", file1, errno);
62 fflush (stderr);
63 abort ();
64 }
65 contents2 = read_file (file2, 0, &size2);
66 if (contents2 == NULL)
67 {
68 fprintf (stderr, "error reading file %s: errno = %d\n", file2, errno);
69 fflush (stderr);
70 abort ();
71 }
72
73 if (size2 != size1)
74 {
75 fprintf (stderr, "files %s and %s have different sizes\n",
76 file1, file2);
77 fflush (stderr);
78 abort ();
79 }
80 if (memcmp (contents1, contents2, size1) != 0)
81 {
82 fprintf (stderr, "files %s and %s have different contents\n",
83 file1, file2);
84 fflush (stderr);
85 abort ();
86 }
87
88 free (contents2);
89 free (contents1);
90 }
91
92
93 {
94 struct stat statbuf1;
95 struct stat statbuf2;
96
97 if (stat (file1, &statbuf1) < 0)
98 {
99 fprintf (stderr, "error accessing file %s: errno = %d\n", file1, errno);
100 fflush (stderr);
101 abort ();
102 }
103 if (stat (file2, &statbuf2) < 0)
104 {
105 fprintf (stderr, "error accessing file %s: errno = %d\n", file2, errno);
106 fflush (stderr);
107 abort ();
108 }
109 if (statbuf1.st_mode != statbuf2.st_mode)
110 {
111 fprintf (stderr, "files %s and %s have different access modes: %03o and %03o\n",
112 file1, file2,
113 (unsigned int) statbuf1.st_mode, (unsigned int) statbuf2.st_mode);
114 return 1;
115 }
116 }
117 {
118 #if HAVE_ACL_GET_FILE
119 static const int types[] =
120 {
121 ACL_TYPE_ACCESS
122 # if HAVE_ACL_TYPE_EXTENDED
123 , ACL_TYPE_EXTENDED
124 # endif
125 };
126 int t;
127
128 for (t = 0; t < sizeof (types) / sizeof (types[0]); t++)
129 {
130 int type = types[t];
131 acl_t acl1;
132 char *text1;
133 int errno1;
134 acl_t acl2;
135 char *text2;
136 int errno2;
137
138 acl1 = acl_get_file (file1, type);
139 if (acl1 == (acl_t)NULL)
140 {
141 text1 = NULL;
142 errno1 = errno;
143 }
144 else
145 {
146 text1 = acl_to_text (acl1, NULL);
147 if (text1 == NULL)
148 errno1 = errno;
149 else
150 errno1 = 0;
151 }
152 acl2 = acl_get_file (file2, type);
153 if (acl2 == (acl_t)NULL)
154 {
155 text2 = NULL;
156 errno2 = errno;
157 }
158 else
159 {
160 text2 = acl_to_text (acl2, NULL);
161 if (text2 == NULL)
162 errno2 = errno;
163 else
164 errno2 = 0;
165 }
166
167 if (acl1 != (acl_t)NULL)
168 {
169 if (acl2 != (acl_t)NULL)
170 {
171 if (text1 != NULL)
172 {
173 if (text2 != NULL)
174 {
175 if (strcmp (text1, text2) != 0)
176 {
177 fprintf (stderr, "files %s and %s have different ACLs:\n%s\n%s\n",
178 file1, file2, text1, text2);
179 return 1;
180 }
181 }
182 else
183 {
184 fprintf (stderr, "file %s has a valid ACL, but file %s has an invalid ACL\n",
185 file1, file2);
186 return 1;
187 }
188 }
189 else
190 {
191 if (text2 != NULL)
192 {
193 fprintf (stderr, "file %s has an invalid ACL, but file %s has a valid ACL\n",
194 file1, file2);
195 return 1;
196 }
197 else
198 {
199 if (errno1 != errno2)
200 {
201 fprintf (stderr, "files %s and %s have differently invalid ACLs, errno = %d vs. %d\n",
202 file1, file2, errno1, errno2);
203 return 1;
204 }
205 }
206 }
207 }
208 else
209 {
210 fprintf (stderr, "file %s has an ACL, but file %s has no ACL\n",
211 file1, file2);
212 return 1;
213 }
214 }
215 else
216 {
217 if (acl2 != (acl_t)NULL)
218 {
219 fprintf (stderr, "file %s has no ACL, but file %s has an ACL\n",
220 file1, file2);
221 return 1;
222 }
223 }
224 acl_free (text2);
225 if (acl2 != (acl_t)NULL)
226 acl_free (acl2);
227 acl_free (text1);
228 if (acl1 != (acl_t)NULL)
229 acl_free (acl1);
230 }
231 #elif HAVE_FACL && defined GETACL
232 int count1;
233 int count2;
234
235 count1 = acl (file1, GETACLCNT, 0, NULL);
236 if (count1 < 0 && errno == ENOSYS)
237 count1 = 0;
238 count2 = acl (file2, GETACLCNT, 0, NULL);
239 if (count2 < 0 && errno == ENOSYS)
240 count2 = 0;
241
242 if (count1 < 0)
243 {
244 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
245 fflush (stderr);
246 abort ();
247 }
248 if (count2 < 0)
249 {
250 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
251 fflush (stderr);
252 abort ();
253 }
254 if (count1 != count2)
255 {
256 fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
257 file1, file2, count1, count2);
258 return 1;
259 }
260 else
261 {
262 aclent_t *entries1 = XNMALLOC (count1, aclent_t);
263 aclent_t *entries2 = XNMALLOC (count2, aclent_t);
264 int i;
265
266 if (count1 > 0 && acl (file1, GETACL, count1, entries1) < count1)
267 {
268 fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
269 fflush (stderr);
270 abort ();
271 }
272 if (count2 > 0 && acl (file2, GETACL, count2, entries2) < count1)
273 {
274 fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
275 fflush (stderr);
276 abort ();
277 }
278 for (i = 0; i < count1; i++)
279 {
280 if (entries1[i].a_type != entries2[i].a_type)
281 {
282 fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
283 file1, file2, i, entries1[i].a_type, entries2[i].a_type);
284 return 1;
285 }
286 if (entries1[i].a_id != entries2[i].a_id)
287 {
288 fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
289 file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
290 return 1;
291 }
292 if (entries1[i].a_perm != entries2[i].a_perm)
293 {
294 fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
295 file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
296 return 1;
297 }
298 }
299 free (entries2);
300 free (entries1);
301 }
302 # ifdef ACE_GETACL
303 count1 = acl (file1, ACE_GETACLCNT, 0, NULL);
304 if (count1 < 0 && errno == EINVAL)
305 count1 = 0;
306 count2 = acl (file2, ACE_GETACLCNT, 0, NULL);
307 if (count2 < 0 && errno == EINVAL)
308 count2 = 0;
309 if (count1 < 0)
310 {
311 fprintf (stderr, "error accessing the ACE-ACLs of file %s\n", file1);
312 fflush (stderr);
313 abort ();
314 }
315 if (count2 < 0)
316 {
317 fprintf (stderr, "error accessing the ACE-ACLs of file %s\n", file2);
318 fflush (stderr);
319 abort ();
320 }
321 {
322 ace_t *entries1 = XNMALLOC (count1, ace_t);
323 ace_t *entries2 = XNMALLOC (count2, ace_t);
324 int ret;
325 int i;
326
327 ret = acl (file1, ACE_GETACL, count1, entries1);
328 if (ret < 0 && errno == EINVAL)
329 count1 = 0;
330 else if (ret < count1)
331 {
332 fprintf (stderr, "error retrieving the ACE-ACLs of file %s\n", file1);
333 fflush (stderr);
334 abort ();
335 }
336 ret = acl (file2, ACE_GETACL, count2, entries2);
337 if (ret < 0 && errno == EINVAL)
338 count2 = 0;
339 else if (ret < count2)
340 {
341 fprintf (stderr, "error retrieving the ACE-ACLs of file %s\n", file2);
342 fflush (stderr);
343 abort ();
344 }
345
346 if (count1 != count2)
347 {
348 fprintf (stderr, "files %s and %s have different number of ACE-ACLs: %d and %d\n",
349 file1, file2, count1, count2);
350 return 1;
351 }
352
353 for (i = 0; i < count1; i++)
354 {
355 if (entries1[i].a_type != entries2[i].a_type)
356 {
357 fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different types %d and %d\n",
358 file1, file2, i, entries1[i].a_type, entries2[i].a_type);
359 return 1;
360 }
361 if (entries1[i].a_who != entries2[i].a_who)
362 {
363 fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different ids %d and %d\n",
364 file1, file2, i, (int)entries1[i].a_who, (int)entries2[i].a_who);
365 return 1;
366 }
367 if (entries1[i].a_access_mask != entries2[i].a_access_mask)
368 {
369 fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different access masks %03o and %03o\n",
370 file1, file2, i, (unsigned int) entries1[i].a_access_mask, (unsigned int) entries2[i].a_access_mask);
371 return 1;
372 }
373 if (entries1[i].a_flags != entries2[i].a_flags)
374 {
375 fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different flags 0x%x and 0x%x\n",
376 file1, file2, i, (unsigned int) entries1[i].a_flags, (unsigned int) entries2[i].a_flags);
377 return 1;
378 }
379 }
380 free (entries2);
381 free (entries1);
382 }
383 # endif
384 #elif HAVE_GETACL
385 int count1;
386 int count2;
387
388 count1 = getacl (file1, 0, NULL);
389 if (count1 < 0
390 && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
391 count1 = 0;
392 count2 = getacl (file2, 0, NULL);
393 if (count2 < 0
394 && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
395 count2 = 0;
396
397 if (count1 < 0)
398 {
399 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
400 fflush (stderr);
401 abort ();
402 }
403 if (count2 < 0)
404 {
405 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
406 fflush (stderr);
407 abort ();
408 }
409 if (count1 != count2)
410 {
411 fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
412 file1, file2, count1, count2);
413 return 1;
414 }
415 else if (count1 > 0)
416 {
417 struct acl_entry *entries1 = XNMALLOC (count1, struct acl_entry);
418 struct acl_entry *entries2 = XNMALLOC (count2, struct acl_entry);
419 int i;
420
421 if (getacl (file1, count1, entries1) < count1)
422 {
423 fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
424 fflush (stderr);
425 abort ();
426 }
427 if (getacl (file2, count2, entries2) < count1)
428 {
429 fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
430 fflush (stderr);
431 abort ();
432 }
433 for (i = 0; i < count1; i++)
434 {
435 if (entries1[i].uid != entries2[i].uid)
436 {
437 fprintf (stderr, "files %s and %s: different ACL entry #%d: different uids %d and %d\n",
438 file1, file2, i, (int)entries1[i].uid, (int)entries2[i].uid);
439 return 1;
440 }
441 if (entries1[i].gid != entries2[i].gid)
442 {
443 fprintf (stderr, "files %s and %s: different ACL entry #%d: different gids %d and %d\n",
444 file1, file2, i, (int)entries1[i].gid, (int)entries2[i].gid);
445 return 1;
446 }
447 if (entries1[i].mode != entries2[i].mode)
448 {
449 fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
450 file1, file2, i, (unsigned int) entries1[i].mode, (unsigned int) entries2[i].mode);
451 return 1;
452 }
453 }
454 free (entries2);
455 free (entries1);
456 }
457
458 # if HAVE_ACLV_H
459 {
460 struct acl dummy_entries[NACLVENTRIES];
461
462 count1 = acl ((char *) file1, ACL_CNT, NACLVENTRIES, dummy_entries);
463 if (count1 < 0
464 && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
465 count1 = 0;
466 count2 = acl ((char *) file2, ACL_CNT, NACLVENTRIES, dummy_entries);
467 if (count2 < 0
468 && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
469 count2 = 0;
470 }
471
472 if (count1 < 0)
473 {
474 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
475 fflush (stderr);
476 abort ();
477 }
478 if (count2 < 0)
479 {
480 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
481 fflush (stderr);
482 abort ();
483 }
484 if (count1 != count2)
485 {
486 fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
487 file1, file2, count1, count2);
488 return 1;
489 }
490 else if (count1 > 0)
491 {
492 struct acl *entries1 = XNMALLOC (count1, struct acl);
493 struct acl *entries2 = XNMALLOC (count2, struct acl);
494 int i;
495
496 if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
497 {
498 fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
499 fflush (stderr);
500 abort ();
501 }
502 if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
503 {
504 fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
505 fflush (stderr);
506 abort ();
507 }
508 for (i = 0; i < count1; i++)
509 {
510 if (entries1[i].a_type != entries2[i].a_type)
511 {
512 fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
513 file1, file2, i, entries1[i].a_type, entries2[i].a_type);
514 return 1;
515 }
516 if (entries1[i].a_id != entries2[i].a_id)
517 {
518 fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
519 file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
520 return 1;
521 }
522 if (entries1[i].a_perm != entries2[i].a_perm)
523 {
524 fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
525 file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
526 return 1;
527 }
528 }
529 free (entries2);
530 free (entries1);
531 }
532 # endif
533 #elif HAVE_ACLX_GET
534 acl_type_t type1;
535 char acl1[1000];
536 size_t aclsize1 = sizeof (acl1);
537 mode_t mode1;
538 char text1[1000];
539 size_t textsize1 = sizeof (text1);
540 acl_type_t type2;
541 char acl2[1000];
542 size_t aclsize2 = sizeof (acl2);
543 mode_t mode2;
544 char text2[1000];
545 size_t textsize2 = sizeof (text2);
546
547
548
549 type1.u64 = ACL_ANY;
550 if (aclx_get (file1, 0, &type1, acl1, &aclsize1, &mode1) < 0)
551 {
552 if (errno == ENOSYS)
553 text1[0] = '\0';
554 else
555 {
556 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
557 fflush (stderr);
558 abort ();
559 }
560 }
561 else
562 if (aclx_printStr (text1, &textsize1, acl1, aclsize1, type1, file1, 0) < 0)
563 {
564 fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file1);
565 fflush (stderr);
566 abort ();
567 }
568
569
570
571 type2.u64 = ACL_ANY;
572 if (aclx_get (file2, 0, &type2, acl2, &aclsize2, &mode2) < 0)
573 {
574 if (errno == ENOSYS)
575 text2[0] = '\0';
576 else
577 {
578 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
579 fflush (stderr);
580 abort ();
581 }
582 }
583 else
584 if (aclx_printStr (text2, &textsize2, acl2, aclsize2, type2, file2, 0) < 0)
585 {
586 fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file2);
587 fflush (stderr);
588 abort ();
589 }
590
591 if (strcmp (text1, text2) != 0)
592 {
593 fprintf (stderr, "files %s and %s have different ACLs:\n%s\n%s\n",
594 file1, file2, text1, text2);
595 return 1;
596 }
597 #elif HAVE_STATACL
598 union { struct acl a; char room[4096]; } acl1;
599 union { struct acl a; char room[4096]; } acl2;
600 unsigned int i;
601
602 if (statacl (file1, STX_NORMAL, &acl1.a, sizeof (acl1)) < 0)
603 {
604 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
605 fflush (stderr);
606 abort ();
607 }
608 if (statacl (file2, STX_NORMAL, &acl2.a, sizeof (acl2)) < 0)
609 {
610 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
611 fflush (stderr);
612 abort ();
613 }
614
615 if (acl1.a.acl_len != acl2.a.acl_len)
616 {
617 fprintf (stderr, "files %s and %s have different ACL lengths: %u and %u\n",
618 file1, file2, acl1.a.acl_len, acl2.a.acl_len);
619 return 1;
620 }
621 if (acl1.a.acl_mode != acl2.a.acl_mode)
622 {
623 fprintf (stderr, "files %s and %s have different ACL modes: %03o and %03o\n",
624 file1, file2, acl1.a.acl_mode, acl2.a.acl_mode);
625 return 1;
626 }
627 if (acl1.a.u_access != acl2.a.u_access
628 || acl1.a.g_access != acl2.a.g_access
629 || acl1.a.o_access != acl2.a.o_access)
630 {
631 fprintf (stderr, "files %s and %s have different ACL access masks: %03o %03o %03o and %03o %03o %03o\n",
632 file1, file2,
633 acl1.a.u_access, acl1.a.g_access, acl1.a.o_access,
634 acl2.a.u_access, acl2.a.g_access, acl2.a.o_access);
635 return 1;
636 }
637 if (memcmp (acl1.a.acl_ext, acl2.a.acl_ext, acl1.a.acl_len) != 0)
638 {
639 fprintf (stderr, "files %s and %s have different ACL entries\n",
640 file1, file2);
641 return 1;
642 }
643 #elif HAVE_ACLSORT
644 int count1;
645 int count2;
646
647 count1 = acl ((char *) file1, ACL_CNT, NACLENTRIES, NULL);
648 count2 = acl ((char *) file2, ACL_CNT, NACLENTRIES, NULL);
649
650 if (count1 < 0)
651 {
652 fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
653 fflush (stderr);
654 abort ();
655 }
656 if (count2 < 0)
657 {
658 fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
659 fflush (stderr);
660 abort ();
661 }
662 if (count1 != count2)
663 {
664 fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
665 file1, file2, count1, count2);
666 return 1;
667 }
668 else if (count1 > 0)
669 {
670 struct acl *entries1 = XNMALLOC (count1, struct acl);
671 struct acl *entries2 = XNMALLOC (count2, struct acl);
672 int i;
673
674 if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
675 {
676 fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
677 fflush (stderr);
678 abort ();
679 }
680 if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
681 {
682 fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
683 fflush (stderr);
684 abort ();
685 }
686 for (i = 0; i < count1; i++)
687 {
688 if (entries1[i].a_type != entries2[i].a_type)
689 {
690 fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
691 file1, file2, i, entries1[i].a_type, entries2[i].a_type);
692 return 1;
693 }
694 if (entries1[i].a_id != entries2[i].a_id)
695 {
696 fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
697 file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
698 return 1;
699 }
700 if (entries1[i].a_perm != entries2[i].a_perm)
701 {
702 fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
703 file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
704 return 1;
705 }
706 }
707 free (entries2);
708 free (entries1);
709 }
710 #endif
711 }
712
713 return 0;
714 }