xref: /illumos-gate/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/str_conv.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
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(&timestamp2, &tmbuf);
224505d05c7Sgtb #else
225505d05c7Sgtb     memcpy(&tmbuf, localtime(&timestamp2), 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(&timestamp2, &tmbuf);
253505d05c7Sgtb #else
254505d05c7Sgtb     memcpy((tmp = &tmbuf), localtime(&timestamp2), 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