xref: /illumos-gate/usr/src/cmd/rtc/rtc.c (revision 026e699f086745296cda4664068f50ace71e32e2)
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 /*
23*026e699fSGary Mills  * Copyright 2018 Gary Mills
247c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <sys/sysi86.h>
337c478bd9Sstevel@tonic-gate #include <errno.h>
347c478bd9Sstevel@tonic-gate #include <time.h>
357c478bd9Sstevel@tonic-gate #include <string.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate 
38*026e699fSGary Mills /* RTC modes */
39*026e699fSGary Mills #define	M_UNSET	0 /* Mode never set */
40*026e699fSGary Mills #define	M_VAR	1 /* Tracks local time including DST */
41*026e699fSGary Mills #define	M_UTC	2 /* Clock runs in UTC */
42*026e699fSGary Mills #define	M_STD	3 /* Clock runs in local standard time */
43*026e699fSGary Mills 
447c478bd9Sstevel@tonic-gate static char *progname;
457c478bd9Sstevel@tonic-gate static char *zonefile = "/etc/rtc_config";
467c478bd9Sstevel@tonic-gate static FILE *zonefptr;
477c478bd9Sstevel@tonic-gate static char zone_info[256];
487c478bd9Sstevel@tonic-gate static char zone_lag[256];
497c478bd9Sstevel@tonic-gate static char tz[256] = "TZ=";
50*026e699fSGary Mills static char *utc_zone = "UTC";
517c478bd9Sstevel@tonic-gate int debug = 0;
52*026e699fSGary Mills int rtc_mode = M_UNSET;
537c478bd9Sstevel@tonic-gate int lag;
547c478bd9Sstevel@tonic-gate int errors_ok = 0; /* allow "rtc no-args" to be quiet when not configured */
557c478bd9Sstevel@tonic-gate static time_t clock_val;
567c478bd9Sstevel@tonic-gate static char zone_comment[] =
577c478bd9Sstevel@tonic-gate 	"#\n"
587c478bd9Sstevel@tonic-gate 	"#	This file (%s) contains information used to manage the\n"
597c478bd9Sstevel@tonic-gate 	"#	x86 real time clock hardware.  The hardware is kept in\n"
607c478bd9Sstevel@tonic-gate 	"#	the machine's local time for compatibility with other x86\n"
617c478bd9Sstevel@tonic-gate 	"#	operating systems.  This file is read by the kernel at\n"
627c478bd9Sstevel@tonic-gate 	"#	boot time.  It is set and updated by the /usr/sbin/rtc\n"
637c478bd9Sstevel@tonic-gate 	"#	command.  The 'zone_info' field designates the local\n"
647c478bd9Sstevel@tonic-gate 	"#	time zone.  The 'zone_lag' field indicates the number\n"
657c478bd9Sstevel@tonic-gate 	"#	of seconds between local time and Greenwich Mean Time.\n"
667c478bd9Sstevel@tonic-gate 	"#\n";
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate /*
697c478bd9Sstevel@tonic-gate  *	Open the configuration file and extract the
707c478bd9Sstevel@tonic-gate  *	zone_info and the zone_lag.  Return 0 if successful.
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate int
open_zonefile()737c478bd9Sstevel@tonic-gate open_zonefile()
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	char b[256], *s;
767c478bd9Sstevel@tonic-gate 	int lag_hrs;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	if ((zonefptr = fopen(zonefile, "r")) == NULL) {
797c478bd9Sstevel@tonic-gate 		if (errors_ok == 0)
807c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
817c478bd9Sstevel@tonic-gate 			    "%s: cannot open %s: errno = %d\n",
827c478bd9Sstevel@tonic-gate 			    progname, zonefile, errno);
837c478bd9Sstevel@tonic-gate 		return (1);
847c478bd9Sstevel@tonic-gate 	}
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	for (;;) {
877c478bd9Sstevel@tonic-gate 		if ((s = fgets(b, sizeof (b), zonefptr)) == NULL)
887c478bd9Sstevel@tonic-gate 			break;
897c478bd9Sstevel@tonic-gate 		if ((s = strchr(s, 'z')) == NULL)
907c478bd9Sstevel@tonic-gate 			continue;
917c478bd9Sstevel@tonic-gate 		if (strncmp(s, "zone_info", 9) == 0) {
927c478bd9Sstevel@tonic-gate 			s += 9;
937c478bd9Sstevel@tonic-gate 			while (*s != 0 && *s != '=')
947c478bd9Sstevel@tonic-gate 				s++;
957c478bd9Sstevel@tonic-gate 			if (*s == '=') {
967c478bd9Sstevel@tonic-gate 				s++;
977c478bd9Sstevel@tonic-gate 				while (*s != 0 && (*s == ' ' || *s == '\t'))
987c478bd9Sstevel@tonic-gate 					s++;
997c478bd9Sstevel@tonic-gate 				(void) strncpy(zone_info, s,
1007c478bd9Sstevel@tonic-gate 				    sizeof (zone_info));
1017c478bd9Sstevel@tonic-gate 				s = zone_info;
1027c478bd9Sstevel@tonic-gate 				while (*s != 0 && *s != '\n')
1037c478bd9Sstevel@tonic-gate 					s++;
1047c478bd9Sstevel@tonic-gate 				if (*s == '\n')
1057c478bd9Sstevel@tonic-gate 					*s = 0;
1067c478bd9Sstevel@tonic-gate 			}
1077c478bd9Sstevel@tonic-gate 		} else if (strncmp(s, "zone_lag", 8) == 0) {
1087c478bd9Sstevel@tonic-gate 			s += 8;
1097c478bd9Sstevel@tonic-gate 			while (*s != 0 && *s != '=')
1107c478bd9Sstevel@tonic-gate 				s++;
1117c478bd9Sstevel@tonic-gate 			if (*s == '=') {
1127c478bd9Sstevel@tonic-gate 				s++;
1137c478bd9Sstevel@tonic-gate 				while (*s != 0 && (*s == ' ' || *s == '\t'))
1147c478bd9Sstevel@tonic-gate 					s++;
1157c478bd9Sstevel@tonic-gate 				(void) strncpy(zone_lag, s, sizeof (zone_lag));
1167c478bd9Sstevel@tonic-gate 				s = zone_lag;
1177c478bd9Sstevel@tonic-gate 				while (*s != 0 && *s != '\n')
1187c478bd9Sstevel@tonic-gate 					s++;
1197c478bd9Sstevel@tonic-gate 				if (*s == '\n')
1207c478bd9Sstevel@tonic-gate 					*s = 0;
1217c478bd9Sstevel@tonic-gate 			}
1227c478bd9Sstevel@tonic-gate 		}
1237c478bd9Sstevel@tonic-gate 	}
1247c478bd9Sstevel@tonic-gate 	lag = atoi(zone_lag);
1257c478bd9Sstevel@tonic-gate 	lag_hrs = lag / 3600;
1267c478bd9Sstevel@tonic-gate 	if (zone_info[0] == 0) {
1277c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: zone_info field is invalid\n",
1287c478bd9Sstevel@tonic-gate 		    progname);
1297c478bd9Sstevel@tonic-gate 		zone_info[0] = 0;
1307c478bd9Sstevel@tonic-gate 		zone_lag[0] = 0;
1317c478bd9Sstevel@tonic-gate 		return (1);
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 	if (zone_lag[0] == 0) {
1347c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: zone_lag field is invalid\n",
1357c478bd9Sstevel@tonic-gate 		    progname);
1367c478bd9Sstevel@tonic-gate 		zone_lag[0] = 0;
1377c478bd9Sstevel@tonic-gate 		return (1);
1387c478bd9Sstevel@tonic-gate 	}
1397c478bd9Sstevel@tonic-gate 	if ((lag_hrs < -24) || (lag_hrs > 24)) {
1407c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: a GMT lag of %d is out of range\n",
1417c478bd9Sstevel@tonic-gate 		    progname, lag_hrs);
1427c478bd9Sstevel@tonic-gate 		zone_info[0] = 0;
1437c478bd9Sstevel@tonic-gate 		zone_lag[0] = 0;
1447c478bd9Sstevel@tonic-gate 		return (1);
1457c478bd9Sstevel@tonic-gate 	}
1467c478bd9Sstevel@tonic-gate 	if (debug)
1477c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "zone_info = %s,   zone_lag = %s\n",
1487c478bd9Sstevel@tonic-gate 		    zone_info, zone_lag);
1497c478bd9Sstevel@tonic-gate 	if (debug)
1507c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "lag (decimal) is %d\n", lag);
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	(void) fclose(zonefptr);
1537c478bd9Sstevel@tonic-gate 	zonefptr = NULL;
1547c478bd9Sstevel@tonic-gate 	return (0);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate void
display_zone_string(void)1587c478bd9Sstevel@tonic-gate display_zone_string(void)
1597c478bd9Sstevel@tonic-gate {
1607c478bd9Sstevel@tonic-gate 	if (open_zonefile() == 0)
1617c478bd9Sstevel@tonic-gate 		(void) printf("%s\n", zone_info);
1627c478bd9Sstevel@tonic-gate 	else
1637c478bd9Sstevel@tonic-gate 		(void) printf("GMT\n");
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate 
166*026e699fSGary Mills int
get_local(char * z)167*026e699fSGary Mills get_local(char *z)
168*026e699fSGary Mills {
169*026e699fSGary Mills 	struct tm *tm;
170*026e699fSGary Mills 
171*026e699fSGary Mills 	tz[3] = 0;
172*026e699fSGary Mills 	(void) strncat(tz, z, 253);
173*026e699fSGary Mills 	if (debug)
174*026e699fSGary Mills 		(void) fprintf(stderr, "Time Zone string is '%s'\n", tz);
175*026e699fSGary Mills 
176*026e699fSGary Mills 	(void) putenv(tz);
177*026e699fSGary Mills 	if (debug)
178*026e699fSGary Mills 		(void) system("env | grep TZ");
179*026e699fSGary Mills 
180*026e699fSGary Mills 	(void) time(&clock_val);
181*026e699fSGary Mills 
182*026e699fSGary Mills 	tm = localtime(&clock_val);
183*026e699fSGary Mills 	return (tm->tm_isdst);
184*026e699fSGary Mills }
185*026e699fSGary Mills 
1867c478bd9Sstevel@tonic-gate long
set_zone(char * zone_string)1877c478bd9Sstevel@tonic-gate set_zone(char *zone_string)
1887c478bd9Sstevel@tonic-gate {
189*026e699fSGary Mills 	int isdst;
1907c478bd9Sstevel@tonic-gate 	long current_lag;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	(void) umask(0022);
1937c478bd9Sstevel@tonic-gate 	if ((zonefptr = fopen(zonefile, "w")) == NULL) {
1947c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: cannot open %s: errno = %d\n",
1957c478bd9Sstevel@tonic-gate 		    progname, zonefile, errno);
1967c478bd9Sstevel@tonic-gate 		return (0);
1977c478bd9Sstevel@tonic-gate 	}
1987c478bd9Sstevel@tonic-gate 
199*026e699fSGary Mills 	switch (rtc_mode) {
200*026e699fSGary Mills 	case M_VAR:
201*026e699fSGary Mills 		isdst = get_local(zone_string);
202*026e699fSGary Mills 		current_lag = isdst ? altzone : timezone;
203*026e699fSGary Mills 		break;
204*026e699fSGary Mills 	case M_STD:
205*026e699fSGary Mills 		isdst = get_local(zone_string);
206*026e699fSGary Mills 		current_lag = timezone;
207*026e699fSGary Mills 		break;
208*026e699fSGary Mills 	default:	/* Includes M_UTC */
209*026e699fSGary Mills 		isdst = 0;
210*026e699fSGary Mills 		current_lag = 0;
211*026e699fSGary Mills 		zone_string = utc_zone;
212*026e699fSGary Mills 		break;
213*026e699fSGary Mills 	}
2147c478bd9Sstevel@tonic-gate 	if (debug)
215*026e699fSGary Mills 		(void) printf("%s DST.    Lag is %ld.\n", isdst ? "Is" :
216*026e699fSGary Mills 		    "Is NOT",  current_lag);
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	(void) fprintf(zonefptr, zone_comment, zonefile);
2197c478bd9Sstevel@tonic-gate 	(void) fprintf(zonefptr, "zone_info=%s\n", zone_string);
220*026e699fSGary Mills 	(void) fprintf(zonefptr, "zone_lag=%ld\n", current_lag);
2217c478bd9Sstevel@tonic-gate 	(void) fclose(zonefptr);
2227c478bd9Sstevel@tonic-gate 	zonefptr = NULL;
2237c478bd9Sstevel@tonic-gate 	return (current_lag);
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate void
correct_rtc_and_lag()2277c478bd9Sstevel@tonic-gate correct_rtc_and_lag()
2287c478bd9Sstevel@tonic-gate {
229*026e699fSGary Mills 	int isdst;
2307c478bd9Sstevel@tonic-gate 	long kernels_lag;
2317c478bd9Sstevel@tonic-gate 	long current_lag;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	if (open_zonefile())
2347c478bd9Sstevel@tonic-gate 		return;
2357c478bd9Sstevel@tonic-gate 
236*026e699fSGary Mills 	switch (rtc_mode) {
237*026e699fSGary Mills 	case M_VAR:
238*026e699fSGary Mills 		isdst = get_local(zone_info);
239*026e699fSGary Mills 		current_lag = isdst ? altzone : timezone;
240*026e699fSGary Mills 		break;
241*026e699fSGary Mills 	case M_STD:
242*026e699fSGary Mills 		(void) get_local(zone_info);
243*026e699fSGary Mills 		current_lag = timezone;
244*026e699fSGary Mills 		break;
245*026e699fSGary Mills 	default:	/* Includes M_UTC */
246*026e699fSGary Mills 		current_lag = 0;
247*026e699fSGary Mills 		break;
248*026e699fSGary Mills 	}
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate 	if (current_lag != lag) {	/* if file is wrong */
2517c478bd9Sstevel@tonic-gate 		if (debug)
252*026e699fSGary Mills 			(void) fprintf(stderr, "correcting file\n");
2537c478bd9Sstevel@tonic-gate 		(void) set_zone(zone_info);	/* then rewrite file */
2547c478bd9Sstevel@tonic-gate 	}
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	(void) sysi86(GGMTL, &kernels_lag);
2577c478bd9Sstevel@tonic-gate 	if (current_lag != kernels_lag) {
2587c478bd9Sstevel@tonic-gate 		if (debug)
259*026e699fSGary Mills 			(void) fprintf(stderr, "correcting kernel's lag\n");
2607c478bd9Sstevel@tonic-gate 		(void) sysi86(SGMTL, current_lag);	/* correct the lag */
2617c478bd9Sstevel@tonic-gate 		(void) sysi86(WTODC);			/* set the rtc to */
2627c478bd9Sstevel@tonic-gate 							/* new local time */
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate void
initialize_zone(char * zone_string)2677c478bd9Sstevel@tonic-gate initialize_zone(char *zone_string)
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate 	long current_lag;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	/* write the config file */
2727c478bd9Sstevel@tonic-gate 	current_lag = set_zone(zone_string);
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	/* correct the lag */
2757c478bd9Sstevel@tonic-gate 	(void) sysi86(SGMTL, current_lag);
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	/*
2787c478bd9Sstevel@tonic-gate 	 * set the unix time from the rtc,
2797c478bd9Sstevel@tonic-gate 	 * assuming the rtc was the correct
2807c478bd9Sstevel@tonic-gate 	 * local time.
2817c478bd9Sstevel@tonic-gate 	 */
2827c478bd9Sstevel@tonic-gate 	(void) sysi86(RTCSYNC);
2837c478bd9Sstevel@tonic-gate }
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate void
usage()2867c478bd9Sstevel@tonic-gate usage()
2877c478bd9Sstevel@tonic-gate {
2887c478bd9Sstevel@tonic-gate 	static char Usage[] = "Usage:\n\
289*026e699fSGary Mills rtc [-w] [-s|-u|-v] [-c] [-z time_zone] [-?]\n";
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, Usage);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate void
verbose_usage()2957c478bd9Sstevel@tonic-gate verbose_usage()
2967c478bd9Sstevel@tonic-gate {
2977c478bd9Sstevel@tonic-gate 	static char Usage1[] = "\
2987c478bd9Sstevel@tonic-gate 	Options:\n\
299*026e699fSGary Mills 	    -w\t\tDoes nothing.\n\
300*026e699fSGary Mills 	    -s\t\tRTC runs in local standard time.\n\
301*026e699fSGary Mills 	    -u\t\tRTC runs in UTC time.\n\
302*026e699fSGary Mills 	    -v\t\tRTC tracks local time (with cron command).\n\
3037c478bd9Sstevel@tonic-gate 	    -c\t\tCheck and correct for daylight savings time rollover.\n\
3047c478bd9Sstevel@tonic-gate 	    -z [zone]\tRecord the zone info in the config file.\n";
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, Usage1);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
309*026e699fSGary Mills void
set_default()310*026e699fSGary Mills set_default()
311*026e699fSGary Mills {
312*026e699fSGary Mills 	switch (rtc_mode) {
313*026e699fSGary Mills 	default:	/* Includes M_UNSET */
314*026e699fSGary Mills 		rtc_mode = M_VAR;
315*026e699fSGary Mills 		break;
316*026e699fSGary Mills 	case M_VAR:
317*026e699fSGary Mills 		/*FALLTHROUGH*/
318*026e699fSGary Mills 	case M_UTC:
319*026e699fSGary Mills 		/*FALLTHROUGH*/
320*026e699fSGary Mills 	case M_STD:
321*026e699fSGary Mills 		break;
322*026e699fSGary Mills 	}
323*026e699fSGary Mills }
324*026e699fSGary Mills 
325*026e699fSGary Mills void
check_mode(int letter,int mode)326*026e699fSGary Mills check_mode(int letter, int mode)
327*026e699fSGary Mills {
328*026e699fSGary Mills 	if (rtc_mode == M_UNSET || rtc_mode == mode) {
329*026e699fSGary Mills 		rtc_mode = mode;
330*026e699fSGary Mills 		return;
331*026e699fSGary Mills 	}
332*026e699fSGary Mills 	(void) fprintf(stderr, "%s: option -%c conflicts with other options\n",
333*026e699fSGary Mills 	    progname, letter);
334*026e699fSGary Mills 	exit(1);
335*026e699fSGary Mills }
336*026e699fSGary Mills 
337*026e699fSGary Mills 
3387c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])3397c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
3407c478bd9Sstevel@tonic-gate {
3417c478bd9Sstevel@tonic-gate 	int c;
342*026e699fSGary Mills 	int cflg = 0;
343*026e699fSGary Mills 	char *zone_name = NULL;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	progname = argv[0];
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 	if (argc == 1) {
3487c478bd9Sstevel@tonic-gate 		errors_ok = 1;
3497c478bd9Sstevel@tonic-gate 		display_zone_string();
350*026e699fSGary Mills 		exit(0);
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate 
353*026e699fSGary Mills 	while ((c = getopt(argc, argv, "suvwcz:d")) != EOF) {
3547c478bd9Sstevel@tonic-gate 		switch (c) {
3557c478bd9Sstevel@tonic-gate 		case 'c':
356*026e699fSGary Mills 			cflg++;
3577c478bd9Sstevel@tonic-gate 			continue;
3587c478bd9Sstevel@tonic-gate 		case 'z':
359*026e699fSGary Mills 			zone_name = optarg;
3607c478bd9Sstevel@tonic-gate 			continue;
3617c478bd9Sstevel@tonic-gate 		case 'd':
3627c478bd9Sstevel@tonic-gate 			debug = 1;
3637c478bd9Sstevel@tonic-gate 			continue;
364*026e699fSGary Mills 		case 's':	/* standard: RTC runs local standard time */
365*026e699fSGary Mills 			check_mode(c, M_STD);
366*026e699fSGary Mills 			continue;
367*026e699fSGary Mills 		case 'u':	/* utc: RTC runs UTC time */
368*026e699fSGary Mills 			check_mode(c, M_UTC);
369*026e699fSGary Mills 			continue;
370*026e699fSGary Mills 		case 'v':	/* varies: RTC tracks local time */
371*026e699fSGary Mills 			check_mode(c, M_VAR);
372*026e699fSGary Mills 			continue;
373*026e699fSGary Mills 		case 'w':	/* Does nothing */
374*026e699fSGary Mills 			continue;
3757c478bd9Sstevel@tonic-gate 		case '?':
3767c478bd9Sstevel@tonic-gate 			verbose_usage();
377*026e699fSGary Mills 			exit(0);
3787c478bd9Sstevel@tonic-gate 		default:
3797c478bd9Sstevel@tonic-gate 			usage();
380*026e699fSGary Mills 			exit(1);
3817c478bd9Sstevel@tonic-gate 		}
3827c478bd9Sstevel@tonic-gate 	}
383*026e699fSGary Mills 	set_default();
384*026e699fSGary Mills 	if (zone_name != NULL)
385*026e699fSGary Mills 		initialize_zone(zone_name);
386*026e699fSGary Mills 	if (cflg > 0)
387*026e699fSGary Mills 		correct_rtc_and_lag();
388*026e699fSGary Mills 	exit(0);
389*026e699fSGary Mills 	/*LINTED*/
3907c478bd9Sstevel@tonic-gate }
391