Tizen 2.0 Release
[external/tizen-coreutils.git] / lib / file-has-acl.c
1 /* Test whether a file has a nontrivial access control list.
2
3    Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2, or (at your option)
8    any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19    Written by Paul Eggert and Andreas Gruenbacher.  */
20
21 #include <config.h>
22
23 #include "acl.h"
24
25 #include "acl-internal.h"
26
27 /* Return 1 if NAME has a nontrivial access control list, 0 if NAME
28    only has no or a base access control list, and -1 (setting errno)
29    on error.  SB must be set to the stat buffer of FILE.  */
30
31 int
32 file_has_acl (char const *name, struct stat const *sb)
33 {
34   if (! S_ISLNK (sb->st_mode))
35     {
36 #if USE_ACL && HAVE_ACL_TRIVIAL
37
38       /* Solaris 10, which also has NFSv4 and ZFS style ACLs.  */
39       return acl_trivial (name);
40
41 #elif USE_ACL && HAVE_ACL && defined GETACLCNT
42
43       /* Solaris 2.5 through Solaris 9, and contemporaneous versions of
44          HP-UX and Unixware.  */
45       int n = acl (name, GETACLCNT, 0, NULL);
46       return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
47
48 #elif USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE
49
50       /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
51       int ret;
52
53       if (HAVE_ACL_EXTENDED_FILE)
54         ret = acl_extended_file (name);
55       else
56         {
57           acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
58           if (acl)
59             {
60               ret = (3 < acl_entries (acl));
61               acl_free (acl);
62               if (ret == 0 && S_ISDIR (sb->st_mode))
63                 {
64                   acl = acl_get_file (name, ACL_TYPE_DEFAULT);
65                   if (acl)
66                     {
67                       ret = (0 < acl_entries (acl));
68                       acl_free (acl);
69                     }
70                   else
71                     ret = -1;
72                 }
73             }
74           else
75             ret = -1;
76         }
77       if (ret < 0)
78         return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1;
79       return ret;
80 #endif
81     }
82
83   /* FIXME: Add support for AIX, Irix, and Tru64.  Please see Samba's
84      source/lib/sysacls.c file for fix-related ideas.  */
85
86   return 0;
87 }