Date: Wed, 19 Oct 2022 17:04:17 GMT From: =?utf-8?Q?Dag-Erling=20Sm=C3=B8rgrav?= <des@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: d05e43bc0d57 - main - pax: update date parsing code (from OpenBSD) Message-ID: <202210191704.29JH4HxM049338@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=d05e43bc0d5705919d057793aaa3e6d3df65f815 commit d05e43bc0d5705919d057793aaa3e6d3df65f815 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2022-10-19 17:02:45 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2022-10-19 17:02:45 +0000 pax: update date parsing code (from OpenBSD) Sponsored by: Klara, Inc. MFC after: 1 week --- bin/pax/pax.1 | 25 +++++++----- bin/pax/sel_subs.c | 116 +++++++++++++++++++++++++++++------------------------ bin/pax/sel_subs.h | 2 +- 3 files changed, 78 insertions(+), 65 deletions(-) diff --git a/bin/pax/pax.1 b/bin/pax/pax.1 index abfbacee78b3..b503e1562f8a 100644 --- a/bin/pax/pax.1 +++ b/bin/pax/pax.1 @@ -33,7 +33,7 @@ .\" @(#)pax.1 8.4 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd December 29, 2018 +.Dd October 19, 2022 .Dt PAX 1 .Os .Sh NAME @@ -933,28 +933,31 @@ changed during a specified time range will be archived). A time range is made up of six different fields and each field must contain two digits. The format is: -.Dl [yy[mm[dd[hh]]]]mm[.ss] +.Pp +.Dl [[[[[cc]yy]mm]dd]HH]MM[.SS] +.Pp Where -.Cm yy +.Ar cc +is the first two digits of the year (the century), +.Ar yy is the last two digits of the year, the first -.Cm mm +.Ar mm is the month (from 01 to 12), -.Cm dd +.Ar dd is the day of the month (from 01 to 31), -.Cm hh +.Ar HH is the hour of the day (from 00 to 23), -the second -.Cm mm +.Ar MM is the minute (from 00 to 59), and -.Cm ss +.Ar SS is the seconds (from 00 to 59). The minute field -.Cm mm +.Ar MM is required, while the other fields are optional and must be added in the following order: -.Dl Cm hh , dd , mm , yy . +.Ar HH , dd , mm , yy , cc . The .Cm ss field may be added independently of the other fields. diff --git a/bin/pax/sel_subs.c b/bin/pax/sel_subs.c index 12975f21946f..7ef5bec523a5 100644 --- a/bin/pax/sel_subs.c +++ b/bin/pax/sel_subs.c @@ -44,17 +44,20 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> -#include <pwd.h> + +#include <ctype.h> #include <grp.h> +#include <pwd.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <strings.h> -#include <stdlib.h> + #include "pax.h" #include "sel_subs.h" #include "extern.h" -static int str_sec(char *, time_t *); +static int str_sec(const char *, time_t *); static int usr_match(ARCHD *); static int grp_match(ARCHD *); static int trng_match(ARCHD *); @@ -309,7 +312,7 @@ grp_match(ARCHD *arcn) * trng_add() * add a time range match to the time range list. * This is a non-standard pax option. Lower and upper ranges are in the - * format: [yy[mm[dd[hh]]]]mm[.ss] and are comma separated. + * format: [[[[[cc]yy]mm]dd]HH]MM[.SS] and are comma separated. * Time ranges are based on current time, so 1234 would specify a time of * 12:34 today. * Return: @@ -446,7 +449,7 @@ trng_add(char *str) return(0); out: - paxwarn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]"); + paxwarn(1, "Time range format is: [[[[[cc]yy]mm]dd]HH]MM[.SS][/[c][m]]"); return(-1); } @@ -520,80 +523,87 @@ trng_match(ARCHD *arcn) /* * str_sec() - * Convert a time string in the format of [[[[yy[mm[dd[hh]mm[.ss] to gmt - * seconds. Tval already has current time loaded into it at entry. + * Convert a time string in the format of [[[[[cc]yy]mm]dd]HH]MM[.SS] to + * seconds UTC. Tval already has current time loaded into it at entry. * Return: * 0 if converted ok, -1 otherwise */ static int -str_sec(char *str, time_t *tval) +str_sec(const char *p, time_t *tval) { struct tm *lt; - char *dot = NULL; + const char *dot, *t; + size_t len; + int bigyear; + int yearset; + + yearset = 0; + len = strlen(p); + + for (t = p, dot = NULL; *t; ++t) { + if (isdigit((unsigned char)*t)) + continue; + if (*t == '.' && dot == NULL) { + dot = t; + continue; + } + return(-1); + } lt = localtime(tval); - if ((dot = strchr(str, '.')) != NULL) { - /* - * seconds (.ss) - */ - *dot++ = '\0'; - if (strlen(dot) != 2) + + if (dot != NULL) { /* .SS */ + if (strlen(++dot) != 2) return(-1); - if ((lt->tm_sec = ATOI2(dot)) > 61) + lt->tm_sec = ATOI2(dot); + if (lt->tm_sec > 61) return(-1); + len -= 3; } else lt->tm_sec = 0; - switch (strlen(str)) { - case 10: - /* - * year (yy) - * watch out for year 2000 - */ - if ((lt->tm_year = ATOI2(str)) < 69) - lt->tm_year += 100; - str += 2; + switch (len) { + case 12: /* cc */ + bigyear = ATOI2(p); + lt->tm_year = (bigyear * 100) - 1900; + yearset = 1; /* FALLTHROUGH */ - case 8: - /* - * month (mm) - * watch out months are from 0 - 11 internally - */ - if ((lt->tm_mon = ATOI2(str)) > 12) + case 10: /* yy */ + if (yearset) { + lt->tm_year += ATOI2(p); + } else { + lt->tm_year = ATOI2(p); + if (lt->tm_year < 69) /* hack for 2000 ;-} */ + lt->tm_year += (2000 - 1900); + } + /* FALLTHROUGH */ + case 8: /* mm */ + lt->tm_mon = ATOI2(p); + if ((lt->tm_mon > 12) || !lt->tm_mon) return(-1); - --lt->tm_mon; - str += 2; + --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ - case 6: - /* - * day (dd) - */ - if ((lt->tm_mday = ATOI2(str)) > 31) + case 6: /* dd */ + lt->tm_mday = ATOI2(p); + if ((lt->tm_mday > 31) || !lt->tm_mday) return(-1); - str += 2; /* FALLTHROUGH */ - case 4: - /* - * hour (hh) - */ - if ((lt->tm_hour = ATOI2(str)) > 23) + case 4: /* HH */ + lt->tm_hour = ATOI2(p); + if (lt->tm_hour > 23) return(-1); - str += 2; /* FALLTHROUGH */ - case 2: - /* - * minute (mm) - */ - if ((lt->tm_min = ATOI2(str)) > 59) + case 2: /* MM */ + lt->tm_min = ATOI2(p); + if (lt->tm_min > 59) return(-1); break; default: return(-1); } - /* - * convert broken-down time to GMT clock time seconds - */ + + /* convert broken-down time to UTC clock time seconds */ if ((*tval = mktime(lt)) == -1) return(-1); return(0); diff --git a/bin/pax/sel_subs.h b/bin/pax/sel_subs.h index 7e1ddeedcb87..a628e6981b1a 100644 --- a/bin/pax/sel_subs.h +++ b/bin/pax/sel_subs.h @@ -57,7 +57,7 @@ typedef struct grpt { * data structure for storing user supplied time ranges (-T option) */ -#define ATOI2(s) ((((s)[0] - '0') * 10) + ((s)[1] - '0')) +#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; typedef struct time_rng { time_t low_time; /* lower inclusive time limit */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202210191704.29JH4HxM049338>