summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_write_set_format_ustar.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libarchive/archive_write_set_format_ustar.c')
-rw-r--r--lib/libarchive/archive_write_set_format_ustar.c89
1 files changed, 48 insertions, 41 deletions
diff --git a/lib/libarchive/archive_write_set_format_ustar.c b/lib/libarchive/archive_write_set_format_ustar.c
index 2829ea6..87fc16a 100644
--- a/lib/libarchive/archive_write_set_format_ustar.c
+++ b/lib/libarchive/archive_write_set_format_ustar.c
@@ -50,11 +50,11 @@ __FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
+#include "archive_write_private.h"
struct ustar {
uint64_t entry_bytes_remaining;
uint64_t entry_padding;
- char written;
};
/*
@@ -150,38 +150,40 @@ static const char template_header[] = {
0,0,0,0,0,0,0,0, 0,0,0,0
};
-static ssize_t archive_write_ustar_data(struct archive *a, const void *buff,
+static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
size_t s);
-static int archive_write_ustar_finish(struct archive *);
-static int archive_write_ustar_finish_entry(struct archive *);
-static int archive_write_ustar_header(struct archive *,
+static int archive_write_ustar_destroy(struct archive_write *);
+static int archive_write_ustar_finish(struct archive_write *);
+static int archive_write_ustar_finish_entry(struct archive_write *);
+static int archive_write_ustar_header(struct archive_write *,
struct archive_entry *entry);
static int format_256(int64_t, char *, int);
static int format_number(int64_t, char *, int size, int max, int strict);
static int format_octal(int64_t, char *, int);
-static int write_nulls(struct archive *a, size_t);
+static int write_nulls(struct archive_write *a, size_t);
/*
* Set output format to 'ustar' format.
*/
int
-archive_write_set_format_ustar(struct archive *a)
+archive_write_set_format_ustar(struct archive *_a)
{
+ struct archive_write *a = (struct archive_write *)_a;
struct ustar *ustar;
/* If someone else was already registered, unregister them. */
- if (a->format_finish != NULL)
- (a->format_finish)(a);
+ if (a->format_destroy != NULL)
+ (a->format_destroy)(a);
/* Basic internal sanity test. */
if (sizeof(template_header) != 512) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC, "Internal: template_header wrong size: %d should be 512", sizeof(template_header));
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Internal: template_header wrong size: %d should be 512", sizeof(template_header));
return (ARCHIVE_FATAL);
}
ustar = (struct ustar *)malloc(sizeof(*ustar));
if (ustar == NULL) {
- archive_set_error(a, ENOMEM, "Can't allocate ustar data");
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate ustar data");
return (ARCHIVE_FATAL);
}
memset(ustar, 0, sizeof(*ustar));
@@ -191,6 +193,7 @@ archive_write_set_format_ustar(struct archive *a)
a->format_write_header = archive_write_ustar_header;
a->format_write_data = archive_write_ustar_data;
a->format_finish = archive_write_ustar_finish;
+ a->format_destroy = archive_write_ustar_destroy;
a->format_finish_entry = archive_write_ustar_finish_entry;
a->archive_format = ARCHIVE_FORMAT_TAR_USTAR;
a->archive_format_name = "POSIX ustar";
@@ -198,14 +201,13 @@ archive_write_set_format_ustar(struct archive *a)
}
static int
-archive_write_ustar_header(struct archive *a, struct archive_entry *entry)
+archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
{
char buff[512];
int ret;
struct ustar *ustar;
ustar = (struct ustar *)a->format_data;
- ustar->written = 1;
/* Only regular files (not hardlinks) have data. */
if (archive_entry_hardlink(entry) != NULL ||
@@ -236,7 +238,7 @@ archive_write_ustar_header(struct archive *a, struct archive_entry *entry)
* This is exported so that other 'tar' formats can use it.
*/
int
-__archive_write_format_header_ustar(struct archive *a, char h[512],
+__archive_write_format_header_ustar(struct archive_write *a, char h[512],
struct archive_entry *entry, int tartype, int strict)
{
unsigned int checksum;
@@ -272,11 +274,11 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
* remaining name are too large, return an error.
*/
if (!p) {
- archive_set_error(a, ENAMETOOLONG,
+ archive_set_error(&a->archive, ENAMETOOLONG,
"Pathname too long");
ret = ARCHIVE_WARN;
} else if (p > pp + USTAR_prefix_size) {
- archive_set_error(a, ENAMETOOLONG,
+ archive_set_error(&a->archive, ENAMETOOLONG,
"Pathname too long");
ret = ARCHIVE_WARN;
} else {
@@ -294,7 +296,7 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
if (p != NULL && p[0] != '\0') {
copy_length = strlen(p);
if (copy_length > USTAR_linkname_size) {
- archive_set_error(a, ENAMETOOLONG,
+ archive_set_error(&a->archive, ENAMETOOLONG,
"Link contents too long");
ret = ARCHIVE_WARN;
copy_length = USTAR_linkname_size;
@@ -306,7 +308,7 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
if (p != NULL && p[0] != '\0') {
copy_length = strlen(p);
if (copy_length > USTAR_uname_size) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Username too long");
ret = ARCHIVE_WARN;
copy_length = USTAR_uname_size;
@@ -318,7 +320,7 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
if (p != NULL && p[0] != '\0') {
copy_length = strlen(p);
if (strlen(p) > USTAR_gname_size) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Group name too long");
ret = ARCHIVE_WARN;
copy_length = USTAR_gname_size;
@@ -329,27 +331,27 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
st = archive_entry_stat(entry);
if (format_number(st->st_mode & 07777, h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
- archive_set_error(a, ERANGE, "Numeric mode too large");
+ archive_set_error(&a->archive, ERANGE, "Numeric mode too large");
ret = ARCHIVE_WARN;
}
if (format_number(st->st_uid, h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
- archive_set_error(a, ERANGE, "Numeric user ID too large");
+ archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
ret = ARCHIVE_WARN;
}
if (format_number(st->st_gid, h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
- archive_set_error(a, ERANGE, "Numeric group ID too large");
+ archive_set_error(&a->archive, ERANGE, "Numeric group ID too large");
ret = ARCHIVE_WARN;
}
if (format_number(st->st_size, h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
- archive_set_error(a, ERANGE, "File size out of range");
+ archive_set_error(&a->archive, ERANGE, "File size out of range");
ret = ARCHIVE_WARN;
}
if (format_number(st->st_mtime, h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
- archive_set_error(a, ERANGE,
+ archive_set_error(&a->archive, ERANGE,
"File modification time too large");
ret = ARCHIVE_WARN;
}
@@ -357,14 +359,14 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
if (format_number(major(st->st_rdev), h + USTAR_rdevmajor_offset,
USTAR_rdevmajor_size, USTAR_rdevmajor_max_size, strict)) {
- archive_set_error(a, ERANGE,
+ archive_set_error(&a->archive, ERANGE,
"Major device number too large");
ret = ARCHIVE_WARN;
}
if (format_number(minor(st->st_rdev), h + USTAR_rdevminor_offset,
USTAR_rdevminor_size, USTAR_rdevminor_max_size, strict)) {
- archive_set_error(a, ERANGE,
+ archive_set_error(&a->archive, ERANGE,
"Minor device number too large");
ret = ARCHIVE_WARN;
}
@@ -383,12 +385,12 @@ __archive_write_format_header_ustar(struct archive *a, char h[512],
case S_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
case S_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
case S_IFSOCK:
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive socket");
ret = ARCHIVE_WARN;
break;
default:
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"tar format cannot archive this (mode=0%lo)",
(unsigned long)st->st_mode);
ret = ARCHIVE_WARN;
@@ -486,27 +488,32 @@ format_octal(int64_t v, char *p, int s)
}
static int
-archive_write_ustar_finish(struct archive *a)
+archive_write_ustar_finish(struct archive_write *a)
{
struct ustar *ustar;
int r;
- r = ARCHIVE_OK;
+ if (a->compression_write == NULL)
+ return (ARCHIVE_OK);
+
+ ustar = (struct ustar *)a->format_data;
+ r = write_nulls(a, 512*2);
+ return (r);
+}
+
+static int
+archive_write_ustar_destroy(struct archive_write *a)
+{
+ struct ustar *ustar;
+
ustar = (struct ustar *)a->format_data;
- /*
- * Suppress end-of-archive if nothing else was ever written.
- * This fixes a problem where setting one format, then another
- * ends up writing a gratuitous end-of-archive marker.
- */
- if (ustar->written && a->compression_write != NULL)
- r = write_nulls(a, 512*2);
free(ustar);
a->format_data = NULL;
- return (r);
+ return (ARCHIVE_OK);
}
static int
-archive_write_ustar_finish_entry(struct archive *a)
+archive_write_ustar_finish_entry(struct archive_write *a)
{
struct ustar *ustar;
int ret;
@@ -519,7 +526,7 @@ archive_write_ustar_finish_entry(struct archive *a)
}
static int
-write_nulls(struct archive *a, size_t padding)
+write_nulls(struct archive_write *a, size_t padding)
{
int ret, to_write;
@@ -534,7 +541,7 @@ write_nulls(struct archive *a, size_t padding)
}
static ssize_t
-archive_write_ustar_data(struct archive *a, const void *buff, size_t s)
+archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
{
struct ustar *ustar;
int ret;
OpenPOWER on IntegriCloud