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 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 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 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 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 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 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