diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/configure findutils-4.4.0/configure
*** findutils-4.4.0/configure	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/configure	2009-01-08 23:30:32.000000000 -0500
***************
*** 1568,1573 ****
--- 1568,1576 ----
                            dirent.d_type by readdir()
    --enable-d_type-optimisation
                            Synonym for --enable-d_type-optimization
+   --enable-xattr-predicate
+                           Enable the -xattr predicate which tests for the
+                           presence of extended attributes
    --disable-dependency-tracking  speeds up one-time build
    --enable-dependency-tracking   do not reject slow dependency extractors
    --disable-largefile     omit support for large files
***************
*** 2743,2748 ****
--- 2746,2758 ----
  fi
  
  
+ # Check whether --enable-xattr-predicate was given.
+ if test "${enable_xattr_predicate+set}" = set; then
+   enableval=$enable_xattr_predicate; ac_cv_xattr_predicate=$enableval
+ else
+   ac_cv_xattr_predicate=no
+ fi
+ 
  
  { echo "$as_me:$LINENO: checking whether debug output should be produced" >&5
  echo $ECHO_N "checking whether debug output should be produced... $ECHO_C" >&6; }
***************
*** 2779,2784 ****
--- 2789,2809 ----
  
  fi
  
+ { echo "$as_me:$LINENO: checking for enabling extended attributes" >&5
+ echo $ECHO_N "checking for enabling extended attributes... $ECHO_C" >&6; }
+ if test x$ac_cv_xattr_predicate = xno; then
+    { echo "$as_me:$LINENO: result: no" >&5
+ echo "${ECHO_T}no" >&6; }
+ else
+    { echo "$as_me:$LINENO: result: yes" >&5
+ echo "${ECHO_T}yes" >&6; }
+ 
+ cat >>confdefs.h <<\_ACEOF
+ #define FIND_XATTR 1
+ _ACEOF
+ 
+ fi
+ 
  
  if test -n "$DEFAULT_ARG_SIZE"; then
  
***************
*** 4989,5001 ****
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! #include <sys/types.h> /* for off_t */
!      #include <stdio.h>
  int
  main ()
  {
! int (*fp) (FILE *, off_t, int) = fseeko;
!      return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
    ;
    return 0;
  }
--- 5014,5024 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! #include <stdio.h>
  int
  main ()
  {
! return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
    ;
    return 0;
  }
***************
*** 5035,5047 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #define _LARGEFILE_SOURCE 1
! #include <sys/types.h> /* for off_t */
!      #include <stdio.h>
  int
  main ()
  {
! int (*fp) (FILE *, off_t, int) = fseeko;
!      return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
    ;
    return 0;
  }
--- 5058,5068 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #define _LARGEFILE_SOURCE 1
! #include <stdio.h>
  int
  main ()
  {
! return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
    ;
    return 0;
  }
***************
*** 31453,31458 ****
--- 31474,31626 ----
  
  done
  
+ if test x$ac_cv_xattr_predicate != xno; then
+ 
+ for ac_header in sys/xattr.h
+ do
+ as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+ 	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ else
+   # Is the header compilable?
+ { echo "$as_me:$LINENO: checking $ac_header usability" >&5
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ $ac_includes_default
+ #include <$ac_header>
+ _ACEOF
+ rm -f conftest.$ac_objext
+ if { (ac_try="$ac_compile"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_compile") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && {
+ 	 test -z "$ac_c_werror_flag" ||
+ 	 test ! -s conftest.err
+        } && test -s conftest.$ac_objext; then
+   ac_header_compiler=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ 	ac_header_compiler=no
+ fi
+ 
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+ echo "${ECHO_T}$ac_header_compiler" >&6; }
+ 
+ # Is the header present?
+ { echo "$as_me:$LINENO: checking $ac_header presence" >&5
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <$ac_header>
+ _ACEOF
+ if { (ac_try="$ac_cpp conftest.$ac_ext"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+   ac_status=$?
+   grep -v '^ *+' conftest.er1 >conftest.err
+   rm -f conftest.er1
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } >/dev/null && {
+ 	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ 	 test ! -s conftest.err
+        }; then
+   ac_header_preproc=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+   ac_header_preproc=no
+ fi
+ 
+ rm -f conftest.err conftest.$ac_ext
+ { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+ echo "${ECHO_T}$ac_header_preproc" >&6; }
+ 
+ # So?  What about this header?
+ case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+   yes:no: )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+     ac_header_preproc=yes
+     ;;
+   no:yes:* )
+     { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+ echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+ echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+ echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+     { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+ echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+     ( cat <<\_ASBOX
+ ## ------------------------------------ ##
+ ## Report this to bug-findutils@gnu.org ##
+ ## ------------------------------------ ##
+ _ASBOX
+      ) | sed "s/^/$as_me: WARNING:     /" >&2
+     ;;
+ esac
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+ if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   eval "$as_ac_Header=\$ac_header_preproc"
+ fi
+ ac_res=`eval echo '${'$as_ac_Header'}'`
+ 	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+ echo "${ECHO_T}$ac_res" >&6; }
+ 
+ fi
+ if test `eval echo '${'$as_ac_Header'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+ _ACEOF
+ 
+ fi
+ 
+ done
+ 
+ fi
  { echo "$as_me:$LINENO: checking whether sys/types.h defines makedev" >&5
  echo $ECHO_N "checking whether sys/types.h defines makedev... $ECHO_C" >&6; }
  if test "${ac_cv_header_sys_types_h_makedev+set}" = set; then
diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/configure.ac findutils-4.4.0/configure.ac
*** findutils-4.4.0/configure.ac	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/configure.ac	2009-01-09 00:16:02.000000000 -0500
***************
*** 43,48 ****
--- 43,51 ----
  	AS_HELP_STRING(--enable-d_type-optimisation,Synonym for --enable-d_type-optimization),
  	[ac_cv_d_type=$enableval],[])
  
+ AC_ARG_ENABLE(xattr-predicate,
+ 	AS_HELP_STRING(--enable-xattr-predicate,Enable the -xattr predicate which tests for the presence of extended attributes),
+ 	[ac_cv_xattr_predicate=$enableval],[ac_cv_xattr_predicate=no])
  
  AC_MSG_CHECKING([whether debug output should be produced])
  if test x$ac_cv_debug = xno; then
***************
*** 61,66 ****
--- 64,77 ----
     AC_DEFINE(LEAF_OPTIMISATION, 1, [Define if you want to use the leaf optimisation (this can still be turned off with -noleaf)])
  fi
  
+ AC_MSG_CHECKING([for extended attributes])
+ if test x$ac_cv_xattr_predicate = xno; then
+    AC_MSG_RESULT([no])
+ else
+    AC_MSG_RESULT([yes])
+    AC_DEFINE(FIND_XATTR, 1, [Define if you want to be able to select files by the presence of extended attributes using -xattr])
+ fi
+ 
  AC_ARG_VAR([DEFAULT_ARG_SIZE], [Default size of arguments to child processes
  of find and xargs, 128k if unspecified])
  if test -n "$DEFAULT_ARG_SIZE"; then
***************
*** 122,127 ****
--- 133,142 ----
  AC_CHECK_HEADERS(sys/param.h mntent.h sys/mnttab.h sys/mntio.h sys/mkdev.h)
  dnl find.c needs sys/utsname.h because it calls uname(2).
  AC_CHECK_HEADERS(sys/utsname.h)
+ dnl Look for sys/xattr.h if extended attributes are used
+ if test x$ac_cv_xattr_predicate != xno; then
+   AC_CHECK_HEADERS(sys/xattr.h)
+ fi
  AC_HEADER_MAJOR
  AC_HEADER_DIRENT
  AC_HEADER_STAT
diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/find/defs.h findutils-4.4.0/find/defs.h
*** findutils-4.4.0/find/defs.h	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/find/defs.h	2009-01-09 00:35:06.000000000 -0500
***************
*** 303,309 ****
       Next to each member are listed the predicates that use it. */
    union
    {
!     const char *str;		/* fstype [i]lname [i]name [i]path */
      struct re_pattern_buffer *regex; /* regex */
      struct exec_val exec_vec;	/* exec ok */
      struct long_val numinfo;	/* gid inum links  uid */
--- 303,309 ----
       Next to each member are listed the predicates that use it. */
    union
    {
!     const char *str;		/* fstype [i]lname [i]name [i]path xattr */
      struct re_pattern_buffer *regex; /* regex */
      struct exec_val exec_vec;	/* exec ok */
      struct long_val numinfo;	/* gid inum links  uid */
***************
*** 458,463 ****
--- 458,466 ----
  PREDICATEFUNCTION pred_used;
  PREDICATEFUNCTION pred_user;
  PREDICATEFUNCTION pred_writable;
+ #ifdef FIND_XATTR
+ PREDICATEFUNCTION pred_xattr;
+ #endif
  PREDICATEFUNCTION pred_xtype;
  
  
diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/find/parser.c findutils-4.4.0/find/parser.c
*** findutils-4.4.0/find/parser.c	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/find/parser.c	2009-01-09 01:59:04.000000000 -0500
***************
*** 154,159 ****
--- 154,162 ----
  static boolean parse_ignore_race   PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
  static boolean parse_noignore_race PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
  static boolean parse_warn          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
+ #ifdef FIND_XATTR
+ static boolean parse_xattr         PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
+ #endif
  static boolean parse_xtype         PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
  static boolean parse_quit          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
  
***************
*** 321,326 ****
--- 324,332 ----
    PARSE_TEST_NP    ("wholename",             wholename), /* GNU, replaced -path, but anyway -path will soon be in POSIX */
    {ARG_TEST,       "writable",               parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */
    PARSE_OPTION     ("xdev",                  xdev), /* POSIX */
+ #ifdef FIND_XATTR
+   PARSE_TEST       ("xattr",                 xattr),
+ #endif
    PARSE_TEST       ("xtype",                 xtype),	     /* GNU */
  #ifdef UNIMPLEMENTED_UNIX
    /* It's pretty ugly for find to know about archive formats.
***************
*** 1124,1134 ****
--- 1130,1148 ----
        -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"));
+ #ifdef FIND_XATTR
+   puts (_("\
+       -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
+       -readable -writable -executable\n\
+       -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
+       -used N -user NAME -xattr NAME -xtype [bcdpfls]\n"));
+ #else
    puts (_("\
        -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
        -readable -writable -executable\n\
        -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
        -used N -user NAME -xtype [bcdpfls]\n"));
+ #endif
    puts (_("\
  actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
        -fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
***************
*** 2555,2560 ****
--- 2569,2606 ----
  }
  
  static boolean
+ check_xattr_arg(const char *pred, const char *arg)
+ {
+   if (options.warnings && !(strncmp(arg, "user.", 5) || strncmp(arg, "system.", 7) || strncmp(arg, "trusted.", 8) || strncmp(arg, "security.", 9)))
+     {
+       error(0, 0,_("warning: Extended attributes on Linux exist in one "
+                    "of 4 namespaces: user, system, trusted, or security. "
+                    "So searching for an attribute that doesn't start with "
+                    "`user.', `system.', `trusted.', or `security.' won't "
+                    "give any results."));
+     }
+   return true;			/* allow it anyway */
+ }
+ 
+ static boolean
+ parse_xattr (const struct parser_table* entry, char **argv, int *arg_ptr)
+ {
+   const char *xattr;
+   if (collect_arg(argv, arg_ptr, &xattr))
+     {
+       if (check_xattr_arg("-xattr", xattr))
+ 	{
+ 	  struct predicate *our_pred = insert_primary (entry);
+ 	  our_pred->need_stat = our_pred->need_type = false;
+ 	  our_pred->args.str = xattr;
+ 	  our_pred->est_success_rate = 0.04f; /* random guess, but assume most files don't have any given attribute set */
+ 	  return true;
+ 	}
+     }
+   return false;
+ }
+ 
+ static boolean
  parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr)
  {
    return insert_type (argv, arg_ptr, entry, pred_xtype);
diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/find/pred.c findutils-4.4.0/find/pred.c
*** findutils-4.4.0/find/pred.c	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/find/pred.c	2009-01-09 00:35:56.000000000 -0500
***************
*** 26,31 ****
--- 26,34 ----
  #include <grp.h>
  #include <sys/types.h>
  #include <sys/stat.h>
+ #ifdef FIND_XATTR
+ # include <sys/xattr.h>
+ #endif
  #include <errno.h>
  #include <assert.h>
  #include <stdarg.h>
***************
*** 228,233 ****
--- 231,239 ----
    {pred_used, "used    "},
    {pred_user, "user    "},
    {pred_writable, "writable "},
+ # ifdef FIND_XATTR
+   {pred_xattr, "xattr   "},
+ # endif
    {pred_xtype, "xtype   "},
    {0, "none    "}
  };
***************
*** 1804,1809 ****
--- 1810,1831 ----
      return (false);
  }
  
+ #ifdef FIND_XATTR
+ boolean
+ pred_xattr (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+ {
+   ssize_t vsize;
+ 
+   (void) pathname; /* wtf mate */
+ 
+   if (following_links())
+     vsize = getxattr(pathname, pred_ptr->args.str, NULL, 0);
+   else
+     vsize = lgetxattr(pathname, pred_ptr->args.str, NULL, 0);
+   return (vsize >= 0);
+ }
+ #endif
+ 
  boolean
  pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
  {
diff --recursive --exclude='.*~' --exclude='makepatch.*' --new-file --context=3 findutils-4.4.0/find/tree.c findutils-4.4.0/find/tree.c
*** findutils-4.4.0/find/tree.c	2009-01-08 16:23:50.000000000 -0500
--- findutils-4.4.0/find/tree.c	2009-01-09 02:12:43.000000000 -0500
***************
*** 953,958 ****
--- 953,959 ----
      { pred_used      ,  NeedsStatInfo        },
      { pred_user      ,  NeedsStatInfo        },
      { pred_writable  ,  NeedsAccessInfo      },
+     { pred_xattr     ,  NeedsLinkName        }, /* guess that reading an attribute is akin cost-wise to reading a link target */
      { pred_xtype     ,  NeedsType            } /* roughly correct unless most files are symlinks */
    };
  static int pred_table_sorted = 0;
