VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/path2-posix.cpp@ 96108

Last change on this file since 96108 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 11.5 KB
Line 
1/* $Id: path2-posix.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT - Path Manipulation, POSIX, Part 2 - RTPathQueryInfo.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_PATH
32#include <stdlib.h>
33#include <limits.h>
34#include <errno.h>
35#include <unistd.h>
36#include <sys/stat.h>
37#include <sys/time.h>
38#include <stdio.h>
39#include <sys/types.h>
40
41#include <iprt/path.h>
42#include <iprt/env.h>
43#include <iprt/assert.h>
44#include <iprt/string.h>
45#include <iprt/err.h>
46#include <iprt/log.h>
47#include "internal/path.h"
48#include "internal/process.h"
49#include "internal/fs.h"
50
51
52RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
53{
54 return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK);
55}
56
57
58RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
59{
60 /*
61 * Validate input.
62 */
63 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
64 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
65 AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER);
66 AssertMsgReturn( enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING
67 && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST,
68 ("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs),
69 VERR_INVALID_PARAMETER);
70 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
71
72 /*
73 * Convert the filename.
74 */
75 char const *pszNativePath;
76 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
77 if (RT_SUCCESS(rc))
78 {
79 struct stat Stat;
80 if (fFlags & RTPATH_F_FOLLOW_LINK)
81 rc = stat(pszNativePath, &Stat);
82 else
83 rc = lstat(pszNativePath, &Stat); /** @todo how doesn't have lstat again? */
84 if (!rc)
85 {
86 rtFsConvertStatToObjInfo(pObjInfo, &Stat, pszPath, 0);
87 switch (enmAdditionalAttribs)
88 {
89 case RTFSOBJATTRADD_NOTHING:
90 case RTFSOBJATTRADD_UNIX:
91 Assert(pObjInfo->Attr.enmAdditional == RTFSOBJATTRADD_UNIX);
92 break;
93
94 case RTFSOBJATTRADD_UNIX_OWNER:
95 rtFsObjInfoAttrSetUnixOwner(pObjInfo, Stat.st_uid);
96 break;
97
98 case RTFSOBJATTRADD_UNIX_GROUP:
99 rtFsObjInfoAttrSetUnixGroup(pObjInfo, Stat.st_gid);
100 break;
101
102 case RTFSOBJATTRADD_EASIZE:
103 /** @todo Use SGI extended attribute interface to query EA info. */
104 pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_EASIZE;
105 pObjInfo->Attr.u.EASize.cb = 0;
106 break;
107
108 default:
109 AssertMsgFailed(("Impossible!\n"));
110 return VERR_INTERNAL_ERROR;
111 }
112 }
113 else
114 rc = RTErrConvertFromErrno(errno);
115 rtPathFreeNative(pszNativePath, pszPath);
116 }
117
118 LogFlow(("RTPathQueryInfoEx(%p:{%s}, pObjInfo=%p, %d): returns %Rrc\n",
119 pszPath, pszPath, pObjInfo, enmAdditionalAttribs, rc));
120 return rc;
121}
122
123
124RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
125 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
126{
127 return RTPathSetTimesEx(pszPath, pAccessTime, pModificationTime, pChangeTime, pBirthTime, RTPATH_F_ON_LINK);
128}
129
130
131RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
132 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags)
133{
134 /*
135 * Validate input.
136 */
137 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
138 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
139 AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER);
140 AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER);
141 AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER);
142 AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER);
143 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
144
145 /*
146 * Convert the paths.
147 */
148 char const *pszNativePath;
149 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
150 if (RT_SUCCESS(rc))
151 {
152 RTFSOBJINFO ObjInfo;
153
154 /*
155 * If it's a no-op, we'll only verify the existance of the file.
156 */
157 if (!pAccessTime && !pModificationTime)
158 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, fFlags);
159 else
160 {
161 /*
162 * Convert the input to timeval, getting the missing one if necessary,
163 * and call the API which does the change.
164 */
165 struct timeval aTimevals[2];
166 if (pAccessTime && pModificationTime)
167 {
168 RTTimeSpecGetTimeval(pAccessTime, &aTimevals[0]);
169 RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]);
170 }
171 else
172 {
173 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
174 if (RT_SUCCESS(rc))
175 {
176 RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]);
177 RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]);
178 }
179 else
180 Log(("RTPathSetTimes('%s',%p,%p,,): RTPathQueryInfo failed with %Rrc\n",
181 pszPath, pAccessTime, pModificationTime, rc));
182 }
183 if (RT_SUCCESS(rc))
184 {
185 if (fFlags & RTPATH_F_FOLLOW_LINK)
186 {
187 if (utimes(pszNativePath, aTimevals))
188 rc = RTErrConvertFromErrno(errno);
189 }
190#if (defined(RT_OS_DARWIN) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050) \
191 || defined(RT_OS_FREEBSD) \
192 || defined(RT_OS_LINUX) \
193 || defined(RT_OS_OS2) /** @todo who really has lutimes? */
194 else
195 {
196 if (lutimes(pszNativePath, aTimevals))
197 {
198 /* If lutimes is not supported (e.g. linux < 2.6.22), try fall back on utimes: */
199 if (errno != ENOSYS)
200 rc = RTErrConvertFromErrno(errno);
201 else
202 {
203 if (pAccessTime && pModificationTime)
204 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
205 if (RT_SUCCESS(rc) && !RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
206 {
207 if (utimes(pszNativePath, aTimevals))
208 rc = RTErrConvertFromErrno(errno);
209 }
210 else
211 rc = VERR_NOT_SUPPORTED;
212 }
213 }
214 }
215#else
216 else
217 {
218 if (pAccessTime && pModificationTime)
219 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
220 if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
221 rc = VERR_NS_SYMLINK_SET_TIME;
222 else if (RT_SUCCESS(rc))
223 {
224 if (utimes(pszNativePath, aTimevals))
225 rc = RTErrConvertFromErrno(errno);
226 }
227 }
228#endif
229 if (RT_FAILURE(rc))
230 Log(("RTPathSetTimes('%s',%p,%p,,): failed with %Rrc and errno=%d\n",
231 pszPath, pAccessTime, pModificationTime, rc, errno));
232 }
233 }
234 rtPathFreeNative(pszNativePath, pszPath);
235 }
236
237 LogFlow(("RTPathSetTimes(%p:{%s}, %p:{%RDtimespec}, %p:{%RDtimespec}, %p:{%RDtimespec}, %p:{%RDtimespec}): return %Rrc\n",
238 pszPath, pszPath, pAccessTime, pAccessTime, pModificationTime, pModificationTime,
239 pChangeTime, pChangeTime, pBirthTime, pBirthTime, rc));
240 return rc;
241}
242
243
244RTR3DECL(int) RTPathSetOwner(const char *pszPath, uint32_t uid, uint32_t gid)
245{
246 return RTPathSetOwnerEx(pszPath, uid, gid, RTPATH_F_ON_LINK);
247}
248
249
250RTR3DECL(int) RTPathSetOwnerEx(const char *pszPath, uint32_t uid, uint32_t gid, uint32_t fFlags)
251{
252 /*
253 * Validate input.
254 */
255 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
256 AssertReturn(*pszPath, VERR_INVALID_PARAMETER);
257 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);
258 uid_t uidNative = uid != NIL_RTUID ? (uid_t)uid : (uid_t)-1;
259 AssertReturn(uid == uidNative, VERR_INVALID_PARAMETER);
260 gid_t gidNative = gid != NIL_RTGID ? (gid_t)gid : (uid_t)-1;
261 AssertReturn(gid == gidNative, VERR_INVALID_PARAMETER);
262
263 /*
264 * Convert the path.
265 */
266 char const *pszNativePath;
267 int rc = rtPathToNative(&pszNativePath, pszPath, NULL);
268 if (RT_SUCCESS(rc))
269 {
270 if (fFlags & RTPATH_F_FOLLOW_LINK)
271 {
272 if (chown(pszNativePath, uidNative, gidNative))
273 rc = RTErrConvertFromErrno(errno);
274 }
275#if 1
276 else
277 {
278 if (lchown(pszNativePath, uidNative, gidNative))
279 rc = RTErrConvertFromErrno(errno);
280 }
281#else
282 else
283 {
284 RTFSOBJINFO ObjInfo;
285 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags);
286 if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
287 rc = VERR_NS_SYMLINK_CHANGE_OWNER;
288 else if (RT_SUCCESS(rc))
289 {
290 if (lchown(pszNativePath, uidNative, gidNative))
291 rc = RTErrConvertFromErrno(errno);
292 }
293 }
294#endif
295 if (RT_FAILURE(rc))
296 Log(("RTPathSetOwnerEx('%s',%d,%d): failed with %Rrc and errno=%d\n",
297 pszPath, uid, gid, rc, errno));
298
299 rtPathFreeNative(pszNativePath, pszPath);
300 }
301
302 LogFlow(("RTPathSetOwnerEx(%p:{%s}, uid=%d, gid=%d): return %Rrc\n",
303 pszPath, pszPath, uid, gid, rc));
304 return rc;
305}
306
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette