Closed alejandro-colomar closed 6 months ago
@alejandro-colomar with patches #942 #944 applied, chage does not seem to accept non-numeric date formats at all. It prints the following error message and the usage:
localhost:/home/gus/20230214 # chage gus -d yesterday
chage: invalid date 'yesterday'
localhost:/home/gus/20230214 # chage gus -d 'Feb 12, 2024'
chage: invalid date 'Feb 12, 2024'
@alejandro-colomar with patches #942 #944 applied, chage does not seem to accept non-numeric date formats at all. It prints the following error message and the usage:
localhost:/home/gus/20230214 # chage gus -d yesterday
chage: invalid date 'yesterday'
localhost:/home/gus/20230214 # chage gus -d 'Feb 12, 2024'
chage: invalid date 'Feb 12, 2024'
Hmmm, I'll have to debug that thing. Thanks for trying!
For what it's worth, I was testing with 4.14.3 with the patches applied.
v1b changes:
$ git range-diff gh/master..gh/getdate shadow/master..getdate
1: 1b054708 < -: -------- lib/strtoday.c: strtoday(): Fix calculation
2: 1d61c562 = 1: 781724c7 lib/strtoday.c: strtoday(): Reimplement in terms of getdate(3)+mktime(3)
3: a8fd09ac = 2: 6028ac4e lib/getdate.[yh]: Remove get_date()
Here's the reason why getdate(3) isn't working:
$ cat strtoday.c
#define _XOPEN_SOURCE 500
#include <ctype.h>
#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <a2i/str2i.h>
#define DAY ((time_t) 24 * 3600)
static long strtoday(const char *str);
int
main(int argc, char *argv[])
{
if (argc != 2)
errx(EXIT_FAILURE, "argc should be 2.");
strtoday(argv[1]);
}
static long
strtoday(const char *str)
{
bool isnum = true;
time_t t;
struct tm *tp;
const char *s = str;
if ((NULL == str) || ('\0' == *str))
return -1;
/* If a numerical value is provided, this is already a number of
* days since EPOCH.
*/
if ('-' == *s) {
s++;
}
while (' ' == *s) {
s++;
}
while (isnum && ('\0' != *s)) {
if (!isdigit (*s)) {
isnum = false;
}
s++;
}
if (isnum) {
long retdate;
if (str2sl(&retdate, str) == -1) {
return -2;
}
return retdate;
}
fprintf(stderr, "ALX: %s: %s(): %d\n", __FILE__, __func__, __LINE__);
tp = getdate(str);
fprintf(stderr, "ALX: getdate(): %p\n", (void *) tp);
fprintf(stderr, "ALX: getdate_err: %d\n", getdate_err);
if (tp == NULL)
return -2;
fprintf(stderr, "ALX: %s: %s(): %d\n", __FILE__, __func__, __LINE__);
t = mktime(tp);
fprintf(stderr, "ALX: mktime(): %jd\n", (intmax_t) t);
if ((time_t) -1 == t)
return -2;
fprintf(stderr, "ALX: %s: %s(): %d\n", __FILE__, __func__, __LINE__);
return t / DAY;
}
$ ./a.out today
ALX: strtoday.c: strtoday(): 62
ALX: getdate(): (nil)
ALX: getdate_err: 1
$ man_section $(man -w getdate) ERRORS
getdate(3) Library Functions Manual getdate(3)
ERRORS
The following errors are returned via getdate_err (for getdate()) or as
the function result (for getdate_r()):
1 The DATEMSK environment variable is not defined, or its value is an
empty string.
2 The template file specified by DATEMSK cannot be opened for
reading.
3 Failed to get file status information.
4 The template file is not a regular file.
5 An error was encountered while reading the template file.
6 Memory allocation failed (not enough memory available).
7 There is no line in the file that matches the input.
8 Invalid input specification.
Linux man-pages (unreleased) (date) getdate(3)
So it seems the problem is with DATEMSK
. We would need to specify a file with the formats we support.
@kenion, @jubalh, before I start investigating into the second (actually, the first) part of the bug that you reported, I was wondering if this would fix it by chance. Maybe something inside get_date() is broken, and this solves it. Would you mind testing with these patches?