/* $Id: tstNtStat.c 3007 2016-11-06 16:46:43Z bird $ */ /** @file * Manual lstat/stat testcase. */ /* * Copyright (c) 2013 knut st. osmundsen * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Alternatively, the content of this file may be used under the terms of the * GPL version 2 or later, or LGPL version 2.1 or later. */ /******************************************************************************* * Header Files * *******************************************************************************/ #include #include #include "ntstat.h" static int IsLeapYear(int iYear) { return iYear % 4 == 0 && ( iYear % 100 != 0 || iYear % 400 == 0); } static int DaysInMonth(int iYear, int iMonth) { switch (iMonth) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 4: case 6: case 9: case 11: return 30; case 2: return IsLeapYear(iYear) ? 29 : 28; default: *(void **)(size_t)iMonth = 0; /* crash! */ return 0; } } static char *FormatTimeSpec(char *pszBuf, BirdTimeSpec_T const *pTimeSpec) { if (pTimeSpec->tv_sec >= 0) { int iYear = 1970; int iMonth = 1; int iDay = 1; int iHour = 0; int iMin = 0; int iSec = 0; __int64 cSecs = pTimeSpec->tv_sec; /* lazy bird approach, find date, day by day */ while (cSecs >= 24*3600) { if ( iDay < 28 || iDay < DaysInMonth(iYear, iMonth)) iDay++; else { if (iMonth < 12) iMonth++; else { iYear++; iMonth = 1; } iDay = 1; } cSecs -= 24*3600; } iHour = (int)cSecs / 3600; cSecs %= 3600; iMin = (int)cSecs / 60; iSec = (int)cSecs % 60; sprintf(pszBuf, "%04d-%02d-%02dT%02u:%02u:%02u.%09u (%I64d.%09u)", iYear, iMonth, iDay, iHour, iMin, iSec, pTimeSpec->tv_nsec, pTimeSpec->tv_sec, pTimeSpec->tv_nsec); } else sprintf(pszBuf, "%I64d.%09u (before 1970-01-01)", pTimeSpec->tv_sec, pTimeSpec->tv_nsec); return pszBuf; } int main(int argc, char **argv) { int rc = 0; int i; for (i = 1; i < argc; i++) { struct stat st; if (lstat(argv[i], &st) == 0) { char szBuf[256]; printf("%s:\n", argv[i]); printf(" st_mode: %o\n", st.st_mode); printf(" st_isdirsymlink: %d\n", st.st_isdirsymlink); printf(" st_ismountpoint: %d\n", st.st_ismountpoint); printf(" st_size: %I64u (%#I64x)\n", st.st_size, st.st_size); printf(" st_atim: %s\n", FormatTimeSpec(szBuf, &st.st_atim)); printf(" st_mtim: %s\n", FormatTimeSpec(szBuf, &st.st_mtim)); printf(" st_ctim: %s\n", FormatTimeSpec(szBuf, &st.st_ctim)); printf(" st_birthtim: %s\n", FormatTimeSpec(szBuf, &st.st_birthtim)); printf(" st_ino: %#I64x\n", st.st_ino); printf(" st_dev: %#I64x\n", st.st_dev); printf(" st_nlink: %u\n", st.st_nlink); printf(" st_rdev: %#x\n", st.st_rdev); printf(" st_uid: %d\n", st.st_uid); printf(" st_gid: %d\n", st.st_gid); printf(" st_blksize: %d (%#x)\n", st.st_blksize, st.st_blksize); printf(" st_blocks: %I64u (%#I64x)\n", st.st_blocks, st.st_blocks); } else { fprintf(stderr, "stat failed on '%s': errno=%u\n", argv[i], errno); rc = 1; } } return rc; }