extract: move uvol extraction code to extract
fix also the progress callback on uvol extractioncute-signatures
parent
d821265865
commit
5c0c249b78
|
@ -25,9 +25,8 @@ struct apk_extract_ctx;
|
|||
|
||||
int apk_extract_file(int atfd, const struct apk_file_info *ae,
|
||||
const char *extract_name, const char *hardlink_name,
|
||||
struct apk_istream *is,
|
||||
apk_progress_cb cb, void *cb_ctx, struct apk_digest_ctx *dctx,
|
||||
unsigned int extract_flags, struct apk_out *out);
|
||||
struct apk_istream *is, apk_progress_cb cb, void *cb_ctx,
|
||||
unsigned int extract_flags, struct apk_ctx *ac);
|
||||
|
||||
struct apk_extract_ops {
|
||||
int (*v2index)(struct apk_extract_ctx *, apk_blob_t *desc, struct apk_istream *is);
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "apk_applet.h"
|
||||
#include "apk_print.h"
|
||||
|
@ -56,83 +54,6 @@ static const struct apk_option_group optgroup_applet = {
|
|||
.parse = option_parse_applet,
|
||||
};
|
||||
|
||||
static int uvol_run(struct apk_ctx *ac, char *action, const char *volname, char *arg1, char *arg2)
|
||||
{
|
||||
struct apk_out *out = &ac->out;
|
||||
pid_t pid;
|
||||
int r, status;
|
||||
char *argv[] = { (char*)apk_ctx_get_uvol(ac), action, (char*) volname, arg1, arg2, 0 };
|
||||
posix_spawn_file_actions_t act;
|
||||
|
||||
posix_spawn_file_actions_init(&act);
|
||||
posix_spawn_file_actions_addclose(&act, STDIN_FILENO);
|
||||
r = posix_spawn(&pid, apk_ctx_get_uvol(ac), &act, 0, argv, environ);
|
||||
posix_spawn_file_actions_destroy(&act);
|
||||
if (r != 0) {
|
||||
apk_err(out, "%s: uvol exec error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
apk_err(out, "%s: uvol exited with error %d", volname, WEXITSTATUS(status));
|
||||
return -APKE_UVOL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uvol_extract(struct apk_ctx *ac, const char *volname, char *arg1, off_t sz, struct apk_istream *is)
|
||||
{
|
||||
struct apk_out *out = &ac->out;
|
||||
struct apk_ostream *os;
|
||||
pid_t pid;
|
||||
int r, status, pipefds[2];
|
||||
char *argv[] = { (char*)apk_ctx_get_uvol(ac), "write", (char*) volname, arg1, 0 };
|
||||
posix_spawn_file_actions_t act;
|
||||
|
||||
if (pipe2(pipefds, O_CLOEXEC) != 0) return -errno;
|
||||
|
||||
posix_spawn_file_actions_init(&act);
|
||||
posix_spawn_file_actions_adddup2(&act, pipefds[0], STDIN_FILENO);
|
||||
r = posix_spawn(&pid, apk_ctx_get_uvol(ac), &act, 0, argv, environ);
|
||||
posix_spawn_file_actions_destroy(&act);
|
||||
if (r != 0) {
|
||||
apk_err(out, "%s: uvol exec error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
close(pipefds[0]);
|
||||
os = apk_ostream_to_fd(pipefds[1]);
|
||||
apk_stream_copy(is, os, sz, 0, 0, 0);
|
||||
r = apk_ostream_close(os);
|
||||
if (r != 0) {
|
||||
if (r >= 0) r = -APKE_UVOL;
|
||||
apk_err(out, "%s: uvol write error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
apk_err(out, "%s: uvol exited with error %d", volname, WEXITSTATUS(status));
|
||||
return -APKE_UVOL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apk_extract_volume(struct apk_ctx *ac, const struct apk_file_info *fi, struct apk_istream *is)
|
||||
{
|
||||
char size[64];
|
||||
int r;
|
||||
|
||||
snprintf(size, sizeof size, "%ju", fi->size);
|
||||
r = uvol_run(ac, "create", fi->uvol_name, size, "ro");
|
||||
if (r != 0) return r;
|
||||
|
||||
r = uvol_extract(ac, fi->uvol_name, size, fi->size, is);
|
||||
if (r == 0) r = uvol_run(ac, "up", fi->uvol_name, 0, 0);
|
||||
if (r != 0) uvol_run(ac, "remove", fi->uvol_name, 0, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int extract_v3_meta(struct apk_extract_ctx *ectx, struct adb_obj *pkg)
|
||||
{
|
||||
return 0;
|
||||
|
@ -142,18 +63,11 @@ static int extract_file(struct apk_extract_ctx *ectx, const struct apk_file_info
|
|||
{
|
||||
struct extract_ctx *ctx = container_of(ectx, struct extract_ctx, ectx);
|
||||
struct apk_out *out = &ctx->ac->out;
|
||||
int r;
|
||||
|
||||
apk_dbg2(out, "%s", fi->name);
|
||||
|
||||
if (fi->uvol_name && is) {
|
||||
r = apk_extract_volume(ectx->ac, fi, is);
|
||||
} else {
|
||||
r = apk_extract_file(ctx->root_fd, fi, 0, 0, is, 0, 0, 0,
|
||||
ctx->extract_flags, &ectx->ac->out);
|
||||
}
|
||||
if (is) r = apk_istream_close_error(is, r);
|
||||
return r;
|
||||
return apk_extract_file(ctx->root_fd, fi, 0, 0, is, 0, 0,
|
||||
ctx->extract_flags, ectx->ac);
|
||||
}
|
||||
|
||||
static const struct apk_extract_ops extract_ops = {
|
||||
|
|
|
@ -2415,7 +2415,8 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi
|
|||
struct install_ctx *ctx = container_of(ectx, struct install_ctx, ectx);
|
||||
static const char dot1[] = "/./", dot2[] = "/../";
|
||||
struct apk_database *db = ctx->db;
|
||||
struct apk_out *out = &db->ctx->out;
|
||||
struct apk_ctx *ac = db->ctx;
|
||||
struct apk_out *out = &ac->out;
|
||||
struct apk_package *pkg = ctx->pkg, *opkg;
|
||||
struct apk_dependency *dep;
|
||||
struct apk_installed_package *ipkg = pkg->ipkg;
|
||||
|
@ -2566,7 +2567,7 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi
|
|||
db->root_fd, ae,
|
||||
format_tmpname(pkg, file, tmpname_file),
|
||||
format_tmpname(pkg, link_target_file, tmpname_link_target),
|
||||
is, extract_cb, ctx, 0, db->extract_flags, out);
|
||||
is, extract_cb, ctx, db->extract_flags, ac);
|
||||
|
||||
switch (r) {
|
||||
case 0:
|
||||
|
|
|
@ -7,22 +7,110 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include "apk_context.h"
|
||||
#include "apk_extract.h"
|
||||
|
||||
static int uvol_run(struct apk_ctx *ac, char *action, const char *volname, char *arg1, char *arg2)
|
||||
{
|
||||
struct apk_out *out = &ac->out;
|
||||
pid_t pid;
|
||||
int r, status;
|
||||
char *argv[] = { (char*)apk_ctx_get_uvol(ac), action, (char*) volname, arg1, arg2, 0 };
|
||||
posix_spawn_file_actions_t act;
|
||||
|
||||
posix_spawn_file_actions_init(&act);
|
||||
posix_spawn_file_actions_addclose(&act, STDIN_FILENO);
|
||||
r = posix_spawn(&pid, apk_ctx_get_uvol(ac), &act, 0, argv, environ);
|
||||
posix_spawn_file_actions_destroy(&act);
|
||||
if (r != 0) {
|
||||
apk_err(out, "%s: uvol exec error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
apk_err(out, "%s: uvol exited with error %d", volname, WEXITSTATUS(status));
|
||||
return -APKE_UVOL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uvol_extract(struct apk_ctx *ac, const char *volname, char *arg1, off_t sz,
|
||||
struct apk_istream *is, apk_progress_cb cb, void *cb_ctx)
|
||||
{
|
||||
struct apk_out *out = &ac->out;
|
||||
struct apk_ostream *os;
|
||||
pid_t pid;
|
||||
int r, status, pipefds[2];
|
||||
char *argv[] = { (char*)apk_ctx_get_uvol(ac), "write", (char*) volname, arg1, 0 };
|
||||
posix_spawn_file_actions_t act;
|
||||
|
||||
if (pipe2(pipefds, O_CLOEXEC) != 0) return -errno;
|
||||
|
||||
posix_spawn_file_actions_init(&act);
|
||||
posix_spawn_file_actions_adddup2(&act, pipefds[0], STDIN_FILENO);
|
||||
r = posix_spawn(&pid, apk_ctx_get_uvol(ac), &act, 0, argv, environ);
|
||||
posix_spawn_file_actions_destroy(&act);
|
||||
if (r != 0) {
|
||||
apk_err(out, "%s: uvol exec error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
close(pipefds[0]);
|
||||
os = apk_ostream_to_fd(pipefds[1]);
|
||||
apk_stream_copy(is, os, sz, cb, cb_ctx, 0);
|
||||
r = apk_ostream_close(os);
|
||||
if (r != 0) {
|
||||
if (r >= 0) r = -APKE_UVOL;
|
||||
apk_err(out, "%s: uvol write error: %s", volname, apk_error_str(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
apk_err(out, "%s: uvol exited with error %d", volname, WEXITSTATUS(status));
|
||||
return -APKE_UVOL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apk_extract_volume(struct apk_ctx *ac, const struct apk_file_info *fi,
|
||||
struct apk_istream *is, apk_progress_cb cb, void *cb_ctx)
|
||||
{
|
||||
char size[64];
|
||||
int r;
|
||||
|
||||
snprintf(size, sizeof size, "%ju", fi->size);
|
||||
r = uvol_run(ac, "create", fi->uvol_name, size, "ro");
|
||||
if (r != 0) return r;
|
||||
|
||||
r = uvol_extract(ac, fi->uvol_name, size, fi->size, is, cb, cb_ctx);
|
||||
if (r == 0) r = uvol_run(ac, "up", fi->uvol_name, 0, 0);
|
||||
if (r != 0) uvol_run(ac, "remove", fi->uvol_name, 0, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
int apk_extract_file(int atfd, const struct apk_file_info *ae,
|
||||
const char *extract_name, const char *link_target,
|
||||
struct apk_istream *is,
|
||||
apk_progress_cb cb, void *cb_ctx, struct apk_digest_ctx *dctx,
|
||||
unsigned int extract_flags, struct apk_out *out)
|
||||
apk_progress_cb cb, void *cb_ctx,
|
||||
unsigned int extract_flags, struct apk_ctx *ac)
|
||||
{
|
||||
struct apk_out *out = &ac->out;
|
||||
struct apk_xattr *xattr;
|
||||
const char *fn = extract_name ?: ae->name;
|
||||
int fd, r = -1, atflags = 0, ret = 0;
|
||||
|
||||
if (ae->uvol_name && is) {
|
||||
if (extract_name || link_target) return -APKE_UVOL;
|
||||
return apk_extract_volume(ac, ae, is, cb, cb_ctx);
|
||||
}
|
||||
|
||||
if (!S_ISDIR(ae->mode) && !(extract_flags & APK_EXTRACTF_NO_OVERWRITE)) {
|
||||
if (unlinkat(atfd, fn, 0) != 0 && errno != ENOENT) return -errno;
|
||||
}
|
||||
|
@ -46,7 +134,7 @@ int apk_extract_file(int atfd, const struct apk_file_info *ae,
|
|||
ret = PTR_ERR(os);
|
||||
break;
|
||||
}
|
||||
apk_stream_copy(is, os, ae->size, cb, cb_ctx, dctx);
|
||||
apk_stream_copy(is, os, ae->size, cb, cb_ctx, 0);
|
||||
r = apk_ostream_close(os);
|
||||
if (r < 0) {
|
||||
unlinkat(atfd, fn, 0);
|
||||
|
|
Loading…
Reference in New Issue