(xheader_format_name): Fix memory leak.
This commit is contained in:
@@ -235,6 +235,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
|
||||
size_t len = strlen (fmt);
|
||||
char *q;
|
||||
const char *p;
|
||||
char *dirp = NULL;
|
||||
char *dir = NULL;
|
||||
char *base = NULL;
|
||||
char pidbuf[UINTMAX_STRSIZE_BOUND];
|
||||
@@ -253,8 +254,9 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
|
||||
case 'd':
|
||||
if (st)
|
||||
{
|
||||
dir = safer_name_suffix (dir_name (st->orig_file_name),
|
||||
false, absolute_names_option);
|
||||
if (!dirp)
|
||||
dirp = dir_name (st->orig_file_name);
|
||||
dir = safer_name_suffix (dirp, false, absolute_names_option);
|
||||
len += strlen (dir) - 2;
|
||||
}
|
||||
break;
|
||||
@@ -328,6 +330,8 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
|
||||
*q++ = *p++;
|
||||
}
|
||||
|
||||
free (dirp);
|
||||
|
||||
/* Do not allow it to end in a slash */
|
||||
while (q > buf && ISSLASH (q[-1]))
|
||||
q--;
|
||||
@@ -370,6 +374,17 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
size_t size;
|
||||
char *p;
|
||||
|
||||
if (multi_volume_option)
|
||||
{
|
||||
/* Estimate the total size of the extended header and, in case
|
||||
if XHDTYPE, the ustar header following it, and make sure that
|
||||
these fit into the current volume */
|
||||
size_t hblocks = 1 + (extended_header.size + BLOCKSIZE - 1) / BLOCKSIZE;
|
||||
if (type == XHDTYPE)
|
||||
hblocks++;
|
||||
multi_volume_fixup (hblocks);
|
||||
}
|
||||
|
||||
size = xhdr->size;
|
||||
header = start_private_header (name, size);
|
||||
header->header.typeflag = type;
|
||||
@@ -400,6 +415,44 @@ xheader_write (char type, char *name, struct xheader *xhdr)
|
||||
global_header_count++;
|
||||
}
|
||||
|
||||
/* SIZE is guaranteed to be divisible by BLOCKSIZE */
|
||||
void
|
||||
xheader_eof (size_t size)
|
||||
{
|
||||
union block *header;
|
||||
char *name;
|
||||
int first_block = 1;
|
||||
int nl = 0;
|
||||
|
||||
size -= BLOCKSIZE;
|
||||
name = xheader_ghdr_name ();
|
||||
header = start_private_header (name, size);
|
||||
header->header.typeflag = XGLTYPE;
|
||||
free (name);
|
||||
simple_finish_header (header);
|
||||
if (size)
|
||||
nl = 1;
|
||||
while (size > 0)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
header = find_next_block ();
|
||||
len = BLOCKSIZE;
|
||||
if (len > size)
|
||||
len = size;
|
||||
memset (header->buffer, 0, len);
|
||||
if (first_block)
|
||||
{
|
||||
first_block = 0;
|
||||
sprintf (header->buffer, "%d GNU.volume.eof=", size);
|
||||
}
|
||||
size -= len;
|
||||
set_next_block_after (header);
|
||||
}
|
||||
if (nl)
|
||||
header->buffer[BLOCKSIZE-1] = '\n';
|
||||
}
|
||||
|
||||
void
|
||||
xheader_write_global (void)
|
||||
{
|
||||
@@ -615,6 +668,20 @@ extended_header_init (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xheader_save (struct xheader *xhdr)
|
||||
{
|
||||
*xhdr = extended_header;
|
||||
memset (&extended_header, 0, sizeof extended_header);
|
||||
}
|
||||
|
||||
void
|
||||
xheader_restore (struct xheader *xhdr)
|
||||
{
|
||||
xheader_destroy (&extended_header);
|
||||
extended_header = *xhdr;
|
||||
}
|
||||
|
||||
void
|
||||
xheader_store (char const *keyword, struct tar_stat_info const *st,
|
||||
void const *data)
|
||||
|
||||
Reference in New Issue
Block a user