Skip to content
This repository was archived by the owner on Jun 28, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ so your version of libtar will not be thread-safe.
fi


dnl ### Eable large file support. ##################################
AC_SYS_LARGEFILE


dnl ### Checks for header files. ###################################
AC_HEADER_STDC
AC_CHECK_HEADERS([unistd.h])
Expand Down
15 changes: 10 additions & 5 deletions lib/libtar.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <tar.h>
#include <unistd.h>

#include <libtar_listhash.h>

#if (defined(_POSIX_V6_ILP32_OFF32) || defined(_POSIX_V7_ILP32_OFF32)) && _FILE_OFFSET_BITS != 64
#warning _FILE_OFFSET_BITS is not set to 64. libtar may demonstrate errors.
#endif

#ifdef __cplusplus
extern "C"
{
Expand Down Expand Up @@ -277,15 +282,15 @@ int th_signed_crc_calc(TAR *t);
#define th_crc_ok(t) (th_get_crc(t) == th_crc_calc(t) || th_get_crc(t) == th_signed_crc_calc(t))

/* string-octal to integer conversion */
int oct_to_int(char *oct);
size_t oct_to_size(char *oct);
#define oct_to_int(value) oct_to_int_bounds(value, sizeof(value), 0, ~0 ^ (int)1<<sizeof(int)*8-1)
#define oct_to_size(value) oct_to_int_bounds(value, sizeof(value), 0, ~0 ^ (off_t)1<<sizeof(off_t)*8-1)
off_t oct_to_int_bounds(char *oct, int len, off_t min, off_t max);

/* integer to NULL-terminated string-octal conversion */
#define int_to_oct(num, oct, octlen) \
snprintf((oct), (octlen), "%*lo ", (octlen) - 2, (unsigned long)(num))
void int_to_oct(off_t num, char * oct, int octlen);

/* integer to string-octal conversion, no NULL */
void int_to_oct_nonull(int num, char *oct, size_t octlen);
void int_to_oct_nonull(off_t num, char *oct, size_t octlen);


/***** wrapper.c **********************************************************/
Expand Down
2 changes: 1 addition & 1 deletion lib/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ th_print_long_ls(TAR *t)
if (TH_ISCHR(t) || TH_ISBLK(t))
printf(" %3d, %3d ", th_get_devmajor(t), th_get_devminor(t));
else
printf("%9ld ", (long)th_get_size(t));
printf("%9llu ", (unsigned long long)th_get_size(t));

mtime = th_get_mtime(t);
mtm = localtime(&mtime);
Expand Down
52 changes: 38 additions & 14 deletions lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,30 +143,54 @@ th_signed_crc_calc(TAR *t)


/* string-octal to integer conversion */
int
oct_to_int(char *oct)
off_t
oct_to_int_bounds(char *oct, int len, off_t min, off_t max)
{
int i;

return sscanf(oct, "%o", &i) == 1 ? i : 0;
long long i;
if (oct[0] & 0x80) {
// common base 256 extension

// sign-extend
i = (oct[0] & 0x40) ? (off_t)-1 << ((len - 1) * 8) : 0;
// remove sign from first byte
i |= (off_t)(oct[0] & 0x7f) << ((len - 1) * 8);
// base 256
for (int w = 1; w < len; w ++) {
i |= (off_t)oct[w] << ((len - 1 - w) * 8);
}
} else {
if (sscanf(oct, "%llo", &i) == 0) {
i = 0;
}
}
return (i >= min && i <= max) ? i : 0;
}

/* string-octal to size_t conversion */
size_t
oct_to_size(char *oct)
/* integer to NULL-terminated string-octal conversion */
void
int_to_oct(off_t num, char * oct, int octlen)
{
size_t i;

return sscanf(oct, "%zo", &i) == 1 ? i : 0;
int_to_oct_nonull(num, oct, octlen - 1);
oct[octlen - 1] = '\0';
}


/* integer to string-octal conversion, no NULL */
void
int_to_oct_nonull(int num, char *oct, size_t octlen)
int_to_oct_nonull(off_t num, char *oct, size_t octlen)
{
snprintf(oct, octlen, "%*lo", (int)(octlen - 1), (unsigned long)num);
oct[octlen - 1] = ' ';
if (num >= 0 && num <= 077777777777) {
snprintf(oct, octlen, "%*llo", (int)(octlen - 1), (unsigned long long)num);
oct[octlen - 1] = ' ';
} else {
// common base 256 extension
while (octlen) {
octlen --;
oct[octlen] = num & 0xff;
num >>= 8;
}
oct[0] |= 0x80;
}
}