1 /* $Id: tstNtStat.c 3007 2016-11-06 16:46:43Z bird $ */
2 /** @file
3  * Manual lstat/stat testcase.
4  */
5 
6 /*
7  * Copyright (c) 2013 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25  * IN THE SOFTWARE.
26  *
27  * Alternatively, the content of this file may be used under the terms of the
28  * GPL version 2 or later, or LGPL version 2.1 or later.
29  */
30 
31 /*******************************************************************************
32 *   Header Files                                                               *
33 *******************************************************************************/
34 #include <stdio.h>
35 #include <errno.h>
36 #include "ntstat.h"
37 
38 
IsLeapYear(int iYear)39 static int IsLeapYear(int iYear)
40 {
41     return iYear % 4 == 0
42         && (   iYear % 100 != 0
43             || iYear % 400 == 0);
44 }
45 
DaysInMonth(int iYear,int iMonth)46 static int DaysInMonth(int iYear, int iMonth)
47 {
48     switch (iMonth)
49     {
50         case 1:
51         case 3:
52         case 5:
53         case 7:
54         case 8:
55         case 10:
56         case 12:
57             return 31;
58         case 4:
59         case 6:
60         case 9:
61         case 11:
62             return 30;
63         case 2:
64             return IsLeapYear(iYear) ? 29 : 28;
65 
66         default:
67             *(void **)(size_t)iMonth = 0; /* crash! */
68             return 0;
69     }
70 }
71 
72 
FormatTimeSpec(char * pszBuf,BirdTimeSpec_T const * pTimeSpec)73 static char *FormatTimeSpec(char *pszBuf, BirdTimeSpec_T const *pTimeSpec)
74 {
75     if (pTimeSpec->tv_sec >= 0)
76     {
77         int     iYear  = 1970;
78         int     iMonth = 1;
79         int     iDay   = 1;
80         int     iHour  = 0;
81         int     iMin   = 0;
82         int     iSec   = 0;
83         __int64 cSecs  = pTimeSpec->tv_sec;
84 
85         /* lazy bird approach, find date, day by day */
86         while (cSecs >= 24*3600)
87         {
88             if (   iDay < 28
89                 || iDay < DaysInMonth(iYear, iMonth))
90                 iDay++;
91             else
92             {
93                 if (iMonth < 12)
94                     iMonth++;
95                 else
96                 {
97                     iYear++;
98                     iMonth = 1;
99                 }
100                 iDay = 1;
101             }
102             cSecs -= 24*3600;
103         }
104 
105         iHour  = (int)cSecs / 3600;
106         cSecs %= 3600;
107         iMin   = (int)cSecs / 60;
108         iSec   = (int)cSecs % 60;
109 
110         sprintf(pszBuf, "%04d-%02d-%02dT%02u:%02u:%02u.%09u (%I64d.%09u)",
111                 iYear, iMonth, iDay, iHour, iMin, iSec, pTimeSpec->tv_nsec,
112                 pTimeSpec->tv_sec, pTimeSpec->tv_nsec);
113     }
114     else
115         sprintf(pszBuf, "%I64d.%09u (before 1970-01-01)", pTimeSpec->tv_sec, pTimeSpec->tv_nsec);
116     return pszBuf;
117 }
118 
119 
main(int argc,char ** argv)120 int main(int argc, char **argv)
121 {
122     int rc = 0;
123     int i;
124 
125     for (i = 1; i < argc; i++)
126     {
127         struct stat st;
128         if (lstat(argv[i], &st) == 0)
129         {
130             char szBuf[256];
131             printf("%s:\n", argv[i]);
132             printf("  st_mode:          %o\n", st.st_mode);
133             printf("  st_isdirsymlink:  %d\n", st.st_isdirsymlink);
134             printf("  st_ismountpoint:  %d\n", st.st_ismountpoint);
135             printf("  st_size:          %I64u (%#I64x)\n", st.st_size, st.st_size);
136             printf("  st_atim:          %s\n", FormatTimeSpec(szBuf, &st.st_atim));
137             printf("  st_mtim:          %s\n", FormatTimeSpec(szBuf, &st.st_mtim));
138             printf("  st_ctim:          %s\n", FormatTimeSpec(szBuf, &st.st_ctim));
139             printf("  st_birthtim:      %s\n", FormatTimeSpec(szBuf, &st.st_birthtim));
140             printf("  st_ino:           %#I64x\n", st.st_ino);
141             printf("  st_dev:           %#I64x\n", st.st_dev);
142             printf("  st_nlink:         %u\n", st.st_nlink);
143             printf("  st_rdev:          %#x\n", st.st_rdev);
144             printf("  st_uid:           %d\n", st.st_uid);
145             printf("  st_gid:           %d\n", st.st_gid);
146             printf("  st_blksize:       %d (%#x)\n", st.st_blksize, st.st_blksize);
147             printf("  st_blocks:        %I64u (%#I64x)\n", st.st_blocks, st.st_blocks);
148         }
149         else
150         {
151             fprintf(stderr, "stat failed on '%s': errno=%u\n", argv[i], errno);
152             rc = 1;
153         }
154     }
155     return rc;
156 }
157 
158