17c478bd9Sstevel@tonic-gate /* 2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate /* 87c478bd9Sstevel@tonic-gate * lib/kadm/str_conv.c 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * Copyright 1995, 1999 by the Massachusetts Institute of Technology. 117c478bd9Sstevel@tonic-gate * All Rights Reserved. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 177c478bd9Sstevel@tonic-gate * 187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 307c478bd9Sstevel@tonic-gate * or implied warranty. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * str_conv.c - Convert between strings and Kerberos internal data. 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * Table of contents: 407c478bd9Sstevel@tonic-gate * 417c478bd9Sstevel@tonic-gate * String decoding: 427c478bd9Sstevel@tonic-gate * ---------------- 437c478bd9Sstevel@tonic-gate * krb5_string_to_salttype() - Convert string to salttype (krb5_int32) 447c478bd9Sstevel@tonic-gate * krb5_string_to_timestamp() - Convert string to krb5_timestamp. 457c478bd9Sstevel@tonic-gate * krb5_string_to_deltat() - Convert string to krb5_deltat. 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * String encoding: 487c478bd9Sstevel@tonic-gate * ---------------- 497c478bd9Sstevel@tonic-gate * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string. 507c478bd9Sstevel@tonic-gate * krb5_timestamp_to_string() - Convert krb5_timestamp to string. 517c478bd9Sstevel@tonic-gate * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string 527c478bd9Sstevel@tonic-gate * krb5_deltat_to_string() - Convert krb5_deltat to string. 537c478bd9Sstevel@tonic-gate */ 547c478bd9Sstevel@tonic-gate 55505d05c7Sgtb #include "k5-int.h" 56505d05c7Sgtb #include <ctype.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* Salt type conversions */ 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* 617c478bd9Sstevel@tonic-gate * Local data structures. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate struct salttype_lookup_entry { 647c478bd9Sstevel@tonic-gate krb5_int32 stt_enctype; /* Salt type */ 657c478bd9Sstevel@tonic-gate const char * stt_specifier; /* How to recognize it */ 667c478bd9Sstevel@tonic-gate const char * stt_output; /* How to spit it out */ 677c478bd9Sstevel@tonic-gate }; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 707c478bd9Sstevel@tonic-gate * Lookup tables. 717c478bd9Sstevel@tonic-gate */ 72*159d09a2SMark Phalan 73*159d09a2SMark Phalan #include "kdb.h" 747c478bd9Sstevel@tonic-gate static const struct salttype_lookup_entry salttype_table[] = { 757c478bd9Sstevel@tonic-gate /* salt type input specifier output string */ 767c478bd9Sstevel@tonic-gate /*----------------------------- --------------- ---------------*/ 777c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NORMAL, "normal", "Version 5" }, 787c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_V4, "v4", "Version 4" }, 797c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NOREALM, "norealm", "Version 5 - No Realm" }, 807c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_ONLYREALM, "onlyrealm", "Version 5 - Realm Only" }, 817c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_SPECIAL, "special", "Special" }, 827c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_AFS3, "afs3", "AFS version 3" } 837c478bd9Sstevel@tonic-gate }; 847c478bd9Sstevel@tonic-gate static const int salttype_table_nents = sizeof(salttype_table)/ 857c478bd9Sstevel@tonic-gate sizeof(salttype_table[0]); 867c478bd9Sstevel@tonic-gate 87505d05c7Sgtb krb5_error_code KRB5_CALLCONV 88505d05c7Sgtb krb5_string_to_salttype(char *string, krb5_int32 *salttypep) 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate int i; 917c478bd9Sstevel@tonic-gate int found; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate found = 0; 947c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) { 957c478bd9Sstevel@tonic-gate if (!strcasecmp(string, salttype_table[i].stt_specifier)) { 967c478bd9Sstevel@tonic-gate found = 1; 977c478bd9Sstevel@tonic-gate *salttypep = salttype_table[i].stt_enctype; 987c478bd9Sstevel@tonic-gate break; 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate return((found) ? 0 : EINVAL); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * Internal datatype to string routines. 1067c478bd9Sstevel@tonic-gate * 1077c478bd9Sstevel@tonic-gate * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM 1087c478bd9Sstevel@tonic-gate * if the supplied buffer/length will not contain the output. 1097c478bd9Sstevel@tonic-gate */ 110505d05c7Sgtb krb5_error_code KRB5_CALLCONV 111505d05c7Sgtb krb5_salttype_to_string(krb5_int32 salttype, char *buffer, size_t buflen) 1127c478bd9Sstevel@tonic-gate { 1137c478bd9Sstevel@tonic-gate int i; 1147c478bd9Sstevel@tonic-gate const char *out; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate out = (char *) NULL; 1177c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) { 1187c478bd9Sstevel@tonic-gate if (salttype == salttype_table[i].stt_enctype) { 1197c478bd9Sstevel@tonic-gate out = salttype_table[i].stt_output; 1207c478bd9Sstevel@tonic-gate break; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate if (out) { 1247c478bd9Sstevel@tonic-gate if (buflen > strlen(out)) 1257c478bd9Sstevel@tonic-gate strcpy(buffer, out); 1267c478bd9Sstevel@tonic-gate else 1277c478bd9Sstevel@tonic-gate out = (char *) NULL; 1287c478bd9Sstevel@tonic-gate return((out) ? 0 : ENOMEM); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate else 1317c478bd9Sstevel@tonic-gate return(EINVAL); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* (absolute) time conversions */ 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate #ifndef HAVE_STRFTIME 1377c478bd9Sstevel@tonic-gate #undef strftime 1387c478bd9Sstevel@tonic-gate #define strftime my_strftime 1397c478bd9Sstevel@tonic-gate static size_t strftime (char *, size_t, const char *, const struct tm *); 1407c478bd9Sstevel@tonic-gate #endif 1417c478bd9Sstevel@tonic-gate 142505d05c7Sgtb #ifdef HAVE_STRPTIME 143505d05c7Sgtb #ifdef NEED_STRPTIME_PROTO 144505d05c7Sgtb extern char *strptime (const char *, const char *, 145505d05c7Sgtb struct tm *) 146505d05c7Sgtb #ifdef __cplusplus 147505d05c7Sgtb throw() 148505d05c7Sgtb #endif 149505d05c7Sgtb ; 150505d05c7Sgtb #endif 151505d05c7Sgtb #else /* HAVE_STRPTIME */ 1527c478bd9Sstevel@tonic-gate #undef strptime 1537c478bd9Sstevel@tonic-gate #define strptime my_strptime 1547c478bd9Sstevel@tonic-gate static char *strptime (const char *, const char *, struct tm *); 1557c478bd9Sstevel@tonic-gate #endif 1567c478bd9Sstevel@tonic-gate 157505d05c7Sgtb krb5_error_code KRB5_CALLCONV 158505d05c7Sgtb krb5_string_to_timestamp(char *string, krb5_timestamp *timestampp) 1597c478bd9Sstevel@tonic-gate { 160505d05c7Sgtb int i; 161505d05c7Sgtb struct tm timebuf; 162505d05c7Sgtb time_t now, ret_time; 1637c478bd9Sstevel@tonic-gate char *s; 1647c478bd9Sstevel@tonic-gate static const char * const atime_format_table[] = { 165*159d09a2SMark Phalan "%Y%m%d%H%M%S", /* yyyymmddhhmmss */ 1667c478bd9Sstevel@tonic-gate "%Y.%m.%d.%H.%M.%S", /* yyyy.mm.dd.hh.mm.ss */ 167*159d09a2SMark Phalan "%y%m%d%H%M%S", /* yymmddhhmmss */ 1687c478bd9Sstevel@tonic-gate "%y.%m.%d.%H.%M.%S", /* yy.mm.dd.hh.mm.ss */ 169*159d09a2SMark Phalan "%y%m%d%H%M", /* yymmddhhmm */ 170*159d09a2SMark Phalan "%H%M%S", /* hhmmss */ 171*159d09a2SMark Phalan "%H%M", /* hhmm */ 1727c478bd9Sstevel@tonic-gate "%T", /* hh:mm:ss */ 1737c478bd9Sstevel@tonic-gate "%R", /* hh:mm */ 1747c478bd9Sstevel@tonic-gate /* The following not really supported unless native strptime present */ 1757c478bd9Sstevel@tonic-gate "%x:%X", /* locale-dependent short format */ 1767c478bd9Sstevel@tonic-gate "%d-%b-%Y:%T", /* dd-month-yyyy:hh:mm:ss */ 1777c478bd9Sstevel@tonic-gate "%d-%b-%Y:%R" /* dd-month-yyyy:hh:mm */ 1787c478bd9Sstevel@tonic-gate }; 1797c478bd9Sstevel@tonic-gate static const int atime_format_table_nents = 1807c478bd9Sstevel@tonic-gate sizeof(atime_format_table)/sizeof(atime_format_table[0]); 1817c478bd9Sstevel@tonic-gate 182505d05c7Sgtb 183505d05c7Sgtb now = time((time_t *) NULL); 1847c478bd9Sstevel@tonic-gate for (i=0; i<atime_format_table_nents; i++) { 185505d05c7Sgtb /* We reset every time throughout the loop as the manual page 186505d05c7Sgtb * indicated that no guarantees are made as to preserving timebuf 187505d05c7Sgtb * when parsing fails 188505d05c7Sgtb */ 189505d05c7Sgtb #ifdef HAVE_LOCALTIME_R 190505d05c7Sgtb (void) localtime_r(&now, &timebuf); 191505d05c7Sgtb #else 192505d05c7Sgtb memcpy(&timebuf, localtime(&now), sizeof(timebuf)); 193505d05c7Sgtb #endif 19454925bf6Swillf /*LINTED*/ 195505d05c7Sgtb if ((s = strptime(string, atime_format_table[i], &timebuf)) 196505d05c7Sgtb && (s != string)) { 197505d05c7Sgtb /* See if at end of buffer - otherwise partial processing */ 198505d05c7Sgtb while(*s != 0 && isspace((int) *s)) s++; 199505d05c7Sgtb if (*s != 0) 200505d05c7Sgtb continue; 201505d05c7Sgtb if (timebuf.tm_year <= 0) 202505d05c7Sgtb continue; /* clearly confused */ 203505d05c7Sgtb ret_time = mktime(&timebuf); 204505d05c7Sgtb if (ret_time == (time_t) -1) 205505d05c7Sgtb continue; /* clearly confused */ 206505d05c7Sgtb *timestampp = (krb5_timestamp) ret_time; 207505d05c7Sgtb return 0; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate } 210505d05c7Sgtb return(EINVAL); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 213505d05c7Sgtb krb5_error_code KRB5_CALLCONV 214505d05c7Sgtb krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate int ret; 2177c478bd9Sstevel@tonic-gate time_t timestamp2 = timestamp; 218505d05c7Sgtb struct tm tmbuf; 219505d05c7Sgtb const char *fmt = "%c"; /* This is to get around gcc -Wall warning that 220505d05c7Sgtb the year returned might be two digits */ 2217c478bd9Sstevel@tonic-gate 222505d05c7Sgtb #ifdef HAVE_LOCALTIME_R 223505d05c7Sgtb (void) localtime_r(×tamp2, &tmbuf); 224505d05c7Sgtb #else 225505d05c7Sgtb memcpy(&tmbuf, localtime(×tamp2), sizeof(tmbuf)); 226505d05c7Sgtb #endif 227505d05c7Sgtb ret = strftime(buffer, buflen, fmt, &tmbuf); 2287c478bd9Sstevel@tonic-gate if (ret == 0 || ret == buflen) 2297c478bd9Sstevel@tonic-gate return(ENOMEM); 2307c478bd9Sstevel@tonic-gate return(0); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 233505d05c7Sgtb krb5_error_code KRB5_CALLCONV 234505d05c7Sgtb krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen, char *pad) 2357c478bd9Sstevel@tonic-gate { 2367c478bd9Sstevel@tonic-gate struct tm *tmp; 2377c478bd9Sstevel@tonic-gate size_t i; 2387c478bd9Sstevel@tonic-gate size_t ndone; 2397c478bd9Sstevel@tonic-gate time_t timestamp2 = timestamp; 240505d05c7Sgtb struct tm tmbuf; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate static const char * const sftime_format_table[] = { 2437c478bd9Sstevel@tonic-gate "%c", /* Default locale-dependent date and time */ 2447c478bd9Sstevel@tonic-gate "%d %b %Y %T", /* dd mon yyyy hh:mm:ss */ 2457c478bd9Sstevel@tonic-gate "%x %X", /* locale-dependent short format */ 2467c478bd9Sstevel@tonic-gate "%d/%m/%Y %R" /* dd/mm/yyyy hh:mm */ 2477c478bd9Sstevel@tonic-gate }; 2487c478bd9Sstevel@tonic-gate static const int sftime_format_table_nents = 2497c478bd9Sstevel@tonic-gate sizeof(sftime_format_table)/sizeof(sftime_format_table[0]); 2507c478bd9Sstevel@tonic-gate 251505d05c7Sgtb #ifdef HAVE_LOCALTIME_R 252505d05c7Sgtb tmp = localtime_r(×tamp2, &tmbuf); 253505d05c7Sgtb #else 254505d05c7Sgtb memcpy((tmp = &tmbuf), localtime(×tamp2), sizeof(tmbuf)); 255505d05c7Sgtb #endif 2567c478bd9Sstevel@tonic-gate ndone = 0; 2577c478bd9Sstevel@tonic-gate for (i=0; i<sftime_format_table_nents; i++) { 2587c478bd9Sstevel@tonic-gate if ((ndone = strftime(buffer, buflen, sftime_format_table[i], tmp))) 2597c478bd9Sstevel@tonic-gate break; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate if (!ndone) { 2627c478bd9Sstevel@tonic-gate #define sftime_default_len 2+1+2+1+4+1+2+1+2+1 2637c478bd9Sstevel@tonic-gate if (buflen >= sftime_default_len) { 2647c478bd9Sstevel@tonic-gate sprintf(buffer, "%02d/%02d/%4d %02d:%02d", 2657c478bd9Sstevel@tonic-gate tmp->tm_mday, tmp->tm_mon+1, 1900+tmp->tm_year, 2667c478bd9Sstevel@tonic-gate tmp->tm_hour, tmp->tm_min); 2677c478bd9Sstevel@tonic-gate ndone = strlen(buffer); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate if (ndone && pad) { 2717c478bd9Sstevel@tonic-gate for (i=ndone; i<buflen-1; i++) 2727c478bd9Sstevel@tonic-gate buffer[i] = *pad; 2737c478bd9Sstevel@tonic-gate buffer[buflen-1] = '\0'; 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate return((ndone) ? 0 : ENOMEM); 2767c478bd9Sstevel@tonic-gate } 277505d05c7Sgtb 278*159d09a2SMark Phalan /* Solaris Kerberos */ 2797c478bd9Sstevel@tonic-gate #ifdef SUNW_INC_DEAD_CODE 2807c478bd9Sstevel@tonic-gate /* relative time (delta-t) conversions */ 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* string->deltat is in deltat.y */ 2837c478bd9Sstevel@tonic-gate 284505d05c7Sgtb krb5_error_code KRB5_CALLCONV 285505d05c7Sgtb krb5_deltat_to_string(krb5_deltat deltat, char *buffer, size_t buflen) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate int days, hours, minutes, seconds; 2887c478bd9Sstevel@tonic-gate krb5_deltat dt; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* 2917c478bd9Sstevel@tonic-gate * We want something like ceil(log10(2**(nbits-1))) + 1. That log 2927c478bd9Sstevel@tonic-gate * value is log10(2)*(nbits-1) or log10(2**8)*(nbits-1)/8. So, 2937c478bd9Sstevel@tonic-gate * 2.4... is log10(256), rounded up. Add one to handle leading 2947c478bd9Sstevel@tonic-gate * minus, and one more to force int cast to round the value up. 2957c478bd9Sstevel@tonic-gate * This doesn't include room for a trailing nul. 2967c478bd9Sstevel@tonic-gate * 2977c478bd9Sstevel@tonic-gate * This will break if bytes are more than 8 bits. 2987c478bd9Sstevel@tonic-gate */ 2997c478bd9Sstevel@tonic-gate #define MAX_CHARS_FOR_INT_TYPE(TYPE) ((int) (2 + 2.408241 * sizeof (TYPE))) 3007c478bd9Sstevel@tonic-gate char tmpbuf[MAX_CHARS_FOR_INT_TYPE(int) * 4 + 8]; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate days = (int) (deltat / (24*3600L)); 3037c478bd9Sstevel@tonic-gate dt = deltat % (24*3600L); 3047c478bd9Sstevel@tonic-gate hours = (int) (dt / 3600); 3057c478bd9Sstevel@tonic-gate dt %= 3600; 3067c478bd9Sstevel@tonic-gate minutes = (int) (dt / 60); 3077c478bd9Sstevel@tonic-gate seconds = (int) (dt % 60); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate memset (tmpbuf, 0, sizeof (tmpbuf)); 3107c478bd9Sstevel@tonic-gate if (days == 0) 3117c478bd9Sstevel@tonic-gate sprintf(buffer, "%d:%02d:%02d", hours, minutes, seconds); 3127c478bd9Sstevel@tonic-gate else if (hours || minutes || seconds) 3137c478bd9Sstevel@tonic-gate sprintf(buffer, "%d %s %02d:%02d:%02d", days, 3147c478bd9Sstevel@tonic-gate (days > 1) ? "days" : "day", 3157c478bd9Sstevel@tonic-gate hours, minutes, seconds); 3167c478bd9Sstevel@tonic-gate else 3177c478bd9Sstevel@tonic-gate sprintf(buffer, "%d %s", days, 3187c478bd9Sstevel@tonic-gate (days > 1) ? "days" : "day"); 3197c478bd9Sstevel@tonic-gate if (tmpbuf[sizeof(tmpbuf)-1] != 0) 3207c478bd9Sstevel@tonic-gate /* Something must be very wrong with my math above, or the 3217c478bd9Sstevel@tonic-gate assumptions going into it... */ 3227c478bd9Sstevel@tonic-gate abort (); 3237c478bd9Sstevel@tonic-gate if (strlen (tmpbuf) > buflen) 3247c478bd9Sstevel@tonic-gate return ENOMEM; 3257c478bd9Sstevel@tonic-gate else 3267c478bd9Sstevel@tonic-gate strncpy (buffer, tmpbuf, buflen); 3277c478bd9Sstevel@tonic-gate return 0; 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate #endif /* SUNW_INC_DEAD_CODE */ 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate #undef __P 3327c478bd9Sstevel@tonic-gate #define __P(X) X 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate #if !defined (HAVE_STRFTIME) || !defined (HAVE_STRPTIME) 3357c478bd9Sstevel@tonic-gate #undef _CurrentTimeLocale 3367c478bd9Sstevel@tonic-gate #define _CurrentTimeLocale (&dummy_locale_info) 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate struct dummy_locale_info_t { 3397c478bd9Sstevel@tonic-gate char d_t_fmt[15]; 3407c478bd9Sstevel@tonic-gate char t_fmt_ampm[12]; 3417c478bd9Sstevel@tonic-gate char t_fmt[9]; 3427c478bd9Sstevel@tonic-gate char d_fmt[9]; 3437c478bd9Sstevel@tonic-gate char day[7][10]; 3447c478bd9Sstevel@tonic-gate char abday[7][4]; 3457c478bd9Sstevel@tonic-gate char mon[12][10]; 3467c478bd9Sstevel@tonic-gate char abmon[12][4]; 3477c478bd9Sstevel@tonic-gate char am_pm[2][3]; 3487c478bd9Sstevel@tonic-gate }; 3497c478bd9Sstevel@tonic-gate static const struct dummy_locale_info_t dummy_locale_info = { 3507c478bd9Sstevel@tonic-gate "%a %b %d %X %Y", /* %c */ 3517c478bd9Sstevel@tonic-gate "%I:%M:%S %p", /* %r */ 3527c478bd9Sstevel@tonic-gate "%H:%M:%S", /* %X */ 3537c478bd9Sstevel@tonic-gate "%m/%d/%y", /* %x */ 3547c478bd9Sstevel@tonic-gate { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 3557c478bd9Sstevel@tonic-gate "Saturday" }, 3567c478bd9Sstevel@tonic-gate { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, 3577c478bd9Sstevel@tonic-gate { "January", "February", "March", "April", "May", "June", 3587c478bd9Sstevel@tonic-gate "July", "August", "September", "October", "November", "December" }, 3597c478bd9Sstevel@tonic-gate { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 3607c478bd9Sstevel@tonic-gate "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, 3617c478bd9Sstevel@tonic-gate { "AM", "PM" }, 3627c478bd9Sstevel@tonic-gate }; 3637c478bd9Sstevel@tonic-gate #undef TM_YEAR_BASE 3647c478bd9Sstevel@tonic-gate #define TM_YEAR_BASE 1900 3657c478bd9Sstevel@tonic-gate #endif 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate #ifndef HAVE_STRFTIME 3687c478bd9Sstevel@tonic-gate #undef DAYSPERLYEAR 3697c478bd9Sstevel@tonic-gate #define DAYSPERLYEAR 366 3707c478bd9Sstevel@tonic-gate #undef DAYSPERNYEAR 3717c478bd9Sstevel@tonic-gate #define DAYSPERNYEAR 365 3727c478bd9Sstevel@tonic-gate #undef DAYSPERWEEK 3737c478bd9Sstevel@tonic-gate #define DAYSPERWEEK 7 3747c478bd9Sstevel@tonic-gate #undef isleap 3757c478bd9Sstevel@tonic-gate #define isleap(N) ((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0)) 3767c478bd9Sstevel@tonic-gate #undef tzname 3777c478bd9Sstevel@tonic-gate #define tzname my_tzname 3787c478bd9Sstevel@tonic-gate static const char *const tzname[2] = { 0, 0 }; 3797c478bd9Sstevel@tonic-gate #undef tzset 3807c478bd9Sstevel@tonic-gate #define tzset() 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate #include "strftime.c" 3837c478bd9Sstevel@tonic-gate #endif 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate #ifndef HAVE_STRPTIME 3867c478bd9Sstevel@tonic-gate #include "strptime.c" 3877c478bd9Sstevel@tonic-gate #endif 388