48int tar_strcmp(
const char *s1,
const char *s1_end,
const char *s2) {
53 if (s1_end != NULL && s1 >= s1_end)
56 unsigned char c1 = (
unsigned char)*s1;
57 unsigned char c2 = (
unsigned char)*s2;
59 if (c1 ==
'\0' || c1 ==
'\r' || c1 ==
'\n')
62 if (c2 ==
'\0' || c2 ==
'\r' || c2 ==
'\n')
66 return (
int)c1 - (int)c2;
78 unsigned char c2 = (
unsigned char)*s2;
80 if (c2 ==
'\r' || c2 ==
'\n')
94 unsigned char c1 = (
unsigned char)*s1;
95 unsigned char c2 = (
unsigned char)*s2;
97 if (c1 ==
'\0' || c1 ==
'\r' || c1 ==
'\n')
100 if (c2 ==
'\0' || c2 ==
'\r' || c2 ==
'\n')
104 return (
int)c1 - (int)c2;
117 unsigned char c2 = (
unsigned char)*s2;
119 if (c2 ==
'\r' || c2 ==
'\n')
136 if (s1_end != NULL && c >= s1_end)
138 if (*c == 0 || *c ==
'\r' || *c ==
'\n')
156 if (*src == 0 || *src ==
'\r' || *src ==
'\n')
198 while(max_len > 0 && *p ==
' ') {
204 while (max_len > 0 && *p >=
'0' && *p <=
'7' ) {
206 value = (value << 3) | (*p -
'0');
223 uint8_t
const *p = (uint8_t
const *)hdr;
226 for (
size_t i = 0; i <
sizeof(tarhdr_t); i++)
227 if (i >= 148 && i < (148 + 8))
289 expc =
tar_octal(hdr->checksum,
sizeof(hdr->checksum));
294 if (expc != calc || (calc == 0 && expc == 0))
310 int bad = 0, files = 0, dirs = 0, links = 0, bad_total = 0, hdr_no = 0;
311 uintptr_t tar_end = (uintptr_t )((
const uint8_t *)tar_start + tar_length);
313 while (off +
sizeof(tarhdr_t) <= tar_length) {
315 const tarhdr_t *hdr = (
const tarhdr_t *)(tar_start + off);
320 off +=
sizeof(tarhdr_t);
332 if (((uintptr_t)(hdr + 1)) +
size >= tar_end) {
339 case TART_FILE: files++;
break;
342 case TART_HARDLINK: links++;
break;
344 case TART_DIR: dirs++;
break;
351 off +=
sizeof(tarhdr_t);
355 off += ((size_t)
size + 511) & ~511u;
360 unsigned int total = files + links + dirs;
362 log(
"headers processed: %u, number of bad metadata headers: %u\r\n", hdr_no, bad_total);
363 log(
"# of inodes calculated: %u (%u files, %u dirs, %u links\r\n",total, files, dirs, links);
372bool tar_rootdir(
const uint8_t *tar_start,
size_t tar_length,
char *base_dir,
size_t out_len) {
376 uintptr_t tar_end = (uintptr_t )((
const uint8_t *)tar_start + tar_length);
378 while (off +
sizeof(tarhdr_t) <= tar_length) {
380 const tarhdr_t *hdr = (
const tarhdr_t *)(tar_start + off);
387 if (((uintptr_t)(hdr + 1)) +
size < tar_end) {
390 if (hdr->type == TART_DIR) {
394 int l =
tar_strlen(hdr->name, &hdr->name[0] +
sizeof(hdr->name));
396 memcpy(base_dir, hdr->name, l - 1 );
407 off += (((size_t)
size + 511) & ~511u) +
sizeof(tarhdr_t);
409 log(
"failed to guess root directory\r\n");
420void tar_print(
const char *buf,
const char *end) {
423 const char *text = buf;
426 end = (
const char *)(-1);
429 for (; (text + len) < end; len++) {
430 if (text[len] ==
'\0' || text[len] ==
'\r' || text[len] ==
'\n' )
444#if TARSUM_BUILD && CONFIG_TARFS_INTEGRITY
449int tar_addsum(uint8_t *tar_start,
size_t tar_length) {
455 uintptr_t tar_end = (uintptr_t )(tar_start + tar_length);
457 while (off +
sizeof(tarhdr_t) <= tar_length) {
459 tarhdr_t *hdr = (tarhdr_t *)(tar_start + off);
467 off +=
sizeof(tarhdr_t);
475 if (((uintptr_t)(hdr + 1)) +
size >= tar_end)
486 char tmp[9] = {
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' ',
' '};
487 void const *data = (
void *)(hdr + 1);
494 for (
int i = 0; i < 8; i++) {
497 hdr->digest[i] = octet;
511 snprintf(tmp,
sizeof(tmp),
"%-8o", new_sum);
512 memcpy(hdr->checksum, tmp, 8);
517 off +=
sizeof(tarhdr_t) + (((
size_t)
size + 511) & ~511u);
531#if CONFIG_TARFS_INTEGRITY
532 uint64_t icv_calc, icv_hdr;
540 void const *data = (
void *)(hdr + 1);
544 memcpy(&icv_hdr, hdr->digest, 8);
546#if CONFIG_TARFS_BIG_ENDIAN
548 icv_hdr = __builtin_bswap64(icv_hdr);
550 return icv_hdr != icv_calc;
uint64_t hash64(uint64_t prev_crc, void const *buffer0, size_t buf_len)
CRC-64/ECMA-182 algoritm.
size_t tarfs_os_mp_maxlen()
Return the maximum mount point name length supported by the platform.
void * tarfs_os_malloc(size_t size)
Memory allocation backend.
For TAR files with modified PADDING field (see tarsum.c TARFS Checksum Utility): The type and meaning...
void tar_strcpy(char *dst, const char *src)
int tar_strncmp(const char *s1, const char *s2, size_t len)
char * tar_strdup1(const char *s1, const char *s1_end)
Duplicate a TAR string as a regular NUL-terminated C string.
uint32_t tar_octal(const char *p, size_t max_len)
bool tar_badhdr(tarhdr_t const *hdr)
Validate a TAR header.
int tar_getnino(const uint8_t *tar_start, size_t tar_length)
Quick run through the tarfile to count number of inodes we have to create.
uint32_t tar_hdrsum(tarhdr_t const *hdr)
int tar_strcmp(const char *s1, const char *s1_end, const char *s2)
Compare an UTS/CTS to a CTS.
int tar_strlen(const char *s1, const char *s1_end)
Return the length of a TAR string.
bool tar_baddata(struct tarhdr const *hdr, size_t size)
Verify CRC64 checksum stored in a TAR archive, if present.
bool tar_rootdir(const uint8_t *tar_start, size_t tar_length, char *base_dir, size_t out_len)
Detect the archive root directory.