17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 2663ff6dceSGarrett D'Amore /* 27bde2df36SYuri Pankov * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 2863ff6dceSGarrett D'Amore */ 2972fb660eSKeith M Wesolowski /* 30*2f4149eaSRobert Mustacchi * Copyright (c) 2017, Joyent, Inc. 3172fb660eSKeith M Wesolowski */ 327c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 337c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 367c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 377c478bd9Sstevel@tonic-gate * The Regents of the University of California 387c478bd9Sstevel@tonic-gate * All Rights Reserved 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 417c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 427c478bd9Sstevel@tonic-gate * contributors. 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate /* 467c478bd9Sstevel@tonic-gate * date - with format capabilities and international flair 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate #include <locale.h> 507c478bd9Sstevel@tonic-gate #include <fcntl.h> 517c478bd9Sstevel@tonic-gate #include <langinfo.h> 527c478bd9Sstevel@tonic-gate #include <stdio.h> 537c478bd9Sstevel@tonic-gate #include <stdlib.h> 547c478bd9Sstevel@tonic-gate #include <string.h> 557c478bd9Sstevel@tonic-gate #include <time.h> 567c478bd9Sstevel@tonic-gate #include <unistd.h> 577c478bd9Sstevel@tonic-gate #include <sys/time.h> 587c478bd9Sstevel@tonic-gate #include <sys/types.h> 59*2f4149eaSRobert Mustacchi #include <sys/stat.h> 607c478bd9Sstevel@tonic-gate #include <ctype.h> 61*2f4149eaSRobert Mustacchi #include <errno.h> 627c478bd9Sstevel@tonic-gate #include <utmpx.h> 637c478bd9Sstevel@tonic-gate #include <tzfile.h> 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #define year_size(A) ((isleap(A)) ? 366 : 365) 667c478bd9Sstevel@tonic-gate static char buf[BUFSIZ]; 677c478bd9Sstevel@tonic-gate static time_t clock_val; 687c478bd9Sstevel@tonic-gate static short month_size[12] = 697c478bd9Sstevel@tonic-gate { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 707c478bd9Sstevel@tonic-gate static struct utmpx wtmpx[2] = { 717c478bd9Sstevel@tonic-gate {"", "", OTIME_MSG, 0, OLD_TIME, 0, 0, 0}, 727c478bd9Sstevel@tonic-gate {"", "", NTIME_MSG, 0, NEW_TIME, 0, 0, 0} 737c478bd9Sstevel@tonic-gate }; 747c478bd9Sstevel@tonic-gate static char *usage = 75*2f4149eaSRobert Mustacchi "usage:\tdate [-u] mmddHHMM[[cc]yy][.SS]\n" 76*2f4149eaSRobert Mustacchi "\tdate [-Ru] [-r seconds | filename] [+format]\n" 777c478bd9Sstevel@tonic-gate "\tdate -a [-]sss[.fff]\n"; 787c478bd9Sstevel@tonic-gate static int uflag = 0; 7963ff6dceSGarrett D'Amore static int Rflag = 0; 80*2f4149eaSRobert Mustacchi static int rflag = 0; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate static int get_adj(char *, struct timeval *); 837c478bd9Sstevel@tonic-gate static int setdate(struct tm *, char *); 8472fb660eSKeith M Wesolowski static void fmt_extensions(char *, size_t, 8572fb660eSKeith M Wesolowski const char *, const struct timespec *); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate int 887c478bd9Sstevel@tonic-gate main(int argc, char **argv) 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate struct tm *tp, tm; 917c478bd9Sstevel@tonic-gate struct timeval tv; 92*2f4149eaSRobert Mustacchi char *fmt, *eptr; 9372fb660eSKeith M Wesolowski char fmtbuf[BUFSIZ]; 947c478bd9Sstevel@tonic-gate int c, aflag = 0, illflag = 0; 9572fb660eSKeith M Wesolowski struct timespec ts; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1007c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1017c478bd9Sstevel@tonic-gate #endif 1027c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1037c478bd9Sstevel@tonic-gate 104*2f4149eaSRobert Mustacchi while ((c = getopt(argc, argv, "a:uRr:")) != EOF) 1057c478bd9Sstevel@tonic-gate switch (c) { 1067c478bd9Sstevel@tonic-gate case 'a': 1077c478bd9Sstevel@tonic-gate aflag++; 1087c478bd9Sstevel@tonic-gate if (get_adj(optarg, &tv) < 0) { 1097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1107c478bd9Sstevel@tonic-gate gettext("date: invalid argument -- %s\n"), 11163ff6dceSGarrett D'Amore optarg); 1127c478bd9Sstevel@tonic-gate illflag++; 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate break; 1157c478bd9Sstevel@tonic-gate case 'u': 1167c478bd9Sstevel@tonic-gate uflag++; 1177c478bd9Sstevel@tonic-gate break; 11863ff6dceSGarrett D'Amore case 'R': 11963ff6dceSGarrett D'Amore Rflag++; 12063ff6dceSGarrett D'Amore break; 121*2f4149eaSRobert Mustacchi case 'r': 122*2f4149eaSRobert Mustacchi 123*2f4149eaSRobert Mustacchi /* 124*2f4149eaSRobert Mustacchi * BSD originally used -r to specify a unix time. GNU 125*2f4149eaSRobert Mustacchi * used -r to specify a reference to a file. Now, like 126*2f4149eaSRobert Mustacchi * some BSDs we attempt to parse the time. If we can, 127*2f4149eaSRobert Mustacchi * then we use that, otherwise we fall back and treat it 128*2f4149eaSRobert Mustacchi * like GNU. 129*2f4149eaSRobert Mustacchi */ 130*2f4149eaSRobert Mustacchi rflag++; 131*2f4149eaSRobert Mustacchi errno = 0; 132*2f4149eaSRobert Mustacchi ts.tv_sec = strtol(optarg, &eptr, 0); 133*2f4149eaSRobert Mustacchi if (errno == EINVAL || *eptr != '\0') { 134*2f4149eaSRobert Mustacchi struct stat st; 135*2f4149eaSRobert Mustacchi if (stat(optarg, &st) == 0) { 136*2f4149eaSRobert Mustacchi ts.tv_sec = st.st_mtime; 137*2f4149eaSRobert Mustacchi } else { 138*2f4149eaSRobert Mustacchi (void) fprintf(stderr, 139*2f4149eaSRobert Mustacchi gettext("date: failed to get stat " 140*2f4149eaSRobert Mustacchi "information about %s: %s\n"), 141*2f4149eaSRobert Mustacchi optarg, strerror(errno)); 142*2f4149eaSRobert Mustacchi exit(1); 143*2f4149eaSRobert Mustacchi } 144*2f4149eaSRobert Mustacchi } else if (errno != 0) { 145*2f4149eaSRobert Mustacchi (void) fprintf(stderr, 146*2f4149eaSRobert Mustacchi gettext("date: failed to parse -r " 147*2f4149eaSRobert Mustacchi "argument: %s\n"), optarg); 148*2f4149eaSRobert Mustacchi exit(1); 149*2f4149eaSRobert Mustacchi } 150*2f4149eaSRobert Mustacchi break; 1517c478bd9Sstevel@tonic-gate default: 1527c478bd9Sstevel@tonic-gate illflag++; 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate argc -= optind; 1567c478bd9Sstevel@tonic-gate argv = &argv[optind]; 1577c478bd9Sstevel@tonic-gate 158*2f4149eaSRobert Mustacchi /* -a is mutually exclusive with -u, -R, and -r */ 1597c478bd9Sstevel@tonic-gate if (uflag && aflag) 1607c478bd9Sstevel@tonic-gate illflag++; 16163ff6dceSGarrett D'Amore if (Rflag && aflag) 16263ff6dceSGarrett D'Amore illflag++; 163*2f4149eaSRobert Mustacchi if (rflag && aflag) 164*2f4149eaSRobert Mustacchi illflag++; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (illflag) { 1677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(usage)); 1687c478bd9Sstevel@tonic-gate exit(1); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 171*2f4149eaSRobert Mustacchi if (rflag == 0) { 172*2f4149eaSRobert Mustacchi if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { 173*2f4149eaSRobert Mustacchi perror(gettext("date: Failed to obtain system time")); 174*2f4149eaSRobert Mustacchi exit(1); 175*2f4149eaSRobert Mustacchi } 17672fb660eSKeith M Wesolowski } 17772fb660eSKeith M Wesolowski clock_val = ts.tv_sec; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate if (aflag) { 1807c478bd9Sstevel@tonic-gate if (adjtime(&tv, 0) < 0) { 1817c478bd9Sstevel@tonic-gate perror(gettext("date: Failed to adjust date")); 1827c478bd9Sstevel@tonic-gate exit(1); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate exit(0); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (argc > 0) { 1887c478bd9Sstevel@tonic-gate if (*argv[0] == '+') 1897c478bd9Sstevel@tonic-gate fmt = &argv[0][1]; 1907c478bd9Sstevel@tonic-gate else { 1917c478bd9Sstevel@tonic-gate if (setdate(localtime(&clock_val), argv[0])) { 1927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(usage)); 1937c478bd9Sstevel@tonic-gate exit(1); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate fmt = nl_langinfo(_DATE_FMT); 1967c478bd9Sstevel@tonic-gate } 19763ff6dceSGarrett D'Amore } else if (Rflag) { 19863ff6dceSGarrett D'Amore fmt = "%a, %d %h %Y %H:%M:%S %z"; 1997c478bd9Sstevel@tonic-gate } else 2007c478bd9Sstevel@tonic-gate fmt = nl_langinfo(_DATE_FMT); 2017c478bd9Sstevel@tonic-gate 20272fb660eSKeith M Wesolowski fmt_extensions(fmtbuf, sizeof (fmtbuf), fmt, &ts); 20372fb660eSKeith M Wesolowski 2047c478bd9Sstevel@tonic-gate if (uflag) { 2057c478bd9Sstevel@tonic-gate (void) putenv("TZ=GMT0"); 2067c478bd9Sstevel@tonic-gate tzset(); 2077c478bd9Sstevel@tonic-gate tp = gmtime(&clock_val); 2087c478bd9Sstevel@tonic-gate } else 2097c478bd9Sstevel@tonic-gate tp = localtime(&clock_val); 2107c478bd9Sstevel@tonic-gate (void) memcpy(&tm, tp, sizeof (struct tm)); 21172fb660eSKeith M Wesolowski (void) strftime(buf, BUFSIZ, fmtbuf, &tm); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate (void) puts(buf); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate return (0); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate int 2197c478bd9Sstevel@tonic-gate setdate(struct tm *current_date, char *date) 2207c478bd9Sstevel@tonic-gate { 2217c478bd9Sstevel@tonic-gate int i; 2227c478bd9Sstevel@tonic-gate int mm; 2237c478bd9Sstevel@tonic-gate int hh; 2247c478bd9Sstevel@tonic-gate int min; 2257c478bd9Sstevel@tonic-gate int sec = 0; 2267c478bd9Sstevel@tonic-gate char *secptr; 2277c478bd9Sstevel@tonic-gate int yy; 2287c478bd9Sstevel@tonic-gate int dd = 0; 2297c478bd9Sstevel@tonic-gate int minidx = 6; 2307c478bd9Sstevel@tonic-gate int len; 2317c478bd9Sstevel@tonic-gate int dd_check; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* Parse date string */ 2347c478bd9Sstevel@tonic-gate if ((secptr = strchr(date, '.')) != NULL && strlen(&secptr[1]) == 2 && 2357c478bd9Sstevel@tonic-gate isdigit(secptr[1]) && isdigit(secptr[2]) && 2367c478bd9Sstevel@tonic-gate (sec = atoi(&secptr[1])) >= 0 && sec < 60) 2377c478bd9Sstevel@tonic-gate secptr[0] = '\0'; /* eat decimal point only on success */ 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate len = strlen(date); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 2427c478bd9Sstevel@tonic-gate if (!isdigit(date[i])) { 2437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2447c478bd9Sstevel@tonic-gate gettext("date: bad conversion\n")); 2457c478bd9Sstevel@tonic-gate exit(1); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate switch (strlen(date)) { 2497c478bd9Sstevel@tonic-gate case 12: 2507c478bd9Sstevel@tonic-gate yy = atoi(&date[8]); 2517c478bd9Sstevel@tonic-gate date[8] = '\0'; 2527c478bd9Sstevel@tonic-gate break; 2537c478bd9Sstevel@tonic-gate case 10: 2547c478bd9Sstevel@tonic-gate /* 2557c478bd9Sstevel@tonic-gate * The YY format has the following representation: 2567c478bd9Sstevel@tonic-gate * 00-68 = 2000 thru 2068 2577c478bd9Sstevel@tonic-gate * 69-99 = 1969 thru 1999 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate if (atoi(&date[8]) <= 68) { 2607c478bd9Sstevel@tonic-gate yy = 1900 + (atoi(&date[8]) + 100); 2617c478bd9Sstevel@tonic-gate } else { 2627c478bd9Sstevel@tonic-gate yy = 1900 + atoi(&date[8]); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate date[8] = '\0'; 2657c478bd9Sstevel@tonic-gate break; 2667c478bd9Sstevel@tonic-gate case 8: 2677c478bd9Sstevel@tonic-gate yy = 1900 + current_date->tm_year; 2687c478bd9Sstevel@tonic-gate break; 2697c478bd9Sstevel@tonic-gate case 4: 2707c478bd9Sstevel@tonic-gate yy = 1900 + current_date->tm_year; 2717c478bd9Sstevel@tonic-gate mm = current_date->tm_mon + 1; /* tm_mon goes from 1 to 11 */ 2727c478bd9Sstevel@tonic-gate dd = current_date->tm_mday; 2737c478bd9Sstevel@tonic-gate minidx = 2; 2747c478bd9Sstevel@tonic-gate break; 2757c478bd9Sstevel@tonic-gate default: 2767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("date: bad conversion\n")); 2777c478bd9Sstevel@tonic-gate return (1); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate min = atoi(&date[minidx]); 2817c478bd9Sstevel@tonic-gate date[minidx] = '\0'; 2827c478bd9Sstevel@tonic-gate hh = atoi(&date[minidx-2]); 2837c478bd9Sstevel@tonic-gate date[minidx-2] = '\0'; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate if (!dd) { 2867c478bd9Sstevel@tonic-gate /* 2877c478bd9Sstevel@tonic-gate * if dd is 0 (not between 1 and 31), then 2887c478bd9Sstevel@tonic-gate * read the value supplied by the user. 2897c478bd9Sstevel@tonic-gate */ 2907c478bd9Sstevel@tonic-gate dd = atoi(&date[2]); 2917c478bd9Sstevel@tonic-gate date[2] = '\0'; 2927c478bd9Sstevel@tonic-gate mm = atoi(&date[0]); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate if (hh == 24) 2967c478bd9Sstevel@tonic-gate hh = 0, dd++; 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* Validate date elements */ 2997c478bd9Sstevel@tonic-gate dd_check = 0; 3007c478bd9Sstevel@tonic-gate if (mm >= 1 && mm <= 12) { 3017c478bd9Sstevel@tonic-gate dd_check = month_size[mm - 1]; /* get days in this month */ 3027c478bd9Sstevel@tonic-gate if (mm == 2 && isleap(yy)) /* adjust for leap year */ 3037c478bd9Sstevel@tonic-gate dd_check++; 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate if (!((mm >= 1 && mm <= 12) && (dd >= 1 && dd <= dd_check) && 30663ff6dceSGarrett D'Amore (hh >= 0 && hh <= 23) && (min >= 0 && min <= 59))) { 3077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("date: bad conversion\n")); 3087c478bd9Sstevel@tonic-gate return (1); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate /* Build date and time number */ 3127c478bd9Sstevel@tonic-gate for (clock_val = 0, i = 1970; i < yy; i++) 3137c478bd9Sstevel@tonic-gate clock_val += year_size(i); 3147c478bd9Sstevel@tonic-gate /* Adjust for leap year */ 3157c478bd9Sstevel@tonic-gate if (isleap(yy) && mm >= 3) 3167c478bd9Sstevel@tonic-gate clock_val += 1; 3177c478bd9Sstevel@tonic-gate /* Adjust for different month lengths */ 3187c478bd9Sstevel@tonic-gate while (--mm) 3197c478bd9Sstevel@tonic-gate clock_val += (time_t)month_size[mm - 1]; 3207c478bd9Sstevel@tonic-gate /* Load up the rest */ 3217c478bd9Sstevel@tonic-gate clock_val += (time_t)(dd - 1); 3227c478bd9Sstevel@tonic-gate clock_val *= 24; 3237c478bd9Sstevel@tonic-gate clock_val += (time_t)hh; 3247c478bd9Sstevel@tonic-gate clock_val *= 60; 3257c478bd9Sstevel@tonic-gate clock_val += (time_t)min; 3267c478bd9Sstevel@tonic-gate clock_val *= 60; 3277c478bd9Sstevel@tonic-gate clock_val += sec; 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (!uflag) { 3307c478bd9Sstevel@tonic-gate /* convert to GMT assuming standard time */ 3317c478bd9Sstevel@tonic-gate /* correction is made in localtime(3C) */ 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * call localtime to set up "timezone" variable applicable 3357c478bd9Sstevel@tonic-gate * for clock_val time, to support Olson timezones which 3367c478bd9Sstevel@tonic-gate * can allow timezone rules to change. 3377c478bd9Sstevel@tonic-gate */ 3387c478bd9Sstevel@tonic-gate (void) localtime(&clock_val); 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate clock_val += (time_t)timezone; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate /* correct if daylight savings time in effect */ 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if (localtime(&clock_val)->tm_isdst) 3457c478bd9Sstevel@tonic-gate clock_val = clock_val - (time_t)(timezone - altzone); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate (void) time(&wtmpx[0].ut_xtime); 3497c478bd9Sstevel@tonic-gate if (stime(&clock_val) < 0) { 3507c478bd9Sstevel@tonic-gate perror("date"); 3517c478bd9Sstevel@tonic-gate return (1); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate #if defined(i386) 3547c478bd9Sstevel@tonic-gate /* correct the kernel's "gmt_lag" and the PC's RTC */ 3557c478bd9Sstevel@tonic-gate (void) system("/usr/sbin/rtc -c > /dev/null 2>&1"); 3567c478bd9Sstevel@tonic-gate #endif 3577c478bd9Sstevel@tonic-gate (void) time(&wtmpx[1].ut_xtime); 3587c478bd9Sstevel@tonic-gate (void) pututxline(&wtmpx[0]); 3597c478bd9Sstevel@tonic-gate (void) pututxline(&wtmpx[1]); 3607c478bd9Sstevel@tonic-gate (void) updwtmpx(WTMPX_FILE, &wtmpx[0]); 3617c478bd9Sstevel@tonic-gate (void) updwtmpx(WTMPX_FILE, &wtmpx[1]); 3627c478bd9Sstevel@tonic-gate return (0); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate int 3667c478bd9Sstevel@tonic-gate get_adj(char *cp, struct timeval *tp) 3677c478bd9Sstevel@tonic-gate { 3687c478bd9Sstevel@tonic-gate register int mult; 3697c478bd9Sstevel@tonic-gate int sign; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* arg must be [-]sss[.fff] */ 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate tp->tv_sec = tp->tv_usec = 0; 3747c478bd9Sstevel@tonic-gate if (*cp == '-') { 3757c478bd9Sstevel@tonic-gate sign = -1; 3767c478bd9Sstevel@tonic-gate cp++; 3777c478bd9Sstevel@tonic-gate } else { 3787c478bd9Sstevel@tonic-gate sign = 1; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate while (*cp >= '0' && *cp <= '9') { 3827c478bd9Sstevel@tonic-gate tp->tv_sec *= 10; 3837c478bd9Sstevel@tonic-gate tp->tv_sec += *cp++ - '0'; 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate if (*cp == '.') { 3867c478bd9Sstevel@tonic-gate cp++; 3877c478bd9Sstevel@tonic-gate mult = 100000; 3887c478bd9Sstevel@tonic-gate while (*cp >= '0' && *cp <= '9') { 3897c478bd9Sstevel@tonic-gate tp->tv_usec += (*cp++ - '0') * mult; 3907c478bd9Sstevel@tonic-gate mult /= 10; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * if there's anything left in the string, 3957c478bd9Sstevel@tonic-gate * the input was invalid. 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate if (*cp) { 3987c478bd9Sstevel@tonic-gate return (-1); 3997c478bd9Sstevel@tonic-gate } else { 4007c478bd9Sstevel@tonic-gate tp->tv_sec *= sign; 4017c478bd9Sstevel@tonic-gate tp->tv_usec *= sign; 4027c478bd9Sstevel@tonic-gate return (0); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate } 40572fb660eSKeith M Wesolowski 40672fb660eSKeith M Wesolowski /* 40772fb660eSKeith M Wesolowski * Extensions that cannot be interpreted by strftime are interpreted here. 40872fb660eSKeith M Wesolowski */ 40972fb660eSKeith M Wesolowski void 41072fb660eSKeith M Wesolowski fmt_extensions(char *fmtbuf, size_t len, 41172fb660eSKeith M Wesolowski const char *fmt, const struct timespec *tsp) 41272fb660eSKeith M Wesolowski { 41372fb660eSKeith M Wesolowski const char *p; 41472fb660eSKeith M Wesolowski char *q; 41572fb660eSKeith M Wesolowski 41672fb660eSKeith M Wesolowski for (p = fmt, q = fmtbuf; *p != '\0' && q < fmtbuf + len; ++p) { 41772fb660eSKeith M Wesolowski if (*p == '%') { 41872fb660eSKeith M Wesolowski switch (*(p + 1)) { 41972fb660eSKeith M Wesolowski case 'N': 42072fb660eSKeith M Wesolowski ++p; 42172fb660eSKeith M Wesolowski q += snprintf(q, len - (q - fmtbuf), 42272fb660eSKeith M Wesolowski "%09lu", tsp->tv_nsec); 42372fb660eSKeith M Wesolowski continue; 42472fb660eSKeith M Wesolowski } 42572fb660eSKeith M Wesolowski } 42672fb660eSKeith M Wesolowski *q++ = *p; 42772fb660eSKeith M Wesolowski } 42872fb660eSKeith M Wesolowski 42972fb660eSKeith M Wesolowski if (q < fmtbuf + len) 43072fb660eSKeith M Wesolowski *q = '\0'; 43172fb660eSKeith M Wesolowski else 43272fb660eSKeith M Wesolowski fmtbuf[len - 1] = '\0'; 43372fb660eSKeith M Wesolowski } 434