diff -uP ./defs.h /home/pietro/findutils-4.4.2/find/defs.h
--- ./defs.h	2009-05-16 17:17:01.000000000 +0200
+++ /home/pietro/findutils-4.4.2/find/defs.h	2009-09-28 19:23:18.000000000 +0200
@@ -49,7 +49,9 @@
 #include <stdint.h>		/* for uintmax_t */
 #include <sys/stat.h> /* S_ISUID etc. */
 
-
+#ifdef HAVE_LIBACL
+#include <sys/acl.h>
+#endif
 
 #ifndef CHAR_BIT
 # define CHAR_BIT 8
@@ -150,6 +152,18 @@
   mode_t val[2];
 };
 
+#ifdef HAVE_LIBACL
+struct meta_acl
+{
+  acl_type_t a_type;
+  acl_tag_t a_tag;
+  id_t a_id;
+  bool a_id_any;
+  acl_perm_t a_perm;
+  bool a_perm_any;
+};
+#endif
+
 /* dir_id is used to support loop detection in find.c
  */
 struct dir_id
@@ -315,6 +329,9 @@
     struct samefile_file_id samefileid; /* samefile */
     mode_t type;		/* type */
     struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
+#ifdef HAVE_LIBACL
+    struct meta_acl *meta_acl;         /* acl */
+#endif
   } args;
 
   /* The next predicate in the user input sequence,
@@ -401,6 +418,9 @@
 /* pred.c */
 
 typedef boolean PREDICATEFUNCTION(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
+#ifdef HAVE_LIBACL
+PREDICATEFUNCTION pred_acl;
+#endif
 PREDICATEFUNCTION pred_amin;
 PREDICATEFUNCTION pred_and;
 PREDICATEFUNCTION pred_anewer;
diff -uP ./parser.c /home/pietro/findutils-4.4.2/find/parser.c
--- ./parser.c	2009-05-16 17:17:01.000000000 +0200
+++ /home/pietro/findutils-4.4.2/find/parser.c	2009-09-29 00:25:44.000000000 +0200
@@ -45,6 +45,9 @@
 
 #include <fcntl.h>
 
+#ifdef HAVE_LIBACL
+#include <sys/acl.h>
+#endif
 
 /* The presence of unistd.h is assumed by gnulib these days, so we
  * might as well assume it too.
@@ -82,6 +85,9 @@
 #define endpwent()
 #endif
 
+#ifdef HAVE_LIBACL
+static boolean parse_acl           PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
+#endif
 static boolean parse_accesscheck   PARAMS((const struct parser_table* entry, char **argv, int *arg_ptr));
 static boolean parse_amin          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_and           PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
@@ -244,6 +250,9 @@
   PARSE_PUNCTUATION(")",                     closeparen), /* POSIX */
   PARSE_PUNCTUATION(",",                     comma),	     /* GNU */
   PARSE_PUNCTUATION("a",                     and), /* POSIX */
+#ifdef HAVE_LIBACL
+  PARSE_TEST       ("acl",                   acl),
+#endif
   PARSE_TEST       ("amin",                  amin),	     /* GNU */
   PARSE_PUNCTUATION("and",                   and),		/* GNU */
   PARSE_TEST       ("anewer",                anewer),	     /* GNU */
@@ -671,6 +680,26 @@
    The predicate structure is updated with the new information. */
 
 
+#ifdef HAVE_LIBACL
+static boolean
+parse_acl (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+  struct predicate *our_pred;
+
+  if ((argv == NULL) || (argv[*arg_ptr] == NULL))
+    return false;
+
+  our_pred = insert_primary (entry);
+  our_pred->need_stat = our_pred->need_type = false;
+
+  if (parse_meta_acl (&argv[*arg_ptr], &our_pred->args.meta_acl) == -1)
+    return false;
+
+  (*arg_ptr)++;
+  return true;
+}
+#endif
+
 static boolean
 parse_and (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
@@ -1119,7 +1148,7 @@
       -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
       --version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
   puts (_("\
-tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
+tests (N can be +N or -N or N): -acl ACL -amin N -anewer FILE -atime N -cmin N\n\
       -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
       -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\
       -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE"));
diff -uP ./pred.c /home/pietro/findutils-4.4.2/find/pred.c
--- ./pred.c	2009-05-16 17:17:01.000000000 +0200
+++ /home/pietro/findutils-4.4.2/find/pred.c	2009-09-28 19:24:38.000000000 +0200
@@ -48,6 +48,9 @@
 #include "error.h"
 #include "verify.h"
 
+#ifdef HAVE_LIBACL
+# include <sys/acl.h>
+#endif
 #if ENABLE_NLS
 # include <libintl.h>
 # define _(Text) gettext (Text)
@@ -173,6 +176,9 @@
 
 struct pred_assoc pred_table[] =
 {
+#ifdef HAVE_LIBACL
+  {pred_acl, "acl     "},
+#endif
   {pred_amin, "amin    "},
   {pred_and, "and     "},
   {pred_anewer, "anewer  "},
@@ -310,6 +316,96 @@
   abort ();
 }
 
+#ifdef HAVE_LIBACL
+boolean
+pred_acl (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+  acl_t acl = NULL;
+  struct meta_acl *meta_acl_val = malloc(sizeof(struct meta_acl));
+  acl_entry_t ent;
+  int ret = 0, e_perm = 0, n = 0;
+  acl_permset_t e_permset;
+  acl_tag_t e_tag;
+  id_t *e_id;
+
+  meta_acl_val = &pred_ptr->args.meta_acl;
+  acl = acl_get_file(pathname, meta_acl_val->a_type);
+  //printf("file: %s\n", pathname);
+  if (acl == NULL)
+    {
+      return false;
+    }
+
+  ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent);
+
+  if (ret != 1)
+    {
+      acl_free(acl);
+      return false;
+    }
+  while (ret > 0)
+    {
+      e_perm = 0;
+      e_id = malloc(sizeof(e_id));
+      *e_id = 0;
+      acl_get_tag_type(ent, &e_tag);
+
+     if (e_tag == ACL_USER || e_tag == ACL_GROUP)
+     {
+       e_id = acl_get_qualifier(ent);
+
+       if (e_id == NULL)
+       {
+         ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
+         continue;
+       }
+     }
+
+     if ( acl_get_permset(ent, &e_permset) != 0)
+       error (0, errno, "%s", pathname);
+
+     if (acl_get_perm(e_permset, ACL_READ))
+       e_perm |= ACL_READ;
+     if (acl_get_perm(e_permset, ACL_WRITE))
+       e_perm |= ACL_WRITE;
+     if (acl_get_perm(e_permset, ACL_EXECUTE))
+       e_perm |= ACL_EXECUTE;
+
+     if ((meta_acl_val->a_id_any == true) ||
+         (meta_acl_val->a_tag == ACL_OTHER) ||
+         (meta_acl_val->a_tag == ACL_MASK))
+       {
+         meta_acl_val->a_id = *e_id;
+       }
+
+     if (meta_acl_val->a_perm_any == true)
+       {
+        meta_acl_val->a_perm = e_perm;
+       }
+    /*
+     printf("e_tag: %d\n", e_tag);
+     printf("a_tag: %d\n", meta_acl_val->a_tag);
+     printf("e_id: %d\n", *e_id);
+     printf("a_id: %d\n", meta_acl_val->a_id);
+     printf("e_perm: %d\n", e_perm);
+     printf("a_perm: %d\n", meta_acl_val->a_perm);
+     printf("\n");
+    */
+     if ((e_tag != meta_acl_val->a_tag) || (*e_id != meta_acl_val->a_id) || e_perm != meta_acl_val->a_perm)
+       {
+        ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
+        continue;
+       }
+
+      acl_free(acl);
+      return true;
+    }
+
+  acl_free(acl);
+  return (false);
+}
+#endif
+
 
 boolean
 pred_amin (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
Common subdirectories: ./testsuite and /home/pietro/findutils-4.4.2/find/testsuite
diff -uP ./util.c /home/pietro/findutils-4.4.2/find/util.c
--- ./util.c	2009-05-16 17:17:01.000000000 +0200
+++ /home/pietro/findutils-4.4.2/find/util.c	2009-09-28 19:30:06.000000000 +0200
@@ -37,6 +37,13 @@
 #include "verify.h"
 #include "openat.h"
 
+#ifdef HAVE_LIBACL
+#include <sys/acl.h>
+#include <pwd.h>
+#include <grp.h>
+#endif
+
+
 #if ENABLE_NLS
 # include <libintl.h>
 # define _(Text) gettext (Text)
@@ -1038,3 +1045,277 @@
   report_file_err(0, errno, name);
 }
 
+#ifdef HAVE_LIBACL
+
+#define SKIP_WS(x) ({ \
+    while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
+        (x)++; \
+    })
+
+static int
+skip_tag_name (const char **text_p, const char *token)
+{
+  size_t len = strlen (token);
+  const char *text = *text_p;
+
+  SKIP_WS (text);
+  if (strncmp (text, token, len) == 0)
+    {
+      text += len;
+      goto delimiter;
+    }
+  if (*text == *token)
+    {
+      text++;
+      goto delimiter;
+    }
+  return 0;
+
+delimiter:
+  SKIP_WS (text);
+  if (*text == ':')
+    {
+      *text_p = text + 1;
+      return 1;
+    }
+  if (*text == ',' || *text == '\0')
+    {
+      *text_p = text;
+      return 1;
+    }
+  return 0;
+}
+
+static char *
+get_token (const char **text_p)
+{
+  char *token = NULL, *t;
+  const char *bp, *ep;
+
+  bp = *text_p;
+  SKIP_WS (bp);
+  ep = bp;
+
+  while (*ep != '\0' && *ep != '\r' && *ep != '\n' && *ep != ':'
+     && *ep != ',')
+    ep++;
+  if (ep == bp)
+    goto after_token;
+  token = (char *) malloc (ep - bp + 1);
+  if (token == NULL)
+    goto after_token;
+  memcpy (token, bp, ep - bp);
+
+  /* Trim trailing whitespace */
+  t = token + (ep - bp - 1);
+  while (t >= token && (*t == ' ' || *t == '\t' || *t == '\n' || *t == '\r'))
+    t--;
+  *(t + 1) = '\0';
+
+after_token:
+  if (*ep == ':')
+    ep++;
+  *text_p = ep;
+  return token;
+}
+
+int
+parse_meta_acl (const char **meta_acl_p, struct meta_acl *acl)
+{
+
+  char *str;
+  int meta_perm;
+  int meta_perm_chars;
+  struct passwd *p;
+  struct group *g;
+  uid_t uid;
+  gid_t gid;
+    
+  /* check ACL_TYPE */
+  if (skip_tag_name (meta_acl_p, "default"))
+    {
+      acl->a_type = ACL_TYPE_DEFAULT;
+    }
+  else
+    {
+      acl->a_type = ACL_TYPE_ACCESS;
+    }
+
+  switch (**meta_acl_p)
+    {
+
+    case 'u':           /* user */
+      if (skip_tag_name (meta_acl_p, "user"))
+    {
+      str = get_token (meta_acl_p);
+      if (str)
+        {
+          acl->a_tag = ACL_USER;
+          if (strcmp (str, "*") == 0)
+        {
+          acl->a_id_any = 1;
+          acl->a_id = NULL;
+        }
+          else
+        {
+          p = getpwnam (str);
+          if (p == NULL)
+            p = getpwuid ((uid_t) atoi (str));
+          if (p != NULL)
+            {
+              acl->a_id = p->pw_uid;
+            }
+
+          else
+            {
+              free (str);
+              return -1;
+            }
+        }
+        }
+      else
+        {
+          acl->a_tag = ACL_USER_OBJ;
+          acl->a_id = NULL;
+        }
+    }
+      break;
+
+    case 'g':           /* group */
+      if (skip_tag_name (meta_acl_p, "group"))
+    {
+      str = get_token (meta_acl_p);
+      if (str)
+        {
+          acl->a_tag = ACL_GROUP;
+          if (strcmp (str, "*") == 0)
+        {
+          acl->a_id_any = 1;
+          acl->a_id = NULL;
+        }
+          else
+        {
+          g = getgrnam (str);
+          if (g == NULL)
+            g = getgrgid ((uid_t) atoi (str));
+          if (g != NULL)
+            {
+              acl->a_id = g->gr_gid;
+            }
+          else
+            {
+              free (str);
+              return -1;
+            }
+        }
+        }
+      else
+        {
+          acl->a_tag = ACL_GROUP_OBJ;
+          acl->a_id = NULL;
+        }
+    }
+      break;
+
+    case 'o':           /* other */
+      if (skip_tag_name (meta_acl_p, "other"))
+    {
+      SKIP_WS (*meta_acl_p);
+      if (**meta_acl_p == ':')
+        (*meta_acl_p)++;
+      acl->a_tag = ACL_OTHER;
+      acl->a_id = NULL;
+    }
+      break;
+
+    case 'm':           /* mask */
+      if (skip_tag_name (meta_acl_p, "mask"))
+    {
+      SKIP_WS (*meta_acl_p);
+      if (**meta_acl_p == ':')
+        (*meta_acl_p)++;
+      acl->a_tag = ACL_MASK;
+      acl->a_id = NULL;
+    }
+      break;
+
+    default:
+      return -1;
+    }
+
+  SKIP_WS (*meta_acl_p);
+
+  meta_perm = 0;
+
+  if (**meta_acl_p == '\0')
+    {
+      acl->a_perm = 0;
+      return 0;
+    }
+
+  if (**meta_acl_p >= '0' && **meta_acl_p <= '7')
+    {
+      while (**meta_acl_p == '0')
+    (*meta_acl_p)++;
+      if (**meta_acl_p >= '1' && **meta_acl_p <= '7')
+    {
+      acl->a_perm = atoi(*meta_acl_p);
+      return 0;
+    }
+      else if (**meta_acl_p == '\0')
+    {
+      acl->a_perm = 0;
+      return 0;
+    }
+      else
+    {
+      return -1;
+    }
+    }
+  else
+    {
+      for (meta_perm_chars = 0; meta_perm_chars < 4;
+       meta_perm_chars++, (*meta_acl_p)++)
+    {
+      switch (**meta_acl_p)
+        {
+        case 'r':       /* read */
+          meta_perm |= ACL_READ;
+          break;
+
+        case 'w':       /* rwite */
+          meta_perm |= ACL_WRITE;
+          break;
+
+        case 'x':       /* execute */
+          meta_perm |= ACL_EXECUTE;
+          break;
+
+        case '-':       /* ignore */
+          break;
+
+        case '*':       /* any */
+          acl->a_perm_any = 1;
+          acl->a_perm = 0;
+          break;
+
+        case '\0':
+          acl->a_perm = meta_perm;
+          return 0;
+
+        default:
+          return -1;
+        }
+    }
+    }
+
+  if (**meta_acl_p == '\0')
+    {
+      acl->a_perm = 0;
+      return 0;
+    }
+
+  return -1;
+
+}
+#endif
