apk: use *at instead of chdir+normal file syscall
this way we never change cwd, and relative filenames are always parsed consistently. this also helps filename construction in many places. this patch also changes '--root' to override location of all configuration to be in the new root. previously it depended on the file which one was used.cute-signatures
parent
67108bf07a
commit
ea90152664
|
@ -9,6 +9,7 @@ apk-objs := state.o database.o package.o archive.o \
|
||||||
version.o io.o url.o gunzip.o blob.o hash.o apk.o \
|
version.o io.o url.o gunzip.o blob.o hash.o apk.o \
|
||||||
add.o del.o update.o info.o search.o upgrade.o \
|
add.o del.o update.o info.o search.o upgrade.o \
|
||||||
cache.o ver.o index.o fetch.o audit.o verify.o
|
cache.o ver.o index.o fetch.o audit.o verify.o
|
||||||
|
CFLAGS += -D_ATFILE_SOURCE
|
||||||
CFLAGS_apk.o := -DAPK_VERSION=\"$(FULL_VERSION)\"
|
CFLAGS_apk.o := -DAPK_VERSION=\"$(FULL_VERSION)\"
|
||||||
|
|
||||||
progs-$(STATIC) += apk.static
|
progs-$(STATIC) += apk.static
|
||||||
|
|
|
@ -101,7 +101,7 @@ static int add_main(void *ctx, int argc, char **argv)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
|
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
|
||||||
NULL);
|
NULL, db.keys_fd);
|
||||||
r = apk_pkg_read(&db, argv[i], &sctx, &pkg);
|
r = apk_pkg_read(&db, argv[i], &sctx, &pkg);
|
||||||
apk_sign_ctx_free(&sctx);
|
apk_sign_ctx_free(&sctx);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
const char *apk_root;
|
const char *apk_root;
|
||||||
struct apk_repository_url apk_repository_list;
|
struct apk_repository_url apk_repository_list;
|
||||||
int apk_verbosity = 1, apk_cwd_fd, apk_wait;
|
int apk_verbosity = 1, apk_wait;
|
||||||
unsigned int apk_flags = 0;
|
unsigned int apk_flags = 0;
|
||||||
|
|
||||||
static struct apk_option generic_options[] = {
|
static struct apk_option generic_options[] = {
|
||||||
|
@ -292,7 +292,6 @@ int main(int argc, char **argv)
|
||||||
struct apk_repository_url *repo = NULL;
|
struct apk_repository_url *repo = NULL;
|
||||||
|
|
||||||
umask(0);
|
umask(0);
|
||||||
apk_cwd_fd = open(".", O_RDONLY);
|
|
||||||
apk_root = getenv("ROOT");
|
apk_root = getenv("ROOT");
|
||||||
list_init(&apk_repository_list.list);
|
list_init(&apk_repository_list.list);
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,8 @@ int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae,
|
||||||
char *data);
|
char *data);
|
||||||
int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
|
int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
|
||||||
|
|
||||||
int apk_archive_entry_extract(const struct apk_file_info *ae,
|
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
|
||||||
struct apk_istream *is,
|
const char *suffix, struct apk_istream *is,
|
||||||
const char *to,
|
|
||||||
apk_progress_cb cb, void *cb_ctx);
|
apk_progress_cb cb, void *cb_ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct apk_repository {
|
||||||
|
|
||||||
struct apk_database {
|
struct apk_database {
|
||||||
char *root;
|
char *root;
|
||||||
int root_fd, lock_fd;
|
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
|
||||||
unsigned name_id, num_repos;
|
unsigned name_id, num_repos;
|
||||||
const char *cache_dir;
|
const char *cache_dir;
|
||||||
int permanent;
|
int permanent;
|
||||||
|
@ -134,7 +134,6 @@ struct apk_db_file *apk_db_file_query(struct apk_database *db,
|
||||||
int apk_db_open(struct apk_database *db, const char *root, unsigned int flags);
|
int apk_db_open(struct apk_database *db, const char *root, unsigned int flags);
|
||||||
int apk_db_write_config(struct apk_database *db);
|
int apk_db_write_config(struct apk_database *db);
|
||||||
void apk_db_close(struct apk_database *db);
|
void apk_db_close(struct apk_database *db);
|
||||||
int apk_db_cache_active(struct apk_database *db);
|
|
||||||
int apk_db_permanent(struct apk_database *db);
|
int apk_db_permanent(struct apk_database *db);
|
||||||
|
|
||||||
struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
|
struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
|
||||||
|
@ -147,10 +146,11 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
|
||||||
|
|
||||||
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
|
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
|
||||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
|
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
|
||||||
int apk_cache_download(struct apk_database *db, struct apk_checksum *csum,
|
|
||||||
const char *url, const char *item, int verify);
|
int apk_db_cache_active(struct apk_database *db);
|
||||||
int apk_cache_exists(struct apk_database *db, struct apk_checksum *csum,
|
void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo, int ver);
|
||||||
const char *item);
|
int apk_cache_download(struct apk_database *db, const char *url,
|
||||||
|
const char *item, const char *cache_item, int verify);
|
||||||
|
|
||||||
int apk_db_install_pkg(struct apk_database *db,
|
int apk_db_install_pkg(struct apk_database *db,
|
||||||
struct apk_package *oldpkg,
|
struct apk_package *oldpkg,
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int apk_cwd_fd, apk_verbosity, apk_wait;
|
extern int apk_verbosity, apk_wait;
|
||||||
extern unsigned int apk_flags;
|
extern unsigned int apk_flags;
|
||||||
|
|
||||||
#define APK_FORCE 0x0001
|
#define APK_FORCE 0x0001
|
||||||
|
|
19
src/apk_io.h
19
src/apk_io.h
|
@ -66,8 +66,8 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *);
|
||||||
struct apk_ostream *apk_ostream_counter(off_t *);
|
struct apk_ostream *apk_ostream_counter(off_t *);
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_fd(int fd);
|
struct apk_istream *apk_istream_from_fd(int fd);
|
||||||
struct apk_istream *apk_istream_from_file(const char *file);
|
struct apk_istream *apk_istream_from_file(int atfd, const char *file);
|
||||||
struct apk_istream *apk_istream_from_file_gz(const char *file);
|
struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file);
|
||||||
struct apk_istream *apk_istream_from_url(const char *url);
|
struct apk_istream *apk_istream_from_url(const char *url);
|
||||||
struct apk_istream *apk_istream_from_url_gz(const char *url);
|
struct apk_istream *apk_istream_from_url_gz(const char *url);
|
||||||
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
|
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
|
||||||
|
@ -76,20 +76,21 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
|
||||||
|
|
||||||
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
|
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
|
||||||
struct apk_bstream *apk_bstream_from_fd(int fd);
|
struct apk_bstream *apk_bstream_from_fd(int fd);
|
||||||
struct apk_bstream *apk_bstream_from_file(const char *file);
|
struct apk_bstream *apk_bstream_from_file(int atfd, const char *file);
|
||||||
struct apk_bstream *apk_bstream_from_url(const char *url);
|
struct apk_bstream *apk_bstream_from_url(const char *url);
|
||||||
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, const char *to);
|
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to);
|
||||||
|
|
||||||
struct apk_ostream *apk_ostream_to_fd(int fd);
|
struct apk_ostream *apk_ostream_to_fd(int fd);
|
||||||
struct apk_ostream *apk_ostream_to_file(const char *file, mode_t mode);
|
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode);
|
||||||
struct apk_ostream *apk_ostream_to_file_gz(const char *file, mode_t mode);
|
struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, mode_t mode);
|
||||||
size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string);
|
size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string);
|
||||||
|
|
||||||
apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
|
apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
|
||||||
apk_blob_t apk_blob_from_file(const char *file);
|
apk_blob_t apk_blob_from_file(int atfd, const char *file);
|
||||||
|
|
||||||
int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *fi);
|
int apk_file_get_info(int atfd, const char *filename, int checksum,
|
||||||
int apk_url_download(const char *url, const char *file);
|
struct apk_file_info *fi);
|
||||||
|
int apk_url_download(const char *url, int atfd, const char *file);
|
||||||
const char *apk_url_local_file(const char *url);
|
const char *apk_url_local_file(const char *url);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct apk_name;
|
||||||
#define APK_SIGN_VERIFY_AND_GENERATE 5
|
#define APK_SIGN_VERIFY_AND_GENERATE 5
|
||||||
|
|
||||||
struct apk_sign_ctx {
|
struct apk_sign_ctx {
|
||||||
|
int keys_fd;
|
||||||
int action;
|
int action;
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
int num_signatures;
|
int num_signatures;
|
||||||
|
@ -97,7 +98,7 @@ APK_ARRAY(apk_package_array, struct apk_package *);
|
||||||
extern const char *apk_script_types[];
|
extern const char *apk_script_types[];
|
||||||
|
|
||||||
void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
|
void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
|
||||||
struct apk_checksum *identity);
|
struct apk_checksum *identity, int keys_fd);
|
||||||
void apk_sign_ctx_free(struct apk_sign_ctx *ctx);
|
void apk_sign_ctx_free(struct apk_sign_ctx *ctx);
|
||||||
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
||||||
const struct apk_file_info *fi,
|
const struct apk_file_info *fi,
|
||||||
|
@ -121,6 +122,8 @@ void apk_deps_parse(struct apk_database *db,
|
||||||
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os);
|
int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os);
|
||||||
int apk_script_type(const char *name);
|
int apk_script_type(const char *name);
|
||||||
|
|
||||||
|
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to);
|
||||||
|
void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to);
|
||||||
struct apk_package *apk_pkg_new(void);
|
struct apk_package *apk_pkg_new(void);
|
||||||
int apk_pkg_read(struct apk_database *db, const char *name,
|
int apk_pkg_read(struct apk_database *db, const char *name,
|
||||||
struct apk_sign_ctx *ctx, struct apk_package **pkg);
|
struct apk_sign_ctx *ctx, struct apk_package **pkg);
|
||||||
|
|
|
@ -309,29 +309,28 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_archive_entry_extract(const struct apk_file_info *ae,
|
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
|
||||||
struct apk_istream *is,
|
const char *suffix, struct apk_istream *is,
|
||||||
const char *fn, apk_progress_cb cb,
|
apk_progress_cb cb, void *cb_ctx)
|
||||||
void *cb_ctx)
|
|
||||||
{
|
{
|
||||||
struct utimbuf utb;
|
char *fn = ae->name;
|
||||||
int r = -1, fd;
|
int fd, r = -1, atflags = 0;
|
||||||
|
|
||||||
if (fn == NULL)
|
if (suffix != NULL) {
|
||||||
fn = ae->name;
|
fn = alloca(PATH_MAX);
|
||||||
|
snprintf(fn, PATH_MAX, "%s%s", ae->name, suffix);
|
||||||
/* BIG HONKING FIXME */
|
}
|
||||||
unlink(fn);
|
unlinkat(atfd, fn, 0);
|
||||||
|
|
||||||
switch (ae->mode & S_IFMT) {
|
switch (ae->mode & S_IFMT) {
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
r = mkdir(fn, ae->mode & 07777);
|
r = mkdirat(atfd, fn, ae->mode & 07777);
|
||||||
if (r < 0 && errno == EEXIST)
|
if (r < 0 && errno == EEXIST)
|
||||||
r = 0;
|
r = 0;
|
||||||
break;
|
break;
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
if (ae->link_target == NULL) {
|
if (ae->link_target == NULL) {
|
||||||
fd = open(fn, O_RDWR | O_CREAT, ae->mode & 07777);
|
fd = openat(atfd, fn, O_RDWR | O_CREAT, ae->mode & 07777);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
r = -1;
|
r = -1;
|
||||||
break;
|
break;
|
||||||
|
@ -341,27 +340,28 @@ int apk_archive_entry_extract(const struct apk_file_info *ae,
|
||||||
r = 0;
|
r = 0;
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
char link_target[PATH_MAX];
|
char *link_target = ae->link_target;
|
||||||
snprintf(link_target, sizeof(link_target),
|
if (suffix != NULL) {
|
||||||
"%s.apk-new", ae->link_target);
|
link_target = alloca(PATH_MAX);
|
||||||
r = link(link_target, fn);
|
snprintf(link_target, PATH_MAX, "%s%s",
|
||||||
|
ae->link_target, suffix);
|
||||||
|
}
|
||||||
|
r = linkat(atfd, link_target, atfd, fn, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
r = symlink(ae->link_target, fn);
|
r = symlinkat(ae->link_target, atfd, fn);
|
||||||
|
atflags |= AT_SYMLINK_NOFOLLOW;
|
||||||
break;
|
break;
|
||||||
case S_IFSOCK:
|
case S_IFSOCK:
|
||||||
case S_IFBLK:
|
case S_IFBLK:
|
||||||
case S_IFCHR:
|
case S_IFCHR:
|
||||||
case S_IFIFO:
|
case S_IFIFO:
|
||||||
r = mknod(fn, ae->mode & 07777, ae->device);
|
r = mknodat(atfd, fn, ae->mode & 07777, ae->device);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
if (!S_ISLNK(ae->mode))
|
r = fchownat(atfd, fn, ae->uid, ae->gid, atflags);
|
||||||
r = chown(fn, ae->uid, ae->gid);
|
|
||||||
else
|
|
||||||
r = lchown(fn, ae->uid, ae->gid);
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
apk_error("Failed to set ownership on %s: %s",
|
apk_error("Failed to set ownership on %s: %s",
|
||||||
fn, strerror(errno));
|
fn, strerror(errno));
|
||||||
|
@ -370,7 +370,7 @@ int apk_archive_entry_extract(const struct apk_file_info *ae,
|
||||||
|
|
||||||
/* chown resets suid bit so we need set it again */
|
/* chown resets suid bit so we need set it again */
|
||||||
if (ae->mode & 07000) {
|
if (ae->mode & 07000) {
|
||||||
r = chmod(fn, ae->mode & 07777);
|
r = fchmodat(atfd, fn, ae->mode & 07777, atflags);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
apk_error("Failed to set file permissions "
|
apk_error("Failed to set file permissions "
|
||||||
"on %s: %s",
|
"on %s: %s",
|
||||||
|
@ -381,8 +381,11 @@ int apk_archive_entry_extract(const struct apk_file_info *ae,
|
||||||
|
|
||||||
if (!S_ISLNK(ae->mode)) {
|
if (!S_ISLNK(ae->mode)) {
|
||||||
/* preserve modification time */
|
/* preserve modification time */
|
||||||
utb.actime = utb.modtime = ae->mtime;
|
struct timespec times[2];
|
||||||
r = utime(fn, &utb);
|
|
||||||
|
times[0].tv_sec = times[1].tv_sec = ae->mtime;
|
||||||
|
times[0].tv_nsec = times[1].tv_nsec = 0;
|
||||||
|
r = utimensat(atfd, fn, times, atflags);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
apk_error("Failed to preserve modification time on %s: %s",
|
apk_error("Failed to preserve modification time on %s: %s",
|
||||||
fn, strerror(errno));
|
fn, strerror(errno));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -42,7 +43,7 @@ static int audit_directory(apk_hash_item item, void *ctx)
|
||||||
if (!(actx->type & AUDIT_BACKUP) && (dbd->flags & APK_DBDIRF_PROTECTED))
|
if (!(actx->type & AUDIT_BACKUP) && (dbd->flags & APK_DBDIRF_PROTECTED))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dir = opendir(dbd->name);
|
dir = fdopendir(openat(db->root_fd, dbd->name, O_RDONLY));
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ static int audit_directory(apk_hash_item item, void *ctx)
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "%s/%s", dbd->name, de->d_name);
|
snprintf(tmp, sizeof(tmp), "%s/%s", dbd->name, de->d_name);
|
||||||
|
|
||||||
if (apk_file_get_info(tmp, APK_CHECKSUM_NONE, &fi) < 0)
|
if (apk_file_get_info(db->root_fd, tmp, APK_CHECKSUM_NONE, &fi) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(actx->type & AUDIT_SYSTEM) &&
|
if (!(actx->type & AUDIT_SYSTEM) &&
|
||||||
|
@ -70,7 +71,7 @@ static int audit_directory(apk_hash_item item, void *ctx)
|
||||||
dbf = apk_db_file_query(db, bdir, APK_BLOB_STR(de->d_name));
|
dbf = apk_db_file_query(db, bdir, APK_BLOB_STR(de->d_name));
|
||||||
if (dbf != NULL) {
|
if (dbf != NULL) {
|
||||||
if (dbf->csum.type != APK_CHECKSUM_NONE &&
|
if (dbf->csum.type != APK_CHECKSUM_NONE &&
|
||||||
apk_file_get_info(tmp, dbf->csum.type, &fi) == 0 &&
|
apk_file_get_info(db->root_fd, tmp, dbf->csum.type, &fi) == 0 &&
|
||||||
apk_checksum_compare(&fi.csum, &dbf->csum) == 0)
|
apk_checksum_compare(&fi.csum, &dbf->csum) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
63
src/cache.c
63
src/cache.c
|
@ -28,7 +28,7 @@ static int cache_download(struct apk_database *db)
|
||||||
struct apk_state *state;
|
struct apk_state *state;
|
||||||
struct apk_change *change;
|
struct apk_change *change;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
char pkgfile[256];
|
char item[PATH_MAX], cacheitem[PATH_MAX];
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
if (db->world == NULL)
|
if (db->world == NULL)
|
||||||
|
@ -38,24 +38,27 @@ static int cache_download(struct apk_database *db)
|
||||||
for (i = 0; i < db->world->num; i++) {
|
for (i = 0; i < db->world->num; i++) {
|
||||||
r = apk_state_lock_dependency(state, &db->world->item[i]);
|
r = apk_state_lock_dependency(state, &db->world->item[i]);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
apk_error("Unable to select version for '%s'",
|
apk_error("Unable to select version for '%s': %d",
|
||||||
db->world->item[i].name->name);
|
db->world->item[i].name->name, r);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(change, &state->change_list_head, change_list) {
|
list_for_each_entry(change, &state->change_list_head, change_list) {
|
||||||
pkg = change->newpkg;
|
pkg = change->newpkg;
|
||||||
snprintf(pkgfile, sizeof(pkgfile), "%s-%s.apk",
|
|
||||||
pkg->name->name, pkg->version);
|
apk_pkg_format_cache(pkg, APK_BLOB_BUF(cacheitem));
|
||||||
if (apk_cache_exists(db, &pkg->csum, pkgfile))
|
if (faccessat(db->cache_fd, cacheitem, R_OK, 0) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = 0; i < db->num_repos; i++) {
|
for (i = 0; i < db->num_repos; i++) {
|
||||||
if (!(pkg->repos & BIT(i)))
|
if (!(pkg->repos & BIT(i)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = apk_cache_download(db, &pkg->csum, db->repos[i].url,
|
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
|
||||||
pkgfile, APK_SIGN_VERIFY_IDENTITY);
|
r = apk_cache_download(db, db->repos[i].url,
|
||||||
|
item, cacheitem,
|
||||||
|
APK_SIGN_VERIFY_IDENTITY);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -68,54 +71,54 @@ err:
|
||||||
|
|
||||||
static int cache_clean(struct apk_database *db)
|
static int cache_clean(struct apk_database *db)
|
||||||
{
|
{
|
||||||
|
char tmp[PATH_MAX];
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
char path[256], csum[APK_CACHE_CSUM_BYTES];
|
|
||||||
int delete, i;
|
int delete, i;
|
||||||
apk_blob_t b, bname, bver;
|
apk_blob_t b, bname, bver;
|
||||||
struct apk_name *name;
|
struct apk_name *name;
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%s", db->root, db->cache_dir);
|
dir = fdopendir(dup(db->cache_fd));
|
||||||
if (chdir(path) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
dir = opendir(path);
|
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
while ((de = readdir(dir)) != NULL) {
|
while ((de = readdir(dir)) != NULL) {
|
||||||
if (de->d_name[0] == '.')
|
if (de->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
delete = TRUE;
|
delete = TRUE;
|
||||||
do {
|
do {
|
||||||
b = APK_BLOB_STR(de->d_name);
|
b = APK_BLOB_STR(de->d_name);
|
||||||
apk_blob_pull_hexdump(&b, APK_BLOB_BUF(csum));
|
|
||||||
apk_blob_pull_char(&b, '.');
|
|
||||||
|
|
||||||
if (apk_blob_compare(b, APK_BLOB_STR(apk_index_gz)) == 0 ||
|
if (apk_blob_compare(b, APK_BLOB_STR("installed")) == 0) {
|
||||||
apk_blob_compare(b, APK_BLOB_STR(apkindex_tar_gz)) == 0) {
|
delete = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apk_pkg_parse_name(b, &bname, &bver) < 0) {
|
||||||
/* Index - check for matching repository */
|
/* Index - check for matching repository */
|
||||||
for (i = 0; i < db->num_repos; i++) {
|
for (i = 0; i < db->num_repos; i++) {
|
||||||
if (memcmp(db->repos[i].csum.data,
|
apk_cache_format_index(APK_BLOB_BUF(tmp), &db->repos[i], 0);
|
||||||
csum, APK_CACHE_CSUM_BYTES) != 0)
|
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) != 0) {
|
||||||
continue;
|
apk_cache_format_index(APK_BLOB_BUF(tmp), &db->repos[i], 1);
|
||||||
|
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) != 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
delete = 0;
|
delete = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (b.len > 4 &&
|
} else {
|
||||||
memcmp(b.ptr+b.len-4, ".apk", 4) == 0) {
|
|
||||||
/* Package - search for it */
|
/* Package - search for it */
|
||||||
if (apk_pkg_parse_name(b, &bname, &bver) < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
name = apk_db_get_name(db, bname);
|
name = apk_db_get_name(db, bname);
|
||||||
if (name == NULL || name->pkgs == NULL)
|
if (name == NULL || name->pkgs == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (i = 0; i < name->pkgs->num; i++) {
|
for (i = 0; i < name->pkgs->num; i++) {
|
||||||
struct apk_package *pkg = name->pkgs->item[i];
|
struct apk_package *pkg = name->pkgs->item[i];
|
||||||
if (memcmp(pkg->csum.data, csum, APK_CACHE_CSUM_BYTES) != 0)
|
|
||||||
|
apk_pkg_format_cache(pkg, APK_BLOB_BUF(tmp));
|
||||||
|
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
delete = 0;
|
delete = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +129,7 @@ static int cache_clean(struct apk_database *db)
|
||||||
if (apk_verbosity >= 2)
|
if (apk_verbosity >= 2)
|
||||||
apk_message("deleting %s", de->d_name);
|
apk_message("deleting %s", de->d_name);
|
||||||
if (!(apk_flags & APK_SIMULATE))
|
if (!(apk_flags & APK_SIMULATE))
|
||||||
unlink(de->d_name);
|
unlinkat(db->cache_fd, de->d_name, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +155,7 @@ static int cache_main(void *ctx, int argc, char **argv)
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
r = apk_db_open(&db, apk_root,
|
r = apk_db_open(&db, apk_root, APK_OPENF_READ |
|
||||||
APK_OPENF_NO_SCRIPTS | APK_OPENF_NO_INSTALLED);
|
APK_OPENF_NO_SCRIPTS | APK_OPENF_NO_INSTALLED);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
330
src/database.c
330
src/database.c
|
@ -285,16 +285,16 @@ static void apk_db_diri_set(struct apk_db_dir_instance *diri, mode_t mode,
|
||||||
diri->gid = gid;
|
diri->gid = gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_diri_mkdir(struct apk_db_dir_instance *diri)
|
static void apk_db_diri_mkdir(struct apk_database *db, struct apk_db_dir_instance *diri)
|
||||||
{
|
{
|
||||||
if (mkdir(diri->dir->name, diri->mode) == 0)
|
if (mkdirat(db->root_fd, diri->dir->name, diri->mode) == 0)
|
||||||
chown(diri->dir->name, diri->uid, diri->gid);
|
fchownat(db->root_fd, diri->dir->name, diri->uid, diri->gid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_diri_rmdir(struct apk_db_dir_instance *diri)
|
static void apk_db_diri_rmdir(struct apk_database *db, struct apk_db_dir_instance *diri)
|
||||||
{
|
{
|
||||||
if (diri->dir->refs == 1)
|
if (diri->dir->refs == 1)
|
||||||
rmdir(diri->dir->name);
|
unlinkat(db->root_fd, diri->dir->name, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_diri_free(struct apk_database *db,
|
static void apk_db_diri_free(struct apk_database *db,
|
||||||
|
@ -409,21 +409,62 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
|
||||||
return idb;
|
return idb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_cache_get_name(char *buf, size_t bufsz,
|
void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo, int ver)
|
||||||
struct apk_database *db,
|
|
||||||
struct apk_checksum *csum,
|
|
||||||
const char *file, int temp)
|
|
||||||
{
|
{
|
||||||
char csumstr[APK_CACHE_CSUM_BYTES*2+1];
|
/* APKINDEX.12345678.tar.gz */
|
||||||
apk_blob_t bbuf = APK_BLOB_BUF(csumstr);
|
/* APK_INDEX.12345678.gz */
|
||||||
|
if (ver == 0)
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR("APKINDEX."));
|
||||||
|
else
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR("APK_INDEX."));
|
||||||
|
apk_blob_push_hexdump(&to, APK_BLOB_PTR_LEN((char *) repo->csum.data,
|
||||||
|
APK_CACHE_CSUM_BYTES));
|
||||||
|
if (ver == 0)
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(".tar.gz"));
|
||||||
|
else
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(".gz"));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
|
||||||
|
}
|
||||||
|
|
||||||
apk_blob_push_hexdump(&bbuf,
|
int apk_cache_download(struct apk_database *db, const char *url,
|
||||||
APK_BLOB_PTR_LEN((char *) csum->data,
|
const char *item, const char *cacheitem, int verify)
|
||||||
APK_CACHE_CSUM_BYTES));
|
{
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN("", 1));
|
char fullurl[PATH_MAX];
|
||||||
|
int r;
|
||||||
|
|
||||||
snprintf(buf, bufsz, "%s/%s/%s.%s%s",
|
snprintf(fullurl, sizeof(fullurl), "%s%s%s",
|
||||||
db->root, db->cache_dir, csumstr, file, temp ? ".new" : "");
|
url, url[strlen(url)-1] == '/' ? "" : "/", item);
|
||||||
|
apk_message("fetch %s", fullurl);
|
||||||
|
|
||||||
|
if (apk_flags & APK_SIMULATE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = apk_url_download(fullurl, db->cachetmp_fd, cacheitem);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (verify != APK_SIGN_NONE) {
|
||||||
|
struct apk_istream *is;
|
||||||
|
struct apk_sign_ctx sctx;
|
||||||
|
|
||||||
|
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
|
||||||
|
is = apk_bstream_gunzip_mpart(
|
||||||
|
apk_bstream_from_file(db->cachetmp_fd, cacheitem),
|
||||||
|
apk_sign_ctx_mpart_cb, &sctx);
|
||||||
|
|
||||||
|
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE);
|
||||||
|
is->close(is);
|
||||||
|
apk_sign_ctx_free(&sctx);
|
||||||
|
if (r != 0) {
|
||||||
|
unlinkat(db->cachetmp_fd, cacheitem, 0);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renameat(db->cachetmp_fd, cacheitem, db->cache_fd, cacheitem) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
|
@ -690,10 +731,8 @@ static int apk_db_read_state(struct apk_database *db, int flags)
|
||||||
* 5. files db
|
* 5. files db
|
||||||
* 6. script db
|
* 6. script db
|
||||||
*/
|
*/
|
||||||
fchdir(db->root_fd);
|
|
||||||
|
|
||||||
if (!(flags & APK_OPENF_NO_WORLD)) {
|
if (!(flags & APK_OPENF_NO_WORLD)) {
|
||||||
blob = apk_blob_from_file("var/lib/apk/world");
|
blob = apk_blob_from_file(db->root_fd, "var/lib/apk/world");
|
||||||
if (APK_BLOB_IS_NULL(blob))
|
if (APK_BLOB_IS_NULL(blob))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
apk_deps_parse(db, &db->world, blob);
|
apk_deps_parse(db, &db->world, blob);
|
||||||
|
@ -704,13 +743,13 @@ static int apk_db_read_state(struct apk_database *db, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & APK_OPENF_NO_INSTALLED)) {
|
if (!(flags & APK_OPENF_NO_INSTALLED)) {
|
||||||
bs = apk_bstream_from_file("var/lib/apk/installed");
|
bs = apk_bstream_from_file(db->root_fd, "var/lib/apk/installed");
|
||||||
if (bs != NULL) {
|
if (bs != NULL) {
|
||||||
apk_db_index_read(db, bs, -1);
|
apk_db_index_read(db, bs, -1);
|
||||||
bs->close(bs, NULL);
|
bs->close(bs, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bs = apk_bstream_from_file("etc/apk/cache/installed");
|
bs = apk_bstream_from_file(db->cache_fd, "installed");
|
||||||
if (bs != NULL) {
|
if (bs != NULL) {
|
||||||
apk_db_index_read(db, bs, -2);
|
apk_db_index_read(db, bs, -2);
|
||||||
bs->close(bs, NULL);
|
bs->close(bs, NULL);
|
||||||
|
@ -718,12 +757,12 @@ static int apk_db_read_state(struct apk_database *db, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
|
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
|
||||||
is = apk_istream_from_file("var/lib/apk/scripts.tar");
|
is = apk_istream_from_file(db->root_fd, "var/lib/apk/scripts.tar");
|
||||||
if (is != NULL) {
|
if (is != NULL) {
|
||||||
apk_tar_parse(is, apk_read_script_archive_entry, db,
|
apk_tar_parse(is, apk_read_script_archive_entry, db,
|
||||||
FALSE);
|
FALSE);
|
||||||
} else {
|
} else {
|
||||||
is = apk_istream_from_file("var/lib/apk/scripts");
|
is = apk_istream_from_file(db->root_fd, "var/lib/apk/scripts");
|
||||||
if (is != NULL)
|
if (is != NULL)
|
||||||
apk_db_scriptdb_read_v1(db, is);
|
apk_db_scriptdb_read_v1(db, is);
|
||||||
}
|
}
|
||||||
|
@ -772,10 +811,11 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
|
||||||
|
|
||||||
/* Write list of installed non-repository packages to
|
/* Write list of installed non-repository packages to
|
||||||
* cached index file */
|
* cached index file */
|
||||||
ctx.os = os = apk_ostream_to_file("etc/apk/cache/installed.new", 0644);
|
os = apk_ostream_to_file(db->cache_fd, "installed.new", 0644);
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
ctx.os = os;
|
||||||
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
if (pkg->repos != 0)
|
if (pkg->repos != 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -785,8 +825,8 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
|
||||||
}
|
}
|
||||||
|
|
||||||
os->close(os);
|
os->close(os);
|
||||||
if (rename("etc/apk/cache/installed.new",
|
if (renameat(db->cache_fd, "installed.new",
|
||||||
"etc/apk/cache/installed") < 0)
|
db->cache_fd, "installed") < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return ctx.count;
|
return ctx.count;
|
||||||
|
@ -815,15 +855,14 @@ static int apk_db_create(struct apk_database *db)
|
||||||
"apk-tools alpine-conf");
|
"apk-tools alpine-conf");
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fchdir(db->root_fd);
|
mkdirat(db->root_fd, "tmp", 01777);
|
||||||
mkdir("tmp", 01777);
|
mkdirat(db->root_fd, "dev", 0755);
|
||||||
mkdir("dev", 0755);
|
mknodat(db->root_fd, "dev/null", 0666, makedev(1, 3));
|
||||||
mknod("dev/null", 0666, makedev(1, 3));
|
mkdirat(db->root_fd, "var", 0755);
|
||||||
mkdir("var", 0755);
|
mkdirat(db->root_fd, "var/lib", 0755);
|
||||||
mkdir("var/lib", 0755);
|
mkdirat(db->root_fd, "var/lib/apk", 0755);
|
||||||
mkdir("var/lib/apk", 0755);
|
|
||||||
|
|
||||||
fd = creat("var/lib/apk/world", 0644);
|
fd = openat(db->root_fd, "var/lib/apk/world", O_CREAT|O_RDWR|O_TRUNC, 0644);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
write(fd, deps.ptr, deps.len);
|
write(fd, deps.ptr, deps.len);
|
||||||
|
@ -840,7 +879,7 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
{
|
{
|
||||||
const char *apk_repos = getenv("APK_REPOS"), *msg = NULL;
|
const char *apk_repos = getenv("APK_REPOS"), *msg = NULL;
|
||||||
struct apk_repository_url *repo = NULL;
|
struct apk_repository_url *repo = NULL;
|
||||||
struct stat st;
|
struct stat64 st;
|
||||||
apk_blob_t blob;
|
apk_blob_t blob;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -854,27 +893,26 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
db->permanent = 1;
|
db->permanent = 1;
|
||||||
|
|
||||||
if (root != NULL) {
|
if (root != NULL) {
|
||||||
fchdir(apk_cwd_fd);
|
|
||||||
db->root = strdup(root);
|
db->root = strdup(root);
|
||||||
db->root_fd = open(root, O_RDONLY);
|
db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY);
|
||||||
if (db->root_fd < 0 && (flags & APK_OPENF_CREATE)) {
|
if (db->root_fd < 0 && (flags & APK_OPENF_CREATE)) {
|
||||||
mkdir(db->root, 0755);
|
mkdirat(AT_FDCWD, db->root, 0755);
|
||||||
db->root_fd = open(root, O_RDONLY);
|
db->root_fd = openat(AT_FDCWD, root, O_RDONLY);
|
||||||
}
|
}
|
||||||
if (db->root_fd < 0) {
|
if (db->root_fd < 0) {
|
||||||
msg = "Unable to open root";
|
msg = "Unable to open root";
|
||||||
goto ret_errno;
|
goto ret_errno;
|
||||||
}
|
}
|
||||||
if (fstat(db->root_fd, &st) != 0 || major(st.st_dev) == 0)
|
if (fstat64(db->root_fd, &st) != 0 || major(st.st_dev) == 0)
|
||||||
db->permanent = 0;
|
db->permanent = 0;
|
||||||
|
|
||||||
fchdir(db->root_fd);
|
if (fstatat64(db->root_fd, apk_linked_cache_dir, &st, 0) == 0 &&
|
||||||
if (stat(apk_linked_cache_dir, &st) == 0 && S_ISDIR(st.st_mode))
|
S_ISDIR(st.st_mode))
|
||||||
db->cache_dir = apk_linked_cache_dir;
|
db->cache_dir = apk_linked_cache_dir;
|
||||||
|
|
||||||
if (flags & APK_OPENF_WRITE) {
|
if (flags & APK_OPENF_WRITE) {
|
||||||
db->lock_fd = open("var/lib/apk/lock",
|
db->lock_fd = openat(db->root_fd, "var/lib/apk/lock",
|
||||||
O_CREAT | O_WRONLY, 0400);
|
O_CREAT | O_RDWR, 0400);
|
||||||
if (db->lock_fd < 0 && errno == ENOENT &&
|
if (db->lock_fd < 0 && errno == ENOENT &&
|
||||||
(flags & APK_OPENF_CREATE)) {
|
(flags & APK_OPENF_CREATE)) {
|
||||||
r = apk_db_create(db);
|
r = apk_db_create(db);
|
||||||
|
@ -882,8 +920,9 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
msg = "Unable to create database";
|
msg = "Unable to create database";
|
||||||
goto ret_r;
|
goto ret_r;
|
||||||
}
|
}
|
||||||
db->lock_fd = open("var/lib/apk/lock",
|
db->lock_fd = openat(db->root_fd,
|
||||||
O_CREAT | O_WRONLY, 0400);
|
"var/lib/apk/lock",
|
||||||
|
O_CREAT | O_RDWR, 0400);
|
||||||
}
|
}
|
||||||
if (db->lock_fd < 0 ||
|
if (db->lock_fd < 0 ||
|
||||||
flock(db->lock_fd, LOCK_EX | LOCK_NB) < 0) {
|
flock(db->lock_fd, LOCK_EX | LOCK_NB) < 0) {
|
||||||
|
@ -912,6 +951,11 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
blob = APK_BLOB_STR("etc:*etc/init.d");
|
blob = APK_BLOB_STR("etc:*etc/init.d");
|
||||||
apk_blob_for_each_segment(blob, ":", add_protected_path, db);
|
apk_blob_for_each_segment(blob, ":", add_protected_path, db);
|
||||||
|
|
||||||
|
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY);
|
||||||
|
mkdirat(db->cache_fd, "tmp", 0644);
|
||||||
|
db->cachetmp_fd = openat(db->cache_fd, "tmp", O_RDONLY);
|
||||||
|
db->keys_fd = openat(db->root_fd, "etc/apk/keys", O_RDONLY);
|
||||||
|
|
||||||
if (root != NULL) {
|
if (root != NULL) {
|
||||||
r = apk_db_read_state(db, flags);
|
r = apk_db_read_state(db, flags);
|
||||||
if (r == -ENOENT && (flags & APK_OPENF_CREATE)) {
|
if (r == -ENOENT && (flags & APK_OPENF_CREATE)) {
|
||||||
|
@ -929,8 +973,8 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
|
|
||||||
if (!(flags & APK_OPENF_NO_REPOS)) {
|
if (!(flags & APK_OPENF_NO_REPOS)) {
|
||||||
if (apk_repos == NULL)
|
if (apk_repos == NULL)
|
||||||
apk_repos = "/etc/apk/repositories";
|
apk_repos = "etc/apk/repositories";
|
||||||
blob = apk_blob_from_file(apk_repos);
|
blob = apk_blob_from_file(db->root_fd, apk_repos);
|
||||||
if (!APK_BLOB_IS_NULL(blob)) {
|
if (!APK_BLOB_IS_NULL(blob)) {
|
||||||
apk_blob_for_each_segment(blob, "\n",
|
apk_blob_for_each_segment(blob, "\n",
|
||||||
apk_db_add_repository, db);
|
apk_db_add_repository, db);
|
||||||
|
@ -947,7 +991,6 @@ int apk_db_open(struct apk_database *db, const char *root, unsigned int flags)
|
||||||
apk_db_index_write_nr_cache(db);
|
apk_db_index_write_nr_cache(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
fchdir(apk_cwd_fd);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret_errno:
|
ret_errno:
|
||||||
|
@ -956,7 +999,7 @@ ret_r:
|
||||||
if (msg != NULL)
|
if (msg != NULL)
|
||||||
apk_error("%s: %s", msg, strerror(-r));
|
apk_error("%s: %s", msg, strerror(-r));
|
||||||
apk_db_close(db);
|
apk_db_close(db);
|
||||||
fchdir(apk_cwd_fd);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,35 +1020,36 @@ int apk_db_write_config(struct apk_database *db)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fchdir(db->root_fd);
|
os = apk_ostream_to_file(db->root_fd, "var/lib/apk/world.new", 0644);
|
||||||
|
|
||||||
os = apk_ostream_to_file("var/lib/apk/world.new", 0644);
|
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
apk_deps_write(db->world, os);
|
apk_deps_write(db->world, os);
|
||||||
os->write(os, "\n", 1);
|
os->write(os, "\n", 1);
|
||||||
os->close(os);
|
os->close(os);
|
||||||
if (rename("var/lib/apk/world.new", "var/lib/apk/world") < 0)
|
if (renameat(db->root_fd, "var/lib/apk/world.new",
|
||||||
|
db->root_fd, "var/lib/apk/world") < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
os = apk_ostream_to_file("var/lib/apk/installed.new", 0644);
|
os = apk_ostream_to_file(db->root_fd, "var/lib/apk/installed.new", 0644);
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
apk_db_write_fdb(db, os);
|
apk_db_write_fdb(db, os);
|
||||||
os->close(os);
|
os->close(os);
|
||||||
|
|
||||||
if (rename("var/lib/apk/installed.new", "var/lib/apk/installed") < 0)
|
if (renameat(db->root_fd, "var/lib/apk/installed.new",
|
||||||
|
db->root_fd, "var/lib/apk/installed") < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
os = apk_ostream_to_file("var/lib/apk/scripts.tar.new", 0644);
|
os = apk_ostream_to_file(db->root_fd, "var/lib/apk/scripts.tar.new", 0644);
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
apk_db_scriptdb_write(db, os);
|
apk_db_scriptdb_write(db, os);
|
||||||
os->close(os);
|
os->close(os);
|
||||||
if (rename("var/lib/apk/scripts.tar.new", "var/lib/apk/scripts.tar") < 0)
|
if (renameat(db->root_fd, "var/lib/apk/scripts.tar.new",
|
||||||
|
db->root_fd, "var/lib/apk/scripts.tar") < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
unlink("var/lib/apk/scripts");
|
unlinkat(db->root_fd, "var/lib/apk/scripts", 0);
|
||||||
apk_db_index_write_nr_cache(db);
|
apk_db_index_write_nr_cache(db);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1040,6 +1084,12 @@ void apk_db_close(struct apk_database *db)
|
||||||
apk_hash_free(&db->installed.files);
|
apk_hash_free(&db->installed.files);
|
||||||
apk_hash_free(&db->installed.dirs);
|
apk_hash_free(&db->installed.dirs);
|
||||||
|
|
||||||
|
if (db->keys_fd)
|
||||||
|
close(db->keys_fd);
|
||||||
|
if (db->cachetmp_fd)
|
||||||
|
close(db->cachetmp_fd);
|
||||||
|
if (db->cache_fd)
|
||||||
|
close(db->cache_fd);
|
||||||
if (db->root_fd)
|
if (db->root_fd)
|
||||||
close(db->root_fd);
|
close(db->root_fd);
|
||||||
if (db->lock_fd)
|
if (db->lock_fd)
|
||||||
|
@ -1084,19 +1134,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db,
|
||||||
return dbf->diri->pkg;
|
return dbf->diri->pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apk_bstream *apk_db_cache_open(struct apk_database *db,
|
|
||||||
struct apk_checksum *csum,
|
|
||||||
const char *file)
|
|
||||||
{
|
|
||||||
char tmp[256];
|
|
||||||
|
|
||||||
if (db->root == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
apk_db_cache_get_name(tmp, sizeof(tmp), db, csum, file, FALSE);
|
|
||||||
return apk_bstream_from_file(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
|
static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
|
||||||
const char *file)
|
const char *file)
|
||||||
{
|
{
|
||||||
|
@ -1109,91 +1146,26 @@ static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
|
||||||
return apk_bstream_from_url(tmp);
|
return apk_bstream_from_url(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_cache_download(struct apk_database *db, struct apk_checksum *csum,
|
|
||||||
const char *url, const char *item, int verify)
|
|
||||||
{
|
|
||||||
char tmp[256], tmp2[256];
|
|
||||||
int r;
|
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "%s%s%s",
|
|
||||||
url, url[strlen(url)-1] == '/' ? "" : "/", item);
|
|
||||||
apk_message("fetch %s", tmp);
|
|
||||||
|
|
||||||
if (apk_flags & APK_SIMULATE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
apk_db_cache_get_name(tmp2, sizeof(tmp2), db, csum, item, TRUE);
|
|
||||||
r = apk_url_download(tmp, tmp2);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (verify != APK_SIGN_NONE) {
|
|
||||||
struct apk_istream *is;
|
|
||||||
struct apk_sign_ctx sctx;
|
|
||||||
|
|
||||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL);
|
|
||||||
is = apk_bstream_gunzip_mpart(apk_bstream_from_file(tmp2),
|
|
||||||
apk_sign_ctx_mpart_cb, &sctx);
|
|
||||||
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE);
|
|
||||||
is->close(is);
|
|
||||||
apk_sign_ctx_free(&sctx);
|
|
||||||
if (r != 0) {
|
|
||||||
unlink(tmp2);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apk_db_cache_get_name(tmp, sizeof(tmp), db, csum, item, FALSE);
|
|
||||||
if (rename(tmp2, tmp) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int apk_cache_exists(struct apk_database *db, struct apk_checksum *csum,
|
|
||||||
const char *item)
|
|
||||||
{
|
|
||||||
char tmp[256];
|
|
||||||
|
|
||||||
if (db->root == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
apk_db_cache_get_name(tmp, sizeof(tmp), db, csum, item, FALSE);
|
|
||||||
return access(tmp, R_OK | W_OK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int apk_cache_delete(struct apk_database *db, struct apk_checksum *csum,
|
|
||||||
const char *item)
|
|
||||||
{
|
|
||||||
char tmp[256];
|
|
||||||
|
|
||||||
if (db->root == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
apk_db_cache_get_name(tmp, sizeof(tmp), db, csum, item, FALSE);
|
|
||||||
return unlink(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
|
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
|
||||||
{
|
{
|
||||||
|
char cacheitem[PATH_MAX];
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (repo->csum.type == APK_CHECKSUM_NONE)
|
if (repo->csum.type == APK_CHECKSUM_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = apk_cache_download(db, &repo->csum, repo->url, apkindex_tar_gz,
|
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 0);
|
||||||
|
r = apk_cache_download(db, repo->url, apkindex_tar_gz, cacheitem,
|
||||||
(apk_flags & APK_ALLOW_UNTRUSTED) ?
|
(apk_flags & APK_ALLOW_UNTRUSTED) ?
|
||||||
APK_SIGN_NONE : APK_SIGN_VERIFY);
|
APK_SIGN_NONE : APK_SIGN_VERIFY);
|
||||||
if (r == 0 || r == -ENOKEY || r == -EKEYREJECTED) {
|
if (r == 0 || r == -ENOKEY || r == -EKEYREJECTED) {
|
||||||
if (r == -ENOKEY)
|
if (r != 0)
|
||||||
apk_error("%s: verify: UNTRUSTED", repo->url);
|
apk_error("%s: %s", repo->url, apk_error_str(r));
|
||||||
else if (r == -EKEYREJECTED)
|
|
||||||
apk_error("%s: verify: FAILED", repo->url);
|
|
||||||
apk_cache_delete(db, &repo->csum, apk_index_gz);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = apk_cache_download(db, &repo->csum, repo->url, apk_index_gz,
|
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 1);
|
||||||
|
r = apk_cache_download(db, repo->url, apk_index_gz, cacheitem,
|
||||||
APK_SIGN_NONE);
|
APK_SIGN_NONE);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
apk_error("Failed to update %s: download failed", repo->url);
|
apk_error("Failed to update %s: download failed", repo->url);
|
||||||
|
@ -1238,7 +1210,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
|
||||||
ctx.db = db;
|
ctx.db = db;
|
||||||
ctx.repo = repo;
|
ctx.repo = repo;
|
||||||
ctx.found = 0;
|
ctx.found = 0;
|
||||||
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL);
|
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
|
||||||
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
|
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
|
||||||
r = apk_tar_parse(is, load_apkindex, &ctx, FALSE);
|
r = apk_tar_parse(is, load_apkindex, &ctx, FALSE);
|
||||||
is->close(is);
|
is->close(is);
|
||||||
|
@ -1260,7 +1232,7 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo)
|
||||||
if (strstr(file, ".tar.gz") == NULL && strstr(file, ".gz") != NULL)
|
if (strstr(file, ".tar.gz") == NULL && strstr(file, ".gz") != NULL)
|
||||||
targz = 0;
|
targz = 0;
|
||||||
|
|
||||||
return load_index(db, apk_bstream_from_file(file), targz, repo);
|
return load_index(db, apk_bstream_from_file(AT_FDCWD, file), targz, repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
||||||
|
@ -1285,14 +1257,18 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (apk_url_local_file(repo->url) == NULL) {
|
if (apk_url_local_file(repo->url) == NULL) {
|
||||||
|
char cacheitem[PATH_MAX];
|
||||||
|
|
||||||
apk_blob_checksum(repository, apk_default_checksum(), &repo->csum);
|
apk_blob_checksum(repository, apk_default_checksum(), &repo->csum);
|
||||||
|
|
||||||
if (apk_flags & APK_UPDATE_CACHE)
|
if (apk_flags & APK_UPDATE_CACHE)
|
||||||
apk_repository_update(db, repo);
|
apk_repository_update(db, repo);
|
||||||
|
|
||||||
bs = apk_db_cache_open(db, &repo->csum, apkindex_tar_gz);
|
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 0);
|
||||||
|
bs = apk_bstream_from_file(db->cache_fd, cacheitem);
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
bs = apk_db_cache_open(db, &repo->csum, apk_index_gz);
|
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 1);
|
||||||
|
bs = apk_bstream_from_file(db->cache_fd, cacheitem);
|
||||||
targz = 0;
|
targz = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1356,7 +1332,6 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
apk_blob_t name = APK_BLOB_STR(ae->name), bdir, bfile;
|
apk_blob_t name = APK_BLOB_STR(ae->name), bdir, bfile;
|
||||||
struct apk_db_dir_instance *diri = ctx->diri;
|
struct apk_db_dir_instance *diri = ctx->diri;
|
||||||
struct apk_db_file *file;
|
struct apk_db_file *file;
|
||||||
char alt_name[PATH_MAX];
|
|
||||||
const char *p;
|
const char *p;
|
||||||
int r = 0, type = APK_SCRIPT_INVALID;
|
int r = 0, type = APK_SCRIPT_INVALID;
|
||||||
|
|
||||||
|
@ -1455,9 +1430,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
apk_message("%s", ae->name);
|
apk_message("%s", ae->name);
|
||||||
|
|
||||||
/* Extract the file as name.apk-new */
|
/* Extract the file as name.apk-new */
|
||||||
snprintf(alt_name, sizeof(alt_name), "%s/%s.apk-new",
|
r = apk_archive_entry_extract(db->root_fd, ae, ".apk-new", is,
|
||||||
diri->dir->name, file->name);
|
|
||||||
r = apk_archive_entry_extract(ae, is, alt_name,
|
|
||||||
extract_cb, ctx);
|
extract_cb, ctx);
|
||||||
memcpy(&file->csum, &ae->csum, sizeof(file->csum));
|
memcpy(&file->csum, &ae->csum, sizeof(file->csum));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1474,7 +1447,7 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
ctx->file_diri_node = hlist_tail_ptr(&diri->owned_files);
|
ctx->file_diri_node = hlist_tail_ptr(&diri->owned_files);
|
||||||
|
|
||||||
apk_db_diri_set(diri, ae->mode & 0777, ae->uid, ae->gid);
|
apk_db_diri_set(diri, ae->mode & 0777, ae->uid, ae->gid);
|
||||||
apk_db_diri_mkdir(diri);
|
apk_db_diri_mkdir(db, diri);
|
||||||
}
|
}
|
||||||
ctx->installed_size += ctx->current_file_size;
|
ctx->installed_size += ctx->current_file_size;
|
||||||
|
|
||||||
|
@ -1505,9 +1478,9 @@ static void apk_db_purge_pkg(struct apk_database *db, struct apk_package *pkg,
|
||||||
if (!(diri->dir->flags & APK_DBDIRF_PROTECTED) ||
|
if (!(diri->dir->flags & APK_DBDIRF_PROTECTED) ||
|
||||||
(apk_flags & APK_PURGE) ||
|
(apk_flags & APK_PURGE) ||
|
||||||
(file->csum.type != APK_CHECKSUM_NONE &&
|
(file->csum.type != APK_CHECKSUM_NONE &&
|
||||||
apk_file_get_info(name, file->csum.type, &fi) == 0 &&
|
apk_file_get_info(db->root_fd, name, file->csum.type, &fi) == 0 &&
|
||||||
apk_checksum_compare(&file->csum, &fi.csum) == 0))
|
apk_checksum_compare(&file->csum, &fi.csum) == 0))
|
||||||
unlink(name);
|
unlinkat(db->root_fd, name, 0);
|
||||||
if (apk_verbosity >= 3)
|
if (apk_verbosity >= 3)
|
||||||
apk_message("%s", name);
|
apk_message("%s", name);
|
||||||
__hlist_del(fc, &diri->owned_files.first);
|
__hlist_del(fc, &diri->owned_files.first);
|
||||||
|
@ -1516,7 +1489,7 @@ static void apk_db_purge_pkg(struct apk_database *db, struct apk_package *pkg,
|
||||||
db->installed.stats.files--;
|
db->installed.stats.files--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apk_db_diri_rmdir(diri);
|
apk_db_diri_rmdir(db, diri);
|
||||||
__hlist_del(dc, &pkg->owned_dirs.first);
|
__hlist_del(dc, &pkg->owned_dirs.first);
|
||||||
apk_db_diri_free(db, diri);
|
apk_db_diri_free(db, diri);
|
||||||
}
|
}
|
||||||
|
@ -1564,7 +1537,7 @@ static void apk_db_migrate_files(struct apk_database *db,
|
||||||
(diri->dir->flags & APK_DBDIRF_PROTECTED))
|
(diri->dir->flags & APK_DBDIRF_PROTECTED))
|
||||||
cstype = ofile->csum.type;
|
cstype = ofile->csum.type;
|
||||||
|
|
||||||
r = apk_file_get_info(name, cstype, &fi);
|
r = apk_file_get_info(db->root_fd, name, cstype, &fi);
|
||||||
if ((diri->dir->flags & APK_DBDIRF_PROTECTED) &&
|
if ((diri->dir->flags & APK_DBDIRF_PROTECTED) &&
|
||||||
(r == 0) &&
|
(r == 0) &&
|
||||||
(ofile == NULL ||
|
(ofile == NULL ||
|
||||||
|
@ -1577,14 +1550,15 @@ static void apk_db_migrate_files(struct apk_database *db,
|
||||||
* existing file */
|
* existing file */
|
||||||
if (ofile == NULL ||
|
if (ofile == NULL ||
|
||||||
ofile->csum.type != file->csum.type)
|
ofile->csum.type != file->csum.type)
|
||||||
apk_file_get_info(name, file->csum.type, &fi);
|
apk_file_get_info(db->root_fd, name, file->csum.type, &fi);
|
||||||
if ((apk_flags & APK_CLEAN_PROTECTED) ||
|
if ((apk_flags & APK_CLEAN_PROTECTED) ||
|
||||||
(file->csum.type != APK_CHECKSUM_NONE &&
|
(file->csum.type != APK_CHECKSUM_NONE &&
|
||||||
apk_checksum_compare(&file->csum, &fi.csum) == 0))
|
apk_checksum_compare(&file->csum, &fi.csum) == 0))
|
||||||
unlink(tmpname);
|
unlinkat(db->root_fd, tmpname, 0);
|
||||||
} else {
|
} else {
|
||||||
/* Overwrite the old file */
|
/* Overwrite the old file */
|
||||||
rename(tmpname, name);
|
renameat(db->root_fd, tmpname,
|
||||||
|
db->root_fd, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Claim ownership of the file in db */
|
/* Claim ownership of the file in db */
|
||||||
|
@ -1608,12 +1582,9 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
struct install_ctx ctx;
|
struct install_ctx ctx;
|
||||||
struct apk_bstream *bs = NULL;
|
struct apk_bstream *bs = NULL;
|
||||||
struct apk_istream *tar;
|
struct apk_istream *tar;
|
||||||
char pkgname[256], file[256];
|
char file[PATH_MAX];
|
||||||
int r, i, need_copy = FALSE;
|
int r, i, need_copy = FALSE;
|
||||||
|
|
||||||
snprintf(pkgname, sizeof(pkgname), "%s-%s.apk",
|
|
||||||
newpkg->name->name, newpkg->version);
|
|
||||||
|
|
||||||
if (newpkg->filename == NULL) {
|
if (newpkg->filename == NULL) {
|
||||||
struct apk_repository *repo;
|
struct apk_repository *repo;
|
||||||
|
|
||||||
|
@ -1629,24 +1600,26 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
|
|
||||||
repo = &db->repos[i];
|
repo = &db->repos[i];
|
||||||
if (apk_db_cache_active(db) &&
|
if (apk_db_cache_active(db) &&
|
||||||
repo->csum.type != APK_CHECKSUM_NONE)
|
repo->csum.type != APK_CHECKSUM_NONE) {
|
||||||
bs = apk_db_cache_open(db, &newpkg->csum, pkgname);
|
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
|
||||||
|
bs = apk_bstream_from_file(db->cache_fd, file);
|
||||||
|
}
|
||||||
|
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
bs = apk_repository_file_open(repo, pkgname);
|
apk_pkg_format_plain(newpkg, APK_BLOB_BUF(file));
|
||||||
|
bs = apk_repository_file_open(repo, file);
|
||||||
if (repo->csum.type != APK_CHECKSUM_NONE)
|
if (repo->csum.type != APK_CHECKSUM_NONE)
|
||||||
need_copy = TRUE;
|
need_copy = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bs = apk_bstream_from_file(newpkg->filename);
|
bs = apk_bstream_from_file(AT_FDCWD, newpkg->filename);
|
||||||
need_copy = TRUE;
|
need_copy = TRUE;
|
||||||
}
|
}
|
||||||
if (!apk_db_cache_active(db))
|
if (!apk_db_cache_active(db))
|
||||||
need_copy = FALSE;
|
need_copy = FALSE;
|
||||||
if (need_copy) {
|
if (need_copy) {
|
||||||
apk_db_cache_get_name(file, sizeof(file), db, &newpkg->csum,
|
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
|
||||||
pkgname, TRUE);
|
bs = apk_bstream_tee(bs, db->cachetmp_fd, file);
|
||||||
bs = apk_bstream_tee(bs, file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
|
@ -1662,7 +1635,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
.cb = cb,
|
.cb = cb,
|
||||||
.cb_ctx = cb_ctx,
|
.cb_ctx = cb_ctx,
|
||||||
};
|
};
|
||||||
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &newpkg->csum);
|
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &newpkg->csum, db->keys_fd);
|
||||||
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
|
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
|
||||||
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE);
|
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE);
|
||||||
apk_sign_ctx_free(&ctx.sctx);
|
apk_sign_ctx_free(&ctx.sctx);
|
||||||
|
@ -1680,12 +1653,8 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
|
|
||||||
apk_db_migrate_files(db, newpkg);
|
apk_db_migrate_files(db, newpkg);
|
||||||
|
|
||||||
if (need_copy) {
|
if (need_copy)
|
||||||
char file2[256];
|
renameat(db->cachetmp_fd, file, db->cache_fd, file);
|
||||||
apk_db_cache_get_name(file2, sizeof(file2), db,
|
|
||||||
&newpkg->csum, pkgname, FALSE);
|
|
||||||
rename(file, file2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
|
@ -1700,9 +1669,6 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (fchdir(db->root_fd) < 0)
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
/* Just purging? */
|
/* Just purging? */
|
||||||
if (oldpkg != NULL && newpkg == NULL) {
|
if (oldpkg != NULL && newpkg == NULL) {
|
||||||
r = apk_pkg_run_script(oldpkg, db->root_fd,
|
r = apk_pkg_run_script(oldpkg, db->root_fd,
|
||||||
|
|
54
src/fetch.c
54
src/fetch.c
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
@ -26,7 +27,7 @@
|
||||||
|
|
||||||
struct fetch_ctx {
|
struct fetch_ctx {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
const char *outdir;
|
int outdir_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cup(void)
|
static int cup(void)
|
||||||
|
@ -80,7 +81,7 @@ static int fetch_parse(void *ctx, int optch, int optindex, const char *optarg)
|
||||||
fctx->flags |= FETCH_LINK;
|
fctx->flags |= FETCH_LINK;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
fctx->outdir = optarg;
|
fctx->outdir_fd = openat(AT_FDCWD, optarg, O_RDONLY);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -93,22 +94,21 @@ static int fetch_package(struct fetch_ctx *fctx,
|
||||||
struct apk_package *pkg)
|
struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
struct apk_istream *is;
|
struct apk_istream *is;
|
||||||
char infile[256];
|
char pkgfile[PATH_MAX], url[PATH_MAX];
|
||||||
char outfile[256];
|
|
||||||
int i, r, fd;
|
int i, r, fd;
|
||||||
|
|
||||||
|
apk_pkg_format_plain(pkg, APK_BLOB_BUF(pkgfile));
|
||||||
|
|
||||||
if (!(fctx->flags & FETCH_STDOUT)) {
|
if (!(fctx->flags & FETCH_STDOUT)) {
|
||||||
struct stat st;
|
struct apk_file_info fi;
|
||||||
|
|
||||||
snprintf(outfile, sizeof(outfile), "%s/%s-%s.apk",
|
if (apk_file_get_info(fctx->outdir_fd, pkgfile,
|
||||||
fctx->outdir ? fctx->outdir : ".",
|
APK_CHECKSUM_NONE, &fi) == 0 &&
|
||||||
pkg->name->name, pkg->version);
|
fi.size == pkg->size)
|
||||||
|
|
||||||
if (lstat(outfile, &st) == 0 && st.st_size == pkg->size)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
apk_message("Downloading %s-%s", pkg->name->name, pkg->version);
|
|
||||||
|
|
||||||
|
apk_message("Downloading %s-%s", pkg->name->name, pkg->version);
|
||||||
for (i = 0; i < APK_MAX_REPOS; i++)
|
for (i = 0; i < APK_MAX_REPOS; i++)
|
||||||
if (pkg->repos & BIT(i))
|
if (pkg->repos & BIT(i))
|
||||||
break;
|
break;
|
||||||
|
@ -122,31 +122,30 @@ static int fetch_package(struct fetch_ctx *fctx,
|
||||||
if (apk_flags & APK_SIMULATE)
|
if (apk_flags & APK_SIMULATE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
snprintf(infile, sizeof(infile), "%s/%s-%s.apk",
|
snprintf(url, sizeof(url), "%s%s%s", db->repos[i].url,
|
||||||
db->repos[i].url, pkg->name->name, pkg->version);
|
db->repos[i].url[strlen(db->repos[i].url)-1] == '/' ? "" : "/",
|
||||||
|
pkgfile);
|
||||||
|
|
||||||
if (fctx->flags & FETCH_STDOUT) {
|
if (fctx->flags & FETCH_STDOUT) {
|
||||||
fd = STDOUT_FILENO;
|
fd = STDOUT_FILENO;
|
||||||
} else {
|
} else {
|
||||||
if ((fctx->flags & FETCH_LINK) && apk_url_local_file(infile)) {
|
if ((fctx->flags & FETCH_LINK) && apk_url_local_file(url)) {
|
||||||
char real_infile[256];
|
if (linkat(AT_FDCWD, url,
|
||||||
int n;
|
fctx->outdir_fd, pkgfile,
|
||||||
n = readlink(infile, real_infile, sizeof(real_infile));
|
AT_SYMLINK_FOLLOW) == 0)
|
||||||
if (n > 0 && n < sizeof(real_infile))
|
|
||||||
real_infile[n] = '\0';
|
|
||||||
if (link(real_infile, outfile) == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fd = creat(outfile, 0644);
|
fd = openat(fctx->outdir_fd, pkgfile,
|
||||||
|
O_CREAT|O_RDWR|O_TRUNC, 0644);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
apk_error("%s: %s", outfile, strerror(errno));
|
apk_error("%s: %s", pkgfile, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is = apk_istream_from_url(infile);
|
is = apk_istream_from_url(url);
|
||||||
if (is == NULL) {
|
if (is == NULL) {
|
||||||
apk_error("Unable to download '%s'", infile);
|
apk_error("Unable to download '%s'", url);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +154,8 @@ static int fetch_package(struct fetch_ctx *fctx,
|
||||||
if (fd != STDOUT_FILENO)
|
if (fd != STDOUT_FILENO)
|
||||||
close(fd);
|
close(fd);
|
||||||
if (r != pkg->size) {
|
if (r != pkg->size) {
|
||||||
apk_error("Unable to download '%s'", infile);
|
apk_error("Unable to download '%s'", url);
|
||||||
unlink(outfile);
|
unlinkat(fctx->outdir_fd, pkgfile, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +168,9 @@ static int fetch_main(void *ctx, int argc, char **argv)
|
||||||
struct apk_database db;
|
struct apk_database db;
|
||||||
int i, j, r;
|
int i, j, r;
|
||||||
|
|
||||||
|
if (fctx->outdir_fd == 0)
|
||||||
|
fctx->outdir_fd = AT_FDCWD;
|
||||||
|
|
||||||
if ((argc > 0) && (strcmp(argv[0], "coffee") == 0)) {
|
if ((argc > 0) && (strcmp(argv[0], "coffee") == 0)) {
|
||||||
if (apk_flags & APK_FORCE)
|
if (apk_flags & APK_FORCE)
|
||||||
return cup();
|
return cup();
|
||||||
|
|
|
@ -55,7 +55,7 @@ static int index_read_file(struct apk_database *db, struct index_ctx *ictx)
|
||||||
|
|
||||||
if (ictx->index == NULL)
|
if (ictx->index == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if (apk_file_get_info(ictx->index, APK_CHECKSUM_NONE, &fi) < 0)
|
if (apk_file_get_info(AT_FDCWD, ictx->index, APK_CHECKSUM_NONE, &fi) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ictx->index_mtime = fi.mtime;
|
ictx->index_mtime = fi.mtime;
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ static int index_main(void *ctx, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (apk_file_get_info(argv[i], APK_CHECKSUM_NONE, &fi) < 0) {
|
if (apk_file_get_info(AT_FDCWD, argv[i], APK_CHECKSUM_NONE, &fi) < 0) {
|
||||||
apk_warning("File '%s' is unaccessible", argv[i]);
|
apk_warning("File '%s' is unaccessible", argv[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ static int index_main(void *ctx, int argc, char **argv)
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
struct apk_sign_ctx sctx;
|
struct apk_sign_ctx sctx;
|
||||||
apk_sign_ctx_init(&sctx, ictx->method, NULL);
|
apk_sign_ctx_init(&sctx, ictx->method, NULL, db.keys_fd);
|
||||||
if (apk_pkg_read(&db, argv[i], &sctx, NULL) == 0)
|
if (apk_pkg_read(&db, argv[i], &sctx, NULL) == 0)
|
||||||
newpkgs++;
|
newpkgs++;
|
||||||
apk_sign_ctx_free(&sctx);
|
apk_sign_ctx_free(&sctx);
|
||||||
|
@ -171,7 +171,7 @@ static int index_main(void *ctx, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ictx->output != NULL)
|
if (ictx->output != NULL)
|
||||||
os = apk_ostream_to_file(ictx->output, 0644);
|
os = apk_ostream_to_file(AT_FDCWD, ictx->output, 0644);
|
||||||
else
|
else
|
||||||
os = apk_ostream_to_fd(STDOUT_FILENO);
|
os = apk_ostream_to_fd(STDOUT_FILENO);
|
||||||
if (ictx->method == APK_SIGN_GENERATE) {
|
if (ictx->method == APK_SIGN_GENERATE) {
|
||||||
|
|
34
src/io.c
34
src/io.c
|
@ -77,11 +77,11 @@ struct apk_istream *apk_istream_from_fd(int fd)
|
||||||
return &fis->is;
|
return &fis->is;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_file(const char *file)
|
struct apk_istream *apk_istream_from_file(int atfd, const char *file)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
fd = openat(atfd, file, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -342,11 +342,11 @@ struct apk_bstream *apk_bstream_from_fd(int fd)
|
||||||
return apk_bstream_from_istream(apk_istream_from_fd(fd));
|
return apk_bstream_from_istream(apk_istream_from_fd(fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_bstream *apk_bstream_from_file(const char *file)
|
struct apk_bstream *apk_bstream_from_file(int atfd, const char *file)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
fd = openat(atfd, file, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -387,12 +387,13 @@ static void tee_close(void *stream, size_t *size)
|
||||||
free(tbs);
|
free(tbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, const char *to)
|
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to)
|
||||||
{
|
{
|
||||||
struct apk_tee_bstream *tbs;
|
struct apk_tee_bstream *tbs;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = creat(to, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
fd = openat(atfd, to, O_CREAT | O_RDWR | O_TRUNC,
|
||||||
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -433,13 +434,13 @@ apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
|
||||||
return APK_BLOB_PTR_LEN(ptr, rsize);
|
return APK_BLOB_PTR_LEN(ptr, rsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
apk_blob_t apk_blob_from_file(const char *file)
|
apk_blob_t apk_blob_from_file(int atfd, const char *file)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
fd = openat(atfd, file, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return APK_BLOB_NULL;
|
return APK_BLOB_NULL;
|
||||||
|
|
||||||
|
@ -462,12 +463,13 @@ err_fd:
|
||||||
return APK_BLOB_NULL;
|
return APK_BLOB_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *fi)
|
int apk_file_get_info(int atfd, const char *filename, int checksum,
|
||||||
|
struct apk_file_info *fi)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat64 st;
|
||||||
struct apk_bstream *bs;
|
struct apk_bstream *bs;
|
||||||
|
|
||||||
if (lstat(filename, &st) != 0)
|
if (fstatat64(atfd, filename, &st, AT_SYMLINK_NOFOLLOW) != 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
*fi = (struct apk_file_info) {
|
*fi = (struct apk_file_info) {
|
||||||
|
@ -482,7 +484,7 @@ int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *
|
||||||
if (checksum == APK_CHECKSUM_NONE)
|
if (checksum == APK_CHECKSUM_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bs = apk_bstream_from_file(filename);
|
bs = apk_bstream_from_file(atfd, filename);
|
||||||
if (bs != NULL) {
|
if (bs != NULL) {
|
||||||
EVP_MD_CTX mdctx;
|
EVP_MD_CTX mdctx;
|
||||||
apk_blob_t blob;
|
apk_blob_t blob;
|
||||||
|
@ -501,9 +503,9 @@ int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_file_gz(const char *file)
|
struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file)
|
||||||
{
|
{
|
||||||
return apk_bstream_gunzip(apk_bstream_from_file(file));
|
return apk_bstream_gunzip(apk_bstream_from_file(atfd, file));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_fd_ostream {
|
struct apk_fd_ostream {
|
||||||
|
@ -593,11 +595,11 @@ struct apk_ostream *apk_ostream_to_fd(int fd)
|
||||||
return &fos->os;
|
return &fos->os;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_ostream *apk_ostream_to_file(const char *file, mode_t mode)
|
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = creat(file, mode);
|
fd = openat(atfd, file, O_CREAT | O_RDWR | O_TRUNC, mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,29 @@
|
||||||
#include "apk_database.h"
|
#include "apk_database.h"
|
||||||
#include "apk_state.h"
|
#include "apk_state.h"
|
||||||
|
|
||||||
|
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to)
|
||||||
|
{
|
||||||
|
/* pkgname-1.0.apk */
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(pkg->name->name));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR("-"));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(pkg->version));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(".apk"));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to)
|
||||||
|
{
|
||||||
|
/* pkgname-1.0_alpha1.12345678.apk */
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(pkg->name->name));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR("-"));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(pkg->version));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR("."));
|
||||||
|
apk_blob_push_hexdump(&to, APK_BLOB_PTR_LEN((char *) pkg->csum.data,
|
||||||
|
APK_CACHE_CSUM_BYTES));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_STR(".apk"));
|
||||||
|
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
|
||||||
|
}
|
||||||
|
|
||||||
struct apk_package *apk_pkg_new(void)
|
struct apk_package *apk_pkg_new(void)
|
||||||
{
|
{
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
|
@ -56,6 +79,9 @@ int apk_pkg_parse_name(apk_blob_t apkname,
|
||||||
if (++dash >= 2)
|
if (++dash >= 2)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (i < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
*name = APK_BLOB_PTR_LEN(apkname.ptr, i);
|
*name = APK_BLOB_PTR_LEN(apkname.ptr, i);
|
||||||
if (version != NULL)
|
if (version != NULL)
|
||||||
|
@ -282,9 +308,10 @@ int apk_script_type(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
|
void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
|
||||||
struct apk_checksum *identity)
|
struct apk_checksum *identity, int keys_fd)
|
||||||
{
|
{
|
||||||
memset(ctx, 0, sizeof(struct apk_sign_ctx));
|
memset(ctx, 0, sizeof(struct apk_sign_ctx));
|
||||||
|
ctx->keys_fd = keys_fd;
|
||||||
ctx->action = action;
|
ctx->action = action;
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case APK_SIGN_NONE:
|
case APK_SIGN_NONE:
|
||||||
|
@ -359,14 +386,19 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
|
||||||
ctx->signature.pkey != NULL)
|
ctx->signature.pkey != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (ctx->keys_fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (strncmp(&fi->name[6], "RSA.", 4) == 0 ||
|
if (strncmp(&fi->name[6], "RSA.", 4) == 0 ||
|
||||||
strncmp(&fi->name[6], "DSA.", 4) == 0) {
|
strncmp(&fi->name[6], "DSA.", 4) == 0) {
|
||||||
char file[256];
|
int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY);
|
||||||
BIO *bio = BIO_new(BIO_s_file());
|
BIO *bio;
|
||||||
snprintf(file, sizeof(file), "/etc/apk/keys/%s", &fi->name[10]);
|
|
||||||
if (BIO_read_filename(bio, file) > 0)
|
if (fd < 0)
|
||||||
ctx->signature.pkey =
|
return 0;
|
||||||
PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
|
bio = BIO_new_fp(fdopen(fd, "r"), 0);
|
||||||
|
ctx->signature.pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
||||||
if (ctx->signature.pkey != NULL) {
|
if (ctx->signature.pkey != NULL) {
|
||||||
if (fi->name[6] == 'R')
|
if (fi->name[6] == 'R')
|
||||||
ctx->md = EVP_sha1();
|
ctx->md = EVP_sha1();
|
||||||
|
@ -690,12 +722,9 @@ int apk_pkg_read(struct apk_database *db, const char *file,
|
||||||
struct apk_file_info fi;
|
struct apk_file_info fi;
|
||||||
struct apk_bstream *bs;
|
struct apk_bstream *bs;
|
||||||
struct apk_istream *tar;
|
struct apk_istream *tar;
|
||||||
char realfile[PATH_MAX];
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (realpath(file, realfile) < 0)
|
r = apk_file_get_info(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi);
|
||||||
return -errno;
|
|
||||||
r = apk_file_get_info(realfile, APK_CHECKSUM_NONE, &fi);
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -705,7 +734,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
if (ctx.pkg == NULL)
|
if (ctx.pkg == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
bs = apk_bstream_from_file(realfile);
|
bs = apk_bstream_from_file(AT_FDCWD, file);
|
||||||
if (bs == NULL)
|
if (bs == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -723,7 +752,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
|
||||||
}
|
}
|
||||||
if (sctx->action != APK_SIGN_VERIFY)
|
if (sctx->action != APK_SIGN_VERIFY)
|
||||||
ctx.pkg->csum = sctx->identity;
|
ctx.pkg->csum = sctx->identity;
|
||||||
ctx.pkg->filename = strdup(realfile);
|
ctx.pkg->filename = strdup(file);
|
||||||
|
|
||||||
ctx.pkg = apk_db_pkg_add(db, ctx.pkg);
|
ctx.pkg = apk_db_pkg_add(db, ctx.pkg);
|
||||||
if (pkg != NULL)
|
if (pkg != NULL)
|
||||||
|
@ -814,18 +843,17 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
||||||
struct hlist_node *c;
|
struct hlist_node *c;
|
||||||
int fd, status;
|
int fd, status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char fn[1024];
|
char fn[PATH_MAX];
|
||||||
|
|
||||||
fchdir(root_fd);
|
|
||||||
hlist_for_each_entry(script, c, &pkg->scripts, script_list) {
|
hlist_for_each_entry(script, c, &pkg->scripts, script_list) {
|
||||||
if (script->type != type)
|
if (script->type != type)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(fn, sizeof(fn),
|
snprintf(fn, sizeof(fn), "tmp/%s-%s.%s",
|
||||||
"tmp/%s-%s.%s",
|
|
||||||
pkg->name->name, pkg->version,
|
pkg->name->name, pkg->version,
|
||||||
apk_script_types[type]);
|
apk_script_types[type]);
|
||||||
fd = creat(fn, 0777);
|
|
||||||
|
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC, 0777);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
write(fd, script->script, script->size);
|
write(fd, script->script, script->size);
|
||||||
|
@ -837,6 +865,7 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
fchdir(root_fd);
|
||||||
if (chroot(".") < 0) {
|
if (chroot(".") < 0) {
|
||||||
apk_error("chroot: %s", strerror(errno));
|
apk_error("chroot: %s", strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
|
@ -846,7 +875,7 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
unlink(fn);
|
unlinkat(root_fd, fn, 0);
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -711,7 +711,7 @@ int apk_state_commit(struct apk_state *state,
|
||||||
if (apk_flags & APK_PROGRESS)
|
if (apk_flags & APK_PROGRESS)
|
||||||
apk_draw_progress(20, 1);
|
apk_draw_progress(20, 1);
|
||||||
|
|
||||||
if (!(apk_flags & APK_SIMULATE) && prog.done.packages != 0)
|
if (!(apk_flags & APK_SIMULATE))
|
||||||
apk_db_write_config(db);
|
apk_db_write_config(db);
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
|
21
src/url.c
21
src/url.c
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -61,7 +62,7 @@ static int fork_wget(const char *url)
|
||||||
struct apk_istream *apk_istream_from_url(const char *url)
|
struct apk_istream *apk_istream_from_url(const char *url)
|
||||||
{
|
{
|
||||||
if (apk_url_local_file(url) != NULL)
|
if (apk_url_local_file(url) != NULL)
|
||||||
return apk_istream_from_file(apk_url_local_file(url));
|
return apk_istream_from_file(AT_FDCWD, apk_url_local_file(url));
|
||||||
|
|
||||||
return apk_istream_from_fd(fork_wget(url));
|
return apk_istream_from_fd(fork_wget(url));
|
||||||
}
|
}
|
||||||
|
@ -74,16 +75,19 @@ struct apk_istream *apk_istream_from_url_gz(const char *file)
|
||||||
struct apk_bstream *apk_bstream_from_url(const char *url)
|
struct apk_bstream *apk_bstream_from_url(const char *url)
|
||||||
{
|
{
|
||||||
if (apk_url_local_file(url))
|
if (apk_url_local_file(url))
|
||||||
return apk_bstream_from_file(url);
|
return apk_bstream_from_file(AT_FDCWD, url);
|
||||||
|
|
||||||
return apk_bstream_from_fd(fork_wget(url));
|
return apk_bstream_from_fd(fork_wget(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_url_download(const char *url, const char *file)
|
int apk_url_download(const char *url, int atfd, const char *file)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status, fd;
|
||||||
char tmp[256];
|
|
||||||
|
fd = openat(atfd, file, O_CREAT|O_RDWR|O_TRUNC, 0644);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
|
@ -92,15 +96,14 @@ int apk_url_download(const char *url, const char *file)
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
setsid();
|
setsid();
|
||||||
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
|
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
|
||||||
snprintf(tmp, sizeof(tmp), "%s.backup", file);
|
dup2(fd, STDOUT_FILENO);
|
||||||
rename(file, tmp);
|
execlp("wget", "wget", "-q", "-O", "-", url, NULL);
|
||||||
execlp("wget", "wget", "-q", "-O", file, url, NULL);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
unlink(file);
|
unlinkat(atfd, file, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
src/verify.c
11
src/verify.c
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "apk_applet.h"
|
#include "apk_applet.h"
|
||||||
|
@ -19,12 +20,17 @@ static int verify_main(void *ctx, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct apk_sign_ctx sctx;
|
struct apk_sign_ctx sctx;
|
||||||
struct apk_istream *is;
|
struct apk_istream *is;
|
||||||
|
struct apk_database db;
|
||||||
int i, r, ok, rc = 0;
|
int i, r, ok, rc = 0;
|
||||||
|
|
||||||
apk_flags |= APK_ALLOW_UNTRUSTED;
|
apk_flags |= APK_ALLOW_UNTRUSTED;
|
||||||
|
r = apk_db_open(&db, apk_root, APK_OPENF_READ | APK_OPENF_NO_STATE);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL);
|
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db.keys_fd);
|
||||||
is = apk_bstream_gunzip_mpart(apk_bstream_from_file(argv[i]),
|
is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, argv[i]),
|
||||||
apk_sign_ctx_mpart_cb, &sctx);
|
apk_sign_ctx_mpart_cb, &sctx);
|
||||||
if (is == NULL) {
|
if (is == NULL) {
|
||||||
apk_error("%s: %s", strerror(errno), argv[i]);
|
apk_error("%s: %s", strerror(errno), argv[i]);
|
||||||
|
@ -43,6 +49,7 @@ static int verify_main(void *ctx, int argc, char **argv)
|
||||||
rc++;
|
rc++;
|
||||||
apk_sign_ctx_free(&sctx);
|
apk_sign_ctx_free(&sctx);
|
||||||
}
|
}
|
||||||
|
apk_db_close(&db);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue