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