#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char elsieid[] = "@(#)asctime.c 8.5";
#else
__RCSID("$NetBSD: asctime.c,v 1.32 2025/01/23 22:44:22 christos Exp $");
#endif
#endif
#include "namespace.h"
#include "private.h"
#include <stdio.h>
#if SUPPORT_POSIX2008 || defined(__NetBSD__)
# define asctime_static
#else
# define asctime_static static
# undef asctime_r
# undef ctime_r
# define asctime_r static_asctime_r
# define ctime_r static_ctime_r
#endif
#ifndef __LIBC12_SOURCE__
#ifdef __weak_alias
__weak_alias(asctime_r,_asctime_r)
#endif
enum { STD_ASCTIME_BUF_SIZE = 26 };
static char buf_asctime[2*3 + 5*INT_STRLEN_MAXIMUM(int) + 7 + 2 + 1 + 1];
#if !HAVE_SNPRINTF
# include <stdarg.h>
ATTRIBUTE_FORMAT((printf, 3, 4)) static int
my_snprintf(char *s, size_t size, char const *format, ...)
{
int n;
va_list args;
char stackbuf[sizeof buf_asctime];
va_start(args, format);
n = vsprintf(stackbuf, format, args);
va_end (args);
if (0 <= n && n < size)
memcpy (s, stackbuf, n + 1);
return n;
}
# undef snprintf
# define snprintf my_snprintf
#endif
asctime_static
char *
asctime_r(struct tm const *restrict timeptr, char *restrict buf)
{
static const char wday_name[][4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char * wn;
const char * mn;
int year, mday, hour, min, sec;
long long_TM_YEAR_BASE = TM_YEAR_BASE;
size_t bufsize = (buf == buf_asctime
? sizeof buf_asctime : STD_ASCTIME_BUF_SIZE);
if (timeptr == NULL) {
strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
errno = EINVAL;
return buf;
}
if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
wn = "???";
else wn = wday_name[timeptr->tm_wday];
if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
mn = "???";
else mn = mon_name[timeptr->tm_mon];
year = timeptr->tm_year;
mday = timeptr->tm_mday;
hour = timeptr->tm_hour;
min = timeptr->tm_min;
sec = timeptr->tm_sec;
if ((size_t)(year <= INT_MAX - TM_YEAR_BASE
? snprintf (buf, bufsize,
((-999 - TM_YEAR_BASE <= year
&& year <= 9999 - TM_YEAR_BASE)
? "%s %s%3d %.2d:%.2d:%.2d %04ld\n"
: "%s %s%3d %.2d:%.2d:%.2d %ld\n"),
wn, mn, mday, hour, min, sec,
year + long_TM_YEAR_BASE)
: snprintf (buf, bufsize,
"%s %s%3d %.2d:%.2d:%.2d %d%d\n",
wn, mn, mday, hour, min, sec,
year / 10 + TM_YEAR_BASE / 10,
year % 10))
< bufsize)
return buf;
else {
errno = EOVERFLOW;
return NULL;
}
}
char *
asctime(const struct tm *timeptr)
{
return asctime_r(timeptr, buf_asctime);
}
#endif
char *
ctime_rz(timezone_t sp, const time_t *timep, char *buf)
{
struct tm mytm;
struct tm *tmp = localtime_rz(sp, timep, &mytm);
return tmp ? asctime_r(tmp, buf) : NULL;
}
asctime_static
char *
ctime_r(const time_t *timep, char *buf)
{
struct tm mytm;
struct tm *tmp = localtime_r(timep, &mytm);
return tmp ? asctime_r(tmp, buf) : NULL;
}
char *
ctime(const time_t *timep)
{
struct tm *tmp = localtime(timep);
return tmp ? asctime(tmp) : NULL;
}