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