1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * lib/kadm/str_conv.c 10*7c478bd9Sstevel@tonic-gate * 11*7c478bd9Sstevel@tonic-gate * Copyright 1995, 1999 by the Massachusetts Institute of Technology. 12*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 15*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 16*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 17*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 18*7c478bd9Sstevel@tonic-gate * 19*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 21*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 22*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 23*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 24*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 25*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 26*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 27*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 28*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 29*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 30*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 31*7c478bd9Sstevel@tonic-gate * or implied warranty. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate /* 36*7c478bd9Sstevel@tonic-gate * str_conv.c - Convert between strings and Kerberos internal data. 37*7c478bd9Sstevel@tonic-gate */ 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* 40*7c478bd9Sstevel@tonic-gate * Table of contents: 41*7c478bd9Sstevel@tonic-gate * 42*7c478bd9Sstevel@tonic-gate * String decoding: 43*7c478bd9Sstevel@tonic-gate * ---------------- 44*7c478bd9Sstevel@tonic-gate * krb5_string_to_salttype() - Convert string to salttype (krb5_int32) 45*7c478bd9Sstevel@tonic-gate * krb5_string_to_timestamp() - Convert string to krb5_timestamp. 46*7c478bd9Sstevel@tonic-gate * krb5_string_to_deltat() - Convert string to krb5_deltat. 47*7c478bd9Sstevel@tonic-gate * 48*7c478bd9Sstevel@tonic-gate * String encoding: 49*7c478bd9Sstevel@tonic-gate * ---------------- 50*7c478bd9Sstevel@tonic-gate * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string. 51*7c478bd9Sstevel@tonic-gate * krb5_timestamp_to_string() - Convert krb5_timestamp to string. 52*7c478bd9Sstevel@tonic-gate * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string 53*7c478bd9Sstevel@tonic-gate * krb5_deltat_to_string() - Convert krb5_deltat to string. 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include <k5-int.h> 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* Salt type conversions */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * Local data structures. 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate struct salttype_lookup_entry { 64*7c478bd9Sstevel@tonic-gate krb5_int32 stt_enctype; /* Salt type */ 65*7c478bd9Sstevel@tonic-gate const char * stt_specifier; /* How to recognize it */ 66*7c478bd9Sstevel@tonic-gate const char * stt_output; /* How to spit it out */ 67*7c478bd9Sstevel@tonic-gate }; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * Lookup tables. 71*7c478bd9Sstevel@tonic-gate */ 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate static const struct salttype_lookup_entry salttype_table[] = { 74*7c478bd9Sstevel@tonic-gate /* salt type input specifier output string */ 75*7c478bd9Sstevel@tonic-gate /*----------------------------- --------------- ---------------*/ 76*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NORMAL, "normal", "Version 5" }, 77*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_V4, "v4", "Version 4" }, 78*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NOREALM, "norealm", "Version 5 - No Realm" }, 79*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_ONLYREALM, "onlyrealm", "Version 5 - Realm Only" }, 80*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_SPECIAL, "special", "Special" }, 81*7c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_AFS3, "afs3", "AFS version 3" } 82*7c478bd9Sstevel@tonic-gate }; 83*7c478bd9Sstevel@tonic-gate static const int salttype_table_nents = sizeof(salttype_table)/ 84*7c478bd9Sstevel@tonic-gate sizeof(salttype_table[0]); 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 87*7c478bd9Sstevel@tonic-gate krb5_string_to_salttype(string, salttypep) 88*7c478bd9Sstevel@tonic-gate char FAR * string; 89*7c478bd9Sstevel@tonic-gate krb5_int32 FAR * salttypep; 90*7c478bd9Sstevel@tonic-gate { 91*7c478bd9Sstevel@tonic-gate int i; 92*7c478bd9Sstevel@tonic-gate int found; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate found = 0; 95*7c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) { 96*7c478bd9Sstevel@tonic-gate if (!strcasecmp(string, salttype_table[i].stt_specifier)) { 97*7c478bd9Sstevel@tonic-gate found = 1; 98*7c478bd9Sstevel@tonic-gate *salttypep = salttype_table[i].stt_enctype; 99*7c478bd9Sstevel@tonic-gate break; 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate return((found) ? 0 : EINVAL); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* 106*7c478bd9Sstevel@tonic-gate * Internal datatype to string routines. 107*7c478bd9Sstevel@tonic-gate * 108*7c478bd9Sstevel@tonic-gate * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM 109*7c478bd9Sstevel@tonic-gate * if the supplied buffer/length will not contain the output. 110*7c478bd9Sstevel@tonic-gate */ 111*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 112*7c478bd9Sstevel@tonic-gate krb5_salttype_to_string(salttype, buffer, buflen) 113*7c478bd9Sstevel@tonic-gate krb5_int32 salttype; 114*7c478bd9Sstevel@tonic-gate char FAR * buffer; 115*7c478bd9Sstevel@tonic-gate size_t buflen; 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate int i; 118*7c478bd9Sstevel@tonic-gate const char *out; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate out = (char *) NULL; 121*7c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) { 122*7c478bd9Sstevel@tonic-gate if (salttype == salttype_table[i].stt_enctype) { 123*7c478bd9Sstevel@tonic-gate out = salttype_table[i].stt_output; 124*7c478bd9Sstevel@tonic-gate break; 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate if (out) { 128*7c478bd9Sstevel@tonic-gate if (buflen > strlen(out)) 129*7c478bd9Sstevel@tonic-gate strcpy(buffer, out); 130*7c478bd9Sstevel@tonic-gate else 131*7c478bd9Sstevel@tonic-gate out = (char *) NULL; 132*7c478bd9Sstevel@tonic-gate return((out) ? 0 : ENOMEM); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate else 135*7c478bd9Sstevel@tonic-gate return(EINVAL); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* (absolute) time conversions */ 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate #ifndef HAVE_STRFTIME 141*7c478bd9Sstevel@tonic-gate #undef strftime 142*7c478bd9Sstevel@tonic-gate #define strftime my_strftime 143*7c478bd9Sstevel@tonic-gate static size_t strftime (char *, size_t, const char *, const struct tm *); 144*7c478bd9Sstevel@tonic-gate #endif 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate #ifndef HAVE_STRPTIME 147*7c478bd9Sstevel@tonic-gate #undef strptime 148*7c478bd9Sstevel@tonic-gate #define strptime my_strptime 149*7c478bd9Sstevel@tonic-gate static char *strptime (const char *, const char *, struct tm *); 150*7c478bd9Sstevel@tonic-gate #endif 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 153*7c478bd9Sstevel@tonic-gate krb5_string_to_timestamp(string, timestampp) 154*7c478bd9Sstevel@tonic-gate char FAR * string; 155*7c478bd9Sstevel@tonic-gate krb5_timestamp FAR * timestampp; 156*7c478bd9Sstevel@tonic-gate { 157*7c478bd9Sstevel@tonic-gate int i,found; 158*7c478bd9Sstevel@tonic-gate struct tm timebuf, nowbuf; 159*7c478bd9Sstevel@tonic-gate time_t now; 160*7c478bd9Sstevel@tonic-gate char *s; 161*7c478bd9Sstevel@tonic-gate static const char * const atime_format_table[] = { 162*7c478bd9Sstevel@tonic-gate "%Y" "%m%d%H" "%M" "%S",/* yyyymmddhhmmss */ 163*7c478bd9Sstevel@tonic-gate "%Y.%m.%d.%H.%M.%S", /* yyyy.mm.dd.hh.mm.ss */ 164*7c478bd9Sstevel@tonic-gate "%y%m%d%H" "%M" "%S", /* yymmddhhmmss */ 165*7c478bd9Sstevel@tonic-gate "%y.%m.%d.%H.%M.%S", /* yy.mm.dd.hh.mm.ss */ 166*7c478bd9Sstevel@tonic-gate "%y%m%d%H" "%M", /* yymmddhhmm */ 167*7c478bd9Sstevel@tonic-gate "%H" "%M" "%S", /* hhmmss */ 168*7c478bd9Sstevel@tonic-gate "%H" "%M", /* hhmm */ 169*7c478bd9Sstevel@tonic-gate "%T", /* hh:mm:ss */ 170*7c478bd9Sstevel@tonic-gate "%R", /* hh:mm */ 171*7c478bd9Sstevel@tonic-gate /* The following not really supported unless native strptime present */ 172*7c478bd9Sstevel@tonic-gate "%x:%X", /* locale-dependent short format */ 173*7c478bd9Sstevel@tonic-gate "%d-%b-%Y:%T", /* dd-month-yyyy:hh:mm:ss */ 174*7c478bd9Sstevel@tonic-gate "%d-%b-%Y:%R" /* dd-month-yyyy:hh:mm */ 175*7c478bd9Sstevel@tonic-gate }; 176*7c478bd9Sstevel@tonic-gate static const int atime_format_table_nents = 177*7c478bd9Sstevel@tonic-gate sizeof(atime_format_table)/sizeof(atime_format_table[0]); 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate found = 0; 180*7c478bd9Sstevel@tonic-gate for (i=0; i<atime_format_table_nents; i++) { 181*7c478bd9Sstevel@tonic-gate s = strptime(string, atime_format_table[i], &timebuf); 182*7c478bd9Sstevel@tonic-gate /* make sure the entire string was parsed */ 183*7c478bd9Sstevel@tonic-gate if (s && (*s == '\0')) { 184*7c478bd9Sstevel@tonic-gate /* If only time and no date was provided, assume today */ 185*7c478bd9Sstevel@tonic-gate if ((timebuf.tm_mday == 0) && (timebuf.tm_mon == 0) && 186*7c478bd9Sstevel@tonic-gate (timebuf.tm_year == 0)) { 187*7c478bd9Sstevel@tonic-gate now = time((time_t *) NULL); 188*7c478bd9Sstevel@tonic-gate (void) memcpy(&nowbuf, localtime(&now), sizeof(timebuf)); 189*7c478bd9Sstevel@tonic-gate timebuf.tm_mday = nowbuf.tm_mday; 190*7c478bd9Sstevel@tonic-gate timebuf.tm_mon = nowbuf.tm_mon; 191*7c478bd9Sstevel@tonic-gate timebuf.tm_year = nowbuf.tm_year; 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate found = 1; 194*7c478bd9Sstevel@tonic-gate break; 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate if (found) { 198*7c478bd9Sstevel@tonic-gate if ((*timestampp = (krb5_timestamp) mktime(&timebuf)) != -1) { 199*7c478bd9Sstevel@tonic-gate if (timebuf.tm_isdst == 1) { 200*7c478bd9Sstevel@tonic-gate *timestampp -= (timezone - altzone); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate return (0); 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate return(EINVAL); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 209*7c478bd9Sstevel@tonic-gate krb5_timestamp_to_string(timestamp, buffer, buflen) 210*7c478bd9Sstevel@tonic-gate krb5_timestamp timestamp; 211*7c478bd9Sstevel@tonic-gate char FAR * buffer; 212*7c478bd9Sstevel@tonic-gate size_t buflen; 213*7c478bd9Sstevel@tonic-gate { 214*7c478bd9Sstevel@tonic-gate int ret; 215*7c478bd9Sstevel@tonic-gate time_t timestamp2 = timestamp; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate ret = strftime(buffer, buflen, "%c", localtime(×tamp2)); 218*7c478bd9Sstevel@tonic-gate if (ret == 0 || ret == buflen) 219*7c478bd9Sstevel@tonic-gate return(ENOMEM); 220*7c478bd9Sstevel@tonic-gate return(0); 221*7c478bd9Sstevel@tonic-gate } 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 224*7c478bd9Sstevel@tonic-gate krb5_timestamp_to_sfstring(timestamp, buffer, buflen, pad) 225*7c478bd9Sstevel@tonic-gate krb5_timestamp timestamp; 226*7c478bd9Sstevel@tonic-gate char FAR * buffer; 227*7c478bd9Sstevel@tonic-gate size_t buflen; 228*7c478bd9Sstevel@tonic-gate char FAR * pad; 229*7c478bd9Sstevel@tonic-gate { 230*7c478bd9Sstevel@tonic-gate struct tm *tmp; 231*7c478bd9Sstevel@tonic-gate size_t i; 232*7c478bd9Sstevel@tonic-gate size_t ndone; 233*7c478bd9Sstevel@tonic-gate time_t timestamp2 = timestamp; 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate static const char * const sftime_format_table[] = { 236*7c478bd9Sstevel@tonic-gate "%c", /* Default locale-dependent date and time */ 237*7c478bd9Sstevel@tonic-gate "%d %b %Y %T", /* dd mon yyyy hh:mm:ss */ 238*7c478bd9Sstevel@tonic-gate "%x %X", /* locale-dependent short format */ 239*7c478bd9Sstevel@tonic-gate "%d/%m/%Y %R" /* dd/mm/yyyy hh:mm */ 240*7c478bd9Sstevel@tonic-gate }; 241*7c478bd9Sstevel@tonic-gate static const int sftime_format_table_nents = 242*7c478bd9Sstevel@tonic-gate sizeof(sftime_format_table)/sizeof(sftime_format_table[0]); 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate tmp = localtime(×tamp2); 245*7c478bd9Sstevel@tonic-gate ndone = 0; 246*7c478bd9Sstevel@tonic-gate for (i=0; i<sftime_format_table_nents; i++) { 247*7c478bd9Sstevel@tonic-gate if ((ndone = strftime(buffer, buflen, sftime_format_table[i], tmp))) 248*7c478bd9Sstevel@tonic-gate break; 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate if (!ndone) { 251*7c478bd9Sstevel@tonic-gate #define sftime_default_len 2+1+2+1+4+1+2+1+2+1 252*7c478bd9Sstevel@tonic-gate if (buflen >= sftime_default_len) { 253*7c478bd9Sstevel@tonic-gate sprintf(buffer, "%02d/%02d/%4d %02d:%02d", 254*7c478bd9Sstevel@tonic-gate tmp->tm_mday, tmp->tm_mon+1, 1900+tmp->tm_year, 255*7c478bd9Sstevel@tonic-gate tmp->tm_hour, tmp->tm_min); 256*7c478bd9Sstevel@tonic-gate ndone = strlen(buffer); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate if (ndone && pad) { 260*7c478bd9Sstevel@tonic-gate for (i=ndone; i<buflen-1; i++) 261*7c478bd9Sstevel@tonic-gate buffer[i] = *pad; 262*7c478bd9Sstevel@tonic-gate buffer[buflen-1] = '\0'; 263*7c478bd9Sstevel@tonic-gate } 264*7c478bd9Sstevel@tonic-gate return((ndone) ? 0 : ENOMEM); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate #ifdef SUNW_INC_DEAD_CODE 268*7c478bd9Sstevel@tonic-gate /* relative time (delta-t) conversions */ 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* string->deltat is in deltat.y */ 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 273*7c478bd9Sstevel@tonic-gate krb5_deltat_to_string(deltat, buffer, buflen) 274*7c478bd9Sstevel@tonic-gate krb5_deltat deltat; 275*7c478bd9Sstevel@tonic-gate char FAR * buffer; 276*7c478bd9Sstevel@tonic-gate size_t buflen; 277*7c478bd9Sstevel@tonic-gate { 278*7c478bd9Sstevel@tonic-gate int days, hours, minutes, seconds; 279*7c478bd9Sstevel@tonic-gate krb5_deltat dt; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* 282*7c478bd9Sstevel@tonic-gate * We want something like ceil(log10(2**(nbits-1))) + 1. That log 283*7c478bd9Sstevel@tonic-gate * value is log10(2)*(nbits-1) or log10(2**8)*(nbits-1)/8. So, 284*7c478bd9Sstevel@tonic-gate * 2.4... is log10(256), rounded up. Add one to handle leading 285*7c478bd9Sstevel@tonic-gate * minus, and one more to force int cast to round the value up. 286*7c478bd9Sstevel@tonic-gate * This doesn't include room for a trailing nul. 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * This will break if bytes are more than 8 bits. 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate #define MAX_CHARS_FOR_INT_TYPE(TYPE) ((int) (2 + 2.408241 * sizeof (TYPE))) 291*7c478bd9Sstevel@tonic-gate char tmpbuf[MAX_CHARS_FOR_INT_TYPE(int) * 4 + 8]; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate days = (int) (deltat / (24*3600L)); 294*7c478bd9Sstevel@tonic-gate dt = deltat % (24*3600L); 295*7c478bd9Sstevel@tonic-gate hours = (int) (dt / 3600); 296*7c478bd9Sstevel@tonic-gate dt %= 3600; 297*7c478bd9Sstevel@tonic-gate minutes = (int) (dt / 60); 298*7c478bd9Sstevel@tonic-gate seconds = (int) (dt % 60); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate memset (tmpbuf, 0, sizeof (tmpbuf)); 301*7c478bd9Sstevel@tonic-gate if (days == 0) 302*7c478bd9Sstevel@tonic-gate sprintf(buffer, "%d:%02d:%02d", hours, minutes, seconds); 303*7c478bd9Sstevel@tonic-gate else if (hours || minutes || seconds) 304*7c478bd9Sstevel@tonic-gate sprintf(buffer, "%d %s %02d:%02d:%02d", days, 305*7c478bd9Sstevel@tonic-gate (days > 1) ? "days" : "day", 306*7c478bd9Sstevel@tonic-gate hours, minutes, seconds); 307*7c478bd9Sstevel@tonic-gate else 308*7c478bd9Sstevel@tonic-gate sprintf(buffer, "%d %s", days, 309*7c478bd9Sstevel@tonic-gate (days > 1) ? "days" : "day"); 310*7c478bd9Sstevel@tonic-gate if (tmpbuf[sizeof(tmpbuf)-1] != 0) 311*7c478bd9Sstevel@tonic-gate /* Something must be very wrong with my math above, or the 312*7c478bd9Sstevel@tonic-gate assumptions going into it... */ 313*7c478bd9Sstevel@tonic-gate abort (); 314*7c478bd9Sstevel@tonic-gate if (strlen (tmpbuf) > buflen) 315*7c478bd9Sstevel@tonic-gate return ENOMEM; 316*7c478bd9Sstevel@tonic-gate else 317*7c478bd9Sstevel@tonic-gate strncpy (buffer, tmpbuf, buflen); 318*7c478bd9Sstevel@tonic-gate return 0; 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate #endif /* SUNW_INC_DEAD_CODE */ 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate #undef __P 323*7c478bd9Sstevel@tonic-gate #define __P(X) X 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate #if !defined (HAVE_STRFTIME) || !defined (HAVE_STRPTIME) 326*7c478bd9Sstevel@tonic-gate #undef _CurrentTimeLocale 327*7c478bd9Sstevel@tonic-gate #define _CurrentTimeLocale (&dummy_locale_info) 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate struct dummy_locale_info_t { 330*7c478bd9Sstevel@tonic-gate char d_t_fmt[15]; 331*7c478bd9Sstevel@tonic-gate char t_fmt_ampm[12]; 332*7c478bd9Sstevel@tonic-gate char t_fmt[9]; 333*7c478bd9Sstevel@tonic-gate char d_fmt[9]; 334*7c478bd9Sstevel@tonic-gate char day[7][10]; 335*7c478bd9Sstevel@tonic-gate char abday[7][4]; 336*7c478bd9Sstevel@tonic-gate char mon[12][10]; 337*7c478bd9Sstevel@tonic-gate char abmon[12][4]; 338*7c478bd9Sstevel@tonic-gate char am_pm[2][3]; 339*7c478bd9Sstevel@tonic-gate }; 340*7c478bd9Sstevel@tonic-gate static const struct dummy_locale_info_t dummy_locale_info = { 341*7c478bd9Sstevel@tonic-gate "%a %b %d %X %Y", /* %c */ 342*7c478bd9Sstevel@tonic-gate "%I:%M:%S %p", /* %r */ 343*7c478bd9Sstevel@tonic-gate "%H:%M:%S", /* %X */ 344*7c478bd9Sstevel@tonic-gate "%m/%d/%y", /* %x */ 345*7c478bd9Sstevel@tonic-gate { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 346*7c478bd9Sstevel@tonic-gate "Saturday" }, 347*7c478bd9Sstevel@tonic-gate { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, 348*7c478bd9Sstevel@tonic-gate { "January", "February", "March", "April", "May", "June", 349*7c478bd9Sstevel@tonic-gate "July", "August", "September", "October", "November", "December" }, 350*7c478bd9Sstevel@tonic-gate { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 351*7c478bd9Sstevel@tonic-gate "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, 352*7c478bd9Sstevel@tonic-gate { "AM", "PM" }, 353*7c478bd9Sstevel@tonic-gate }; 354*7c478bd9Sstevel@tonic-gate #undef TM_YEAR_BASE 355*7c478bd9Sstevel@tonic-gate #define TM_YEAR_BASE 1900 356*7c478bd9Sstevel@tonic-gate #endif 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate #ifndef HAVE_STRFTIME 359*7c478bd9Sstevel@tonic-gate #undef DAYSPERLYEAR 360*7c478bd9Sstevel@tonic-gate #define DAYSPERLYEAR 366 361*7c478bd9Sstevel@tonic-gate #undef DAYSPERNYEAR 362*7c478bd9Sstevel@tonic-gate #define DAYSPERNYEAR 365 363*7c478bd9Sstevel@tonic-gate #undef DAYSPERWEEK 364*7c478bd9Sstevel@tonic-gate #define DAYSPERWEEK 7 365*7c478bd9Sstevel@tonic-gate #undef isleap 366*7c478bd9Sstevel@tonic-gate #define isleap(N) ((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0)) 367*7c478bd9Sstevel@tonic-gate #undef tzname 368*7c478bd9Sstevel@tonic-gate #define tzname my_tzname 369*7c478bd9Sstevel@tonic-gate static const char *const tzname[2] = { 0, 0 }; 370*7c478bd9Sstevel@tonic-gate #undef tzset 371*7c478bd9Sstevel@tonic-gate #define tzset() 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate #include "strftime.c" 374*7c478bd9Sstevel@tonic-gate #endif 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate #ifndef HAVE_STRPTIME 377*7c478bd9Sstevel@tonic-gate #include "strptime.c" 378*7c478bd9Sstevel@tonic-gate #endif 379