Link Here
|
783 |
xheader_print (xhdr, keyword, sbuf); |
783 |
xheader_print (xhdr, keyword, sbuf); |
784 |
} |
784 |
} |
785 |
|
785 |
|
|
|
786 |
static bool |
787 |
decode_num (uintmax_t *num, char const *arg, uintmax_t maxval, |
788 |
char const *keyword) |
789 |
{ |
790 |
uintmax_t u; |
791 |
char *arg_lim; |
792 |
|
793 |
if (! (ISDIGIT (*arg) |
794 |
&& (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim))) |
795 |
{ |
796 |
ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), |
797 |
keyword, arg)); |
798 |
return false; |
799 |
} |
800 |
|
801 |
if (! (u <= maxval && errno != ERANGE)) |
802 |
{ |
803 |
ERROR ((0, 0, _("Extended header %s=%s is out of range"), |
804 |
keyword, arg)); |
805 |
return false; |
806 |
} |
807 |
|
808 |
*num = u; |
809 |
return true; |
810 |
} |
811 |
|
786 |
static void |
812 |
static void |
787 |
dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), |
813 |
dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), |
788 |
char const *keyword __attribute__ ((unused)), |
814 |
char const *keyword __attribute__ ((unused)), |
Link Here
|
821 |
gid_decoder (struct tar_stat_info *st, char const *arg) |
847 |
gid_decoder (struct tar_stat_info *st, char const *arg) |
822 |
{ |
848 |
{ |
823 |
uintmax_t u; |
849 |
uintmax_t u; |
824 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
850 |
if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), "gid")) |
825 |
st->stat.st_gid = u; |
851 |
st->stat.st_gid = u; |
826 |
} |
852 |
} |
827 |
|
853 |
|
Link Here
|
903 |
size_decoder (struct tar_stat_info *st, char const *arg) |
929 |
size_decoder (struct tar_stat_info *st, char const *arg) |
904 |
{ |
930 |
{ |
905 |
uintmax_t u; |
931 |
uintmax_t u; |
906 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
932 |
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "size")) |
907 |
st->archive_file_size = st->stat.st_size = u; |
933 |
st->archive_file_size = st->stat.st_size = u; |
908 |
} |
934 |
} |
909 |
|
935 |
|
Link Here
|
918 |
uid_decoder (struct tar_stat_info *st, char const *arg) |
944 |
uid_decoder (struct tar_stat_info *st, char const *arg) |
919 |
{ |
945 |
{ |
920 |
uintmax_t u; |
946 |
uintmax_t u; |
921 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
947 |
if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), "uid")) |
922 |
st->stat.st_uid = u; |
948 |
st->stat.st_uid = u; |
923 |
} |
949 |
} |
924 |
|
950 |
|
Link Here
|
946 |
sparse_size_decoder (struct tar_stat_info *st, char const *arg) |
972 |
sparse_size_decoder (struct tar_stat_info *st, char const *arg) |
947 |
{ |
973 |
{ |
948 |
uintmax_t u; |
974 |
uintmax_t u; |
949 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
975 |
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.size")) |
950 |
st->stat.st_size = u; |
976 |
st->stat.st_size = u; |
951 |
} |
977 |
} |
952 |
|
978 |
|
Link Here
|
962 |
sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) |
988 |
sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) |
963 |
{ |
989 |
{ |
964 |
uintmax_t u; |
990 |
uintmax_t u; |
965 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
991 |
if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numblocks")) |
966 |
{ |
992 |
{ |
967 |
st->sparse_map_size = u; |
993 |
st->sparse_map_size = u; |
968 |
st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0])); |
994 |
st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]); |
969 |
st->sparse_map_avail = 0; |
995 |
st->sparse_map_avail = 0; |
970 |
} |
996 |
} |
971 |
} |
997 |
} |
Link Here
|
982 |
sparse_offset_decoder (struct tar_stat_info *st, char const *arg) |
1008 |
sparse_offset_decoder (struct tar_stat_info *st, char const *arg) |
983 |
{ |
1009 |
{ |
984 |
uintmax_t u; |
1010 |
uintmax_t u; |
985 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
1011 |
if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.offset")) |
|
|
1012 |
{ |
1013 |
if (st->sparse_map_avail < st->sparse_map_size) |
986 |
st->sparse_map[st->sparse_map_avail].offset = u; |
1014 |
st->sparse_map[st->sparse_map_avail].offset = u; |
|
|
1015 |
else |
1016 |
ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), |
1017 |
"GNU.sparse.offset", arg)); |
1018 |
} |
987 |
} |
1019 |
} |
988 |
|
1020 |
|
989 |
static void |
1021 |
static void |
Link Here
|
998 |
sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) |
1030 |
sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) |
999 |
{ |
1031 |
{ |
1000 |
uintmax_t u; |
1032 |
uintmax_t u; |
1001 |
if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) |
1033 |
if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numbytes")) |
1002 |
{ |
1034 |
{ |
1003 |
if (st->sparse_map_avail == st->sparse_map_size) |
1035 |
if (st->sparse_map_avail == st->sparse_map_size) |
1004 |
{ |
1036 |
st->sparse_map = x2nrealloc (st->sparse_map, |
1005 |
st->sparse_map_size *= 2; |
1037 |
&st->sparse_map_size, |
1006 |
st->sparse_map = xrealloc (st->sparse_map, |
1038 |
sizeof st->sparse_map[0]); |
1007 |
st->sparse_map_size |
1039 |
|
1008 |
* sizeof st->sparse_map[0]); |
|
|
1009 |
} |
1010 |
st->sparse_map[st->sparse_map_avail++].numbytes = u; |
1040 |
st->sparse_map[st->sparse_map_avail++].numbytes = u; |
1011 |
} |
1041 |
} |
1012 |
} |
1042 |
} |