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)
54 assert(entry != NULL);
56 len = archive_entry_size(entry);
58 buf = malloc(len + 1);
60 xbps_error_printf(
"out of memory\n");
66 ssize_t rd = archive_read_data(ar, buf + used, len - used);
67 if (rd == ARCHIVE_FATAL || rd == ARCHIVE_WARN) {
68 r = -xbps_archive_errno(ar);
70 "failed to read archive entry: %s: %s\n",
71 archive_entry_pathname(entry),
72 archive_error_string(ar));
74 }
else if (rd == ARCHIVE_RETRY) {
78 if (rd == 0 || used == len)
84 "failed to read archive entry: %s: could not read enough "
86 archive_entry_pathname(entry), strerror(-r));
98xbps_dictionary_t HIDDEN
99xbps_archive_get_dictionary(
struct archive *ar,
struct archive_entry *entry)
101 xbps_dictionary_t d = NULL;
104 if ((buf = xbps_archive_get_file(ar, entry)) == NULL)
108 d = xbps_dictionary_internalize(buf);
115 const char *fname,
const mode_t mode,
const char *uname,
const char *gname)
117 struct archive_entry *entry;
125 entry = archive_entry_new();
127 return -xbps_archive_errno(ar);
129 archive_entry_set_filetype(entry, AE_IFREG);
130 archive_entry_set_perm(entry, mode);
131 archive_entry_set_uname(entry, uname);
132 archive_entry_set_gname(entry, gname);
133 archive_entry_set_pathname(entry, fname);
134 archive_entry_set_size(entry, buflen);
136 if (archive_write_header(ar, entry) != ARCHIVE_OK) {
137 archive_entry_free(entry);
138 return -xbps_archive_errno(ar);
140 if (archive_write_data(ar, buf, buflen) != ARCHIVE_OK) {
141 archive_entry_free(entry);
142 return -xbps_archive_errno(ar);
144 if (archive_write_finish_entry(ar) != ARCHIVE_OK) {
145 archive_entry_free(entry);
146 return -xbps_archive_errno(ar);
148 archive_entry_free(entry);
153struct fetch_archive {
155 struct fetchIO *fetch;
160fetch_archive_open(
struct archive *a,
void *client_data)
162 struct fetch_archive *f = client_data;
164 f->fetch = fetchGet(f->url, NULL);
168 switch (fetchLastErrCode) {
176 archive_set_error(a, err,
"%s", errstr ? errstr :
"unknown fetch error");
177 return ARCHIVE_FATAL;
184fetch_archive_read(
struct archive *a UNUSED,
void *client_data,
const void **buf)
186 struct fetch_archive *f = client_data;
190 rd = fetchIO_read(f->fetch, f->buffer,
sizeof(f->buffer));
193 archive_set_error(a, EIO,
"%s", errstr ? errstr :
"unknown fetch error");
200fetch_archive_close(
struct archive *a UNUSED,
void *client_data)
202 struct fetch_archive *f = client_data;
204 if (f->fetch != NULL)
205 fetchIO_close(f->fetch);
206 fetchFreeURL(f->url);
212struct archive HIDDEN *
213xbps_archive_read_new(
void)
215 struct archive *ar = archive_read_new();
218 archive_read_support_filter_gzip(ar);
219 archive_read_support_filter_bzip2(ar);
220 archive_read_support_filter_xz(ar);
221 archive_read_support_filter_lz4(ar);
222 archive_read_support_filter_zstd(ar);
223 archive_read_support_format_tar(ar);
228xbps_archive_read_open(
struct archive *ar,
const char *filename)
230 int r = archive_read_open_filename(ar, filename, 4096);
231 if (r == ARCHIVE_FATAL)
232 return -xbps_archive_errno(ar);
237xbps_archive_read_open_remote(
struct archive *ar,
const char *url)
240 struct fetch_archive *f;
243 furl = fetchParseURL(url);
247 f = calloc(1,
sizeof(*f));
255 r = archive_read_open(ar, f, fetch_archive_open, fetch_archive_read,
256 fetch_archive_close);
257 if (r == ARCHIVE_FATAL) {
258 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)