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