diff --git a/lib/prototypes.h b/lib/prototypes.h index 535c671f..42908132 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -131,6 +131,9 @@ extern int copy_tree (const char *src_root, const char *dst_root, uid_t old_uid, uid_t new_uid, 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 */ extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *); diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index 9f237e0d..3d319cd8 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -19,6 +19,7 @@ libmisc_la_SOURCES = \ cleanup_user.c \ console.c \ copydir.c \ + date_to_str.c \ entry.c \ env.c \ failure.c \ diff --git a/libmisc/date_to_str.c b/libmisc/date_to_str.c new file mode 100644 index 00000000..07e99f1a --- /dev/null +++ b/libmisc/date_to_str.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, Alejandro Colomar + * + * 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 +#include + +#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'; +} diff --git a/po/POTFILES.in b/po/POTFILES.in index df761283..61b79dbd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -41,6 +41,7 @@ libmisc/cleanup_group.c libmisc/cleanup_user.c libmisc/console.c libmisc/copydir.c +libmisc/date_to_str.c libmisc/entry.c libmisc/env.c libmisc/failure.c diff --git a/src/chage.c b/src/chage.c index df34da1d..5dfc68e8 100644 --- a/src/chage.c +++ b/src/chage.c @@ -90,7 +90,6 @@ static long expdate; /* local function prototypes */ 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 void print_date (time_t date); static void list_fields (void); @@ -161,19 +160,6 @@ static /*@noreturn@*/void usage (int 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. * @@ -207,7 +193,7 @@ static int new_fields (void) if (-1 == lstchgdate || lstchgdate > LONG_MAX / SCALE) { strcpy (buf, "-1"); } 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)")); @@ -238,7 +224,7 @@ static int new_fields (void) if (-1 == expdate || LONG_MAX / SCALE < expdate) { strcpy (buf, "-1"); } else { - date_to_str (buf, sizeof buf, (time_t) (expdate * SCALE)); + date_to_str (sizeof(buf), buf, expdate * SCALE); } change_field (buf, sizeof buf, diff --git a/src/passwd.c b/src/passwd.c index be217d31..e17ea8bb 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -135,7 +135,6 @@ static int new_password (const struct passwd *); static void check_password (const struct passwd *, const struct spwd *); #endif /* !USE_PAM */ -static /*@observer@*/const char *date_to_str (time_t); static /*@observer@*/const char *pw_status (const char *); static void print_status (const struct passwd *); 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 */ -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) { if (*pass == '*' || *pass == '!') { @@ -478,14 +462,16 @@ static /*@observer@*/const char *pw_status (const char *pass) */ static void print_status (const struct passwd *pw) { + char date[80]; struct spwd *sp; sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */ if (NULL != sp) { + date_to_str (sizeof(date), date, sp->sp_lstchg * SCALE), (void) printf ("%s %s %s %lld %lld %lld %lld\n", pw->pw_name, pw_status (sp->sp_pwdp), - date_to_str (sp->sp_lstchg * SCALE), + date, ((long long)sp->sp_min * SCALE) / DAY, ((long long)sp->sp_max * SCALE) / DAY, ((long long)sp->sp_warn * SCALE) / DAY, diff --git a/src/usermod.c b/src/usermod.c index 10f9ccfd..5169039c 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -185,8 +185,6 @@ static bool sub_gid_locked = false; /* local function prototypes */ -static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, - long int date); static int get_groups (char *); static /*@noreturn@*/void usage (int status); static void new_pwent (struct passwd *); @@ -213,28 +211,6 @@ static void move_mailbox (void); 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 * @@ -637,10 +613,8 @@ static void new_spent (struct spwd *spent) if (eflg) { /* log dates rather than numbers of days. */ char new_exp[16], old_exp[16]; - date_to_str (new_exp, sizeof(new_exp), - user_newexpire * DAY); - date_to_str (old_exp, sizeof(old_exp), - user_expire * DAY); + date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); + date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing expiration date",