# define AR_HDR_SIZE (sizeof (struct ar_hdr))
#endif
+#include "intprops.h"
+
#include "output.h"
\f
static uintmax_t
-parse_int (const char *ptr, const size_t len, const int base,
+parse_int (const char *ptr, const size_t len, const int base, uintmax_t max,
const char *type, const char *archive, const char *name)
{
const char *const ep = ptr + len;
- const char max = '0' + base - 1;
+ const int maxchar = '0' + base - 1;
uintmax_t val = 0;
/* In all the versions I know of the spaces come last, but be safe. */
while (ptr < ep && *ptr != ' ')
{
- if (*ptr < '0' || *ptr > max)
- OSSS (fatal, NILF, _("Invalid %s for archive %s member %s"),
- type, archive, name);
- val = (val * base) + (*ptr - '0');
+ uintmax_t nv;
+
+ if (*ptr < '0' || *ptr > maxchar)
+ OSSS (fatal, NILF,
+ _("Invalid %s for archive %s member %s"), type, archive, name);
+ nv = (val * base) + (*ptr - '0');
+ if (nv < val || nv > max)
+ OSSS (fatal, NILF,
+ _("Invalid %s for archive %s member %s"), type, archive, name);
+ val = nv;
++ptr;
}
#endif
long int eltsize;
unsigned int eltmode;
+ intmax_t eltdate;
+ int eltuid, eltgid;
intmax_t fnval;
off_t o;
}
#ifndef M_XENIX
- eltmode = parse_int (TOCHAR (member_header.ar_mode), sizeof (member_header.ar_mode), 8, "mode", archive, name);
- eltsize = parse_int (TOCHAR (member_header.ar_size), sizeof (member_header.ar_size), 10, "size", archive, name);
+#define PARSE_INT(_m, _t, _b, _n) \
+ (_t) parse_int (TOCHAR (member_header._m), sizeof (member_header._m), \
+ _b, TYPE_MAXIMUM (_t), _n, archive, name)
+
+ eltmode = PARSE_INT (ar_mode, unsigned int, 8, "mode");
+ eltsize = PARSE_INT (ar_size, long, 10, "size");
+ eltdate = PARSE_INT (ar_date, intmax_t, 10, "date");
+ eltuid = PARSE_INT (ar_uid, int, 10, "uid");
+ eltgid = PARSE_INT (ar_gid, int, 10, "gid");
+#undef PARSE_INT
#else /* Xenix. */
eltmode = (unsigned short int) member_header.ar_mode;
eltsize = member_header.ar_size;
(*function) (desc, name, ! long_name, member_offset,
member_offset + AR_HDR_SIZE, eltsize,
#ifndef M_XENIX
- parse_int (TOCHAR (member_header.ar_date), sizeof (member_header.ar_date), 10, "date", archive, name),
- parse_int (TOCHAR (member_header.ar_uid), sizeof (member_header.ar_uid), 10, "uid", archive, name),
- parse_int (TOCHAR (member_header.ar_gid), sizeof (member_header.ar_gid), 10, "gid", archive, name),
+ eltdate, eltuid, eltgid,
#else /* Xenix. */
member_header.ar_date,
member_header.ar_uid,
int
ar_member_touch (const char *arname, const char *memname)
{
- long int pos = ar_scan (arname, ar_member_pos, memname);
+ intmax_t pos = ar_scan (arname, ar_member_pos, memname);
+ off_t opos;
int fd;
struct ar_hdr ar_hdr;
off_t o;
if (!pos)
return 1;
+ opos = (off_t) pos;
+
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
if (fd < 0)
return -3;
/* Read in this member's header */
- EINTRLOOP (o, lseek (fd, pos, 0));
+ EINTRLOOP (o, lseek (fd, opos, 0));
if (o < 0)
goto lose;
r = readbuf (fd, &ar_hdr, AR_HDR_SIZE);
ar_hdr.ar_date = statbuf.st_mtime;
#endif
/* Write back this member's header */
- EINTRLOOP (o, lseek (fd, pos, 0));
+ EINTRLOOP (o, lseek (fd, opos, 0));
if (o < 0)
goto lose;
r = writebuf (fd, &ar_hdr, AR_HDR_SIZE);
static int
a_word_hash_cmp (const void *x, const void *y)
{
- int result = (int) ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
- if (result)
- return result;
- return_STRING_N_COMPARE (((struct a_word const *) x)->str,
- ((struct a_word const *) y)->str,
- ((struct a_word const *) y)->length);
+ const struct a_word *ax = x;
+ const struct a_word *ay = y;
+
+ if (ax->length != ay->length)
+ return ax->length > ay->length ? 1 : -1;
+
+ return_STRING_N_COMPARE (ax->str, ay->str, ax->length);
}
struct a_pattern
struct a_pattern *patterns;
struct a_pattern *pat_end;
struct a_pattern *pp;
- size_t pat_count = 0, word_count = 0;
+ unsigned long pat_count = 0, word_count = 0;
struct hash_table a_word_table;
int is_filter = funcname[CSTRLEN ("filter")] == '\0';