Print this page
XXXX Update zdump to better-handle POSIX timezones
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/zdump/zdump.c
+++ new/usr/src/cmd/zdump/zdump.c
1 1 /*
2 2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 3 * Use is subject to license terms.
4 4 */
5 5
6 6 #pragma ident "%Z%%M% %I% %E% SMI"
7 7
8 8 /*
9 9 * zdump 7.24
10 10 * Taken from elsie.nci.nih.gov to replace the existing Solaris zdump,
11 11 * which was based on an earlier version of the elsie code.
12 12 *
13 13 * For zdump 7.24, the following changes were made to the elsie code:
14 14 * locale/textdomain/messages to match existing Solaris style.
15 15 * Solaris verbose mode is documented to display the current time first.
16 16 * cstyle cleaned code.
17 17 * removed old locale/textdomain code.
18 18 */
19 19
20 20 static char elsieid[] = "@(#)zdump.c 7.74";
21 21
22 22 /*
23 23 * This code has been made independent of the rest of the time
24 24 * conversion package to increase confidence in the verification it provides.
25 25 * You can use this code to help in verifying other implementations.
26 26 */
27 27
28 28 #include "stdio.h" /* for stdout, stderr, perror */
29 29 #include "string.h" /* for strcpy */
30 30 #include "sys/types.h" /* for time_t */
31 31 #include "time.h" /* for struct tm */
32 32 #include "stdlib.h" /* for exit, malloc, atoi */
33 33 #include "locale.h" /* for setlocale, textdomain */
34 34 #include "libintl.h"
35 35 #include <ctype.h>
36 36 #include "tzfile.h" /* for defines */
37 37 #include <limits.h>
38 38
39 39 #ifndef ZDUMP_LO_YEAR
40 40 #define ZDUMP_LO_YEAR (-500)
41 41 #endif /* !defined ZDUMP_LO_YEAR */
42 42
43 43 #ifndef ZDUMP_HI_YEAR
44 44 #define ZDUMP_HI_YEAR 2500
45 45 #endif /* !defined ZDUMP_HI_YEAR */
46 46
47 47 #ifndef MAX_STRING_LENGTH
48 48 #define MAX_STRING_LENGTH 1024
49 49 #endif /* !defined MAX_STRING_LENGTH */
50 50
51 51 #ifndef TRUE
52 52 #define TRUE 1
53 53 #endif /* !defined TRUE */
54 54
55 55 #ifndef FALSE
56 56 #define FALSE 0
57 57 #endif /* !defined FALSE */
58 58
59 59 #ifndef isleap_sum
60 60 /*
61 61 * See tzfile.h for details on isleap_sum.
62 62 */
63 63 #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
64 64 #endif /* !defined isleap_sum */
65 65
66 66 #ifndef SECSPERDAY
67 67 #define SECSPERDAY ((long)SECSPERHOUR * HOURSPERDAY)
68 68 #endif
69 69 #define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR)
70 70 #define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY)
71 71
72 72 #ifndef GNUC_or_lint
73 73 #ifdef lint
74 74 #define GNUC_or_lint
75 75 #else /* !defined lint */
76 76 #ifdef __GNUC__
77 77 #define GNUC_or_lint
78 78 #endif /* defined __GNUC__ */
79 79 #endif /* !defined lint */
80 80 #endif /* !defined GNUC_or_lint */
81 81
82 82 #ifndef INITIALIZE
83 83 #ifdef GNUC_or_lint
84 84 #define INITIALIZE(x) ((x) = 0)
85 85 #else /* !defined GNUC_or_lint */
86 86 #define INITIALIZE(x)
87 87 #endif /* !defined GNUC_or_lint */
88 88 #endif /* !defined INITIALIZE */
89 89
90 90 static time_t absolute_min_time;
91 91 static time_t absolute_max_time;
92 92 static size_t longest;
93 93 static char *progname;
94 94 static int warned;
95 95
96 96 static char *abbr(struct tm *);
97 97 static void abbrok(const char *, const char *);
98 98 static long delta(struct tm *, struct tm *);
99 99 static void dumptime(const struct tm *);
100 100 static time_t hunt(char *, time_t, time_t);
101 101 static void setabsolutes(void);
102 102 static void show(char *, time_t, int);
103 103 static void usage(void);
104 104 static const char *tformat(void);
105 105 static time_t yeartot(long y);
106 106
107 107 #ifndef TYPECHECK
108 108 #define my_localtime localtime
109 109 #else /* !defined TYPECHECK */
110 110 static struct tm *
111 111 my_localtime(tp)
112 112 time_t *tp;
113 113 {
114 114 register struct tm *tmp;
115 115
116 116 tmp = localtime(tp);
117 117 if (tp != NULL && tmp != NULL) {
118 118 struct tm tm;
119 119 register time_t t;
120 120
121 121 tm = *tmp;
122 122 t = mktime(&tm);
123 123 if (t - *tp >= 1 || *tp - t >= 1) {
124 124 (void) fflush(stdout);
125 125 (void) fprintf(stderr, "\n%s: ", progname);
126 126 (void) fprintf(stderr, tformat(), *tp);
127 127 (void) fprintf(stderr, " ->");
128 128 (void) fprintf(stderr, " year=%d", tmp->tm_year);
129 129 (void) fprintf(stderr, " mon=%d", tmp->tm_mon);
130 130 (void) fprintf(stderr, " mday=%d", tmp->tm_mday);
131 131 (void) fprintf(stderr, " hour=%d", tmp->tm_hour);
132 132 (void) fprintf(stderr, " min=%d", tmp->tm_min);
133 133 (void) fprintf(stderr, " sec=%d", tmp->tm_sec);
134 134 (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst);
|
↓ open down ↓ |
134 lines elided |
↑ open up ↑ |
135 135 (void) fprintf(stderr, " -> ");
136 136 (void) fprintf(stderr, tformat(), t);
137 137 (void) fprintf(stderr, "\n");
138 138 }
139 139 }
140 140 return (tmp);
141 141 }
142 142 #endif /* !defined TYPECHECK */
143 143
144 144 static void
145 -abbrok(abbrp, zone)
146 -const char * const abbrp;
147 -const char * const zone;
145 +abbrok(const char * const abbrp, const char * const zone)
148 146 {
149 147 register const char *cp;
150 148 int error = 0;
151 149
152 150 if (warned)
153 151 return;
154 152 cp = abbrp;
155 - while (isascii(*cp) && isalpha((unsigned char)*cp))
153 + while (isalpha(*cp) || isdigit(*cp) || *cp == '-' || *cp == '+')
156 154 ++cp;
157 155 (void) fflush(stdout);
158 - if (cp - abbrp == 0) {
159 - /*
160 - * TRANSLATION_NOTE
161 - * The first %s prints for the program name (zdump),
162 - * the second %s prints the timezone name, the third
163 - * %s prints the timezone abbreviation (tzname[0] or
164 - * tzname[1]).
165 - */
156 + if (cp - abbrp < 3) {
166 157 (void) fprintf(stderr, gettext("%s: warning: zone \"%s\" "
167 - "abbreviation \"%s\" lacks alphabetic at start\n"),
168 - progname, zone, abbrp);
169 - error = 1;
170 - } else if (cp - abbrp < 3) {
171 - (void) fprintf(stderr, gettext("%s: warning: zone \"%s\" "
172 158 "abbreviation \"%s\" has fewer than 3 alphabetics\n"),
173 159 progname, zone, abbrp);
174 160 error = 1;
175 161 } else if (cp - abbrp > 6) {
176 162 (void) fprintf(stderr, gettext("%s: warning: zone \"%s\" "
177 - "abbreviation \"%s\" has more than 6 alphabetics\n"),
163 + "abbreviation \"%s\" has more than 6 characters\n"),
178 164 progname, zone, abbrp);
179 165 error = 1;
166 + } else if (*cp != '\0') {
167 + (void) fprintf(stderr, gettext("%s: warning: zone \"%s\" "
168 + "abbreviation \"%s\" has characters other than "
169 + "alphanumerics\n"), progname, zone, abbrp);
170 + error = 1;
180 171 }
181 - if (error == 0 && (*cp == '+' || *cp == '-')) {
182 - ++cp;
183 - if (isascii(*cp) && isdigit((unsigned char)*cp))
184 - if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
185 - ++cp;
186 - if (*cp != '\0') {
187 - (void) fprintf(stderr, gettext("%s: warning: "
188 - "zone \"%s\" abbreviation \"%s\" differs from "
189 - "POSIX standard\n"), progname, zone, abbrp);
190 - error = 1;
191 - }
192 - }
193 172 if (error)
194 173 warned = TRUE;
195 174 }
196 175
197 176 int
198 177 main(argc, argv)
199 178 int argc;
200 179 char *argv[];
201 180 {
202 181 register int i;
203 182 register int c;
204 183 register int vflag;
205 184 register char *cutarg;
206 185 register long cutloyear = ZDUMP_LO_YEAR;
207 186 register long cuthiyear = ZDUMP_HI_YEAR;
208 187 register time_t cutlotime;
209 188 register time_t cuthitime;
210 189 time_t now;
211 190 time_t t;
212 191 time_t newt;
213 192 struct tm tm;
214 193 struct tm newtm;
215 194 register struct tm *tmp;
216 195 register struct tm *newtmp;
217 196
218 197 INITIALIZE(cutlotime);
219 198 INITIALIZE(cuthitime);
220 199
221 200 (void) setlocale(LC_ALL, "");
222 201 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
223 202 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
224 203 #endif
225 204 (void) textdomain(TEXT_DOMAIN);
226 205
227 206 progname = argv[0];
228 207 for (i = 1; i < argc; ++i)
229 208 if (strcmp(argv[i], "--version") == 0) {
230 209 (void) printf("%s\n", elsieid);
231 210 exit(EXIT_SUCCESS);
232 211 }
233 212 vflag = 0;
234 213 cutarg = NULL;
235 214 while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
236 215 if (c == 'v')
237 216 vflag = 1;
238 217 else cutarg = optarg;
239 218 if (c != EOF ||
240 219 (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
241 220 usage();
242 221 /* NOTREACHED */
243 222 }
244 223 if (vflag) {
245 224 if (cutarg != NULL) {
246 225 long lo;
247 226 long hi;
248 227 char dummy;
249 228
250 229 if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) {
251 230 cuthiyear = hi;
252 231 } else if (sscanf(cutarg, "%ld,%ld%c",
253 232 &lo, &hi, &dummy) == 2) {
254 233 cutloyear = lo;
255 234 cuthiyear = hi;
256 235 } else {
257 236 (void) fprintf(stderr, gettext("%s: wild -c argument %s\n"),
258 237 progname, cutarg);
259 238 exit(EXIT_FAILURE);
260 239 }
261 240 }
262 241 setabsolutes();
263 242 cutlotime = yeartot(cutloyear);
264 243 cuthitime = yeartot(cuthiyear);
265 244 }
266 245 (void) time(&now);
267 246 longest = 0;
268 247 for (i = optind; i < argc; ++i)
269 248 if (strlen(argv[i]) > longest)
270 249 longest = strlen(argv[i]);
271 250
272 251 for (i = optind; i < argc; ++i) {
273 252 static char buf[MAX_STRING_LENGTH];
274 253 static char *tzp = NULL;
275 254
276 255 (void) unsetenv("TZ");
277 256 if (tzp != NULL)
278 257 free(tzp);
279 258 if ((tzp = malloc(3 + strlen(argv[i]) + 1)) == NULL) {
280 259 perror(progname);
281 260 exit(EXIT_FAILURE);
282 261 }
283 262 (void) strcpy(tzp, "TZ=");
284 263 (void) strcat(tzp, argv[i]);
285 264 if (putenv(tzp) != 0) {
286 265 perror(progname);
287 266 exit(EXIT_FAILURE);
288 267 }
289 268 if (!vflag) {
290 269 show(argv[i], now, FALSE);
291 270 continue;
292 271 }
293 272
294 273 #if defined(sun)
295 274 /*
296 275 * We show the current time first, probably because we froze
297 276 * the behavior of zdump some time ago and then it got
298 277 * changed.
299 278 */
300 279 show(argv[i], now, TRUE);
301 280 #endif
302 281 warned = FALSE;
303 282 t = absolute_min_time;
304 283 show(argv[i], t, TRUE);
305 284 t += SECSPERHOUR * HOURSPERDAY;
306 285 show(argv[i], t, TRUE);
307 286 if (t < cutlotime)
308 287 t = cutlotime;
309 288 tmp = my_localtime(&t);
310 289 if (tmp != NULL) {
311 290 tm = *tmp;
312 291 (void) strncpy(buf, abbr(&tm), sizeof (buf) - 1);
313 292 }
314 293 for (;;) {
315 294 if (t >= cuthitime)
316 295 break;
317 296 /* check if newt will overrun maximum time_t value */
318 297 if (t > LONG_MAX - (SECSPERHOUR * 12))
319 298 break;
320 299 newt = t + SECSPERHOUR * 12;
321 300 if (newt >= cuthitime)
322 301 break;
323 302 newtmp = localtime(&newt);
324 303 if (newtmp != NULL)
325 304 newtm = *newtmp;
326 305 if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) :
327 306 (delta(&newtm, &tm) != (newt - t) ||
328 307 newtm.tm_isdst != tm.tm_isdst ||
329 308 strcmp(abbr(&newtm), buf) != 0)) {
330 309 newt = hunt(argv[i], t, newt);
331 310 newtmp = localtime(&newt);
332 311 if (newtmp != NULL) {
333 312 newtm = *newtmp;
334 313 (void) strncpy(buf,
335 314 abbr(&newtm),
336 315 sizeof (buf) - 1);
337 316 }
338 317 }
339 318 t = newt;
340 319 tm = newtm;
341 320 tmp = newtmp;
342 321 }
343 322 t = absolute_max_time;
344 323 #if defined(sun)
345 324 show(argv[i], t, TRUE);
346 325 t -= SECSPERHOUR * HOURSPERDAY;
347 326 show(argv[i], t, TRUE);
348 327 #else /* !defined(sun) */
349 328 t -= SECSPERHOUR * HOURSPERDAY;
350 329 show(argv[i], t, TRUE);
351 330 t += SECSPERHOUR * HOURSPERDAY;
352 331 show(argv[i], t, TRUE);
353 332 #endif /* !defined(sun) */
354 333 }
355 334 if (fflush(stdout) || ferror(stdout)) {
356 335 (void) fprintf(stderr, "%s: ", progname);
357 336 (void) perror(gettext("Error writing standard output"));
358 337 exit(EXIT_FAILURE);
359 338 }
360 339 return (EXIT_SUCCESS);
361 340 }
362 341
363 342 static void
364 343 setabsolutes()
365 344 {
366 345 #if defined(sun)
367 346 absolute_min_time = LONG_MIN;
368 347 absolute_max_time = LONG_MAX;
369 348 #else
370 349 if (0.5 == (time_t)0.5) {
371 350 /*
372 351 * time_t is floating.
373 352 */
374 353 if (sizeof (time_t) == sizeof (float)) {
375 354 absolute_min_time = (time_t)-FLT_MAX;
376 355 absolute_max_time = (time_t)FLT_MAX;
377 356 } else if (sizeof (time_t) == sizeof (double)) {
378 357 absolute_min_time = (time_t)-DBL_MAX;
379 358 absolute_max_time = (time_t)DBL_MAX;
380 359 } else {
381 360 (void) fprintf(stderr, gettext("%s: use of -v on "
382 361 "system with floating time_t other than float "
383 362 "or double\n"), progname);
384 363 exit(EXIT_FAILURE);
385 364 }
386 365 } else
387 366 /*CONSTANTCONDITION*/
388 367 if (0 > (time_t)-1) {
389 368 /*
390 369 * time_t is signed.
391 370 */
392 371 register time_t hibit;
393 372
394 373 for (hibit = 1; (hibit * 2) != 0; hibit *= 2)
395 374 continue;
396 375 absolute_min_time = hibit;
397 376 absolute_max_time = -(hibit + 1);
398 377 } else {
399 378 /*
400 379 * time_t is unsigned.
401 380 */
402 381 absolute_min_time = 0;
403 382 absolute_max_time = absolute_min_time - 1;
404 383 }
405 384 #endif
406 385 }
407 386
408 387 static time_t
409 388 yeartot(y)
410 389 const long y;
411 390 {
412 391 register long myy;
413 392 register long seconds;
414 393 register time_t t;
415 394
416 395 myy = EPOCH_YEAR;
417 396 t = 0;
418 397 while (myy != y) {
419 398 if (myy < y) {
420 399 seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
421 400 ++myy;
422 401 if (t > absolute_max_time - seconds) {
423 402 t = absolute_max_time;
424 403 break;
425 404 }
426 405 t += seconds;
427 406 } else {
428 407 --myy;
429 408 seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR;
430 409 if (t < absolute_min_time + seconds) {
431 410 t = absolute_min_time;
432 411 break;
433 412 }
434 413 t -= seconds;
435 414 }
436 415 }
437 416 return (t);
438 417 }
439 418
440 419 static time_t
441 420 hunt(name, lot, hit)
442 421 char *name;
443 422 time_t lot;
444 423 time_t hit;
445 424 {
446 425 time_t t;
447 426 long diff;
448 427 struct tm lotm;
449 428 register struct tm *lotmp;
450 429 struct tm tm;
451 430 register struct tm *tmp;
452 431 char loab[MAX_STRING_LENGTH];
453 432
454 433 lotmp = my_localtime(&lot);
455 434 if (lotmp != NULL) {
456 435 lotm = *lotmp;
457 436 (void) strncpy(loab, abbr(&lotm), sizeof (loab) - 1);
458 437 }
459 438 for (;;) {
460 439 diff = (long)(hit - lot);
461 440 if (diff < 2)
462 441 break;
463 442 t = lot;
464 443 t += diff / 2;
465 444 if (t <= lot)
466 445 ++t;
467 446 else if (t >= hit)
468 447 --t;
469 448 tmp = my_localtime(&t);
470 449 if (tmp != NULL)
471 450 tm = *tmp;
472 451 if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) :
473 452 (delta(&tm, &lotm) == (t - lot) &&
474 453 tm.tm_isdst == lotm.tm_isdst &&
475 454 strcmp(abbr(&tm), loab) == 0)) {
476 455 lot = t;
477 456 lotm = tm;
478 457 lotmp = tmp;
479 458 } else hit = t;
480 459 }
481 460 show(name, lot, TRUE);
482 461 show(name, hit, TRUE);
483 462 return (hit);
484 463 }
485 464
486 465 /*
487 466 * Thanks to Paul Eggert for logic used in delta.
488 467 */
489 468
490 469 static long
491 470 delta(newp, oldp)
492 471 struct tm *newp;
493 472 struct tm *oldp;
494 473 {
495 474 register long result;
496 475 register int tmy;
497 476
498 477 if (newp->tm_year < oldp->tm_year)
499 478 return (-delta(oldp, newp));
500 479 result = 0;
501 480 for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
502 481 result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
503 482 result += newp->tm_yday - oldp->tm_yday;
504 483 result *= HOURSPERDAY;
505 484 result += newp->tm_hour - oldp->tm_hour;
506 485 result *= MINSPERHOUR;
507 486 result += newp->tm_min - oldp->tm_min;
508 487 result *= SECSPERMIN;
509 488 result += newp->tm_sec - oldp->tm_sec;
510 489 return (result);
511 490 }
512 491
513 492 static void
514 493 show(zone, t, v)
515 494 char *zone;
516 495 time_t t;
517 496 int v;
518 497 {
519 498 register struct tm *tmp;
520 499
521 500 (void) printf("%-*s ", (int)longest, zone);
522 501 if (v) {
523 502 tmp = gmtime(&t);
524 503 if (tmp == NULL) {
525 504 (void) printf(tformat(), t);
526 505 } else {
527 506 dumptime(tmp);
528 507 (void) printf(" UTC");
529 508 }
530 509 (void) printf(" = ");
531 510 }
532 511 tmp = my_localtime(&t);
533 512 dumptime(tmp);
534 513 if (tmp != NULL) {
535 514 if (*abbr(tmp) != '\0')
536 515 (void) printf(" %s", abbr(tmp));
537 516 if (v) {
538 517 (void) printf(" isdst=%d", tmp->tm_isdst);
539 518 #ifdef TM_GMTOFF
540 519 (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
541 520 #endif /* defined TM_GMTOFF */
542 521 }
543 522 }
544 523 (void) printf("\n");
545 524 if (tmp != NULL && *abbr(tmp) != '\0')
546 525 abbrok(abbr(tmp), zone);
547 526 }
548 527
549 528 static char *
550 529 abbr(tmp)
551 530 struct tm *tmp;
552 531 {
553 532 register char *result;
554 533 static char nada;
555 534
556 535 if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
557 536 return (&nada);
558 537 result = tzname[tmp->tm_isdst];
559 538 return ((result == NULL) ? &nada : result);
560 539 }
561 540
562 541 /*
563 542 * The code below can fail on certain theoretical systems;
564 543 * it works on all known real-world systems as of 2004-12-30.
565 544 */
566 545
567 546 static const char *
568 547 tformat()
569 548 {
570 549 #if defined(sun)
571 550 /* time_t is signed long */
572 551 return ("%ld");
573 552 #else
574 553 /*CONSTANTCONDITION*/
575 554 if (0.5 == (time_t)0.5) { /* floating */
576 555 /*CONSTANTCONDITION*/
577 556 if (sizeof (time_t) > sizeof (double))
578 557 return ("%Lg");
579 558 return ("%g");
580 559 }
581 560 /*CONSTANTCONDITION*/
582 561 if (0 > (time_t)-1) { /* signed */
583 562 /*CONSTANTCONDITION*/
584 563 if (sizeof (time_t) > sizeof (long))
585 564 return ("%lld");
586 565 /*CONSTANTCONDITION*/
587 566 if (sizeof (time_t) > sizeof (int))
588 567 return ("%ld");
589 568 return ("%d");
590 569 }
591 570 /*CONSTANTCONDITION*/
592 571 if (sizeof (time_t) > sizeof (unsigned long))
593 572 return ("%llu");
594 573 /*CONSTANTCONDITION*/
595 574 if (sizeof (time_t) > sizeof (unsigned int))
596 575 return ("%lu");
597 576 return ("%u");
598 577 #endif
599 578 }
600 579
601 580 static void
602 581 dumptime(timeptr)
603 582 register const struct tm *timeptr;
604 583 {
605 584 static const char wday_name[][3] = {
606 585 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
607 586 };
608 587 static const char mon_name[][3] = {
609 588 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
610 589 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
611 590 };
612 591 register const char *wn;
613 592 register const char *mn;
614 593 register int lead;
615 594 register int trail;
616 595
617 596 if (timeptr == NULL) {
618 597 (void) printf("NULL");
619 598 return;
620 599 }
621 600 /*
622 601 * The packaged versions of localtime and gmtime never put out-of-range
623 602 * values in tm_wday or tm_mon, but since this code might be compiled
624 603 * with other (perhaps experimental) versions, paranoia is in order.
625 604 */
626 605 if (timeptr->tm_wday < 0 || timeptr->tm_wday >=
627 606 (int)(sizeof (wday_name) / sizeof (wday_name[0])))
628 607 wn = "???";
629 608 else wn = wday_name[timeptr->tm_wday];
630 609 if (timeptr->tm_mon < 0 || timeptr->tm_mon >=
631 610 (int)(sizeof (mon_name) / sizeof (mon_name[0])))
632 611 mn = "???";
633 612 else mn = mon_name[timeptr->tm_mon];
634 613 (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
635 614 wn, mn,
636 615 timeptr->tm_mday, timeptr->tm_hour,
637 616 timeptr->tm_min, timeptr->tm_sec);
638 617 #define DIVISOR 10
639 618 trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR;
640 619 lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR +
641 620 trail / DIVISOR;
642 621 trail %= DIVISOR;
643 622 if (trail < 0 && lead > 0) {
644 623 trail += DIVISOR;
645 624 --lead;
646 625 } else if (lead < 0 && trail > 0) {
647 626 trail -= DIVISOR;
648 627 ++lead;
649 628 }
650 629 if (lead == 0)
651 630 (void) printf("%d", trail);
652 631 else
653 632 (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail));
654 633 }
655 634
656 635 static void
657 636 usage()
658 637 {
659 638 (void) fprintf(stderr, gettext(
660 639 "%s: [ --version ] [ -v ] [ -c [loyear,]hiyear ] zonename ...\n"),
661 640 progname);
662 641 exit(EXIT_FAILURE);
663 642 /* NOTREACHED */
664 643 }
|
↓ open down ↓ |
462 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX