diff options
-rw-r--r-- | src/apk_io.h | 7 | ||||
-rw-r--r-- | src/database.c | 25 | ||||
-rw-r--r-- | src/io.c | 30 |
3 files changed, 54 insertions, 8 deletions
diff --git a/src/apk_io.h b/src/apk_io.h index 9a6c63a..b88293c 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -106,13 +106,16 @@ 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_file(int atfd, const char *file); -typedef int apk_dir_file_cb(void *ctx, int dirfd, const char *entry); +#define APK_BTF_ADD_EOL 0x00000001 +int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flags); #define APK_FI_NOFOLLOW 0x80000000 - int apk_file_get_info(int atfd, const char *filename, unsigned int flags, struct apk_file_info *fi); + +typedef int apk_dir_file_cb(void *ctx, int dirfd, const char *entry); int apk_dir_foreach_file(int dirfd, apk_dir_file_cb cb, void *ctx); + int apk_move_file(int atfd, const char *from, const char *to); int apk_url_download(const char *url, int atfd, const char *file); const char *apk_url_local_file(const char *url); diff --git a/src/database.c b/src/database.c index da3dcb9..ca6c524 100644 --- a/src/database.c +++ b/src/database.c @@ -55,6 +55,7 @@ static const char * const apk_lock_file = "var/lock/apkdb"; static const char * const apk_world_file = "etc/apk/world"; static const char * const apk_world_file_tmp = "etc/apk/world.new"; static const char * const apk_world_file_old = "var/lib/apk/world"; +static const char * const apk_arch_file = "etc/apk/arch"; static const char * const apk_scripts_file = "lib/apk/db/scripts.tar"; static const char * const apk_scripts_file_tmp = "lib/apk/db/scripts.tar.new"; @@ -1339,7 +1340,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) struct apk_bstream *bs; struct statfs stfs; apk_blob_t blob; - int r, fd; + int r, fd, write_arch = FALSE; memset(db, 0, sizeof(*db)); if (apk_flags & APK_SIMULATE) { @@ -1365,11 +1366,6 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) /* Get first repository tag (the NULL tag) */ apk_db_get_tag_id(db, APK_BLOB_NULL); - if (dbopts->root && dbopts->arch) { - db->arch = apk_blob_atomize(APK_BLOB_STR(dbopts->arch)); - } else { - db->arch = apk_blob_atomize(APK_BLOB_STR(APK_DEFAULT_ARCH)); - } db->root = strdup(dbopts->root ?: "/"); db->root_fd = openat(AT_FDCWD, db->root, O_RDONLY | O_CLOEXEC); if (db->root_fd < 0 && (dbopts->open_flags & APK_OPENF_CREATE)) { @@ -1384,6 +1380,21 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) stfs.f_type == 0x01021994 /* TMPFS_MAGIC */) db->permanent = 0; + if (dbopts->root && dbopts->arch) { + db->arch = apk_blob_atomize(APK_BLOB_STR(dbopts->arch)); + write_arch = TRUE; + } else { + apk_blob_t arch; + arch = apk_blob_from_file(db->root_fd, apk_arch_file); + if (!APK_BLOB_IS_NULL(arch)) { + db->arch = apk_blob_atomize_dup(apk_blob_trim(arch)); + free(arch.ptr); + } else { + db->arch = apk_blob_atomize(APK_BLOB_STR(APK_DEFAULT_ARCH)); + write_arch = TRUE; + } + } + apk_id_cache_init(&db->id_cache, db->root_fd); if (dbopts->open_flags & APK_OPENF_WRITE) { @@ -1423,6 +1434,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) } else goto ret_errno; } + if (write_arch) + apk_blob_to_file(db->root_fd, apk_arch_file, *db->arch, APK_BTF_ADD_EOL); } blob = APK_BLOB_STR("+etc\n" "@etc/init.d\n"); @@ -486,6 +486,36 @@ err_fd: return APK_BLOB_NULL; } +int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flags) +{ + int fd, r, len; + + fd = openat(atfd, file, O_CREAT | O_WRONLY | O_CLOEXEC, 0644); + if (fd < 0) + return -errno; + + len = b.len; + r = write(fd, b.ptr, len); + if ((r == len) && + (flags & APK_BTF_ADD_EOL) && (b.len == 0 || b.ptr[b.len-1] != '\n')) { + len = 1; + r = write(fd, "\n", len); + } + + if (r < 0) + r = -errno; + else if (r != len) + r = -ENOSPC; + else + r = 0; + close(fd); + + if (r != 0) + unlinkat(atfd, file, 0); + + return r; +} + int apk_file_get_info(int atfd, const char *filename, unsigned int flags, struct apk_file_info *fi) { |