strnlen
strtoimax
strtol
-strtoul
strtoumax
symlinkat
sys_stat
xalloc
xalloc-die
xgetcwd
+xstrtoimax
xstrtoumax
xvasprintf
year2038-recommended
};
/* Checkpointing counter */
-static unsigned checkpoint;
+static intmax_t checkpoint;
/* List of checkpoint actions */
static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail;
else if (strncmp (str, "sleep=", 6) == 0)
{
char *p;
- time_t n = strtoul (str+6, &p, 10);
- if (*p)
+ intmax_t sleepsec = strtoimax (str + 6, &p, 10);
+ if (*p || sleepsec < 0)
FATAL_ERROR ((0, 0, _("%s: not a valid timeout"), str));
+ time_t n = ckd_add (&n, sleepsec, 0) ? TYPE_MAXIMUM (time_t) : n;
act = alloc_action (cop_sleep);
act->v.time = n;
}
static int
format_checkpoint_string (FILE *fp, size_t len,
const char *input, bool do_write,
- unsigned cpn)
+ intmax_t cpn)
{
const char *opstr = do_write ? gettext ("write") : gettext ("read");
const char *ip;
break;
case 'u':
- len += fprintf (fp, "%u", cpn);
+ len += fprintf (fp, "%jd", cpn);
break;
case 's':
extern bool block_number_option;
-extern unsigned checkpoint_option;
+extern intmax_t checkpoint_option;
#define DEFAULT_CHECKPOINT 10
/* Specified name of compression program, or "gzip" as implied by -z. */
extern bool show_omitted_dirs_option;
extern bool sparse_option;
-extern unsigned tar_sparse_major;
-extern unsigned tar_sparse_minor;
+extern intmax_t tar_sparse_major, tar_sparse_minor;
enum hole_detection_method
{
int sys_exec_info_script (const char **archive_name, int volume_number);
void sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
- int checkpoint_number);
+ intmax_t checkpoint_number);
bool mtioseek (bool count_files, off_t count);
int sys_exec_setmtime_script (const char *script_name,
int dirfd,
void
sys_exec_checkpoint_script (const char *script_name,
const char *archive_name,
- int checkpoint_number)
+ intmax_t checkpoint_number)
{
pid_t pid = xfork ();
/* Child */
setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
setenv ("TAR_ARCHIVE", archive_name, 1);
- char intbuf[INT_BUFSIZE_BOUND (int)];
- sprintf (intbuf, "%d", checkpoint_number);
+ char intbuf[INT_BUFSIZE_BOUND (intmax_t)];
+ sprintf (intbuf, "%jd", checkpoint_number);
setenv ("TAR_CHECKPOINT", intbuf, 1);
sprintf (intbuf, "%d", blocking_factor);
setenv ("TAR_BLOCKING_FACTOR", intbuf, 1);
bool backup_option;
enum backup_type backup_type;
bool block_number_option;
-unsigned checkpoint_option;
+intmax_t checkpoint_option;
const char *use_compress_program_option;
bool dereference_option;
bool hard_dereference_option;
size_t strip_name_components;
bool show_omitted_dirs_option;
bool sparse_option;
-unsigned tar_sparse_major;
-unsigned tar_sparse_minor;
+intmax_t tar_sparse_major;
+intmax_t tar_sparse_minor;
enum hole_detection_method hole_detection;
bool starting_file_option;
tarlong tape_length_option;
sparse_option = true;
{
char *p;
- tar_sparse_major = strtoul (arg, &p, 10);
- if (*p)
+ bool ok;
+ switch (xstrtoimax (arg, &p, 10, &tar_sparse_major, ""))
{
- if (*p != '.')
- USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
- tar_sparse_minor = strtoul (p + 1, &p, 10);
- if (*p)
- USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
+ case LONGINT_OK:
+ tar_sparse_minor = 0;
+ ok = 0 <= tar_sparse_major;
+ break;
+
+ case LONGINT_INVALID_SUFFIX_CHAR:
+ ok = (*p == '.'
+ && (xstrtoimax (p + 1, nullptr, 10, &tar_sparse_minor, "")
+ == LONGINT_OK)
+ && 0 <= tar_sparse_minor && 0 <= tar_sparse_major);
+ break;
+
+ default:
+ ok = false;
+ break;
}
+ if (!ok)
+ USAGE_ERROR ((0, 0, _("Invalid sparse version value")));
}
break;
checkpoint_compile_action (".");
arg++;
}
- checkpoint_option = strtoul (arg, &p, 0);
- if (*p)
+ checkpoint_option = strtoimax (arg, &p, 0);
+ if (*p || checkpoint_option <= 0)
FATAL_ERROR ((0, 0,
- _("--checkpoint value is not an integer")));
+ _("invalid --checkpoint value")));
}
else
checkpoint_option = DEFAULT_CHECKPOINT;
bool is_sparse; /* Is the file sparse */
/* For sparse files: */
- unsigned sparse_major;
- unsigned sparse_minor;
+ intmax_t sparse_major;
+ intmax_t sparse_minor;
size_t sparse_map_avail; /* Index to the first unused element in
sparse_map array. Zero if the file is
not sparse */
struct transform *next;
enum transform_type transform_type;
int flags;
- unsigned match_number;
+ idx_t match_number;
regex_t regex;
/* Compiled replacement expression */
struct replace_segm *repl_head, *repl_tail;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- tf->match_number = strtoul (p, (char**) &p, 0);
- p--;
+ {
+ char *endp;
+ intmax_t match_number = strtoimax (p, &endp, 10);
+ assume (0 <= match_number);
+ if (ckd_add (&tf->match_number, match_number, 0))
+ tf->match_number = IDX_MAX;
+ p = endp - 1;
+ }
break;
default:
{
if (*cur == '\\')
{
- size_t n;
-
add_literal_segment (tf, beg, cur);
switch (*++cur)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- n = strtoul (cur, &cur, 10);
- if (n > tf->regex.re_nsub)
- USAGE_ERROR ((0, 0, _("Invalid transform replacement: back reference out of range")));
- add_backref_segment (tf, n);
+ {
+ intmax_t n = strtoimax (cur, &cur, 10);
+ assume (0 <= n);
+ if (tf->regex.re_nsub < n)
+ USAGE_ERROR ((0, 0, _("Invalid transform replacement:"
+ " back reference out of range")));
+ add_backref_segment (tf, n);
+ }
break;
case '\\':
MAYBE_UNUSED size_t size)
{
uintmax_t u;
- if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
+ if (decode_num (&u, arg, INTMAX_MAX, keyword))
st->sparse_major = u;
}
MAYBE_UNUSED size_t size)
{
uintmax_t u;
- if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
+ if (decode_num (&u, arg, INTMAX_MAX, keyword))
st->sparse_minor = u;
}