/** * Explodes a time spec to the localized timezone. * * @returns pTime. * @param pTime Where to store the exploded time. * @param pTimeSpec The time spec to exploded. (UTC) */ RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec) { RTTIMESPEC LocalTime = *pTimeSpec; RTTimeSpecAddNano(&LocalTime, rtTimeLocalUTCOffset(&LocalTime, true /* current time, skip fallback */)); pTime = RTTimeExplode(pTime, &LocalTime); if (pTime) pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL; return pTime; }
RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec) { /* * FileTimeToLocalFileTime does not do the right thing, so we'll have * to convert to system time and SystemTimeToTzSpecificLocalTime instead. */ RTTIMESPEC LocalTime; SYSTEMTIME SystemTimeIn; FILETIME FileTime; if (FileTimeToSystemTime(RTTimeSpecGetNtFileTime(pTimeSpec, &FileTime), &SystemTimeIn)) { SYSTEMTIME SystemTimeOut; if (SystemTimeToTzSpecificLocalTime(NULL /* use current TZI */, &SystemTimeIn, &SystemTimeOut)) { if (SystemTimeToFileTime(&SystemTimeOut, &FileTime)) { RTTimeSpecSetNtFileTime(&LocalTime, &FileTime); pTime = RTTimeExplode(pTime, &LocalTime); if (pTime) pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL; return pTime; } } } /* * The fallback is to use the current offset. * (A better fallback would be to use the offset of the same time of the year.) */ LocalTime = *pTimeSpec; RTTimeSpecAddNano(&LocalTime, RTTimeLocalDeltaNano()); pTime = RTTimeExplode(pTime, &LocalTime); if (pTime) pTime->fFlags = (pTime->fFlags & ~RTTIME_FLAGS_TYPE_MASK) | RTTIME_FLAGS_TYPE_LOCAL; return pTime; }
/** * Internal worker function which setups RTFSOBJINFO based on a UNIX stat struct. * * @param pObjInfo The file system object info structure to setup. * @param pStat The stat structure to use. * @param pszName The filename which this applies to (exe/hidden check). * @param cbName The length of that filename. (optional, set 0) */ void rtFsConvertStatToObjInfo(PRTFSOBJINFO pObjInfo, const struct stat *pStat, const char *pszName, unsigned cbName) { pObjInfo->cbObject = pStat->st_size; pObjInfo->cbAllocated = pStat->st_blocks * DEV_BSIZE; #ifdef HAVE_STAT_NSEC RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->AccessTime, pStat->st_atime), pStat->st_atimensec); RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->ModificationTime, pStat->st_mtime), pStat->st_mtimensec); RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->ChangeTime, pStat->st_ctime), pStat->st_ctimensec); # ifdef HAVE_STAT_BIRTHTIME RTTimeSpecAddNano(RTTimeSpecSetSeconds(&pObjInfo->BirthTime, pStat->st_birthtime), pStat->st_birthtimensec); # endif #elif defined(HAVE_STAT_TIMESPEC_BRIEF) RTTimeSpecSetTimespec(&pObjInfo->AccessTime, &pStat->st_atim); RTTimeSpecSetTimespec(&pObjInfo->ModificationTime, &pStat->st_mtim); RTTimeSpecSetTimespec(&pObjInfo->ChangeTime, &pStat->st_ctim); # ifdef HAVE_STAT_BIRTHTIME RTTimeSpecSetTimespec(&pObjInfo->BirthTime, &pStat->st_birthtim); # endif #elif defined(HAVE_STAT_TIMESPEC) RTTimeSpecSetTimespec(&pObjInfo->AccessTime, pStat->st_atimespec); RTTimeSpecSetTimespec(&pObjInfo->ModificationTime, pStat->st_mtimespec); RTTimeSpecSetTimespec(&pObjInfo->ChangeTime, pStat->st_ctimespec); # ifdef HAVE_STAT_BIRTHTIME RTTimeSpecSetTimespec(&pObjInfo->BirthTime, pStat->st_birthtimespec); # endif #else /* just the normal stuff */ RTTimeSpecSetSeconds(&pObjInfo->AccessTime, pStat->st_atime); RTTimeSpecSetSeconds(&pObjInfo->ModificationTime, pStat->st_mtime); RTTimeSpecSetSeconds(&pObjInfo->ChangeTime, pStat->st_ctime); # ifdef HAVE_STAT_BIRTHTIME RTTimeSpecSetSeconds(&pObjInfo->BirthTime, pStat->st_birthtime); # endif #endif #ifndef HAVE_STAT_BIRTHTIME pObjInfo->BirthTime = pObjInfo->ChangeTime; #endif /* the file mode */ RTFMODE fMode = pStat->st_mode & RTFS_UNIX_MASK; Assert(RTFS_UNIX_ISUID == S_ISUID); Assert(RTFS_UNIX_ISGID == S_ISGID); #ifdef S_ISTXT Assert(RTFS_UNIX_ISTXT == S_ISTXT); #elif defined(S_ISVTX) Assert(RTFS_UNIX_ISTXT == S_ISVTX); #else #error "S_ISVTX / S_ISTXT isn't defined" #endif Assert(RTFS_UNIX_IRWXU == S_IRWXU); Assert(RTFS_UNIX_IRUSR == S_IRUSR); Assert(RTFS_UNIX_IWUSR == S_IWUSR); Assert(RTFS_UNIX_IXUSR == S_IXUSR); Assert(RTFS_UNIX_IRWXG == S_IRWXG); Assert(RTFS_UNIX_IRGRP == S_IRGRP); Assert(RTFS_UNIX_IWGRP == S_IWGRP); Assert(RTFS_UNIX_IXGRP == S_IXGRP); Assert(RTFS_UNIX_IRWXO == S_IRWXO); Assert(RTFS_UNIX_IROTH == S_IROTH); Assert(RTFS_UNIX_IWOTH == S_IWOTH); Assert(RTFS_UNIX_IXOTH == S_IXOTH); Assert(RTFS_TYPE_FIFO == S_IFIFO); Assert(RTFS_TYPE_DEV_CHAR == S_IFCHR); Assert(RTFS_TYPE_DIRECTORY == S_IFDIR); Assert(RTFS_TYPE_DEV_BLOCK == S_IFBLK); Assert(RTFS_TYPE_FILE == S_IFREG); Assert(RTFS_TYPE_SYMLINK == S_IFLNK); Assert(RTFS_TYPE_SOCKET == S_IFSOCK); #ifdef S_IFWHT Assert(RTFS_TYPE_WHITEOUT == S_IFWHT); #endif Assert(RTFS_TYPE_MASK == S_IFMT); pObjInfo->Attr.fMode = rtFsModeFromUnix(fMode, pszName, cbName); /* additional unix attribs */ pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_UNIX; pObjInfo->Attr.u.Unix.uid = pStat->st_uid; pObjInfo->Attr.u.Unix.gid = pStat->st_gid; pObjInfo->Attr.u.Unix.cHardlinks = pStat->st_nlink; pObjInfo->Attr.u.Unix.INodeIdDevice = pStat->st_dev; pObjInfo->Attr.u.Unix.INodeId = pStat->st_ino; #ifdef HAVE_STAT_FLAGS pObjInfo->Attr.u.Unix.fFlags = pStat->st_flags; #else pObjInfo->Attr.u.Unix.fFlags = 0; #endif #ifdef HAVE_STAT_GEN pObjInfo->Attr.u.Unix.GenerationId = pStat->st_gen; #else pObjInfo->Attr.u.Unix.GenerationId = 0; #endif pObjInfo->Attr.u.Unix.Device = pStat->st_rdev; }