(xheader_format_name): Fix memory leak.

This commit is contained in:
Sergey Poznyakoff
2005-11-26 19:31:02 +00:00
parent 87dfaf3176
commit 9590e781c0

View File

@@ -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)