aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2025-07-04 00:55:59 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2025-07-06 22:21:50 +0200
commit892ecce78dec37a1b2701611dd72986442cd094d (patch)
treebbd7fb0a0229795bf52d0b8a9ff9b06251363a67 /tools
parent99554cc243c4b2ec290639a04ebc2f189890d6dd (diff)
downloadwnix-892ecce78dec37a1b2701611dd72986442cd094d.tar.gz
Import project skeleton from rts
https://gitea.privatedns.org/xavi/rts
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt8
-rw-r--r--tools/add-header.c67
-rw-r--r--tools/container.c129
3 files changed, 204 insertions, 0 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644
index 0000000..14d2b0e
--- /dev/null
+++ b/tools/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.0)
+project(utils)
+add_executable(container "container.c")
+add_executable(add-header "add-header.c")
+set(cflags -Wall -g3)
+target_compile_options(container PUBLIC ${cflags})
+target_compile_options(add-header PUBLIC ${cflags})
+install(TARGETS container add-header DESTINATION bin)
diff --git a/tools/add-header.c b/tools/add-header.c
new file mode 100644
index 0000000..75f7458
--- /dev/null
+++ b/tools/add-header.c
@@ -0,0 +1,67 @@
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **const argv)
+{
+ int ret = EXIT_FAILURE;
+ FILE *in = NULL, *out = NULL;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "%s [arg ...] <in-file> <out-file>\n", *argv);
+ goto end;
+ }
+
+ const char *const in_path = argv[argc - 2],
+ *const out_path = argv[argc - 1];
+
+ if (!(out = fopen(out_path, "wb")))
+ {
+ fprintf(stderr, "could not open %s: %s\n", out_path, strerror(errno));
+ goto end;
+ }
+ else if (!(in = fopen(in_path, "rb")))
+ {
+ fprintf(stderr, "could not open %s: %s\n", in_path, strerror(errno));
+ goto end;
+ }
+
+ for (int i = 1; i < argc - 2; i++)
+ {
+ if (fprintf(out, "%s", argv[i]) < 0
+ || putc('\0', out) == EOF
+ || ferror(out))
+ {
+ fprintf(stderr, "failed writing to %s\n", out_path);
+ goto end;
+ }
+ }
+
+ while (!feof(in))
+ {
+ char c;
+
+ if ((!fread(&c, sizeof c, 1, in)
+ || !fwrite(&c, sizeof c, 1, out))
+ && (ferror(in) || ferror(out)))
+ {
+ fprintf(stderr, "ferror(%s)=%d, ferror(%s)=%d\n",
+ in_path, ferror(in), out_path, ferror(out));
+ goto end;
+ }
+ }
+
+ ret = EXIT_SUCCESS;
+
+end:
+ if (out)
+ fclose(out);
+
+ if (in)
+ fclose(in);
+
+ return ret;
+}
diff --git a/tools/container.c b/tools/container.c
new file mode 100644
index 0000000..254eee3
--- /dev/null
+++ b/tools/container.c
@@ -0,0 +1,129 @@
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *filename(const char *const path)
+{
+ const char *ret = &path[strlen(path)];
+
+ while (ret != path && *(ret - 1) != '\\' && *(ret - 1) != '/')
+ ret--;
+
+ return ret;
+}
+
+static int dump_file(const char *const path, const char *const outpath,
+ FILE *const out)
+{
+ int ret = -1;
+ FILE *const f = fopen(path, "rb");
+
+ if (!f)
+ {
+ fprintf(stderr, "%s: could not open %s: %s\n",
+ __func__, path, strerror(errno));
+ goto end;
+ }
+
+ const char *const bname = filename(path);
+
+ if (fprintf(out, "%s", bname) < 0)
+ {
+ fprintf(stderr, "fprintf(f, %s): %s\n", path, strerror(errno));
+ goto end;
+ }
+ else if (fputc('\0', out) == EOF)
+ {
+ perror("could not write null character");
+ goto end;
+ }
+ else if (fseek(f, 0, SEEK_END))
+ {
+ perror("fseek(SEEK_END)");
+ goto end;
+ }
+
+ /* This won't work on files larger than 2 GiB if sizeof sz == 4,
+ * but this is acceptable for a PS1 video game. */
+ const long sz = ftell(f);
+
+ if (fprintf(out, "%ld", sz) < 0)
+ {
+ perror("could not write file size");
+ goto end;
+ }
+ else if (fputc('\0', out) == EOF)
+ {
+ perror("could not write null character");
+ goto end;
+ }
+ else if (fseek(f, 0, SEEK_SET))
+ {
+ fprintf(stderr, "%s: fseek(SEEK_SET): %s\n", __func__, strerror(errno));
+ goto end;
+ }
+
+ while (!feof(f))
+ {
+ char c;
+
+ if (!fread(&c, sizeof c, 1, f))
+ {
+ if (ferror(f))
+ {
+ fprintf(stderr, "%s: ferror\n", path);
+ goto end;
+ }
+ }
+ else if (fputc(c, out) == EOF)
+ {
+ fprintf(stderr, "could not dump %s to %s", path, outpath);
+ goto end;
+ }
+ }
+
+ ret = 0;
+
+end:
+ if (f)
+ fclose(f);
+
+ return ret;
+}
+
+int main(const int argc, const char *const *const argv)
+{
+ int ret = EXIT_FAILURE;
+ size_t n_in = 0;
+ FILE *out = NULL;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "%s <file1> [<file2> ...] <output>\n", *argv);
+ goto end;
+ }
+
+ const char *const outpath = argv[argc - 1];
+
+ n_in = argc - 2;
+
+ if (!(out = fopen(outpath, "wb")))
+ {
+ fprintf(stderr, "could not open %s: %s\n", outpath, strerror(errno));
+ goto end;
+ }
+
+ for (size_t i = 0; i < n_in; i++)
+ if (dump_file(argv[i + 1], outpath, out))
+ goto end;
+
+ ret = EXIT_SUCCESS;
+
+end:
+ if (out)
+ fclose(out);
+
+ return ret;
+}