33#include <archive_entry.h>
36#include "xbps_api_impl.h"
39xbps_archive_errno(
struct archive *ar)
41 int err = archive_errno(ar);
42 return err == -1 ? EINVAL : err;
46xbps_archive_get_file(
struct archive *ar,
struct archive_entry *entry)
55 assert(entry != NULL);
57 entry_size = archive_entry_size(entry);
58 if (entry_size < 0 || (uint64_t)entry_size >= SIZE_MAX) {
64 buf = malloc(len + 1);
72 ssize_t rd = archive_read_data(ar, buf + used, len - used);
73 if (rd == ARCHIVE_FATAL || rd == ARCHIVE_WARN) {
74 const char *pname = archive_entry_pathname(entry);
77 r = -xbps_archive_errno(ar);
79 "failed to read archive entry: %s: %s\n",
80 pname, archive_error_string(ar));
82 }
else if (rd == ARCHIVE_RETRY) {
86 if (rd == 0 || used == len)
90 const char *pname = archive_entry_pathname(entry);
95 "failed to read archive entry: %s: could not read enough "
96 "data: %s\n", pname, strerror(-r));
108xbps_dictionary_t HIDDEN
109xbps_archive_get_dictionary(
struct archive *ar,
struct archive_entry *entry)
111 xbps_dictionary_t d = NULL;
114 if ((buf = xbps_archive_get_file(ar, entry)) == NULL)
118 d = xbps_dictionary_internalize(buf);
125 const char *fname,
const mode_t mode,
const char *uname,
const char *gname)
127 struct archive_entry *entry;
135 entry = archive_entry_new();
137 return -xbps_archive_errno(ar);
139 archive_entry_set_filetype(entry, AE_IFREG);
140 archive_entry_set_perm(entry, mode);
141 archive_entry_set_uname(entry, uname);
142 archive_entry_set_gname(entry, gname);
143 archive_entry_set_pathname(entry, fname);
144 archive_entry_set_size(entry, buflen);
146 if (archive_write_header(ar, entry) != ARCHIVE_OK) {
147 archive_entry_free(entry);
148 return -xbps_archive_errno(ar);
150 if (archive_write_data(ar, buf, buflen) != ARCHIVE_OK) {
151 archive_entry_free(entry);
152 return -xbps_archive_errno(ar);
154 if (archive_write_finish_entry(ar) != ARCHIVE_OK) {
155 archive_entry_free(entry);
156 return -xbps_archive_errno(ar);
158 archive_entry_free(entry);
163struct fetch_archive {
165 struct fetchIO *fetch;
170fetch_archive_open(
struct archive *a,
void *client_data)
172 struct fetch_archive *f = client_data;
174 f->fetch = fetchGet(f->url, NULL);
178 switch (fetchLastErrCode) {
186 archive_set_error(a, err,
"%s", errstr ? errstr :
"unknown fetch error");
187 return ARCHIVE_FATAL;
194fetch_archive_read(
struct archive *a UNUSED,
void *client_data,
const void **buf)
196 struct fetch_archive *f = client_data;
200 rd = fetchIO_read(f->fetch, f->buffer,
sizeof(f->buffer));
203 archive_set_error(a, EIO,
"%s", errstr ? errstr :
"unknown fetch error");
210fetch_archive_close(
struct archive *a UNUSED,
void *client_data)
212 struct fetch_archive *f = client_data;
214 if (f->fetch != NULL)
215 fetchIO_close(f->fetch);
216 fetchFreeURL(f->url);
222struct archive HIDDEN *
223xbps_archive_read_new(
void)
225 struct archive *ar = archive_read_new();
228 archive_read_support_filter_gzip(ar);
229 archive_read_support_filter_bzip2(ar);
230 archive_read_support_filter_xz(ar);
231 archive_read_support_filter_lz4(ar);
232 archive_read_support_filter_zstd(ar);
233 archive_read_support_format_tar(ar);
238xbps_archive_read_open(
struct archive *ar,
const char *filename)
240 int r = archive_read_open_filename(ar, filename, 4096);
241 if (r == ARCHIVE_FATAL)
242 return -xbps_archive_errno(ar);
247xbps_archive_read_open_remote(
struct archive *ar,
const char *url)
250 struct fetch_archive *f;
253 furl = fetchParseURL(url);
257 f = calloc(1,
sizeof(*f));
265 r = archive_read_open(ar, f, fetch_archive_open, fetch_archive_read,
266 fetch_archive_close);
267 if (r == ARCHIVE_FATAL) {
268 return -xbps_archive_errno(ar);
int xbps_archive_append_buf(struct archive *ar, const void *buf, const size_t buflen, const char *fname, const mode_t mode, const char *uname, const char *gname)
const char * xbps_fetch_error_string(void)
#define xbps_unreachable()
Log and abort for code that should be unreachable.
#define xbps_error_oom()
Log out of memory condition.
void xbps_error_printf(const char *fmt,...)
Prints error messages to stderr.