OpenCoverage

get-permissions.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/get-permissions.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Get permissions of a file. -*- coding: utf-8 -*--
2-
3 Copyright (C) 2002-2003, 2005-2018 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 3 of the License, or-
8 (at your option) 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, see <https://www.gnu.org/licenses/>.-
17-
18 Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */-
19-
20#include <config.h>-
21-
22#include <string.h>-
23#include "acl.h"-
24-
25#include "acl-internal.h"-
26-
27/* Read the permissions of a file into CTX. If DESC is a valid file descriptor,-
28 use file descriptor operations, else use filename based operations on NAME.-
29 MODE is the file mode obtained from a previous stat call.-
30 Return 0 if successful. Return -1 and set errno upon failure. */-
31-
32int-
33get_permissions (const char *name, int desc, mode_t mode,-
34 struct permission_context *ctx)-
35{-
36 memset (ctx, 0, sizeof *ctx);-
37 ctx->mode = mode;-
38-
39#if USE_ACL && HAVE_ACL_GET_FILE-
40 /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */-
41 /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */-
42# if !HAVE_ACL_TYPE_EXTENDED-
43 /* Linux, FreeBSD, IRIX, Tru64 */-
44-
45 if (HAVE_ACL_GET_FD && desc != -1)-
46 ctx->acl = acl_get_fd (desc);-
47 else-
48 ctx->acl = acl_get_file (name, ACL_TYPE_ACCESS);-
49 if (ctx->acl == NULL)-
50 return acl_errno_valid (errno) ? -1 : 0;-
51-
52 /* With POSIX ACLs, a file cannot have "no" acl; a file without-
53 extended permissions has a "minimal" acl which is equivalent to the-
54 file mode. */-
55-
56 if (S_ISDIR (mode))-
57 {-
58 ctx->default_acl = acl_get_file (name, ACL_TYPE_DEFAULT);-
59 if (ctx->default_acl == NULL)-
60 return -1;-
61 }-
62-
63# if HAVE_ACL_TYPE_NFS4 /* FreeBSD */-
64-
65 /* TODO (see set_permissions). */-
66-
67# endif-
68-
69# else /* HAVE_ACL_TYPE_EXTENDED */-
70 /* Mac OS X */-
71-
72 /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)-
73 and acl_get_file (name, ACL_TYPE_DEFAULT)-
74 always return NULL / EINVAL. You have to use-
75 acl_get_file (name, ACL_TYPE_EXTENDED)-
76 or acl_get_fd (open (name, ...))-
77 to retrieve an ACL.-
78 On the other hand,-
79 acl_set_file (name, ACL_TYPE_ACCESS, acl)-
80 and acl_set_file (name, ACL_TYPE_DEFAULT, acl)-
81 have the same effect as-
82 acl_set_file (name, ACL_TYPE_EXTENDED, acl):-
83 Each of these calls sets the file's ACL. */-
84-
85 if (HAVE_ACL_GET_FD && desc != -1)-
86 ctx->acl = acl_get_fd (desc);-
87 else-
88 ctx->acl = acl_get_file (name, ACL_TYPE_EXTENDED);-
89 if (ctx->acl == NULL)-
90 return acl_errno_valid (errno) ? -1 : 0;-
91-
92# endif-
93-
94#elif USE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */-
95-
96 /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions-
97 of Unixware. The acl() call returns the access and default ACL both-
98 at once. */-
99# ifdef ACE_GETACL-
100 /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4-
101 file systems (whereas the other ones are used in UFS file systems).-
102 There is an API-
103 pathconf (name, _PC_ACL_ENABLED)-
104 fpathconf (desc, _PC_ACL_ENABLED)-
105 that allows us to determine which of the two kinds of ACLs is supported-
106 for the given file. But some file systems may implement this call-
107 incorrectly, so better not use it.-
108 When fetching the source ACL, we simply fetch both ACL types.-
109 When setting the destination ACL, we try either ACL types, assuming-
110 that the kernel will translate the ACL from one form to the other.-
111 (See in <http://docs.sun.com/app/docs/doc/819-2241/6n4huc7ia?l=en&a=view>-
112 the description of ENOTSUP.) */-
113 for (;;)-
114 {-
115 int ret;-
116-
117 if (desc != -1)-
118 ret = facl (desc, ACE_GETACLCNT, 0, NULL);-
119 else-
120 ret = acl (name, ACE_GETACLCNT, 0, NULL);-
121 if (ret < 0)-
122 {-
123 if (errno == ENOSYS || errno == EINVAL)-
124 ret = 0;-
125 else-
126 return -1;-
127 }-
128 ctx->ace_count = ret;-
129-
130 if (ctx->ace_count == 0)-
131 break;-
132-
133 ctx->ace_entries = (ace_t *) malloc (ctx->ace_count * sizeof (ace_t));-
134 if (ctx->ace_entries == NULL)-
135 {-
136 errno = ENOMEM;-
137 return -1;-
138 }-
139-
140 if (desc != -1)-
141 ret = facl (desc, ACE_GETACL, ctx->ace_count, ctx->ace_entries);-
142 else-
143 ret = acl (name, ACE_GETACL, ctx->ace_count, ctx->ace_entries);-
144 if (ret < 0)-
145 {-
146 if (errno == ENOSYS || errno == EINVAL)-
147 {-
148 free (ctx->ace_entries);-
149 ctx->ace_entries = NULL;-
150 ctx->ace_count = 0;-
151 break;-
152 }-
153 else-
154 return -1;-
155 }-
156 if (ret <= ctx->ace_count)-
157 {-
158 ctx->ace_count = ret;-
159 break;-
160 }-
161 /* Huh? The number of ACL entries has increased since the last call.-
162 Repeat. */-
163 free (ctx->ace_entries);-
164 ctx->ace_entries = NULL;-
165 }-
166# endif-
167-
168 for (;;)-
169 {-
170 int ret;-
171-
172 if (desc != -1)-
173 ret = facl (desc, GETACLCNT, 0, NULL);-
174 else-
175 ret = acl (name, GETACLCNT, 0, NULL);-
176 if (ret < 0)-
177 {-
178 if (errno == ENOSYS || errno == ENOTSUP || errno == EOPNOTSUPP)-
179 ret = 0;-
180 else-
181 return -1;-
182 }-
183 ctx->count = ret;-
184-
185 if (ctx->count == 0)-
186 break;-
187-
188 ctx->entries = (aclent_t *) malloc (ctx->count * sizeof (aclent_t));-
189 if (ctx->entries == NULL)-
190 {-
191 errno = ENOMEM;-
192 return -1;-
193 }-
194-
195 if (desc != -1)-
196 ret = facl (desc, GETACL, ctx->count, ctx->entries);-
197 else-
198 ret = acl (name, GETACL, ctx->count, ctx->entries);-
199 if (ret < 0)-
200 {-
201 if (errno == ENOSYS || errno == ENOTSUP || errno == EOPNOTSUPP)-
202 {-
203 free (ctx->entries);-
204 ctx->entries = NULL;-
205 ctx->count = 0;-
206 break;-
207 }-
208 else-
209 return -1;-
210 }-
211 if (ret <= ctx->count)-
212 {-
213 ctx->count = ret;-
214 break;-
215 }-
216 /* Huh? The number of ACL entries has increased since the last call.-
217 Repeat. */-
218 free (ctx->entries);-
219 ctx->entries = NULL;-
220 }-
221-
222#elif USE_ACL && HAVE_GETACL /* HP-UX */-
223-
224 {-
225 int ret;-
226-
227 if (desc != -1)-
228 ret = fgetacl (desc, NACLENTRIES, ctx->entries);-
229 else-
230 ret = getacl (name, NACLENTRIES, ctx->entries);-
231 if (ret < 0)-
232 {-
233 if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP)-
234 ret = 0;-
235 else-
236 return -1;-
237 }-
238 else if (ret > NACLENTRIES)-
239 /* If NACLENTRIES cannot be trusted, use dynamic memory allocation. */-
240 abort ();-
241 ctx->count = ret;-
242-
243# if HAVE_ACLV_H-
244 ret = acl ((char *) name, ACL_GET, NACLVENTRIES, ctx->aclv_entries);-
245 if (ret < 0)-
246 {-
247 if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL)-
248 ret = 0;-
249 else-
250 return -2;-
251 }-
252 else if (ret > NACLVENTRIES)-
253 /* If NACLVENTRIES cannot be trusted, use dynamic memory allocation. */-
254 abort ();-
255 ctx->aclv_count = ret;-
256# endif-
257 }-
258-
259#elif USE_ACL && HAVE_ACLX_GET && ACL_AIX_WIP /* AIX */-
260-
261 /* TODO (see set_permissions). */-
262-
263#elif USE_ACL && HAVE_STATACL /* older AIX */-
264-
265 {-
266 int ret;-
267 if (desc != -1)-
268 ret = fstatacl (desc, STX_NORMAL, &ctx->u.a, sizeof ctx->u);-
269 else-
270 ret = statacl ((char *) name, STX_NORMAL, &ctx->u.a, sizeof ctx->u);-
271 if (ret == 0)-
272 ctx->have_u = true;-
273 }-
274-
275#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */-
276-
277 {-
278 int ret = acl ((char *) name, ACL_GET, NACLENTRIES, ctx->entries);-
279 if (ret < 0)-
280 return -1;-
281 else if (ret > NACLENTRIES)-
282 /* If NACLENTRIES cannot be trusted, use dynamic memory allocation. */-
283 abort ();-
284 ctx->count = ret;-
285 }-
286-
287#endif-
288-
289 return 0;
executed 37879 times by 2 tests: return 0;
Executed by:
  • cp
  • mv
37879
290-
291}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2