Have a single definition of date_to_str()

PARAMETERS:

According to the C2x charter, I reordered the parameters 'size'
and 'buf' from previously existing date_to_str() definitions.

C2x charter:
> 15. Application Programming Interfaces (APIs) should be
> self-documenting when possible.  In particular, the order of
> parameters in function declarations should be arranged such that
> the size of an array appears before the array.  The purpose is to
> allow Variable-Length Array (VLA) notation to be used.  This not
> only makes the code's purpose clearer to human readers, but also
> makes static analysis easier.  Any new APIs added to the Standard
> should take this into consideration.

I used 'long' for the date parameter, as some uses of the function
need to pass a negative value meaning "never".

FUNCTION BODY:

I didn't check '#ifdef HAVE_STRFTIME', which old definitions did,
since strftime(3) is guaranteed by the C89 standard, and all of
the conversion specifiers that we use are also specified by that
standard, so we don't need any extensions at all.

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
This commit is contained in:
Alejandro Colomar 2021-12-22 15:32:17 +01:00
parent b8c67c320c
commit 355ad6a9e0
7 changed files with 58 additions and 61 deletions

View File

@ -134,6 +134,9 @@ extern int copy_tree (const char *src_root, const char *dst_root,
uid_t old_uid, uid_t new_uid, uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid); gid_t old_gid, gid_t new_gid);
/* date_to_str.c */
extern void date_to_str (size_t size, char buf[size], long date);
/* encrypt.c */ /* encrypt.c */
extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *); extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *);

View File

@ -19,6 +19,7 @@ libmisc_la_SOURCES = \
cleanup_user.c \ cleanup_user.c \
console.c \ console.c \
copydir.c \ copydir.c \
date_to_str.c \
entry.c \ entry.c \
env.c \ env.c \
failure.c \ failure.c \

46
libmisc/date_to_str.c Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021, Alejandro Colomar <alx.manpages@gmail.com>
*
* 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. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
* HOLDERS 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.
*/
#include <string.h>
#include <time.h>
#ident "$Id$"
#include "prototypes.h"
void date_to_str (size_t size, char buf[size], long date)
{
time_t t;
t = date;
if (date < 0)
(void) strncpy (buf, "never", size);
else
(void) strftime (buf, size, "%Y-%m-%d", gmtime (&t));
buf[size - 1] = '\0';
}

View File

@ -41,6 +41,7 @@ libmisc/cleanup_group.c
libmisc/cleanup_user.c libmisc/cleanup_user.c
libmisc/console.c libmisc/console.c
libmisc/copydir.c libmisc/copydir.c
libmisc/date_to_str.c
libmisc/entry.c libmisc/entry.c
libmisc/env.c libmisc/env.c
libmisc/failure.c libmisc/failure.c

View File

@ -90,7 +90,6 @@ static long expdate;
/* local function prototypes */ /* local function prototypes */
static /*@noreturn@*/void usage (int status); static /*@noreturn@*/void usage (int status);
static void date_to_str (char *buf, size_t maxsize, time_t date);
static int new_fields (void); static int new_fields (void);
static void print_date (time_t date); static void print_date (time_t date);
static void list_fields (void); static void list_fields (void);
@ -161,19 +160,6 @@ static /*@noreturn@*/void usage (int status)
exit (status); exit (status);
} }
static void date_to_str (char *buf, size_t maxsize, time_t date)
{
struct tm *tp;
tp = gmtime (&date);
#ifdef HAVE_STRFTIME
(void) strftime (buf, maxsize, "%Y-%m-%d", tp);
#else
(void) snprintf (buf, maxsize, "%04d-%02d-%02d",
tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday);
#endif /* HAVE_STRFTIME */
}
/* /*
* new_fields - change the user's password aging information interactively. * new_fields - change the user's password aging information interactively.
* *
@ -207,7 +193,7 @@ static int new_fields (void)
if (-1 == lstchgdate || lstchgdate > LONG_MAX / SCALE) { if (-1 == lstchgdate || lstchgdate > LONG_MAX / SCALE) {
strcpy (buf, "-1"); strcpy (buf, "-1");
} else { } else {
date_to_str (buf, sizeof buf, (time_t) (lstchgdate * SCALE)); date_to_str (sizeof(buf), buf, lstchgdate * SCALE);
} }
change_field (buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)")); change_field (buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)"));
@ -238,7 +224,7 @@ static int new_fields (void)
if (-1 == expdate || LONG_MAX / SCALE < expdate) { if (-1 == expdate || LONG_MAX / SCALE < expdate) {
strcpy (buf, "-1"); strcpy (buf, "-1");
} else { } else {
date_to_str (buf, sizeof buf, (time_t) (expdate * SCALE)); date_to_str (sizeof(buf), buf, expdate * SCALE);
} }
change_field (buf, sizeof buf, change_field (buf, sizeof buf,

View File

@ -135,7 +135,6 @@ static int new_password (const struct passwd *);
static void check_password (const struct passwd *, const struct spwd *); static void check_password (const struct passwd *, const struct spwd *);
#endif /* !USE_PAM */ #endif /* !USE_PAM */
static /*@observer@*/const char *date_to_str (time_t);
static /*@observer@*/const char *pw_status (const char *); static /*@observer@*/const char *pw_status (const char *);
static void print_status (const struct passwd *); static void print_status (const struct passwd *);
static /*@noreturn@*/void fail_exit (int); static /*@noreturn@*/void fail_exit (int);
@ -447,21 +446,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
} }
#endif /* !USE_PAM */ #endif /* !USE_PAM */
static /*@observer@*/const char *date_to_str (time_t t)
{
static char buf[80];
struct tm *tm;
tm = gmtime (&t);
#ifdef HAVE_STRFTIME
(void) strftime (buf, sizeof buf, "%m/%d/%Y", tm);
#else /* !HAVE_STRFTIME */
(void) snprintf (buf, sizeof buf, "%02d/%02d/%04d",
tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
#endif /* !HAVE_STRFTIME */
return buf;
}
static /*@observer@*/const char *pw_status (const char *pass) static /*@observer@*/const char *pw_status (const char *pass)
{ {
if (*pass == '*' || *pass == '!') { if (*pass == '*' || *pass == '!') {
@ -478,14 +462,16 @@ static /*@observer@*/const char *pw_status (const char *pass)
*/ */
static void print_status (const struct passwd *pw) static void print_status (const struct passwd *pw)
{ {
char date[80];
struct spwd *sp; struct spwd *sp;
sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */ sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */
if (NULL != sp) { if (NULL != sp) {
date_to_str (sizeof(date), date, sp->sp_lstchg * SCALE),
(void) printf ("%s %s %s %lld %lld %lld %lld\n", (void) printf ("%s %s %s %lld %lld %lld %lld\n",
pw->pw_name, pw->pw_name,
pw_status (sp->sp_pwdp), pw_status (sp->sp_pwdp),
date_to_str (sp->sp_lstchg * SCALE), date,
((long long)sp->sp_min * SCALE) / DAY, ((long long)sp->sp_min * SCALE) / DAY,
((long long)sp->sp_max * SCALE) / DAY, ((long long)sp->sp_max * SCALE) / DAY,
((long long)sp->sp_warn * SCALE) / DAY, ((long long)sp->sp_warn * SCALE) / DAY,

View File

@ -185,8 +185,6 @@ static bool sub_gid_locked = false;
/* local function prototypes */ /* local function prototypes */
static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
long int date);
static int get_groups (char *); static int get_groups (char *);
static /*@noreturn@*/void usage (int status); static /*@noreturn@*/void usage (int status);
static void new_pwent (struct passwd *); static void new_pwent (struct passwd *);
@ -213,28 +211,6 @@ static void move_mailbox (void);
extern int allow_bad_names; extern int allow_bad_names;
static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
long int date)
{
struct tm *tp;
if (date < 0) {
strncpy (buf, "never", maxsize);
} else {
time_t t = (time_t) date;
tp = gmtime (&t);
#ifdef HAVE_STRFTIME
strftime (buf, maxsize, "%Y-%m-%d", tp);
#else
(void) snprintf (buf, maxsize, "%04d-%02d-%02d",
tp->tm_year + 1900,
tp->tm_mon + 1,
tp->tm_mday);
#endif /* HAVE_STRFTIME */
}
buf[maxsize - 1] = '\0';
}
/* /*
* get_groups - convert a list of group names to an array of group IDs * get_groups - convert a list of group names to an array of group IDs
* *
@ -637,10 +613,8 @@ static void new_spent (struct spwd *spent)
if (eflg) { if (eflg) {
/* log dates rather than numbers of days. */ /* log dates rather than numbers of days. */
char new_exp[16], old_exp[16]; char new_exp[16], old_exp[16];
date_to_str (new_exp, sizeof(new_exp), date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY);
user_newexpire * DAY); date_to_str (sizeof(old_exp), old_exp, user_expire * DAY);
date_to_str (old_exp, sizeof(old_exp),
user_expire * DAY);
#ifdef WITH_AUDIT #ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing expiration date", "changing expiration date",