VirtualBox

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

Last change on this file since 5031 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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