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