From 6d71f49c11e22a617234ef47123ab9287cde23af Mon Sep 17 00:00:00 2001
From: Timo Teräs <timo.teras@iki.fi>
Date: Fri, 2 Oct 2020 15:25:12 +0300
Subject: 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;
 }
 
-- 
cgit v1.2.3-70-g09d2