2 #include "const_defines.h"
3 #include "func_defines.h"
5 #include "RTErrConvertFromErrno.h"
7 #include <sys/statvfs.h>
16 * Query the sizes of a filesystem.
18 * @returns iprt status code.
19 * @param pszFsPath Path within the mounted filesystem.
20 * @param pcbTotal Where to store the total filesystem space. (Optional)
21 * @param pcbFree Where to store the remaining free space in the filesystem. (Optional)
22 * @param pcbBlock Where to store the block size. (Optional)
23 * @param pcbSector Where to store the sector size. (Optional)
25 int RTFsQuerySizes(const char *pszFsPath
, RTFOFF
*pcbTotal
, RTFOFF
*pcbFree
,
26 uint32_t *pcbBlock
, uint32_t *pcbSector
)
31 AssertMsgReturn(VALID_PTR(pszFsPath
) && *pszFsPath
, ("%p", pszFsPath
), VERR_INVALID_PARAMETER
);
34 * Convert the path and query the information.
36 char *pszNativeFsPath
;
37 int rc
= rtPathToNative(&pszNativeFsPath
, pszFsPath
);
40 /** @todo I'm not quite sure if statvfs was properly specified by SuS, I have to check my own
41 * implementation and FreeBSD before this can eventually be promoted to posix. */
42 struct statvfs StatVFS
= {0};
43 if (!statvfs(pszNativeFsPath
, &StatVFS
))
46 * Calc the returned values.
49 *pcbTotal
= (RTFOFF
)StatVFS
.f_blocks
* StatVFS
.f_frsize
;
51 *pcbFree
= (RTFOFF
)StatVFS
.f_bavail
* StatVFS
.f_frsize
;
53 *pcbBlock
= StatVFS
.f_frsize
;
54 /* no idea how to get the sector... */
59 rc
= RTErrConvertFromErrno(errno
);
60 rtPathFreeNative(pszNativeFsPath
);
63 printf("RTFsQuerySizes(%p:{%s}, %p:{%RTfoff}, %p:{%RTfoff}, %p:{%RX32}, %p:{%RX32}): returns %Rrc\n",
64 pszFsPath
, pszFsPath
, pcbTotal
, pcbTotal
? *pcbTotal
: 0, pcbFree
, pcbFree
? *pcbFree
: 0,
65 pcbBlock
, pcbBlock
? *pcbBlock
: 0, pcbSector
, pcbSector
? *pcbSector
: 0, rc
);
70 * Internal worker function which setups RTFSOBJINFO based on a UNIX stat struct.
72 * @param pObjInfo The file system object info structure to setup.
73 * @param pStat The stat structure to use.
75 void rtFsConvertStatToObjInfo(PRTFSOBJINFO pObjInfo
, const struct stat
*pStat
, const char *pszName
, unsigned cbName
)
77 pObjInfo
->cbObject
= pStat
->st_size
;
78 pObjInfo
->cbAllocated
= pStat
->st_size
;
81 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo
->AccessTime
, pStat
->st_atime
), pStat
->st_atimensec
);
82 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo
->ModificationTime
, pStat
->st_mtime
), pStat
->st_mtimensec
);
83 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo
->ChangeTime
, pStat
->st_ctime
), pStat
->st_ctimensec
);
84 #ifdef HAVE_STAT_BIRTHTIME
85 RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo
->BirthTime
, pStat
->st_birthtime
), pStat
->st_birthtimensec
);
88 #elif defined(HAVE_STAT_TIMESPEC_BRIEF)
89 RTTimeSpecSetTimespec(&pObjInfo
->AccessTime
, &pStat
->st_atim
);
90 RTTimeSpecSetTimespec(&pObjInfo
->ModificationTime
, &pStat
->st_mtim
);
91 RTTimeSpecSetTimespec(&pObjInfo
->ChangeTime
, &pStat
->st_ctim
);
92 # ifdef HAVE_STAT_BIRTHTIME
93 RTTimeSpecSetTimespec(&pObjInfo
->BirthTime
, &pStat
->st_birthtim
);
96 #elif defined(HAVE_STAT_TIMESPEC)
97 RTTimeSpecSetTimespec(&pObjInfo
->AccessTime
, pStat
->st_atimespec
);
98 RTTimeSpecSetTimespec(&pObjInfo
->ModificationTime
, pStat
->st_mtimespec
);
99 RTTimeSpecSetTimespec(&pObjInfo
->ChangeTime
, pStat
->st_ctimespec
);
100 # ifdef HAVE_STAT_BIRTHTIME
101 RTTimeSpecSetTimespec(&pObjInfo
->BirthTime
, pStat
->st_birthtimespec
);
104 #else /* just the normal stuff */
105 RTTimeSpecSetSeconds(&pObjInfo
->AccessTime
, pStat
->st_atime
);
106 RTTimeSpecSetSeconds(&pObjInfo
->ModificationTime
, pStat
->st_mtime
);
107 RTTimeSpecSetSeconds(&pObjInfo
->ChangeTime
, pStat
->st_ctime
);
108 # ifdef HAVE_STAT_BIRTHTIME
109 RTTimeSpecSetSeconds(&pObjInfo
->BirthTime
, pStat
->st_birthtime
);
112 #ifndef HAVE_STAT_BIRTHTIME
113 pObjInfo
->BirthTime
= pObjInfo
->ChangeTime
;
118 RTFMODE fMode
= pStat
->st_mode
& RTFS_UNIX_MASK
;
119 Assert(RTFS_UNIX_ISUID
== S_ISUID
);
120 Assert(RTFS_UNIX_ISGID
== S_ISGID
);
121 Assert(RTFS_UNIX_ISTXT
== S_ISTXT
);
122 Assert(RTFS_UNIX_ISTXT
== S_ISVTX
);
123 Assert(RTFS_UNIX_IRWXU
== S_IRWXU
);
124 Assert(RTFS_UNIX_IRUSR
== S_IRUSR
);
125 Assert(RTFS_UNIX_IWUSR
== S_IWUSR
);
126 Assert(RTFS_UNIX_IXUSR
== S_IXUSR
);
127 Assert(RTFS_UNIX_IRWXG
== S_IRWXG
);
128 Assert(RTFS_UNIX_IRGRP
== S_IRGRP
);
129 Assert(RTFS_UNIX_IWGRP
== S_IWGRP
);
130 Assert(RTFS_UNIX_IXGRP
== S_IXGRP
);
131 Assert(RTFS_UNIX_IRWXO
== S_IRWXO
);
132 Assert(RTFS_UNIX_IROTH
== S_IROTH
);
133 Assert(RTFS_UNIX_IWOTH
== S_IWOTH
);
134 Assert(RTFS_UNIX_IXOTH
== S_IXOTH
);
135 Assert(RTFS_TYPE_FIFO
== S_IFIFO
);
136 Assert(RTFS_TYPE_DEV_CHAR
== S_IFCHR
);
137 Assert(RTFS_TYPE_DIRECTORY
== S_IFDIR
);
138 Assert(RTFS_TYPE_DEV_BLOCK
== S_IFBLK
);
139 Assert(RTFS_TYPE_FILE
== S_IFREG
);
140 Assert(RTFS_TYPE_SYMLINK
== S_IFLNK
);
141 Assert(RTFS_TYPE_SOCKET
== S_IFSOCK
);
143 Assert(RTFS_TYPE_WHITEOUT
== S_IFWHT
);
145 Assert(RTFS_TYPE_MASK
== S_IFMT
);
147 pObjInfo
->Attr
.fMode
= rtFsModeFromUnix(fMode
, pszName
, cbName
);
149 /* additional unix attribs */
150 pObjInfo
->Attr
.enmAdditional
= RTFSOBJATTRADD_UNIX
;
151 pObjInfo
->Attr
.u
.Unix
.uid
= pStat
->st_uid
;
152 pObjInfo
->Attr
.u
.Unix
.gid
= pStat
->st_gid
;
153 pObjInfo
->Attr
.u
.Unix
.cHardlinks
= pStat
->st_nlink
;
154 pObjInfo
->Attr
.u
.Unix
.INodeIdDevice
= pStat
->st_dev
;
155 pObjInfo
->Attr
.u
.Unix
.INodeId
= pStat
->st_ino
;
156 #ifdef HAVE_STAT_FLAGS
157 pObjInfo
->Attr
.u
.Unix
.fFlags
= pStat
->st_flags
;
159 pObjInfo
->Attr
.u
.Unix
.fFlags
= 0;
162 pObjInfo
->Attr
.u
.Unix
.GenerationId
= pStat
->st_gen
;
164 pObjInfo
->Attr
.u
.Unix
.GenerationId
= 0;
166 pObjInfo
->Attr
.u
.Unix
.Device
= pStat
->st_rdev
;
170 * Converts dos-style attributes to Unix attributes.
172 * @returns Normalized file mode.
173 * @param fMode The mode mask containing dos-style attibutes only.
174 * @param pszName The filename which this applies to (exe check).
175 * @param cbName The length of that filename. (optional, set 0)
177 RTFMODE
rtFsModeNormalize(RTFMODE fMode
, const char *pszName
, unsigned cbName
)
179 if (!(fMode
& RTFS_UNIX_MASK
))
180 rtFsModeFromDos(fMode
, pszName
, cbName
);
181 else if (!(fMode
& RTFS_DOS_MASK
))
182 rtFsModeFromUnix(fMode
, pszName
, cbName
);
183 else if (!(fMode
& RTFS_TYPE_MASK
))
184 fMode
|= fMode
& RTFS_DOS_DIRECTORY
? RTFS_TYPE_DIRECTORY
: RTFS_TYPE_FILE
;
185 else if (RTFS_IS_DIRECTORY(fMode
))
186 fMode
|= RTFS_DOS_DIRECTORY
;
191 * Checks if the file mode is valid or not.
193 * @return true if valid.
194 * @return false if invalid, done bitching.
195 * @param fMode The file mode.
197 bool rtFsModeIsValid(RTFMODE fMode
)
199 AssertMsgReturn( (!RTFS_IS_DIRECTORY(fMode
) && !(fMode
& RTFS_DOS_DIRECTORY
))
200 || (RTFS_IS_DIRECTORY(fMode
) && (fMode
& RTFS_DOS_DIRECTORY
)),
201 ("%RTfmode\n", fMode
), false);
202 AssertMsgReturn(RTFS_TYPE_MASK
& fMode
,
203 ("%RTfmode\n", fMode
), false);
204 /** @todo more checks! */
209 * Converts Unix attributes to Dos-style attributes.
212 * @param fMode The mode mask containing dos-style attibutes only.
214 RTFMODE
rtFsModeFromUnix(RTFMODE fMode
, const char *pszName
, unsigned cbName
)
216 fMode
&= RTFS_UNIX_MASK
;
218 if (!(fMode
& (RTFS_UNIX_IWUSR
| RTFS_UNIX_IWGRP
| RTFS_UNIX_IWOTH
)))
219 fMode
|= RTFS_DOS_READONLY
;
220 if (RTFS_IS_DIRECTORY(fMode
))
221 fMode
|= RTFS_DOS_DIRECTORY
;
222 if (!(fMode
& RTFS_DOS_MASK
))
223 fMode
|= RTFS_DOS_NT_NORMAL
;
224 if (!(fMode
& RTFS_DOS_HIDDEN
) && pszName
)
226 pszName
= RTPathFilename(pszName
);
227 if (pszName
&& *pszName
== '.')
228 fMode
|= RTFS_DOS_HIDDEN
;
234 * Converts dos-style attributes to Unix attributes.
237 * @param fMode The mode mask containing dos-style attibutes only.
238 * @param pszName The filename which this applies to (exe check).
239 * @param cbName The length of that filename. (optional, set 0)
241 RTFMODE
rtFsModeFromDos(RTFMODE fMode
, const char *pszName
, unsigned cbName
)
243 fMode
&= ~((1 << RTFS_DOS_SHIFT
) - 1);
245 /* everything is readable. */
246 fMode
|= RTFS_UNIX_IRUSR
| RTFS_UNIX_IRGRP
| RTFS_UNIX_IROTH
;
247 if (fMode
& RTFS_DOS_DIRECTORY
)
248 /* directories are executable. */
249 fMode
|= RTFS_TYPE_DIRECTORY
| RTFS_UNIX_IXUSR
| RTFS_UNIX_IXGRP
| RTFS_UNIX_IXOTH
;
252 fMode
|= RTFS_TYPE_FILE
;
253 if (!cbName
&& pszName
)
254 cbName
= strlen(pszName
);
255 if (cbName
>= 4 && pszName
[cbName
- 4] == '.')
257 /* check for executable extension. */
258 const char *pszExt
= &pszName
[cbName
- 3];
260 szExt
[0] = tolower(pszExt
[0]);
261 szExt
[1] = tolower(pszExt
[1]);
262 szExt
[2] = tolower(pszExt
[2]);
264 if ( !memcmp(szExt
, "exe", 4)
265 || !memcmp(szExt
, "bat", 4)
266 || !memcmp(szExt
, "com", 4)
267 || !memcmp(szExt
, "cmd", 4)
268 || !memcmp(szExt
, "btm", 4)
270 fMode
|= RTFS_UNIX_IXUSR
| RTFS_UNIX_IXGRP
| RTFS_UNIX_IXOTH
;
274 if (!(fMode
& RTFS_DOS_READONLY
))
275 fMode
|= RTFS_UNIX_IWUSR
| RTFS_UNIX_IWGRP
| RTFS_UNIX_IWOTH
;