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