root/maint/gnulib/tests/test-sameacls.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* Test whether two files have the same ACLs.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2008.  */
  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[])
     /* [previous][next][first][last][top][bottom][index][help] */
  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   /* Compare the contents of the two files.  */
  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   /* Compare the access permissions of the two files, including ACLs.  */
  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 /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */
 119     static const int types[] =
 120       {
 121         ACL_TYPE_ACCESS
 122 # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
 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 /* Solaris, Cygwin, not HP-UX */
 232   int count1;
 233   int count2;
 234 
 235   count1 = acl (file1, GETACLCNT, 0, NULL);
 236   if (count1 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
 237     count1 = 0;
 238   count2 = acl (file2, GETACLCNT, 0, NULL);
 239   if (count2 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
 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 /* HP-UX */
 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 /* HP-UX >= 11.11 */
 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 /* AIX */
 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   /* The docs say that type1 being 0 is equivalent to ACL_ANY, but it is not
 548      true, in AIX 5.3.  */
 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   /* The docs say that type2 being 0 is equivalent to ACL_ANY, but it is not
 570      true, in AIX 5.3.  */
 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 /* older AIX */
 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 /* NonStop Kernel */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */