krb5 commit: Remove strftime() conditionalization

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/4ffb239bfc44396d72ac8c54103367aa4f9bd3e8
commit 4ffb239bfc44396d72ac8c54103367aa4f9bd3e8
Author: Greg Hudson <[email protected]>
Date:   Wed Sep 5 15:35:12 2018 -0400

    Remove strftime() conditionalization
    
    strftime() is specified in C89.  The tree has not built without a
    native strftime() at least as far back as 1.7 (because it is used
    unconditionally in kdb5_mkey.c) and possibly for much longer.  Remove
    the two copies of the NetBSD strftime.c and the fallback ctime() in
    logger.c.

 src/Makefile.in             |    2 -
 src/configure.in            |    4 +-
 src/kadmin/cli/strftime.c   |  465 -------------------------------------------
 src/lib/kadm5/logger.c      |   20 +--
 src/lib/krb5/krb/str_conv.c |   28 +---
 src/lib/krb5/krb/strftime.c |  416 --------------------------------------
 6 files changed, 5 insertions(+), 930 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index b57d058..08ca9fa 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -588,7 +588,6 @@ INDENTDIRS = \
 	util
 
 BSDFILES = \
-	kadmin/cli/strftime.c \
 	kadmin/server/ipropd_svc.c \
 	kadmin/server/kadm_rpc_svc.c \
 	lib/apputils/daemon.c \
@@ -597,7 +596,6 @@ BSDFILES = \
 	lib/kadm5/kadm_rpc.h \
 	lib/kadm5/kadm_rpc_xdr.c \
 	lib/kadm5/srv/adb_xdr.c \
-	lib/krb5/krb/strftime.c \
 	lib/krb5/krb/strptime.c \
 	slave/kpropd_rpc.c \
 	util/support/getopt.c \
diff --git a/src/configure.in b/src/configure.in
index cfa26eb..086ad52 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -148,7 +148,7 @@ AC_SUBST(po)
 
 # for kdc
 AC_CHECK_HEADERS(sys/sockio.h ifaddrs.h unistd.h fnmatch.h)
-AC_CHECK_FUNCS(strftime vsprintf vasprintf vsnprintf strlcpy fnmatch)
+AC_CHECK_FUNCS(vsprintf vasprintf vsnprintf strlcpy fnmatch)
 
 EXTRA_SUPPORT_SYMS=
 AC_CHECK_FUNC(strlcpy,
@@ -421,7 +421,7 @@ AC_PROG_LEX
 AC_C_CONST
 AC_HEADER_DIRENT
 AC_FUNC_STRERROR_R
-AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm)
+AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm)
 
 AC_CHECK_FUNC(mkstemp,
 [MKSTEMP_ST_OBJ=
diff --git a/src/kadmin/cli/strftime.c b/src/kadmin/cli/strftime.c
deleted file mode 100644
index 382a209..0000000
--- a/src/kadmin/cli/strftime.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
-/*	$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $	*/
-
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char *sccsid = "@(#)strftime.c	5.11 (Berkeley) 2/24/91";
-#else
-__RCSID("$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <string.h>
-#include <time.h>
-
-/* begin krb5 hack - replace stuff that would come from netbsd libc */
-#undef _CurrentTimeLocale
-#define _CurrentTimeLocale (&dummy_locale_info)
-
-struct dummy_locale_info_t {
-    char d_t_fmt[15];
-    char t_fmt_ampm[12];
-    char t_fmt[9];
-    char d_fmt[9];
-    char day[7][10];
-    char abday[7][4];
-    char mon[12][10];
-    char abmon[12][4];
-    char am_pm[2][3];
-};
-static const struct dummy_locale_info_t dummy_locale_info = {
-    "%a %b %d %X %Y",		/* %c */
-    "%I:%M:%S %p",		/* %r */
-    "%H:%M:%S",			/* %X */
-    "%m/%d/%y",			/* %x */
-    { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
-      "Saturday" },
-    { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
-    { "January", "February", "March", "April", "May", "June",
-      "July", "August", "September", "October", "November", "December" },
-    { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" },
-    { "AM", "PM" },
-};
-#undef  TM_YEAR_BASE
-#define TM_YEAR_BASE 1900
-
-#undef  DAYSPERLYEAR
-#define DAYSPERLYEAR 366
-#undef  DAYSPERNYEAR
-#define DAYSPERNYEAR 365
-#undef  DAYSPERWEEK
-#define DAYSPERWEEK 7
-#undef  isleap
-#define isleap(N)	((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0))
-#undef  tzname
-#define tzname my_tzname
-static const char *const tzname[2] = { 0, 0 };
-#undef  tzset
-#define tzset()
-#undef __P
-#define __P(X) X /* we already require ansi c in this tree */
-/* end krb5 hack */
-
-static	int _add __P((const char *, char **, const char *));
-static	int _conv __P((int, int, int, char **, const char *));
-static	int _secs __P((const struct tm *, char **, const char *));
-static	size_t _fmt __P((const char *, const struct tm *, char **,
-	    const char *));
-
-size_t
-strftime(s, maxsize, format, t)
-	char *s;
-	size_t maxsize;
-	const char *format;
-	const struct tm *t;
-{
-	char *pt;
-
-	tzset();
-	if (maxsize < 1)
-		return (0);
-
-	pt = s;
-	if (_fmt(format, t, &pt, s + maxsize)) {
-		*pt = '\0';
-		return (pt - s);
-	} else
-		return (0);
-}
-
-#define SUN_WEEK(t)	(((t)->tm_yday + 7 - \
-				((t)->tm_wday)) / 7)
-#define MON_WEEK(t)	(((t)->tm_yday + 7 - \
-				((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
-
-static size_t
-_fmt(format, t, pt, ptlim)
-	const char *format;
-	const struct tm *t;
-	char **pt;
-	const char * const ptlim;
-{
-	for (; *format; ++format) {
-		if (*format == '%') {
-			++format;
-			if (*format == 'E') {
-				/* Alternate Era */
-				++format;
-			} else if (*format == 'O') {
-				/* Alternate numeric symbols */
-				++format;
-			}
-			switch (*format) {
-			case '\0':
-				--format;
-				break;
-			case 'A':
-				if (t->tm_wday < 0 || t->tm_wday > 6)
-					return (0);
-				if (!_add(_CurrentTimeLocale->day[t->tm_wday],
-				    pt, ptlim))
-					return (0);
-				continue;
-
-			case 'a':
-				if (t->tm_wday < 0 || t->tm_wday > 6)
-					return (0);
-				if (!_add(_CurrentTimeLocale->abday[t->tm_wday],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'B':
-				if (t->tm_mon < 0 || t->tm_mon > 11)
-					return (0);
-				if (!_add(_CurrentTimeLocale->mon[t->tm_mon],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'b':
-			case 'h':
-				if (t->tm_mon < 0 || t->tm_mon > 11)
-					return (0);
-				if (!_add(_CurrentTimeLocale->abmon[t->tm_mon],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'C':
-				if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
-				    2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'c':
-				if (!_fmt(_CurrentTimeLocale->d_t_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'D':
-				if (!_fmt("%m/%d/%y", t, pt, ptlim))
-					return (0);
-				continue;
-			case 'd':
-				if (!_conv(t->tm_mday, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'e':
-				if (!_conv(t->tm_mday, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'H':
-				if (!_conv(t->tm_hour, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'I':
-				if (!_conv(t->tm_hour % 12 ?
-				    t->tm_hour % 12 : 12, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'j':
-				if (!_conv(t->tm_yday + 1, 3, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'k':
-				if (!_conv(t->tm_hour, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'l':
-				if (!_conv(t->tm_hour % 12 ?
-				    t->tm_hour % 12: 12, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'M':
-				if (!_conv(t->tm_min, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'm':
-				if (!_conv(t->tm_mon + 1, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'n':
-				if (!_add("\n", pt, ptlim))
-					return (0);
-				continue;
-			case 'p':
-				if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour
-				    >= 12], pt, ptlim))
-					return (0);
-				continue;
-			case 'R':
-				if (!_fmt("%H:%M", t, pt, ptlim))
-					return (0);
-				continue;
-			case 'r':
-				if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'S':
-				if (!_conv(t->tm_sec, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 's':
-				if (!_secs(t, pt, ptlim))
-					return (0);
-				continue;
-			case 'T':
-				if (!_fmt("%H:%M:%S", t, pt, ptlim))
-					return (0);
-				continue;
-			case 't':
-				if (!_add("\t", pt, ptlim))
-					return (0);
-				continue;
-			case 'U':
-				if (!_conv(SUN_WEEK(t), 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'u':
-				if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0',
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'V':	/* ISO 8601 week number */
-			case 'G':	/* ISO 8601 year (four digits) */
-			case 'g':	/* ISO 8601 year (two digits) */
-/*
-** From Arnold Robbins' strftime version 3.0:  "the week number of the
-** year (the first Monday as the first day of week 1) as a decimal number
-** (01-53)."
-** (ado, 1993-05-24)
-**
-** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
-** "Week 01 of a year is per definition the first week which has the
-** Thursday in this year, which is equivalent to the week which contains
-** the fourth day of January. In other words, the first week of a new year
-** is the week which has the majority of its days in the new year. Week 01
-** might also contain days from the previous year and the week before week
-** 01 of a year is the last week (52 or 53) of the previous year even if
-** it contains days from the new year. A week starts with Monday (day 1)
-** and ends with Sunday (day 7).  For example, the first week of the year
-** 1997 lasts from 1996-12-30 to 1997-01-05..."
-** (ado, 1996-01-02)
-*/
-				{
-					int	year;
-					int	yday;
-					int	wday;
-					int	w;
-
-					year = t->tm_year + TM_YEAR_BASE;
-					yday = t->tm_yday;
-					wday = t->tm_wday;
-					for ( ; ; ) {
-						int	len;
-						int	bot;
-						int	top;
-
-						len = isleap(year) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-						/*
-						** What yday (-3 ... 3) does
-						** the ISO year begin on?
-						*/
-						bot = ((yday + 11 - wday) %
-							DAYSPERWEEK) - 3;
-						/*
-						** What yday does the NEXT
-						** ISO year begin on?
-						*/
-						top = bot -
-							(len % DAYSPERWEEK);
-						if (top < -3)
-							top += DAYSPERWEEK;
-						top += len;
-						if (yday >= top) {
-							++year;
-							w = 1;
-							break;
-						}
-						if (yday >= bot) {
-							w = 1 + ((yday - bot) /
-								DAYSPERWEEK);
-							break;
-						}
-						--year;
-						yday += isleap(year) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-					}
-#ifdef XPG4_1994_04_09
-					if ((w == 52
-					     && t->tm_mon == TM_JANUARY)
-					    || (w == 1
-						&& t->tm_mon == TM_DECEMBER))
-						w = 53;
-#endif /* defined XPG4_1994_04_09 */
-					if (*format == 'V') {
-						if (!_conv(w, 2, '0',
-							pt, ptlim))
-							return (0);
-					} else if (*format == 'g') {
-						if (!_conv(year % 100, 2, '0',
-							pt, ptlim))
-							return (0);
-					} else	if (!_conv(year, 4, '0',
-							pt, ptlim))
-							return (0);
-				}
-				continue;
-			case 'W':
-				if (!_conv(MON_WEEK(t), 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'w':
-				if (!_conv(t->tm_wday, 1, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'x':
-				if (!_fmt(_CurrentTimeLocale->d_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'X':
-				if (!_fmt(_CurrentTimeLocale->t_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'y':
-				if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
-				    2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'Y':
-				if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0',
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'Z':
-				if (tzname[t->tm_isdst ? 1 : 0] &&
-				    !_add(tzname[t->tm_isdst ? 1 : 0], pt,
-				    ptlim))
-					return (0);
-				continue;
-			case '%':
-			/*
-			 * X311J/88-090 (4.12.3.5): if conversion char is
-			 * undefined, behavior is undefined.  Print out the
-			 * character itself as printf(3) does.
-			 */
-			default:
-				break;
-			}
-		}
-		if (*pt == ptlim)
-			return (0);
-		*(*pt)++ = *format;
-	}
-	return (ptlim - *pt);
-}
-
-static int
-_secs(t, pt, ptlim)
-	const struct tm *t;
-	char **pt;
-	const char * const ptlim;
-{
-	char buf[15];
-	time_t s;
-	char *p;
-	struct tm tmp;
-
-	buf[sizeof (buf) - 1] = '\0';
-	/* Make a copy, mktime(3) modifies the tm struct. */
-	tmp = *t;
-	s = mktime(&tmp);
-	for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
-		*p-- = (char)(s % 10 + '0');
-	return (_add(++p, pt, ptlim));
-}
-
-static int
-_conv(n, digits, pad, pt, ptlim)
-	int n, digits;
-	int pad;
-	char **pt;
-	const char * const ptlim;
-{
-	char buf[10];
-	char *p;
-
-	buf[sizeof (buf) - 1] = '\0';
-	for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
-		*p-- = n % 10 + '0';
-	while (p > buf && digits-- > 0)
-		*p-- = pad;
-	return (_add(++p, pt, ptlim));
-}
-
-static int
-_add(str, pt, ptlim)
-	const char *str;
-	char **pt;
-	const char * const ptlim;
-{
-
-	for (;; ++(*pt)) {
-		if (*pt == ptlim)
-			return (0);
-		if ((**pt = *str++) == '\0')
-			return (1);
-	}
-}
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
index 68fd82f..c6885ed 100644
--- a/src/lib/kadm5/logger.c
+++ b/src/lib/kadm5/logger.c
@@ -636,12 +636,8 @@ klog_vsyslog(int priority, const char *format, va_list arglist)
     char        *syslogp;
     char        *cp;
     time_t      now;
-#ifdef  HAVE_STRFTIME
     size_t      soff;
     struct tm  *tm;
-#else
-    char       *r;
-#endif
 
     /*
      * Format a syslog-esque message of the format:
@@ -654,7 +650,7 @@ klog_vsyslog(int priority, const char *format, va_list arglist)
      */
     cp = outbuf;
     (void) time(&now);
-#ifdef  HAVE_STRFTIME
+
     /*
      * Format the date: mon dd hh:mm:ss
      */
@@ -666,19 +662,7 @@ klog_vsyslog(int priority, const char *format, va_list arglist)
         cp += soff;
     else
         return(-1);
-#else   /* HAVE_STRFTIME */
-    /*
-     * Format the date:
-     * We ASSUME here that the output of ctime is of the format:
-     *  dow mon dd hh:mm:ss tzs yyyy\n
-     *  012345678901234567890123456789
-     */
-    r = ctime(&now);
-    if (r == NULL)
-        return(-1);
-    strncpy(outbuf, r + 4, 15);
-    cp += 15;
-#endif  /* HAVE_STRFTIME */
+
 #ifdef VERBOSE_LOGS
     snprintf(cp, sizeof(outbuf) - (cp-outbuf), " %s %s[%ld](%s): ",
              log_control.log_hostname ? log_control.log_hostname : "",
diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c
index efb3096..3d05724 100644
--- a/src/lib/krb5/krb/str_conv.c
+++ b/src/lib/krb5/krb/str_conv.c
@@ -117,12 +117,6 @@ krb5_salttype_to_string(krb5_int32 salttype, char *buffer, size_t buflen)
 
 /* (absolute) time conversions */
 
-#ifndef HAVE_STRFTIME
-#undef strftime
-#define strftime my_strftime
-static size_t strftime (char *, size_t, const char *, const struct tm *);
-#endif
-
 #ifdef HAVE_STRPTIME
 #ifdef NEED_STRPTIME_PROTO
 extern char *strptime (const char *, const char *,
@@ -291,7 +285,7 @@ krb5_deltat_to_string(krb5_deltat deltat, char *buffer, size_t buflen)
 #undef __P
 #define __P(X) X
 
-#if !defined (HAVE_STRFTIME) || !defined (HAVE_STRPTIME)
+#ifndef HAVE_STRPTIME
 #undef _CurrentTimeLocale
 #define _CurrentTimeLocale (&dummy_locale_info)
 
@@ -322,26 +316,6 @@ static const struct dummy_locale_info_t dummy_locale_info = {
 };
 #undef  TM_YEAR_BASE
 #define TM_YEAR_BASE 1900
-#endif
 
-#ifndef HAVE_STRFTIME
-#undef  DAYSPERLYEAR
-#define DAYSPERLYEAR 366
-#undef  DAYSPERNYEAR
-#define DAYSPERNYEAR 365
-#undef  DAYSPERWEEK
-#define DAYSPERWEEK 7
-#undef  isleap
-#define isleap(N)       ((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0))
-#undef  tzname
-#define tzname my_tzname
-static const char *const tzname[2] = { 0, 0 };
-#undef  tzset
-#define tzset()
-
-#include "strftime.c"
-#endif
-
-#ifndef HAVE_STRPTIME
 #include "strptime.c"
 #endif
diff --git a/src/lib/krb5/krb/strftime.c b/src/lib/krb5/krb/strftime.c
deleted file mode 100644
index 65c5e7a..0000000
--- a/src/lib/krb5/krb/strftime.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
-/*	$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $	*/
-
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char *sccsid = "@(#)strftime.c	5.11 (Berkeley) 2/24/91";
-#else
-__RCSID("$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <string.h>
-#include <time.h>
-
-static	int _add __P((const char *, char **, const char *));
-static	int _conv __P((int, int, int, char **, const char *));
-static	int _secs __P((const struct tm *, char **, const char *));
-static	size_t _fmt __P((const char *, const struct tm *, char **,
-	    const char *));
-
-static size_t
-strftime(s, maxsize, format, t)
-	char *s;
-	size_t maxsize;
-	const char *format;
-	const struct tm *t;
-{
-	char *pt;
-
-	tzset();
-	if (maxsize < 1)
-		return (0);
-
-	pt = s;
-	if (_fmt(format, t, &pt, s + maxsize)) {
-		*pt = '\0';
-		return (pt - s);
-	} else
-		return (0);
-}
-
-#define SUN_WEEK(t)	(((t)->tm_yday + 7 - \
-				((t)->tm_wday)) / 7)
-#define MON_WEEK(t)	(((t)->tm_yday + 7 - \
-				((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
-
-static size_t
-_fmt(format, t, pt, ptlim)
-	const char *format;
-	const struct tm *t;
-	char **pt;
-	const char * const ptlim;
-{
-	for (; *format; ++format) {
-		if (*format == '%') {
-			++format;
-			if (*format == 'E') {
-				/* Alternate Era */
-				++format;
-			} else if (*format == 'O') {
-				/* Alternate numeric symbols */
-				++format;
-			}
-			switch (*format) {
-			case '\0':
-				--format;
-				break;
-			case 'A':
-				if (t->tm_wday < 0 || t->tm_wday > 6)
-					return (0);
-				if (!_add(_CurrentTimeLocale->day[t->tm_wday],
-				    pt, ptlim))
-					return (0);
-				continue;
-
-			case 'a':
-				if (t->tm_wday < 0 || t->tm_wday > 6)
-					return (0);
-				if (!_add(_CurrentTimeLocale->abday[t->tm_wday],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'B':
-				if (t->tm_mon < 0 || t->tm_mon > 11)
-					return (0);
-				if (!_add(_CurrentTimeLocale->mon[t->tm_mon],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'b':
-			case 'h':
-				if (t->tm_mon < 0 || t->tm_mon > 11)
-					return (0);
-				if (!_add(_CurrentTimeLocale->abmon[t->tm_mon],
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'C':
-				if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
-				    2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'c':
-				if (!_fmt(_CurrentTimeLocale->d_t_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'D':
-				if (!_fmt("%m/%d/%y", t, pt, ptlim))
-					return (0);
-				continue;
-			case 'd':
-				if (!_conv(t->tm_mday, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'e':
-				if (!_conv(t->tm_mday, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'H':
-				if (!_conv(t->tm_hour, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'I':
-				if (!_conv(t->tm_hour % 12 ?
-				    t->tm_hour % 12 : 12, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'j':
-				if (!_conv(t->tm_yday + 1, 3, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'k':
-				if (!_conv(t->tm_hour, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'l':
-				if (!_conv(t->tm_hour % 12 ?
-				    t->tm_hour % 12: 12, 2, ' ', pt, ptlim))
-					return (0);
-				continue;
-			case 'M':
-				if (!_conv(t->tm_min, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'm':
-				if (!_conv(t->tm_mon + 1, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'n':
-				if (!_add("\n", pt, ptlim))
-					return (0);
-				continue;
-			case 'p':
-				if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour
-				    >= 12], pt, ptlim))
-					return (0);
-				continue;
-			case 'R':
-				if (!_fmt("%H:%M", t, pt, ptlim))
-					return (0);
-				continue;
-			case 'r':
-				if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'S':
-				if (!_conv(t->tm_sec, 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 's':
-				if (!_secs(t, pt, ptlim))
-					return (0);
-				continue;
-			case 'T':
-				if (!_fmt("%H:%M:%S", t, pt, ptlim))
-					return (0);
-				continue;
-			case 't':
-				if (!_add("\t", pt, ptlim))
-					return (0);
-				continue;
-			case 'U':
-				if (!_conv(SUN_WEEK(t), 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'u':
-				if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0',
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'V':	/* ISO 8601 week number */
-			case 'G':	/* ISO 8601 year (four digits) */
-			case 'g':	/* ISO 8601 year (two digits) */
-/*
-** From Arnold Robbins' strftime version 3.0:  "the week number of the
-** year (the first Monday as the first day of week 1) as a decimal number
-** (01-53)."
-** (ado, 1993-05-24)
-**
-** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
-** "Week 01 of a year is per definition the first week which has the
-** Thursday in this year, which is equivalent to the week which contains
-** the fourth day of January. In other words, the first week of a new year
-** is the week which has the majority of its days in the new year. Week 01
-** might also contain days from the previous year and the week before week
-** 01 of a year is the last week (52 or 53) of the previous year even if
-** it contains days from the new year. A week starts with Monday (day 1)
-** and ends with Sunday (day 7).  For example, the first week of the year
-** 1997 lasts from 1996-12-30 to 1997-01-05..."
-** (ado, 1996-01-02)
-*/
-				{
-					int	year;
-					int	yday;
-					int	wday;
-					int	w;
-
-					year = t->tm_year + TM_YEAR_BASE;
-					yday = t->tm_yday;
-					wday = t->tm_wday;
-					for ( ; ; ) {
-						int	len;
-						int	bot;
-						int	top;
-
-						len = isleap(year) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-						/*
-						** What yday (-3 ... 3) does
-						** the ISO year begin on?
-						*/
-						bot = ((yday + 11 - wday) %
-							DAYSPERWEEK) - 3;
-						/*
-						** What yday does the NEXT
-						** ISO year begin on?
-						*/
-						top = bot -
-							(len % DAYSPERWEEK);
-						if (top < -3)
-							top += DAYSPERWEEK;
-						top += len;
-						if (yday >= top) {
-							++year;
-							w = 1;
-							break;
-						}
-						if (yday >= bot) {
-							w = 1 + ((yday - bot) /
-								DAYSPERWEEK);
-							break;
-						}
-						--year;
-						yday += isleap(year) ?
-							DAYSPERLYEAR :
-							DAYSPERNYEAR;
-					}
-#ifdef XPG4_1994_04_09
-					if ((w == 52
-					     && t->tm_mon == TM_JANUARY)
-					    || (w == 1
-						&& t->tm_mon == TM_DECEMBER))
-						w = 53;
-#endif /* defined XPG4_1994_04_09 */
-					if (*format == 'V') {
-						if (!_conv(w, 2, '0',
-							pt, ptlim))
-							return (0);
-					} else if (*format == 'g') {
-						if (!_conv(year % 100, 2, '0',
-							pt, ptlim))
-							return (0);
-					} else	if (!_conv(year, 4, '0',
-							pt, ptlim))
-							return (0);
-				}
-				continue;
-			case 'W':
-				if (!_conv(MON_WEEK(t), 2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'w':
-				if (!_conv(t->tm_wday, 1, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'x':
-				if (!_fmt(_CurrentTimeLocale->d_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'X':
-				if (!_fmt(_CurrentTimeLocale->t_fmt, t, pt,
-				    ptlim))
-					return (0);
-				continue;
-			case 'y':
-				if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
-				    2, '0', pt, ptlim))
-					return (0);
-				continue;
-			case 'Y':
-				if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0',
-				    pt, ptlim))
-					return (0);
-				continue;
-			case 'Z':
-				if (tzname[t->tm_isdst ? 1 : 0] &&
-				    !_add(tzname[t->tm_isdst ? 1 : 0], pt,
-				    ptlim))
-					return (0);
-				continue;
-			case '%':
-			/*
-			 * X311J/88-090 (4.12.3.5): if conversion char is
-			 * undefined, behavior is undefined.  Print out the
-			 * character itself as printf(3) does.
-			 */
-			default:
-				break;
-			}
-		}
-		if (*pt == ptlim)
-			return (0);
-		*(*pt)++ = *format;
-	}
-	return (ptlim - *pt);
-}
-
-static int
-_secs(t, pt, ptlim)
-	const struct tm *t;
-	char **pt;
-	const char * const ptlim;
-{
-	char buf[15];
-	time_t s;
-	char *p;
-	struct tm tmp;
-
-	buf[sizeof (buf) - 1] = '\0';
-	/* Make a copy, mktime(3) modifies the tm struct. */
-	tmp = *t;
-	s = mktime(&tmp);
-	for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
-		*p-- = (char)(s % 10 + '0');
-	return (_add(++p, pt, ptlim));
-}
-
-static int
-_conv(n, digits, pad, pt, ptlim)
-	int n, digits;
-	int pad;
-	char **pt;
-	const char * const ptlim;
-{
-	char buf[10];
-	char *p;
-
-	buf[sizeof (buf) - 1] = '\0';
-	for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
-		*p-- = n % 10 + '0';
-	while (p > buf && digits-- > 0)
-		*p-- = pad;
-	return (_add(++p, pt, ptlim));
-}
-
-static int
-_add(str, pt, ptlim)
-	const char *str;
-	char **pt;
-	const char * const ptlim;
-{
-
-	for (;; ++(*pt)) {
-		if (*pt == ptlim)
-			return (0);
-		if ((**pt = *str++) == '\0')
-			return (1);
-	}
-}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.