Formerly time/time.h.~12~
[kopensolaris-gnu/glibc.git] / time / zdump.c
1 #ifdef  LIBC
2 #include <ansidecl.h>
3 #endif
4
5 #ifndef lint
6 #ifndef NOID
7 static char     elsieid[] = "@(#)zdump.c        7.2";
8 #endif /* !defined NOID */
9 #endif /* !defined lint */
10
11 /*
12 ** This code has been made independent of the rest of the time
13 ** conversion package to increase confidence in the verification it provides.
14 ** You can use this code to help in verifying other implementations.
15 */
16
17 #include "stdio.h"      /* for stdout, stderr */
18 #include "string.h"     /* for strcpy */
19 #include "sys/types.h"  /* for time_t */
20 #include "time.h"       /* for struct tm */
21
22 #ifndef MAX_STRING_LENGTH
23 #define MAX_STRING_LENGTH       1024
24 #endif /* !defined MAX_STRING_LENGTH */
25
26 #ifndef TRUE
27 #define TRUE            1
28 #endif /* !defined TRUE */
29
30 #ifndef FALSE
31 #define FALSE           0
32 #endif /* !defined FALSE */
33
34 #ifndef EXIT_SUCCESS
35 #define EXIT_SUCCESS    0
36 #endif /* !defined EXIT_SUCCESS */
37
38 #ifndef EXIT_FAILURE
39 #define EXIT_FAILURE    1
40 #endif /* !defined EXIT_FAILURE */
41
42 #ifndef SECSPERMIN
43 #define SECSPERMIN      60
44 #endif /* !defined SECSPERMIN */
45
46 #ifndef SECSPERHOUR
47 #define SECSPERHOUR     3600
48 #endif /* !defined SECSPERHOUR */
49
50 #ifndef HOURSPERDAY
51 #define HOURSPERDAY     24
52 #endif /* !defined HOURSPERDAY */
53
54 #ifndef EPOCH_YEAR
55 #define EPOCH_YEAR      1970
56 #endif /* !defined EPOCH_YEAR */
57
58 #ifndef DAYSPERNYEAR
59 #define DAYSPERNYEAR    365
60 #endif /* !defined DAYSPERNYEAR */
61
62 extern char **  environ;
63 extern int      getopt();
64 extern char *   optarg;
65 extern int      optind;
66 extern time_t   time();
67 extern char *   tzname[2];
68 extern void     tzset();
69
70 #ifdef USG
71 extern void     exit();
72 extern void     perror();
73 #endif /* defined USG */
74
75 static char *   abbr();
76 static long     delta();
77 static void     hunt();
78 static int      longest;
79 static char *   progname;
80 static void     show();
81
82 int
83 main(argc, argv)
84 int     argc;
85 char *  argv[];
86 {
87         register int    i, c;
88         register int    vflag;
89         register char * cutoff;
90         register int    cutyear;
91         register long   cuttime;
92         time_t          now;
93         time_t          t, newt;
94         time_t          hibit;
95         struct tm       tm, newtm;
96
97         progname = argv[0];
98         vflag = 0;
99         cutoff = NULL;
100         while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
101                 if (c == 'v')
102                         vflag = 1;
103                 else    cutoff = optarg;
104         if (c != EOF ||
105            (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
106                 (void) fprintf(stderr,
107                         "%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n",
108                         argv[0], argv[0]);
109                 (void) exit(EXIT_FAILURE);
110         }
111         if (cutoff != NULL)
112                 cutyear = atoi(cutoff);
113         /*
114         ** VERY approximate.
115         */
116         cuttime = (long) (cutyear - EPOCH_YEAR) *
117                 SECSPERHOUR * HOURSPERDAY * DAYSPERNYEAR;
118         (void) time(&now);
119         longest = 0;
120         for (i = optind; i < argc; ++i)
121                 if (strlen(argv[i]) > longest)
122                         longest = strlen(argv[i]);
123         for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
124                 ;
125         for (i = optind; i < argc; ++i) {
126                 register char **        saveenv;
127                 static char             buf[MAX_STRING_LENGTH];
128                 char *                  fakeenv[2];
129
130                 if (strlen(argv[i]) + 4 > sizeof buf) {
131                         (void) fflush(stdout);
132                         (void) fprintf(stderr, "%s: argument too long -- %s\n",
133                                 progname, argv[i]);
134                         (void) exit(EXIT_FAILURE);
135                 }
136                 (void) strcpy(buf, "TZ=");
137                 (void) strcat(buf, argv[i]);
138                 fakeenv[0] = buf;
139                 fakeenv[1] = NULL;
140                 saveenv = environ;
141                 environ = fakeenv;
142                 (void) tzset();
143                 environ = saveenv;
144                 show(argv[i], now, FALSE);
145                 if (!vflag)
146                         continue;
147                 /*
148                 ** Get lowest value of t.
149                 */
150                 t = hibit;
151                 if (t > 0)              /* time_t is unsigned */
152                         t = 0;
153                 show(argv[i], t, TRUE);
154                 t += SECSPERHOUR * HOURSPERDAY;
155                 show(argv[i], t, TRUE);
156                 tm = *localtime(&t);
157                 (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
158                 for ( ; ; ) {
159                         if (cutoff != NULL && t >= cuttime)
160                                 break;
161                         newt = t + SECSPERHOUR * 12;
162                         if (cutoff != NULL && newt >= cuttime)
163                                 break;
164                         if (newt <= t)
165                                 break;
166                         newtm = *localtime(&newt);
167                         if (delta(&newtm, &tm) != (newt - t) ||
168                                 newtm.tm_isdst != tm.tm_isdst ||
169                                 strcmp(abbr(&newtm), buf) != 0) {
170                                         hunt(argv[i], t, newt);
171                                         (void) strncpy(buf, abbr(&newtm),
172                                                 (sizeof buf) - 1);
173                         }
174                         t = newt;
175                         tm = newtm;
176                 }
177                 /*
178                 ** Get highest value of t.
179                 */
180                 t = ~((time_t) 0);
181                 if (t < 0)              /* time_t is signed */
182                         t &= ~hibit;
183                 t -= SECSPERHOUR * HOURSPERDAY;
184                 show(argv[i], t, TRUE);
185                 t += SECSPERHOUR * HOURSPERDAY;
186                 show(argv[i], t, TRUE);
187         }
188         if (fflush(stdout) || ferror(stdout)) {
189                 (void) fprintf(stderr, "%s: Error writing standard output ",
190                         argv[0]);
191                 (void) perror("standard output");
192                 (void) exit(EXIT_FAILURE);
193         }
194         exit(EXIT_SUCCESS);
195
196         /* gcc -Wall pacifier */
197         for ( ; ; )
198                 ;
199 }
200
201 static void
202 hunt(name, lot, hit)
203 char *  name;
204 time_t  lot;
205 time_t  hit;
206 {
207         time_t          t;
208         struct tm       lotm;
209         struct tm       tm;
210         static char     loab[MAX_STRING_LENGTH];
211
212         lotm = *localtime(&lot);
213         (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
214         while ((hit - lot) >= 2) {
215                 t = lot / 2 + hit / 2;
216                 if (t <= lot)
217                         ++t;
218                 else if (t >= hit)
219                         --t;
220                 tm = *localtime(&t);
221                 if (delta(&tm, &lotm) == (t - lot) &&
222                         tm.tm_isdst == lotm.tm_isdst &&
223                         strcmp(abbr(&tm), loab) == 0) {
224                                 lot = t;
225                                 lotm = tm;
226                 } else  hit = t;
227         }
228         show(name, lot, TRUE);
229         show(name, hit, TRUE);
230 }
231
232 static long
233 delta(newp, oldp)
234 struct tm *     newp;
235 struct tm *     oldp;
236 {
237         long    result;
238
239         result = newp->tm_hour - oldp->tm_hour;
240         if (result < 0)
241                 result += HOURSPERDAY;
242         result *= SECSPERHOUR;
243         result += (newp->tm_min - oldp->tm_min) * SECSPERMIN;
244         return result + newp->tm_sec - oldp->tm_sec;
245 }
246
247 static void
248 show(zone, t, v)
249 char *  zone;
250 time_t  t;
251 int     v;
252 {
253         struct tm *             tmp;
254         extern struct tm *      localtime();
255
256         (void) printf("%-*s  ", longest, zone);
257         if (v)
258                 (void) printf("%.24s GMT = ", asctime(gmtime(&t)));
259         tmp = localtime(&t);
260         (void) printf("%.24s", asctime(tmp));
261         if (*abbr(tmp) != '\0')
262                 (void) printf(" %s", abbr(tmp));
263         if (v) {
264                 (void) printf(" isdst=%d", tmp->tm_isdst);
265 #ifdef TM_GMTOFF
266                 (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
267 #endif /* defined TM_GMTOFF */
268         }
269         (void) printf("\n");
270 }
271
272 static char *
273 abbr(tmp)
274 struct tm *     tmp;
275 {
276         register char * result;
277
278         if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
279                 return "";
280         result = tzname[tmp->tm_isdst];
281         return (result == NULL) ? "" : result;
282 }