summaryrefslogtreecommitdiff
path: root/src/arscan.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-10-02 17:24:53 -0400
committerPaul Smith <psmith@gnu.org>2022-10-03 15:11:57 -0400
commitae80eefe6559b21de6469ee7d48e418452ef3af7 (patch)
treeb6d53d87fc5376cae3f93480fa910851dc5eff50 /src/arscan.c
parent01142a53c9d99b9b72aedd37ffe5b8c75d795008 (diff)
downloadmake-git-ae80eefe6559b21de6469ee7d48e418452ef3af7.tar.gz
Support systems with 32-bit long and 64-bit time_t
Don't assume that time_t fits in long, as some hosts (e.g., glibc x86 -D_TIME_BITS=64) have 32-bit long and 64-bit time_t. * bootstrap.conf (gnulib_modules): Add largefile, to support files with timestamps after Y2038 on hosts with 32-bit long. * configure.ac: Do not call AC_SYS_LARGEFILE, as the largefile module does that for us. * src/makeint.h (PRIdMAX, PRIuMAX, SCNdMAX): Define if not already defined (taken from gnulib). * src/ar.c: Include intprops.h, for TYPE_MAXIMUM, as INTEGER_TYPE_MAXIMUM does not work on time_t without issuing a bunch of warnings. (ar_member_date): Check that result is in time_t range. (ar_member_date_1): Use intmax_t to hold the date. (ar_glob_match): Ditto. * src/arscan.c (VMS_function, VMS_function_ret, ar_scan) (parse_int, ar_scan, ar_member_pos, ar_member_touch) (describe_member): Convert long int to intmax_t. * src/file.c (file_timestamp_sprintf): Use intmax_t/uintmax_t instead of long/unsigned long for values that might be time_t. * src/arscan.c (ar_member_touch): Fix buffer overrun if the timestamp is too large.
Diffstat (limited to 'src/arscan.c')
-rw-r--r--src/arscan.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/src/arscan.c b/src/arscan.c
index 83377910..eb806a69 100644
--- a/src/arscan.c
+++ b/src/arscan.c
@@ -75,9 +75,9 @@ static void *VMS_lib_idx;
static const void *VMS_saved_arg;
-static long int (*VMS_function) ();
+static intmax_t (*VMS_function) ();
-static long int VMS_function_ret;
+static intmax_t VMS_function_ret;
/* This is a callback procedure for lib$get_index */
@@ -203,7 +203,7 @@ VMS_get_member_info(struct dsc$descriptor_s *module, unsigned long *rfa)
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully. */
-long int
+intmax_t
ar_scan (const char *archive, ar_member_func_t function, const void *varg)
{
char *vms_archive;
@@ -379,13 +379,13 @@ struct ar_hdr
#include "output.h"
-static unsigned long int
+static uintmax_t
parse_int (const char *ptr, const size_t len, const int base,
const char *type, const char *archive, const char *name)
{
const char *const ep = ptr + len;
const char max = '0' + base - 1;
- long int val = 0;
+ uintmax_t val = 0;
/* In all the versions I know of the spaces come last, but be safe. */
while (ptr < ep && *ptr == ' ')
@@ -430,7 +430,7 @@ parse_int (const char *ptr, const size_t len, const int base,
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully. */
-long int
+intmax_t
ar_scan (const char *archive, ar_member_func_t function, const void *arg)
{
#ifdef AIAMAG
@@ -550,7 +550,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
# define ARNAME_MAX 255
char name[ARNAME_MAX + 1];
int name_len;
- long int dateval;
+ intmax_t dateval;
int uidval, gidval;
long int data_offset;
#else
@@ -562,7 +562,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#endif
long int eltsize;
unsigned int eltmode;
- long int fnval;
+ intmax_t fnval;
off_t o;
memset(&member_header, '\0', sizeof (member_header));
@@ -593,7 +593,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
name[name_len] = '\0';
- sscanf (member_header_big.ar_date, "%12ld", &dateval);
+ sscanf (member_header_big.ar_date, "%12" SCNdMAX, &dateval);
sscanf (member_header_big.ar_uid, "%12d", &uidval);
sscanf (member_header_big.ar_gid, "%12d", &gidval);
sscanf (member_header_big.ar_mode, "%12o", &eltmode);
@@ -621,7 +621,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
name[name_len] = '\0';
- sscanf (member_header.ar_date, "%12ld", &dateval);
+ sscanf (member_header.ar_date, "%12" SCNdMAX, &dateval);
sscanf (member_header.ar_uid, "%12d", &uidval);
sscanf (member_header.ar_gid, "%12d", &gidval);
sscanf (member_header.ar_mode, "%12o", &eltmode);
@@ -885,10 +885,10 @@ ar_name_equal (const char *name, const char *mem, int truncated)
#ifndef VMS
/* ARGSUSED */
-static long int
+static intmax_t
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
- long int date UNUSED, int uid UNUSED, int gid UNUSED,
+ intmax_t date UNUSED, int uid UNUSED, int gid UNUSED,
unsigned int mode UNUSED, const void *name)
{
if (!ar_name_equal (name, mem, truncated))
@@ -911,7 +911,7 @@ ar_member_touch (const char *arname, const char *memname)
struct ar_hdr ar_hdr;
off_t o;
int r;
- unsigned int ui;
+ int datelen;
struct stat statbuf;
if (pos < 0)
@@ -935,10 +935,11 @@ ar_member_touch (const char *arname, const char *memname)
goto lose;
/* Advance member's time to that time */
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
- for (ui = 0; ui < sizeof ar_hdr.ar_date; ui++)
- ar_hdr.ar_date[ui] = ' ';
- sprintf (TOCHAR (ar_hdr.ar_date), "%lu", (long unsigned) statbuf.st_mtime);
- ar_hdr.ar_date[strlen ((char *) ar_hdr.ar_date)] = ' ';
+ datelen = snprintf (TOCHAR (ar_hdr.ar_date), sizeof ar_hdr.ar_date,
+ "%" PRIdMAX, (intmax_t) statbuf.st_mtime);
+ if (! (0 <= datelen && datelen < (int) sizeof ar_hdr.ar_date))
+ goto lose;
+ memset (ar_hdr.ar_date + datelen, ' ', sizeof ar_hdr.ar_date - datelen);
#else
ar_hdr.ar_date = statbuf.st_mtime;
#endif
@@ -962,18 +963,21 @@ ar_member_touch (const char *arname, const char *memname)
#ifdef TEST
-long int
+intmax_t
describe_member (int desc, const char *name, int truncated,
long int hdrpos, long int datapos, long int size,
- long int date, int uid, int gid, unsigned int mode,
+ intmax_t date, int uid, int gid, unsigned int mode,
const void *arg)
{
extern char *ctime ();
+ time_t d = date;
+ char const *ds;
printf (_("Member '%s'%s: %ld bytes at %ld (%ld).\n"),
name, truncated ? _(" (name might be truncated)") : "",
size, hdrpos, datapos);
- printf (_(" Date %s"), ctime (&date));
+ ds = ctime (&d);
+ printf (_(" Date %s"), ds ? ds : "?");
printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode);
return 0;