xref: /illumos-gate/usr/src/cmd/scadm/sparc/mpxu/common/date.c (revision 2a8bcb4efb45d99ac41c94a75c396b362c414f7f)
1*03831d35Sstevel /*
2*03831d35Sstevel  * CDDL HEADER START
3*03831d35Sstevel  *
4*03831d35Sstevel  * The contents of this file are subject to the terms of the
5*03831d35Sstevel  * Common Development and Distribution License, Version 1.0 only
6*03831d35Sstevel  * (the "License").  You may not use this file except in compliance
7*03831d35Sstevel  * with the License.
8*03831d35Sstevel  *
9*03831d35Sstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*03831d35Sstevel  * or http://www.opensolaris.org/os/licensing.
11*03831d35Sstevel  * See the License for the specific language governing permissions
12*03831d35Sstevel  * and limitations under the License.
13*03831d35Sstevel  *
14*03831d35Sstevel  * When distributing Covered Code, include this CDDL HEADER in each
15*03831d35Sstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*03831d35Sstevel  * If applicable, add the following below this CDDL HEADER, with the
17*03831d35Sstevel  * fields enclosed by brackets "[]" replaced with your own identifying
18*03831d35Sstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
19*03831d35Sstevel  *
20*03831d35Sstevel  * CDDL HEADER END
21*03831d35Sstevel  */
22*03831d35Sstevel /*
23*03831d35Sstevel  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24*03831d35Sstevel  * Use is subject to license terms.
25*03831d35Sstevel  */
26*03831d35Sstevel 
27*03831d35Sstevel /*
28*03831d35Sstevel  * date.c: support for the scadm date option (change/display service
29*03831d35Sstevel  * processor date)
30*03831d35Sstevel  */
31*03831d35Sstevel 
32*03831d35Sstevel #include <libintl.h>
33*03831d35Sstevel #include <stdio.h>
34*03831d35Sstevel #include <string.h>
35*03831d35Sstevel #include <locale.h>
36*03831d35Sstevel #include <langinfo.h>
37*03831d35Sstevel #include <time.h>  /* required by rsc.h */
38*03831d35Sstevel 
39*03831d35Sstevel #include "librsc.h"
40*03831d35Sstevel #include "adm.h"
41*03831d35Sstevel 
42*03831d35Sstevel static void ADM_Get_Date();
43*03831d35Sstevel static void ADM_Set_Date(int argc, char *argv[]);
44*03831d35Sstevel static int ADM_Decode_Date(char *String, dp_set_date_time_t *Date);
45*03831d35Sstevel static int ADM_twodigits(char *s);
46*03831d35Sstevel static void usage();
47*03831d35Sstevel 
48*03831d35Sstevel extern int cftime(char *, char *, const time_t *);
49*03831d35Sstevel 
50*03831d35Sstevel void
ADM_Process_date(int argc,char * argv[])51*03831d35Sstevel ADM_Process_date(int argc, char *argv[])
52*03831d35Sstevel {
53*03831d35Sstevel 	static dp_set_date_time_t	DateTime;
54*03831d35Sstevel 	static char			date[40];
55*03831d35Sstevel 	time_t				currentTime;
56*03831d35Sstevel 	int				largc;
57*03831d35Sstevel 	char				*largv[3];
58*03831d35Sstevel 
59*03831d35Sstevel 	if ((argc != 2) && (argc != 3)) {
60*03831d35Sstevel 		usage();
61*03831d35Sstevel 		exit(-1);
62*03831d35Sstevel 	}
63*03831d35Sstevel 
64*03831d35Sstevel 	if (argc == 3) {
65*03831d35Sstevel 		if (strcasecmp(argv[2], "-s") != 0) {
66*03831d35Sstevel 			if (ADM_Decode_Date(argv[2], &DateTime) != 0) {
67*03831d35Sstevel 				usage();
68*03831d35Sstevel 				exit(-1);
69*03831d35Sstevel 			}
70*03831d35Sstevel 		}
71*03831d35Sstevel 	}
72*03831d35Sstevel 
73*03831d35Sstevel 	ADM_Start();
74*03831d35Sstevel 
75*03831d35Sstevel 	if (argc == 2) {
76*03831d35Sstevel 		ADM_Get_Date();
77*03831d35Sstevel 	} else if (argc == 3) {
78*03831d35Sstevel 		if (strcasecmp(argv[2], "-s") == 0) {
79*03831d35Sstevel 			currentTime = time(NULL);
80*03831d35Sstevel 			(void) cftime(date, "%m""%d""%H""%M""%Y", &currentTime);
81*03831d35Sstevel 			largc = 3;
82*03831d35Sstevel 			largv[0] = argv[0];
83*03831d35Sstevel 			largv[1] = argv[1];
84*03831d35Sstevel 			largv[2] = date;
85*03831d35Sstevel 			ADM_Set_Date(largc, largv);
86*03831d35Sstevel 		} else {
87*03831d35Sstevel 			ADM_Set_Date(argc, argv);
88*03831d35Sstevel 		}
89*03831d35Sstevel 	}
90*03831d35Sstevel }
91*03831d35Sstevel 
92*03831d35Sstevel 
93*03831d35Sstevel static void
ADM_Get_Date()94*03831d35Sstevel ADM_Get_Date()
95*03831d35Sstevel {
96*03831d35Sstevel 	rscp_msg_t		Message;
97*03831d35Sstevel 	struct timespec		Timeout;
98*03831d35Sstevel 	dp_get_date_time_r_t	*dateInfo;
99*03831d35Sstevel 	struct tm		*tp;
100*03831d35Sstevel 	char			buf[64];
101*03831d35Sstevel 
102*03831d35Sstevel 	Message.type = DP_GET_DATE_TIME;
103*03831d35Sstevel 	Message.len  = 0;
104*03831d35Sstevel 	Message.data = NULL;
105*03831d35Sstevel 
106*03831d35Sstevel 	ADM_Send(&Message);
107*03831d35Sstevel 
108*03831d35Sstevel 	Timeout.tv_nsec = 0;
109*03831d35Sstevel 	Timeout.tv_sec  = ADM_TIMEOUT;
110*03831d35Sstevel 	ADM_Recv(&Message, &Timeout,
111*03831d35Sstevel 	    DP_GET_DATE_TIME_R, sizeof (dp_get_date_time_r_t));
112*03831d35Sstevel 
113*03831d35Sstevel 	if (*(int *)Message.data != 0) {
114*03831d35Sstevel 		(void) fprintf(stderr, "\n%s\n\n",
115*03831d35Sstevel 		    gettext("scadm: could not read date from SC"));
116*03831d35Sstevel 		exit(-1);
117*03831d35Sstevel 	}
118*03831d35Sstevel 
119*03831d35Sstevel 	dateInfo = (dp_get_date_time_r_t *)Message.data;
120*03831d35Sstevel 
121*03831d35Sstevel 	/* Print the date */
122*03831d35Sstevel 	(void) setlocale(LC_ALL, "");
123*03831d35Sstevel 	tp = gmtime((time_t *)&dateInfo->current_datetime);
124*03831d35Sstevel 	(void) strftime(buf, 64, nl_langinfo(D_T_FMT), tp);
125*03831d35Sstevel 	(void) printf("%s\n", buf);
126*03831d35Sstevel 
127*03831d35Sstevel 	ADM_Free(&Message);
128*03831d35Sstevel }
129*03831d35Sstevel 
130*03831d35Sstevel 
131*03831d35Sstevel static void
ADM_Set_Date(int argc,char * argv[])132*03831d35Sstevel ADM_Set_Date(int argc, char *argv[])
133*03831d35Sstevel {
134*03831d35Sstevel 	static dp_set_date_time_t	specTime;
135*03831d35Sstevel 	rscp_msg_t			Message;
136*03831d35Sstevel 	struct timespec			Timeout;
137*03831d35Sstevel 
138*03831d35Sstevel 	if (argc < 3) {
139*03831d35Sstevel 		/* should have caught this earlier */
140*03831d35Sstevel 		(void) fprintf(stderr, "\n%s\n\n",
141*03831d35Sstevel 		    gettext("scadm: arguments error in set date"));
142*03831d35Sstevel 		exit(-1);
143*03831d35Sstevel 	}
144*03831d35Sstevel 
145*03831d35Sstevel 	if (ADM_Decode_Date(argv[2], &specTime) != 0) {
146*03831d35Sstevel 		/* should have caught this earlier */
147*03831d35Sstevel 		(void) fprintf(stderr, "\n%s\n\n",
148*03831d35Sstevel 		    gettext("scadm: INTERNAL ERROR in set date"));
149*03831d35Sstevel 		exit(-1);
150*03831d35Sstevel 	}
151*03831d35Sstevel 
152*03831d35Sstevel 	/* Correct month to be 0 - 11.  Why does firmware want this? */
153*03831d35Sstevel 	/* Correct year to be offset from 1900.  Why does firmware want this? */
154*03831d35Sstevel 	if (specTime.month != DP_SET_DATE_TIME_IGNORE_FIELD)
155*03831d35Sstevel 		specTime.month = specTime.month - 1;
156*03831d35Sstevel 	if (specTime.year != DP_SET_DATE_TIME_IGNORE_FIELD)
157*03831d35Sstevel 		specTime.year  = specTime.year  - 1900;
158*03831d35Sstevel 
159*03831d35Sstevel 	Message.type = DP_SET_DATE_TIME;
160*03831d35Sstevel 	Message.len  = sizeof (dp_set_date_time_t);
161*03831d35Sstevel 	Message.data = &specTime;
162*03831d35Sstevel 	ADM_Send(&Message);
163*03831d35Sstevel 
164*03831d35Sstevel 	Timeout.tv_nsec = 0;
165*03831d35Sstevel 	Timeout.tv_sec  = ADM_TIMEOUT;
166*03831d35Sstevel 	ADM_Recv(&Message, &Timeout,
167*03831d35Sstevel 	    DP_SET_DATE_TIME_R, sizeof (dp_set_date_time_r_t));
168*03831d35Sstevel 
169*03831d35Sstevel 	if (*(int *)Message.data != 0) {
170*03831d35Sstevel 		(void) fprintf(stderr, "\n%s\n\n",
171*03831d35Sstevel 		    gettext("scadm: could not set date on SC"));
172*03831d35Sstevel 		exit(-1);
173*03831d35Sstevel 	}
174*03831d35Sstevel 
175*03831d35Sstevel 	ADM_Free(&Message);
176*03831d35Sstevel }
177*03831d35Sstevel 
178*03831d35Sstevel 
179*03831d35Sstevel static int
ADM_twodigits(char * s)180*03831d35Sstevel ADM_twodigits(char *s)
181*03831d35Sstevel {
182*03831d35Sstevel 	int n;
183*03831d35Sstevel 
184*03831d35Sstevel 	n = ((s[0] - '0') * 10) + (s[1] - '0');
185*03831d35Sstevel 	return (n);
186*03831d35Sstevel }
187*03831d35Sstevel 
188*03831d35Sstevel 
189*03831d35Sstevel static int
ADM_Decode_Date(char * String,dp_set_date_time_t * Date)190*03831d35Sstevel ADM_Decode_Date(char *String, dp_set_date_time_t *Date)
191*03831d35Sstevel {
192*03831d35Sstevel 	int		localDate;
193*03831d35Sstevel 
194*03831d35Sstevel 
195*03831d35Sstevel 	if (strlen(String) == 4) {
196*03831d35Sstevel 
197*03831d35Sstevel 		/* HHMM */
198*03831d35Sstevel 		Date->month	= DP_SET_DATE_TIME_IGNORE_FIELD;
199*03831d35Sstevel 		Date->day	= DP_SET_DATE_TIME_IGNORE_FIELD;
200*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[0]);
201*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[2]);
202*03831d35Sstevel 		Date->second	= DP_SET_DATE_TIME_IGNORE_FIELD;
203*03831d35Sstevel 		Date->year	= DP_SET_DATE_TIME_IGNORE_FIELD;
204*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
205*03831d35Sstevel 			return (-1);
206*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
207*03831d35Sstevel 			return (-1);
208*03831d35Sstevel 
209*03831d35Sstevel 	} else if (strlen(String) == 7) {
210*03831d35Sstevel 
211*03831d35Sstevel 		/* HHMM.SS */
212*03831d35Sstevel 		Date->month	= DP_SET_DATE_TIME_IGNORE_FIELD;
213*03831d35Sstevel 		Date->day	= DP_SET_DATE_TIME_IGNORE_FIELD;
214*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[0]);
215*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[2]);
216*03831d35Sstevel 		Date->second	= ADM_twodigits(&String[5]);
217*03831d35Sstevel 		Date->year	= DP_SET_DATE_TIME_IGNORE_FIELD;
218*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
219*03831d35Sstevel 			return (-1);
220*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
221*03831d35Sstevel 			return (-1);
222*03831d35Sstevel 		if (((int)Date->second < 0) || (Date->second > 59))
223*03831d35Sstevel 			return (-1);
224*03831d35Sstevel 
225*03831d35Sstevel 	} else if (strlen(String) == 8) {
226*03831d35Sstevel 
227*03831d35Sstevel 		/* mmddHHMM */
228*03831d35Sstevel 		Date->month	= ADM_twodigits(&String[0]);
229*03831d35Sstevel 		Date->day	= ADM_twodigits(&String[2]);
230*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[4]);
231*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[6]);
232*03831d35Sstevel 		Date->second	= DP_SET_DATE_TIME_IGNORE_FIELD;
233*03831d35Sstevel 		Date->year	= DP_SET_DATE_TIME_IGNORE_FIELD;
234*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
235*03831d35Sstevel 			return (-1);
236*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
237*03831d35Sstevel 			return (-1);
238*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
239*03831d35Sstevel 			return (-1);
240*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
241*03831d35Sstevel 			return (-1);
242*03831d35Sstevel 
243*03831d35Sstevel 	} else if (strlen(String) == 11) {
244*03831d35Sstevel 
245*03831d35Sstevel 		/* mmddHHMM.SS */
246*03831d35Sstevel 		Date->month  = ADM_twodigits(&String[0]);
247*03831d35Sstevel 		Date->day    = ADM_twodigits(&String[2]);
248*03831d35Sstevel 		Date->hour   = ADM_twodigits(&String[4]);
249*03831d35Sstevel 		Date->minute = ADM_twodigits(&String[6]);
250*03831d35Sstevel 		Date->second = ADM_twodigits(&String[9]);
251*03831d35Sstevel 		Date->year   = DP_SET_DATE_TIME_IGNORE_FIELD;
252*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
253*03831d35Sstevel 			return (-1);
254*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
255*03831d35Sstevel 			return (-1);
256*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
257*03831d35Sstevel 			return (-1);
258*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
259*03831d35Sstevel 			return (-1);
260*03831d35Sstevel 		if (((int)Date->second < 0) || (Date->second > 59))
261*03831d35Sstevel 			return (-1);
262*03831d35Sstevel 
263*03831d35Sstevel 	} else if (strlen(String) == 10) {
264*03831d35Sstevel 
265*03831d35Sstevel 		/* mmddHHMMyy */
266*03831d35Sstevel 		Date->month	= ADM_twodigits(&String[0]);
267*03831d35Sstevel 		Date->day	= ADM_twodigits(&String[2]);
268*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[4]);
269*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[6]);
270*03831d35Sstevel 		Date->second	= DP_SET_DATE_TIME_IGNORE_FIELD;
271*03831d35Sstevel 		localDate	= ADM_twodigits(&String[8]);
272*03831d35Sstevel 		if (localDate > 70)
273*03831d35Sstevel 			Date->year = localDate + 1900;
274*03831d35Sstevel 		else
275*03831d35Sstevel 			Date->year = localDate + 2000;
276*03831d35Sstevel 
277*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
278*03831d35Sstevel 			return (-1);
279*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
280*03831d35Sstevel 			return (-1);
281*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
282*03831d35Sstevel 			return (-1);
283*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
284*03831d35Sstevel 			return (-1);
285*03831d35Sstevel 		if ((Date->year < 1970) || (Date->year > 2038))
286*03831d35Sstevel 			return (-1);
287*03831d35Sstevel 
288*03831d35Sstevel 	} else if (strlen(String) == 13) {
289*03831d35Sstevel 
290*03831d35Sstevel 		/* mmddHHMMyy.SS */
291*03831d35Sstevel 		Date->month	= ADM_twodigits(&String[0]);
292*03831d35Sstevel 		Date->day	= ADM_twodigits(&String[2]);
293*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[4]);
294*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[6]);
295*03831d35Sstevel 		Date->second	= ADM_twodigits(&String[11]);
296*03831d35Sstevel 		localDate	= ADM_twodigits(&String[8]);
297*03831d35Sstevel 		if (localDate > 70)
298*03831d35Sstevel 			Date->year = localDate + 1900;
299*03831d35Sstevel 		else
300*03831d35Sstevel 			Date->year = localDate + 2000;
301*03831d35Sstevel 
302*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
303*03831d35Sstevel 			return (-1);
304*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
305*03831d35Sstevel 			return (-1);
306*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
307*03831d35Sstevel 			return (-1);
308*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
309*03831d35Sstevel 			return (-1);
310*03831d35Sstevel 		if ((Date->year < 1970) || (Date->year > 2038))
311*03831d35Sstevel 			return (-1);
312*03831d35Sstevel 		if (((int)Date->second < 0) || (Date->second > 59))
313*03831d35Sstevel 			return (-1);
314*03831d35Sstevel 
315*03831d35Sstevel 	} else if (strlen(String) == 12) {
316*03831d35Sstevel 
317*03831d35Sstevel 		/* mmddHHMMccyy */
318*03831d35Sstevel 		Date->month	= ADM_twodigits(&String[0]);
319*03831d35Sstevel 		Date->day	= ADM_twodigits(&String[2]);
320*03831d35Sstevel 		Date->hour	= ADM_twodigits(&String[4]);
321*03831d35Sstevel 		Date->minute	= ADM_twodigits(&String[6]);
322*03831d35Sstevel 		Date->second	= DP_SET_DATE_TIME_IGNORE_FIELD;
323*03831d35Sstevel 		Date->year	= (ADM_twodigits(&String[8]) * 100) +
324*03831d35Sstevel 		    ADM_twodigits(&String[10]);
325*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
326*03831d35Sstevel 			return (-1);
327*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
328*03831d35Sstevel 			return (-1);
329*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
330*03831d35Sstevel 			return (-1);
331*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
332*03831d35Sstevel 			return (-1);
333*03831d35Sstevel 		if ((Date->year < 1970) || (Date->year > 2038))
334*03831d35Sstevel 			return (-1);
335*03831d35Sstevel 
336*03831d35Sstevel 	} else if (strlen(String) == 15) {
337*03831d35Sstevel 
338*03831d35Sstevel 		/* mmddHHMMccyy.SS */
339*03831d35Sstevel 		Date->month  = ADM_twodigits(&String[0]);
340*03831d35Sstevel 		Date->day    = ADM_twodigits(&String[2]);
341*03831d35Sstevel 		Date->hour   = ADM_twodigits(&String[4]);
342*03831d35Sstevel 		Date->minute = ADM_twodigits(&String[6]);
343*03831d35Sstevel 		Date->second = ADM_twodigits(&String[13]);
344*03831d35Sstevel 		Date->year   = (ADM_twodigits(&String[8]) * 100) +
345*03831d35Sstevel 		    ADM_twodigits(&String[10]);
346*03831d35Sstevel 		if ((Date->month < 1) || (Date->month > 12))
347*03831d35Sstevel 			return (-1);
348*03831d35Sstevel 		if ((Date->day < 1) || (Date->day > 31))
349*03831d35Sstevel 			return (-1);
350*03831d35Sstevel 		if (((int)Date->hour < 0) || (Date->hour > 23))
351*03831d35Sstevel 			return (-1);
352*03831d35Sstevel 		if (((int)Date->minute < 0) || (Date->minute > 59))
353*03831d35Sstevel 			return (-1);
354*03831d35Sstevel 		if ((Date->year < 1970) || (Date->year > 2038))
355*03831d35Sstevel 			return (-1);
356*03831d35Sstevel 		if (((int)Date->second < 0) || (Date->second > 59))
357*03831d35Sstevel 			return (-1);
358*03831d35Sstevel 
359*03831d35Sstevel 	} else {
360*03831d35Sstevel 		return (-1);
361*03831d35Sstevel 	}
362*03831d35Sstevel 
363*03831d35Sstevel 	return (0);
364*03831d35Sstevel }
365*03831d35Sstevel 
366*03831d35Sstevel 
367*03831d35Sstevel static void
usage()368*03831d35Sstevel usage()
369*03831d35Sstevel {
370*03831d35Sstevel 	(void) fprintf(stderr, "\n%s\n\n",
371*03831d35Sstevel 	    gettext("USAGE: scadm date [-s] "
372*03831d35Sstevel 	    "| [[mmdd]HHMM | mmddHHMM[cc]yy][.SS]\n"
373*03831d35Sstevel 	    "       1  <=  mm  <= 12\n"
374*03831d35Sstevel 	    "       1  <=  dd  <= 31\n"
375*03831d35Sstevel 	    "       1  <=  HH  <= 23\n"
376*03831d35Sstevel 	    "       0  <=  MM  <= 59\n"
377*03831d35Sstevel 	    "     1970 <= ccyy <= 2038\n"
378*03831d35Sstevel 	    "       0  <=  SS  <= 59"));
379*03831d35Sstevel }
380