VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/generic/dirrel-r3-generic.cpp@ 103914

Last change on this file since 103914 was 99758, checked in by vboxsync, 19 months ago

IPRT: Make doxygen 1.9.6 happy. Mostly removing duplicate docs (iprt is documented in the header files). bugref:10442

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1/* $Id: dirrel-r3-generic.cpp 99758 2023-05-11 21:37:59Z vboxsync $ */
2/** @file
3 * IPRT - Directory relative base APIs, generic implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#define LOG_GROUP RTLOGGROUP_DIR
42#include <iprt/dir.h>
43#include "internal/iprt.h"
44
45#include <iprt/assert.h>
46#include <iprt/file.h>
47#include <iprt/err.h>
48#include <iprt/path.h>
49#include <iprt/string.h>
50#include <iprt/symlink.h>
51#define RTDIR_AGNOSTIC
52#include "internal/dir.h"
53
54
55
56/**
57 * Helper that builds a full path for a directory relative path.
58 *
59 * @returns IPRT status code.
60 * @param pThis The directory.
61 * @param pszPathDst The destination buffer.
62 * @param cbPathDst The size of the destination buffer.
63 * @param pszRelPath The relative path.
64 */
65static int rtDirRelBuildFullPath(PRTDIRINTERNAL pThis, char *pszPathDst, size_t cbPathDst, const char *pszRelPath)
66{
67 AssertMsgReturn(!RTPathStartsWithRoot(pszRelPath), ("pszRelPath='%s'\n", pszRelPath), VERR_PATH_IS_NOT_RELATIVE);
68
69 /*
70 * Let's hope we can avoid checking for ascension.
71 *
72 * Note! We don't take symbolic links into account here. That can be
73 * done later if desired.
74 */
75 if ( !(pThis->fFlags & RTDIR_F_DENY_ASCENT)
76 || strstr(pszRelPath, "..") == NULL)
77 {
78 size_t const cchRelPath = strlen(pszRelPath);
79 size_t const cchDirPath = pThis->cchPath;
80 if (cchDirPath + cchRelPath < cbPathDst)
81 {
82 memcpy(pszPathDst, pThis->pszPath, cchDirPath);
83 memcpy(&pszPathDst[cchDirPath], pszRelPath, cchRelPath);
84 pszPathDst[cchDirPath + cchRelPath] = '\0';
85 return VINF_SUCCESS;
86 }
87 return VERR_FILENAME_TOO_LONG;
88 }
89
90 /*
91 * Calc the absolute path using the directory as a base, then check if the result
92 * still starts with the full directory path.
93 *
94 * This ASSUMES that pThis->pszPath is an absolute path.
95 */
96 int rc = RTPathAbsEx(pThis->pszPath, pszRelPath, RTPATH_STR_F_STYLE_HOST, pszPathDst, &cbPathDst);
97 if (RT_SUCCESS(rc))
98 {
99 if (RTPathStartsWith(pszPathDst, pThis->pszPath))
100 return VINF_SUCCESS;
101 return VERR_PATH_NOT_FOUND;
102 }
103 return rc;
104}
105
106
107/*
108 *
109 *
110 * RTFile stuff.
111 * RTFile stuff.
112 * RTFile stuff.
113 *
114 *
115 */
116
117
118
119
120RTDECL(int) RTDirRelFileOpen(RTDIR hDir, const char *pszRelFilename, uint64_t fOpen, PRTFILE phFile)
121{
122 PRTDIRINTERNAL pThis = hDir;
123 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
124 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
125
126 char szPath[RTPATH_MAX];
127 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelFilename);
128 if (RT_SUCCESS(rc))
129 rc = RTFileOpen(phFile, szPath, fOpen);
130 return rc;
131}
132
133
134
135/*
136 *
137 *
138 * RTDir stuff.
139 * RTDir stuff.
140 * RTDir stuff.
141 *
142 *
143 */
144
145
146
147RTDECL(int) RTDirRelDirOpen(RTDIR hDir, const char *pszDir, RTDIR *phDir)
148{
149 PRTDIRINTERNAL pThis = hDir;
150 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
151 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
152
153 char szPath[RTPATH_MAX];
154 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszDir);
155 if (RT_SUCCESS(rc))
156 rc = RTDirOpen(phDir, szPath);
157 return rc;
158
159}
160
161
162RTDECL(int) RTDirRelDirOpenFiltered(RTDIR hDir, const char *pszDirAndFilter, RTDIRFILTER enmFilter,
163 uint32_t fFlags, RTDIR *phDir)
164{
165 PRTDIRINTERNAL pThis = hDir;
166 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
167 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
168
169 char szPath[RTPATH_MAX];
170 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszDirAndFilter);
171 if (RT_SUCCESS(rc))
172 rc = RTDirOpenFiltered(phDir, szPath, enmFilter, fFlags);
173 return rc;
174}
175
176
177RTDECL(int) RTDirRelDirCreate(RTDIR hDir, const char *pszRelPath, RTFMODE fMode, uint32_t fCreate, RTDIR *phSubDir)
178{
179 PRTDIRINTERNAL pThis = hDir;
180 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
181 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
182
183 char szPath[RTPATH_MAX];
184 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
185 if (RT_SUCCESS(rc))
186 {
187 rc = RTDirCreate(szPath, fMode, fCreate);
188 if (RT_SUCCESS(rc) && phSubDir)
189 rc = RTDirOpen(phSubDir, szPath);
190 }
191 return rc;
192}
193
194
195RTDECL(int) RTDirRelDirRemove(RTDIR hDir, const char *pszRelPath)
196{
197 PRTDIRINTERNAL pThis = hDir;
198 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
199 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
200
201 char szPath[RTPATH_MAX];
202 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
203 if (RT_SUCCESS(rc))
204 rc = RTDirRemove(szPath);
205 return rc;
206}
207
208
209/*
210 *
211 * RTPath stuff.
212 * RTPath stuff.
213 * RTPath stuff.
214 *
215 *
216 */
217
218
219RTDECL(int) RTDirRelPathQueryInfo(RTDIR hDir, const char *pszRelPath, PRTFSOBJINFO pObjInfo,
220 RTFSOBJATTRADD enmAddAttr, uint32_t fFlags)
221{
222 PRTDIRINTERNAL pThis = hDir;
223 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
224 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
225
226 char szPath[RTPATH_MAX];
227 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
228 if (RT_SUCCESS(rc))
229 rc = RTPathQueryInfoEx(szPath, pObjInfo, enmAddAttr, fFlags);
230 return rc;
231}
232
233
234RTDECL(int) RTDirRelPathSetMode(RTDIR hDir, const char *pszRelPath, RTFMODE fMode, uint32_t fFlags)
235{
236 PRTDIRINTERNAL pThis = hDir;
237 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
238 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
239 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_FLAGS);
240
241 char szPath[RTPATH_MAX];
242 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
243 if (RT_SUCCESS(rc))
244 {
245#ifndef RT_OS_WINDOWS
246 rc = RTPathSetMode(szPath, fMode); /** @todo fFlags is currently ignored. */
247#else
248 rc = VERR_NOT_IMPLEMENTED; /** @todo implement RTPathSetMode on windows. */
249 RT_NOREF(fMode);
250#endif
251 }
252 return rc;
253}
254
255
256RTDECL(int) RTDirRelPathSetTimes(RTDIR hDir, const char *pszRelPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
257 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags)
258{
259 PRTDIRINTERNAL pThis = hDir;
260 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
261 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
262
263 char szPath[RTPATH_MAX];
264 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
265 if (RT_SUCCESS(rc))
266 rc = RTPathSetTimesEx(szPath, pAccessTime, pModificationTime, pChangeTime, pBirthTime, fFlags);
267 return rc;
268}
269
270
271RTDECL(int) RTDirRelPathSetOwner(RTDIR hDir, const char *pszRelPath, uint32_t uid, uint32_t gid, uint32_t fFlags)
272{
273 PRTDIRINTERNAL pThis = hDir;
274 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
275 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
276
277 char szPath[RTPATH_MAX];
278 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
279 if (RT_SUCCESS(rc))
280 {
281#ifndef RT_OS_WINDOWS
282 rc = RTPathSetOwnerEx(szPath, uid, gid, fFlags);
283#else
284 rc = VERR_NOT_IMPLEMENTED;
285 RT_NOREF(uid, gid, fFlags);
286#endif
287 }
288 return rc;
289}
290
291
292RTDECL(int) RTDirRelPathRename(RTDIR hDirSrc, const char *pszSrc, RTDIR hDirDst, const char *pszDst, unsigned fRename)
293{
294 PRTDIRINTERNAL pThis = hDirSrc;
295 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
296 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
297
298 PRTDIRINTERNAL pThat = hDirDst;
299 if (pThat != pThis)
300 {
301 AssertPtrReturn(pThat, VERR_INVALID_HANDLE);
302 AssertReturn(pThat->u32Magic != RTDIR_MAGIC, VERR_INVALID_HANDLE);
303 }
304
305 char szSrcPath[RTPATH_MAX];
306 int rc = rtDirRelBuildFullPath(pThis, szSrcPath, sizeof(szSrcPath), pszSrc);
307 if (RT_SUCCESS(rc))
308 {
309 char szDstPath[RTPATH_MAX];
310 rc = rtDirRelBuildFullPath(pThis, szDstPath, sizeof(szDstPath), pszDst);
311 if (RT_SUCCESS(rc))
312 rc = RTPathRename(szSrcPath, szDstPath, fRename);
313 }
314 return rc;
315}
316
317
318RTDECL(int) RTDirRelPathUnlink(RTDIR hDir, const char *pszRelPath, uint32_t fUnlink)
319{
320 PRTDIRINTERNAL pThis = hDir;
321 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
322 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
323
324 char szPath[RTPATH_MAX];
325 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszRelPath);
326 if (RT_SUCCESS(rc))
327 rc = RTPathUnlink(szPath, fUnlink);
328 return rc;
329}
330
331
332/*
333 *
334 * RTSymlink stuff.
335 * RTSymlink stuff.
336 * RTSymlink stuff.
337 *
338 *
339 */
340
341
342RTDECL(int) RTDirRelSymlinkCreate(RTDIR hDir, const char *pszSymlink, const char *pszTarget,
343 RTSYMLINKTYPE enmType, uint32_t fCreate)
344{
345 PRTDIRINTERNAL pThis = hDir;
346 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
347 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
348
349 char szPath[RTPATH_MAX];
350 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszSymlink);
351 if (RT_SUCCESS(rc))
352 rc = RTSymlinkCreate(szPath, pszTarget, enmType, fCreate);
353 return rc;
354}
355
356
357RTDECL(int) RTDirRelSymlinkRead(RTDIR hDir, const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead)
358{
359 PRTDIRINTERNAL pThis = hDir;
360 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
361 AssertReturn(pThis->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
362
363 char szPath[RTPATH_MAX];
364 int rc = rtDirRelBuildFullPath(pThis, szPath, sizeof(szPath), pszSymlink);
365 if (RT_SUCCESS(rc))
366 rc = RTSymlinkRead(szPath, pszTarget, cbTarget, fRead);
367 return rc;
368}
369
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