summaryrefslogtreecommitdiff
path: root/src/logic/tpax_archive_write.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2024-05-26 03:07:37 +0000
committermidipix <writeonce@midipix.org>2024-05-26 03:41:30 +0000
commitfb29e19bf5c914aaf4c9445ffc52ac44266eb006 (patch)
tree66693eca14d25bb01acccdee2f9601285ca35753 /src/logic/tpax_archive_write.c
parentacc91bc260046e228d8043e91d33d6793fb41c1a (diff)
downloadtpax-fb29e19bf5c914aaf4c9445ffc52ac44266eb006.tar.bz2
tpax-fb29e19bf5c914aaf4c9445ffc52ac44266eb006.tar.xz
code base: moved tpax_archive_seal() to own translation unit.
Diffstat (limited to 'src/logic/tpax_archive_write.c')
-rw-r--r--src/logic/tpax_archive_write.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/logic/tpax_archive_write.c b/src/logic/tpax_archive_write.c
new file mode 100644
index 0000000..b4dcf2a
--- /dev/null
+++ b/src/logic/tpax_archive_write.c
@@ -0,0 +1,104 @@
+/**************************************************************/
+/* tpax: a topological pax implementation */
+/* Copyright (C) 2020--2024 SysDeer Technologies, LLC */
+/* Released under GPLv2 and GPLv3; see COPYING.TPAX. */
+/**************************************************************/
+
+#include <tpax/tpax.h>
+#include "tpax_driver_impl.h"
+#include "tpax_errinfo_impl.h"
+#include "tpax_visibility_impl.h"
+
+static int tpax_archive_append_memory_data(
+ int fdout,
+ void * buf,
+ ssize_t nbytes)
+{
+ ssize_t ret;
+ char * ch;
+
+ for (ch=buf; nbytes; ch+=ret) {
+ ret = write(fdout,ch,nbytes);
+
+ while ((ret < 0) && (errno == EINTR))
+ ret = write(fdout,ch,nbytes);
+
+ if (ret < 0)
+ return ret;
+
+ nbytes -= ret;
+ }
+
+ return 0;
+}
+
+static int tpax_archive_append_pad(
+ const struct tpax_driver_ctx * dctx,
+ int fdout,
+ const struct stat * st)
+{
+ int ret;
+ off_t cpos;
+ ssize_t nbytes;
+ char buf[512];
+
+ nbytes = st->st_size;
+ nbytes += 0x1ff;
+ nbytes |= 0x1ff;
+ nbytes ^= 0x1ff;
+ nbytes -= st->st_size;
+
+ memset(buf,0,nbytes);
+
+ cpos = tpax_get_driver_cpos(dctx);
+ cpos += st->st_size + nbytes;
+
+ if (!(ret = tpax_archive_append_memory_data(fdout,buf,nbytes)))
+ tpax_set_driver_cpos(dctx,cpos);
+
+ return ret;
+}
+
+int tpax_archive_seal(const struct tpax_driver_ctx * dctx)
+{
+ int fdout;
+ off_t cpos;
+ ssize_t nbytes;
+ ssize_t nwritten;
+ ssize_t blksize;
+ char buf[512];
+
+ blksize = tpax_get_archive_block_size(dctx);
+ cpos = tpax_get_driver_cpos(dctx);
+
+ if (cpos % 512)
+ return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FLOW_ERROR);
+
+ fdout = tpax_driver_fdout(dctx);
+ memset(buf,0,sizeof(buf));
+
+ switch (cpos % blksize) {
+ case 0:
+ nbytes = cpos + blksize;
+ break;
+
+ default:
+ nbytes = cpos / blksize;
+ nbytes *= blksize;
+ nbytes += blksize;
+
+ if (nbytes-cpos == 512)
+ nbytes += blksize;
+ }
+
+ for (nwritten=cpos; nwritten<nbytes; nwritten+=512) {
+ if (tpax_archive_append_memory_data(fdout,buf,512) < 0)
+ return TPAX_SYSTEM_ERROR(dctx);
+
+ tpax_set_driver_cpos(dctx,nwritten);
+ }
+
+ (void)tpax_archive_append_pad;
+
+ return 0;
+}