Changeset 86239 in vbox
- Timestamp:
- Sep 23, 2020 2:23:22 PM (4 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/RTTimeZoneGetCurrent-posix.cpp
r86220 r86239 42 42 #include <iprt/stream.h> 43 43 44 #if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_NETBSD) 45 #define TZDIR "/usr/share/zoneinfo" 46 #define TZ_MAGIC "TZif" 44 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) 45 # include <tzfile.h> 47 46 #else 48 #include <tzfile.h> 47 # define TZDIR "/usr/share/zoneinfo" 48 # define TZ_MAGIC "TZif" 49 49 #endif 50 50 51 52 /********************************************************************************************************************************* 53 * Defined Constants And Macros * 54 *********************************************************************************************************************************/ 51 55 #define PATH_LOCALTIME "/etc/localtime" 52 56 #if defined(RT_OS_FREEBSD) 53 #define PATH_TIMEZONE "/var/db/zoneinfo"57 # define PATH_TIMEZONE "/var/db/zoneinfo" 54 58 #else 55 #define PATH_TIMEZONE "/etc/timezone"59 # define PATH_TIMEZONE "/etc/timezone" 56 60 #endif 57 61 #define PATH_SYSCONFIG_CLOCK "/etc/sysconfig/clock" … … 69 73 static int rtIsValidTimeZoneFile(const char *pszTimeZone) 70 74 { 71 int rc;72 73 75 if (pszTimeZone == NULL || *pszTimeZone == '\0' || *pszTimeZone == '/') 74 76 return VERR_INVALID_PARAMETER; 75 77 76 /* POSIX allows $TZ to begin with a colon (:) so we allow for that here */77 if (*pszTimeZone == ':')78 pszTimeZone++;79 80 78 /* construct full pathname of the time zone file */ 81 79 char szTZPath[RTPATH_MAX]; 82 ssize_t cchStr = RTStrPrintf2(szTZPath, sizeof(szTZPath), "%s/%s", TZDIR, pszTimeZone); 83 if (cchStr <= 0) 84 return VERR_BUFFER_OVERFLOW; 85 86 /* open the time zone file and check that it begins with the correct magic number */ 87 RTFILE hFile = NIL_RTFILE; 88 rc = RTFileOpen(&hFile, szTZPath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 80 int rc = RTPathJoin(szTZPath, sizeof(szTZPath), TZDIR, pszTimeZone); 89 81 if (RT_SUCCESS(rc)) 90 82 { 91 char achTZBuf[sizeof(TZ_MAGIC)]; 92 93 rc = RTFileRead(hFile, achTZBuf, sizeof(achTZBuf), NULL); 94 if (RT_SUCCESS(rc)) 95 { 96 if (RTStrNCmp(achTZBuf, RT_STR_TUPLE(TZ_MAGIC))) 97 { 98 (void) RTFileClose(hFile); 99 return VERR_INVALID_MAGIC; 100 } 101 } 102 (void) RTFileClose(hFile); 83 /* open the time zone file and check that it begins with the correct magic number */ 84 RTFILE hFile = NIL_RTFILE; 85 rc = RTFileOpen(&hFile, szTZPath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 86 if (RT_SUCCESS(rc)) 87 { 88 char achTZBuf[sizeof(TZ_MAGIC)]; 89 rc = RTFileRead(hFile, achTZBuf, sizeof(achTZBuf), NULL); 90 RTFileClose(hFile); 91 if (RT_SUCCESS(rc)) 92 { 93 if (memcmp(achTZBuf, RT_STR_TUPLE(TZ_MAGIC)) == 0) 94 rc = VINF_SUCCESS; 95 else 96 rc = VERR_INVALID_MAGIC; 97 } 98 } 103 99 } 104 100 … … 126 122 * to the other mechanisms to return the system's current time zone. 127 123 */ 124 if (*pszName == ':') /* POSIX allows $TZ to begin with a colon (:) so we allow for that here */ 125 memmove(pszName, pszName + 1, strlen(pszName)); 126 /** @todo this isn't perfect for absolute paths... Should probably try treat 127 * it like /etc/localtime. */ 128 128 rc = rtIsValidTimeZoneFile(pszName); 129 129 if (RT_SUCCESS(rc)) … … 144 144 * specifying the system-wide time zone for the sake of simplicity. 145 145 */ 146 char szBuf[RTPATH_MAX]; 146 147 const char *pszPath = PATH_LOCALTIME; 147 148 if (RTSymlinkExists(pszPath)) 148 149 { 149 char szLinkPath[RTPATH_MAX]; 150 151 rc = RTSymlinkRead(pszPath, szLinkPath, sizeof(szLinkPath), 0); 152 if (RT_SUCCESS(rc)) 153 { 154 char szLinkPathReal[RTPATH_MAX]; 155 156 /* the contents of the symink may contain '..' or other links */ 157 rc = RTPathReal(szLinkPath, szLinkPathReal, sizeof(szLinkPathReal)); 150 /* the contents of the symink may contain '..' or other links */ 151 char szLinkPathReal[RTPATH_MAX]; 152 rc = RTPathReal(pszPath, szLinkPathReal, sizeof(szLinkPathReal)); 153 if (RT_SUCCESS(rc)) 154 { 155 rc = RTPathReal(TZDIR, szBuf, sizeof(szBuf)); 156 AssertRC(rc); 158 157 if (RT_SUCCESS(rc)) 159 158 { 160 char szTZDirPathReal[RTPATH_MAX]; 161 162 rc = RTPathReal(TZDIR, szTZDirPathReal, sizeof(szTZDirPathReal)); 163 if (RT_SUCCESS(rc)) { 159 Assert(RTPathStartsWith(szLinkPathReal, szBuf)); 160 if (RTPathStartsWith(szLinkPathReal, szBuf)) 161 { 164 162 /* <tzfile.h>:TZDIR doesn't include a trailing slash */ 165 rc = rtIsValidTimeZoneFile(szLinkPathReal + strlen(szTZDirPathReal) + 1); 163 const char *pszTimeZone = &szLinkPathReal[strlen(szBuf) + 1]; 164 rc = rtIsValidTimeZoneFile(pszTimeZone); 166 165 if (RT_SUCCESS(rc)) 167 return RTStrCopy(pszName, cbName, szLinkPathReal + strlen(szTZDirPathReal) + 1);166 return RTStrCopy(pszName, cbName, pszTimeZone); 168 167 } 169 168 } 170 169 } 171 return rc;172 170 } 173 171 … … 185 183 if (RT_SUCCESS(rc)) 186 184 { 187 char achBuf[_1K];188 185 size_t cbRead = 0; 189 190 rc = RTFileRead(hFile, achBuf, sizeof(achBuf), &cbRead);186 rc = RTFileRead(hFile, szBuf, sizeof(szBuf), &cbRead); 187 RTFileClose(hFile); 191 188 if (RT_SUCCESS(rc) && cbRead > 0) 192 189 { 193 size_t offNewLine = RTStrOffCharOrTerm(achBuf, '\n'); 194 /* in case no newline or terminating NULL is found */ 195 offNewLine = RT_MIN(offNewLine, sizeof(achBuf) - 1); 196 achBuf[offNewLine] = '\0'; 197 198 rc = rtIsValidTimeZoneFile(achBuf); 190 /* Get the first line and strip it. */ 191 szBuf[RT_MIN(sizeof(szBuf) - 1, cbRead)] = '\0'; 192 size_t const offNewLine = RTStrOffCharOrTerm(szBuf, '\n'); 193 szBuf[offNewLine] = '\0'; 194 const char *pszTimeZone = RTStrStrip(szBuf); 195 196 rc = rtIsValidTimeZoneFile(pszTimeZone); 197 /** @todo UTF-8 encoding. */ 199 198 if (RT_SUCCESS(rc)) 200 { 201 (void) RTFileClose(hFile); 202 return RTStrCopy(pszName, cbName, achBuf); 203 } 204 } 205 (void) RTFileClose(hFile); 206 } 207 return rc; 199 return RTStrCopy(pszName, cbName, pszTimeZone); 200 } 201 } 208 202 } 209 203 … … 217 211 { 218 212 PRTSTREAM pStrm; 219 220 213 rc = RTStrmOpen(pszPath, "r", &pStrm); 221 214 if (RT_SUCCESS(rc)) 222 215 { 223 char szLine[_1K]; 224 225 while (RT_SUCCESS(rc = RTStrmGetLine(pStrm, szLine, sizeof(szLine)))) 226 { 227 if (RTStrNCmp(szLine, RT_STR_TUPLE("ZONE="))) 228 continue; 229 230 rc = rtIsValidTimeZoneFile(szLine + strlen("ZONE=")); 231 if (RT_SUCCESS(rc)) 216 while (RT_SUCCESS(rc = RTStrmGetLine(pStrm, szBuf, sizeof(szBuf)))) 217 { 218 static char const s_szVarEq[] = "ZONE="; 219 if (memcmp(szBuf, RT_STR_TUPLE(s_szVarEq)) == 0) 232 220 { 233 RTStrmClose(pStrm); 234 return RTStrCopy(pszName, cbName, szLine + strlen("ZONE=")); 221 const char *pszTimeZone = &szBuf[sizeof(s_szVarEq) - 1]; 222 rc = rtIsValidTimeZoneFile(pszTimeZone); 223 if (RT_SUCCESS(rc)) 224 { 225 RTStrmClose(pStrm); 226 /** @todo UTF-8 encoding. */ 227 return RTStrCopy(pszName, cbName, pszTimeZone); 228 } 235 229 } 236 230 } 237 231 RTStrmClose(pStrm); 238 232 } 239 return rc;240 233 } 241 234 -
trunk/src/VBox/Runtime/testcase/tstRTTimeSpec.cpp
r82968 r86239 707 707 RTTESTI_CHECK_FROM(RTTimeFromRfc2822(&T2, " 00006 Sep 2018 04:09:08 GMT ")); 708 708 709 /* 710 * Check that RTTimeZoneGetCurrent works (not really timespec, but whatever). 711 */ 712 RTTestSub(hTest, "RTTimeZoneGetCurrent"); 713 szValue[0] = '\0'; 714 RTTESTI_CHECK_RC(RTTimeZoneGetCurrent(szValue, sizeof(szValue)), VINF_SUCCESS); 715 RTTestPrintf(hTest, RTTESTLVL_ALWAYS, "TimeZone: %s", szValue); 709 716 710 717 /*
Note:
See TracChangeset
for help on using the changeset viewer.