From 6d71f49c11e22a617234ef47123ab9287cde23af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 2 Oct 2020 15:25:12 +0300 Subject: [PATCH] io: make ostream_file always use tmpname --- src/apk_io.h | 2 +- src/app_adbsign.c | 15 +++++---------- src/app_convdb.c | 2 +- src/app_index.c | 2 +- src/app_mkndx.c | 2 +- src/database.c | 35 +++++------------------------------ src/io.c | 41 ++++++++++++++++++++++------------------- 7 files changed, 36 insertions(+), 63 deletions(-) diff --git a/src/apk_io.h b/src/apk_io.h index 87b953e..02edf1d 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -147,7 +147,7 @@ struct apk_ostream { struct apk_ostream *apk_ostream_gzip(struct apk_ostream *); struct apk_ostream *apk_ostream_counter(off_t *); struct apk_ostream *apk_ostream_to_fd(int fd); -struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, const char *tmpfile, 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(int atfd, const char *file, const char *tmpfile, mode_t mode); size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string); static inline void apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; } diff --git a/src/app_adbsign.c b/src/app_adbsign.c index 6861776..918948f 100644 --- a/src/app_adbsign.c +++ b/src/app_adbsign.c @@ -64,22 +64,17 @@ static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struc static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { - char tmpname[PATH_MAX]; struct sign_ctx *ctx = pctx; char **arg; int r; ctx->db = db; foreach_array_item(arg, args) { - if (snprintf(tmpname, sizeof tmpname, "%s.tmp", *arg) >= sizeof tmpname) { - r = ENAMETOOLONG; - } else { - ctx->xfrm.is = apk_istream_from_file(AT_FDCWD, *arg); - ctx->xfrm.os = apk_ostream_to_file(AT_FDCWD, *arg, tmpname, 0644); - adb_c_xfrm(&ctx->xfrm, update_signatures); - apk_istream_close(ctx->xfrm.is); - r = apk_ostream_close(ctx->xfrm.os); - } + ctx->xfrm.is = apk_istream_from_file(AT_FDCWD, *arg); + ctx->xfrm.os = apk_ostream_to_file(AT_FDCWD, *arg, 0644); + adb_c_xfrm(&ctx->xfrm, update_signatures); + apk_istream_close(ctx->xfrm.is); + r = apk_ostream_close(ctx->xfrm.os); if (r) apk_error("%s: %s", *arg, apk_error_str(r)); } diff --git a/src/app_convdb.c b/src/app_convdb.c index 39a8ad3..f77bbf8 100644 --- a/src/app_convdb.c +++ b/src/app_convdb.c @@ -216,7 +216,7 @@ static int conv_main(void *pctx, struct apk_database *db, struct apk_string_arra r = adb_c_create( //apk_ostream_to_file(db->root_fd, "lib/apk/db/installed.adb", 0644), - apk_ostream_to_file(AT_FDCWD, "installed.adb", 0, 0644), + apk_ostream_to_file(AT_FDCWD, "installed.adb", 0644), &ctx->dbi, &db->trust); if (r == 0) { // unlink old files diff --git a/src/app_index.c b/src/app_index.c index 18c240f..25ca3b4 100644 --- a/src/app_index.c +++ b/src/app_index.c @@ -199,7 +199,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra return -1; if (ictx->output != NULL) - os = apk_ostream_to_file(AT_FDCWD, ictx->output, NULL, 0644); + os = apk_ostream_to_file(AT_FDCWD, ictx->output, 0644); else os = apk_ostream_to_fd(STDOUT_FILENO); if (IS_ERR_OR_NULL(os)) return -1; diff --git a/src/app_mkndx.c b/src/app_mkndx.c index d06576d..7f136fc 100644 --- a/src/app_mkndx.c +++ b/src/app_mkndx.c @@ -293,7 +293,7 @@ static int mkndx_main(void *pctx, struct apk_database *db, struct apk_string_arr adb_w_rootobj(&ndx); r = adb_c_create( - apk_ostream_to_file(AT_FDCWD, ctx->output, NULL, 0644), + apk_ostream_to_file(AT_FDCWD, ctx->output, 0644), &ctx->db, &db->trust); adb_free(&ctx->db); diff --git a/src/database.c b/src/database.c index 8298f72..9d1c82b 100644 --- a/src/database.c +++ b/src/database.c @@ -53,23 +53,13 @@ unsigned int apk_flags = 0, apk_force = 0; static apk_blob_t tmpprefix = { .len=8, .ptr = ".apknew." }; static const char * const apkindex_tar_gz = "APKINDEX.tar.gz"; - static const char * const apk_static_cache_dir = "var/cache/apk"; - 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_arch_file = "etc/apk/arch"; - static const char * const apk_lock_file = "lib/apk/db/lock"; - 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"; - static const char * const apk_triggers_file = "lib/apk/db/triggers"; -static const char * const apk_triggers_file_tmp = "lib/apk/db/triggers.new"; - const char * const apk_installed_file = "lib/apk/db/installed"; -static const char * const apk_installed_file_tmp = "lib/apk/db/installed.new"; static struct apk_db_acl *apk_default_acl_dir, *apk_default_acl_file; @@ -1221,10 +1211,7 @@ static int apk_db_index_write_nr_cache(struct apk_database *db) /* Write list of installed non-repository packages to * cached index file */ - os = apk_ostream_to_file(db->cache_fd, - "installed", - "installed.new", - 0644); + os = apk_ostream_to_file(db->cache_fd, "installed", 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); ctx.os = os; @@ -1767,29 +1754,20 @@ int apk_db_write_config(struct apk_database *db) return -1; } - os = apk_ostream_to_file(db->root_fd, - apk_world_file, - apk_world_file_tmp, - 0644); + os = apk_ostream_to_file(db->root_fd, apk_world_file, 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_deps_write(db, db->world, os, APK_BLOB_PTR_LEN("\n", 1)); apk_ostream_write(os, "\n", 1); r = apk_ostream_close(os); if (r < 0) return r; - os = apk_ostream_to_file(db->root_fd, - apk_installed_file, - apk_installed_file_tmp, - 0644); + os = apk_ostream_to_file(db->root_fd, apk_installed_file, 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_write_fdb(db, os); r = apk_ostream_close(os); if (r < 0) return r; - os = apk_ostream_to_file(db->root_fd, - apk_scripts_file, - apk_scripts_file_tmp, - 0644); + os = apk_ostream_to_file(db->root_fd, apk_scripts_file, 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_scriptdb_write(db, os); r = apk_ostream_close(os); @@ -1797,10 +1775,7 @@ int apk_db_write_config(struct apk_database *db) apk_db_index_write_nr_cache(db); - os = apk_ostream_to_file(db->root_fd, - apk_triggers_file, - apk_triggers_file_tmp, - 0644); + os = apk_ostream_to_file(db->root_fd, apk_triggers_file, 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_triggers_write(db, os); r = apk_ostream_close(os); diff --git a/src/io.c b/src/io.c index db640da..e6d94f7 100644 --- a/src/io.c +++ b/src/io.c @@ -829,7 +829,7 @@ struct apk_fd_ostream { struct apk_ostream os; int fd; - const char *file, *tmpfile; + const char *file; int atfd; size_t bytes; @@ -902,12 +902,17 @@ static int fdo_close(struct apk_ostream *os) close(fos->fd) < 0) rc = -errno; - if (fos->tmpfile != NULL) { - if (rc == 0) - renameat(fos->atfd, fos->tmpfile, - fos->atfd, fos->file); - else - unlinkat(fos->atfd, fos->tmpfile, 0); + if (fos->file) { + char tmpname[PATH_MAX]; + + snprintf(tmpname, sizeof tmpname, "%s.tmp", fos->file); + if (rc == 0) { + if (renameat(fos->atfd, tmpname, + fos->atfd, fos->file) < 0) + rc = -errno; + } else { + unlinkat(fos->atfd, tmpname, 0); + } } free(fos); @@ -940,15 +945,16 @@ struct apk_ostream *apk_ostream_to_fd(int fd) return &fos->os; } -struct apk_ostream *apk_ostream_to_file(int atfd, - const char *file, - const char *tmpfile, - mode_t mode) +struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode) { + char tmpname[PATH_MAX]; struct apk_ostream *os; int fd; - fd = openat(atfd, tmpfile ?: file, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, mode); + if (snprintf(tmpname, sizeof tmpname, "%s.tmp", file) >= sizeof tmpname) + return ERR_PTR(-ENAMETOOLONG); + + fd = openat(atfd, tmpname, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, mode); if (fd < 0) return ERR_PTR(-errno); fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -956,13 +962,10 @@ struct apk_ostream *apk_ostream_to_file(int atfd, os = apk_ostream_to_fd(fd); if (IS_ERR_OR_NULL(os)) return ERR_CAST(os); - if (tmpfile != NULL) { - struct apk_fd_ostream *fos = - container_of(os, struct apk_fd_ostream, os); - fos->file = file; - fos->tmpfile = tmpfile; - fos->atfd = atfd; - } + struct apk_fd_ostream *fos = container_of(os, struct apk_fd_ostream, os); + fos->file = file; + fos->atfd = atfd; + return os; }