VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/fs.cpp@ 11118

Last change on this file since 11118 was 9786, checked in by vboxsync, 17 years ago

fixed docs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.4 KB
Line 
1/* $Id: fs.cpp 9786 2008-06-18 11:14:50Z vboxsync $ */
2/** @file
3 * IPRT - File System.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#ifndef RT_OS_WINDOWS
36# define RTTIME_INCL_TIMESPEC
37# include <sys/time.h>
38#endif
39
40#include <iprt/fs.h>
41#include <iprt/assert.h>
42#include <iprt/time.h>
43#include <iprt/string.h>
44#include <iprt/path.h>
45#include <iprt/ctype.h>
46#include "internal/fs.h"
47
48
49/**
50 * Converts dos-style attributes to Unix attributes.
51 *
52 * @returns
53 * @param fMode The mode mask containing dos-style attibutes only.
54 * @param pszName The filename which this applies to (exe check).
55 * @param cbName The length of that filename. (optional, set 0)
56 */
57RTFMODE rtFsModeFromDos(RTFMODE fMode, const char *pszName, unsigned cbName)
58{
59 fMode &= ~((1 << RTFS_DOS_SHIFT) - 1);
60
61 /* everything is readable. */
62 fMode |= RTFS_UNIX_IRUSR | RTFS_UNIX_IRGRP | RTFS_UNIX_IROTH;
63 if (fMode & RTFS_DOS_DIRECTORY)
64 /* directories are executable. */
65 fMode |= RTFS_TYPE_DIRECTORY | RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH;
66 else
67 {
68 fMode |= RTFS_TYPE_FILE;
69 if (!cbName && pszName)
70 cbName = strlen(pszName);
71 if (cbName >= 4 && pszName[cbName - 4] == '.')
72 {
73 /* check for executable extension. */
74 const char *pszExt = &pszName[cbName - 3];
75 char szExt[4];
76 szExt[0] = tolower(pszExt[0]);
77 szExt[1] = tolower(pszExt[1]);
78 szExt[2] = tolower(pszExt[2]);
79 szExt[3] = '\0';
80 if ( !memcmp(szExt, "exe", 4)
81 || !memcmp(szExt, "bat", 4)
82 || !memcmp(szExt, "com", 4)
83 || !memcmp(szExt, "cmd", 4)
84 || !memcmp(szExt, "btm", 4)
85 )
86 fMode |= RTFS_UNIX_IXUSR | RTFS_UNIX_IXGRP | RTFS_UNIX_IXOTH;
87 }
88 }
89 /* writable? */
90 if (!(fMode & RTFS_DOS_READONLY))
91 fMode |= RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH;
92 return fMode;
93}
94
95
96/**
97 * Converts Unix attributes to Dos-style attributes.
98 *
99 * @returns File mode mask.
100 * @param fMode The mode mask containing dos-style attibutes only.
101 * @param pszName The filename which this applies to (hidden check).
102 * @param cbName The length of that filename. (optional, set 0)
103 */
104RTFMODE rtFsModeFromUnix(RTFMODE fMode, const char *pszName, unsigned cbName)
105{
106 fMode &= RTFS_UNIX_MASK;
107
108 if (!(fMode & (RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH)))
109 fMode |= RTFS_DOS_READONLY;
110 if (RTFS_IS_DIRECTORY(fMode))
111 fMode |= RTFS_DOS_DIRECTORY;
112 if (!(fMode & RTFS_DOS_MASK))
113 fMode |= RTFS_DOS_NT_NORMAL;
114 if (!(fMode & RTFS_DOS_HIDDEN) && pszName)
115 {
116 pszName = RTPathFilename(pszName);
117 if (pszName && *pszName == '.')
118 fMode |= RTFS_DOS_HIDDEN;
119 }
120 return fMode;
121}
122
123
124/**
125 * Normalizes the give mode mask.
126 *
127 * It will create the missing unix or dos mask from the other (one
128 * of them is required by all APIs), and guess the file type if that's
129 * missing.
130 *
131 * @returns Normalized file mode.
132 * @param fMode The mode mask that may contain a partial/incomplete mask.
133 * @param pszName The filename which this applies to (exe check).
134 * @param cbName The length of that filename. (optional, set 0)
135 */
136RTFMODE rtFsModeNormalize(RTFMODE fMode, const char *pszName, unsigned cbName)
137{
138 if (!(fMode & RTFS_UNIX_MASK))
139 fMode = rtFsModeFromDos(fMode, pszName, cbName);
140 else if (!(fMode & RTFS_DOS_MASK))
141 fMode = rtFsModeFromUnix(fMode, pszName, cbName);
142 else if (!(fMode & RTFS_TYPE_MASK))
143 fMode |= fMode & RTFS_DOS_DIRECTORY ? RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE;
144 else if (RTFS_IS_DIRECTORY(fMode))
145 fMode |= RTFS_DOS_DIRECTORY;
146 return fMode;
147}
148
149
150/**
151 * Checks if the file mode is valid or not.
152 *
153 * @return true if valid.
154 * @return false if invalid, done bitching.
155 * @param fMode The file mode.
156 */
157bool rtFsModeIsValid(RTFMODE fMode)
158{
159 AssertMsgReturn( (!RTFS_IS_DIRECTORY(fMode) && !(fMode & RTFS_DOS_DIRECTORY))
160 || (RTFS_IS_DIRECTORY(fMode) && (fMode & RTFS_DOS_DIRECTORY)),
161 ("%RTfmode\n", fMode), false);
162 AssertMsgReturn(RTFS_TYPE_MASK & fMode,
163 ("%RTfmode\n", fMode), false);
164 /** @todo more checks! */
165 return true;
166}
167
168
169/**
170 * Checks if the file mode is valid as a permission mask or not.
171 *
172 * @return true if valid.
173 * @return false if invalid, done bitching.
174 * @param fMode The file mode.
175 */
176bool rtFsModeIsValidPermissions(RTFMODE fMode)
177{
178 AssertMsgReturn( (!RTFS_IS_DIRECTORY(fMode) && !(fMode & RTFS_DOS_DIRECTORY))
179 || (RTFS_IS_DIRECTORY(fMode) && (fMode & RTFS_DOS_DIRECTORY)),
180 ("%RTfmode\n", fMode), false);
181 /** @todo more checks! */
182 return true;
183}
184
185
186#ifndef RT_OS_WINDOWS
187/**
188 * Internal worker function which setups RTFSOBJINFO based on a UNIX stat struct.
189 *
190 * @param pObjInfo The file system object info structure to setup.
191 * @param pStat The stat structure to use.
192 * @param pszName The filename which this applies to (exe/hidden check).
193 * @param cbName The length of that filename. (optional, set 0)
194 */
195void rtFsConvertStatToObjInfo(PRTFSOBJINFO pObjInfo, const struct stat *pStat, const char *pszName, unsigned cbName)
196{
197 pObjInfo->cbObject = pStat->st_size;
198 pObjInfo->cbAllocated = pStat->st_size;
199
200#ifdef HAVE_STAT_NSEC
201 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->AccessTime, pStat->st_atime), pStat->st_atimensec);
202 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->ModificationTime, pStat->st_mtime), pStat->st_mtimensec);
203 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->ChangeTime, pStat->st_ctime), pStat->st_ctimensec);
204#ifdef HAVE_STAT_BIRTHTIME
205 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->BirthTime, pStat->st_birthtime), pStat->st_birthtimensec);
206#endif
207
208#elif defined(HAVE_STAT_TIMESPEC_BRIEF)
209 RTTimeSpecSetTimespec(&pObjInfo->AccessTime, &pStat->st_atim);
210 RTTimeSpecSetTimespec(&pObjInfo->ModificationTime, &pStat->st_mtim);
211 RTTimeSpecSetTimespec(&pObjInfo->ChangeTime, &pStat->st_ctim);
212# ifdef HAVE_STAT_BIRTHTIME
213 RTTimeSpecSetTimespec(&pObjInfo->BirthTime, &pStat->st_birthtim);
214# endif
215
216#elif defined(HAVE_STAT_TIMESPEC)
217 RTTimeSpecSetTimespec(&pObjInfo->AccessTime, pStat->st_atimespec);
218 RTTimeSpecSetTimespec(&pObjInfo->ModificationTime, pStat->st_mtimespec);
219 RTTimeSpecSetTimespec(&pObjInfo->ChangeTime, pStat->st_ctimespec);
220# ifdef HAVE_STAT_BIRTHTIME
221 RTTimeSpecSetTimespec(&pObjInfo->BirthTime, pStat->st_birthtimespec);
222# endif
223
224#else /* just the normal stuff */
225 RTTimeSpecSetSeconds(&pObjInfo->AccessTime, pStat->st_atime);
226 RTTimeSpecSetSeconds(&pObjInfo->ModificationTime, pStat->st_mtime);
227 RTTimeSpecSetSeconds(&pObjInfo->ChangeTime, pStat->st_ctime);
228# ifdef HAVE_STAT_BIRTHTIME
229 RTTimeSpecSetSeconds(&pObjInfo->BirthTime, pStat->st_birthtime);
230# endif
231#endif
232#ifndef HAVE_STAT_BIRTHTIME
233 pObjInfo->BirthTime = pObjInfo->ChangeTime;
234#endif
235
236
237 /* the file mode */
238 RTFMODE fMode = pStat->st_mode & RTFS_UNIX_MASK;
239 Assert(RTFS_UNIX_ISUID == S_ISUID);
240 Assert(RTFS_UNIX_ISGID == S_ISGID);
241#ifdef S_ISTXT
242 Assert(RTFS_UNIX_ISTXT == S_ISTXT);
243#elif defined(S_ISVTX)
244 Assert(RTFS_UNIX_ISTXT == S_ISVTX);
245#else
246#error "S_ISVTX / S_ISTXT isn't defined"
247#endif
248 Assert(RTFS_UNIX_IRWXU == S_IRWXU);
249 Assert(RTFS_UNIX_IRUSR == S_IRUSR);
250 Assert(RTFS_UNIX_IWUSR == S_IWUSR);
251 Assert(RTFS_UNIX_IXUSR == S_IXUSR);
252 Assert(RTFS_UNIX_IRWXG == S_IRWXG);
253 Assert(RTFS_UNIX_IRGRP == S_IRGRP);
254 Assert(RTFS_UNIX_IWGRP == S_IWGRP);
255 Assert(RTFS_UNIX_IXGRP == S_IXGRP);
256 Assert(RTFS_UNIX_IRWXO == S_IRWXO);
257 Assert(RTFS_UNIX_IROTH == S_IROTH);
258 Assert(RTFS_UNIX_IWOTH == S_IWOTH);
259 Assert(RTFS_UNIX_IXOTH == S_IXOTH);
260 Assert(RTFS_TYPE_FIFO == S_IFIFO);
261 Assert(RTFS_TYPE_DEV_CHAR == S_IFCHR);
262 Assert(RTFS_TYPE_DIRECTORY == S_IFDIR);
263 Assert(RTFS_TYPE_DEV_BLOCK == S_IFBLK);
264 Assert(RTFS_TYPE_FILE == S_IFREG);
265 Assert(RTFS_TYPE_SYMLINK == S_IFLNK);
266 Assert(RTFS_TYPE_SOCKET == S_IFSOCK);
267#ifdef S_IFWHT
268 Assert(RTFS_TYPE_WHITEOUT == S_IFWHT);
269#endif
270 Assert(RTFS_TYPE_MASK == S_IFMT);
271
272 pObjInfo->Attr.fMode = rtFsModeFromUnix(fMode, pszName, cbName);
273
274 /* additional unix attribs */
275 pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_UNIX;
276 pObjInfo->Attr.u.Unix.uid = pStat->st_uid;
277 pObjInfo->Attr.u.Unix.gid = pStat->st_gid;
278 pObjInfo->Attr.u.Unix.cHardlinks = pStat->st_nlink;
279 pObjInfo->Attr.u.Unix.INodeIdDevice = pStat->st_dev;
280 pObjInfo->Attr.u.Unix.INodeId = pStat->st_ino;
281#ifdef HAVE_STAT_FLAGS
282 pObjInfo->Attr.u.Unix.fFlags = pStat->st_flags;
283#else
284 pObjInfo->Attr.u.Unix.fFlags = 0;
285#endif
286#ifdef HAVE_STAT_GEN
287 pObjInfo->Attr.u.Unix.GenerationId = pStat->st_gen;
288#else
289 pObjInfo->Attr.u.Unix.GenerationId = 0;
290#endif
291 pObjInfo->Attr.u.Unix.Device = pStat->st_rdev;
292}
293
294#endif /* !RT_OS_WINDOWS */
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