aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile4
-rw-r--r--Makefile16
-rw-r--r--vis-single.c151
4 files changed, 170 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 1477acd..0b46412 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
/vis
/vis-menu
/vis-single
+/vis-single-payload.inc
/vis-digraph
*.css
*.gcda
diff --git a/Dockerfile b/Dockerfile
index a9d3805..105fd6b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,10 +4,12 @@
# ./configure CC='cc --static'
# make
# docker cp vis:/tmp/vis/vis .
+# make vis-single
+# docker cp vis:/tmp/vis/vis-single .
FROM alpine:edge
ENV DIR /tmp/vis
WORKDIR $DIR
-RUN apk update && apk add musl-dev fortify-headers gcc make libtermkey-dev ncurses-dev ncurses-static lua5.3-dev lua5.3-lpeg lua-lpeg-dev acl-dev
+RUN apk update && apk add musl-dev fortify-headers gcc make libtermkey-dev ncurses-dev ncurses-static lua5.3-dev lua5.3-lpeg lua-lpeg-dev acl-dev libarchive-dev xz-dev xz bzip2-dev
RUN sed -i 's/Libs: /Libs: -L${INSTALL_CMOD} /' /usr/lib/pkgconfig/lua5.3.pc
RUN mv /usr/lib/lua/5.3/lpeg.a /usr/lib/lua/5.3/liblpeg.a
RUN sed -i 's/-ltermkey/-ltermkey -lunibilium/' /usr/lib/pkgconfig/termkey.pc
diff --git a/Makefile b/Makefile
index dd896e2..b71238a 100644
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,20 @@ vis-menu: vis-menu.c
vis-digraph: vis-digraph.c
${CC} ${CFLAGS} ${CFLAGS_AUTO} ${CFLAGS_STD} ${CFLAGS_EXTRA} $< ${LDFLAGS} ${LDFLAGS_STD} ${LDFLAGS_AUTO} -o $@
+vis-single-payload.inc: $(EXECUTABLES) lua/*
+ echo '#ifndef VIS_SINGLE_PAYLOAD_H' > vis-single-payload.inc
+ echo '#define VIS_SINGLE_PAYLOAD_H' >> vis-single-payload.inc
+ echo 'unsigned char vis_single_payload[] = {' >> vis-single-payload.inc
+ tar c $(EXECUTABLES) $$(find lua -name '*.lua') | xz | od -t x1 -A none -v | \
+ sed 's/\([0-9a-f]\+\)/0x\1,/g;$$s/,$$/ };/' >> vis-single-payload.inc
+ echo '#endif' >> vis-single-payload.inc
+
+vis-single: vis-single.c vis-single-payload.inc
+ for e in $(ELF); do \
+ ${STRIP} "$$e"; \
+ done
+ ${CC} ${CFLAGS} ${CFLAGS_AUTO} ${CFLAGS_STD} ${CFLAGS_EXTRA} $< ${LDFLAGS} ${LDFLAGS_STD} ${LDFLAGS_AUTO} -larchive -lacl -lbz2 -llzma -o $@
+
debug: clean
@$(MAKE) CFLAGS_EXTRA='${CFLAGS_EXTRA} ${CFLAGS_DEBUG}'
@@ -91,7 +105,7 @@ test:
clean:
@echo cleaning
- @rm -f $(ELF) vis-single vis-*.tar.gz *.gcov *.gcda *.gcno
+ @rm -f $(ELF) vis-single vis-single-payload.inc vis-*.tar.gz *.gcov *.gcda *.gcno
dist: clean
@echo creating dist tarball
diff --git a/vis-single.c b/vis-single.c
new file mode 100644
index 0000000..b6296c0
--- /dev/null
+++ b/vis-single.c
@@ -0,0 +1,151 @@
+#define _GNU_SOURCE
+
+#include <ftw.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <sys/acl.h>
+
+#include "vis-single-payload.inc"
+
+int copy_data(struct archive *ar, struct archive *aw) {
+ int r;
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ for (;;) {
+ if ((r = archive_read_data_block(ar, &buff, &size, &offset)) == ARCHIVE_EOF)
+ return ARCHIVE_OK;
+
+ if (r != ARCHIVE_OK) {
+ fprintf(stderr, "archive_read_data_block() failed: %s\n", archive_error_string(ar));
+ return r;
+ }
+
+ if ((r = archive_write_data_block(aw, buff, size, offset)) != ARCHIVE_OK) {
+ fprintf(stderr, "archive_write_data_block() failed: %s\n", archive_error_string(aw));
+ return r;
+ }
+ }
+
+ return ARCHIVE_OK;
+}
+
+int extract(const char *path) {
+ struct archive *a;
+ struct archive_entry *entry;
+ struct archive *ext;
+ char * abs_path = NULL;
+ const char * term;
+ char * termenv;
+ int r = ARCHIVE_FAILED;
+
+ if ((a = archive_read_new()) == NULL)
+ return ARCHIVE_FAILED;
+
+ if ((r = archive_read_support_filter_xz(a)) != ARCHIVE_OK)
+ goto out10;
+
+ if ((r = archive_read_support_format_tar(a)) != ARCHIVE_OK)
+ goto out10;
+
+ if ((ext = archive_write_disk_new()) == NULL) {
+ r = ARCHIVE_FAILED;
+ goto out10;
+ }
+
+ if ((r = archive_read_open_memory(a, vis_single_payload, sizeof(vis_single_payload))) != ARCHIVE_OK) {
+ fprintf(stderr, "archive_read_open_memory() failed: %s\n", archive_error_string(a));
+ goto out20;
+ }
+
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ if (asprintf(&abs_path, "%s/%s", path, archive_entry_pathname(entry)) == -1)
+ goto out20;
+
+ archive_entry_set_pathname(entry, abs_path);
+ free(abs_path);
+
+ if ((r = archive_write_header(ext, entry)) != ARCHIVE_OK) {
+ fprintf(stderr, "archive_write_header() failed: %s\n", archive_error_string(ext));
+ goto out20;
+ }
+
+ if ((r = copy_data(a, ext)) != ARCHIVE_OK)
+ goto out20;
+
+ if ((r = archive_write_finish_entry(ext)) != ARCHIVE_OK) {
+ fprintf(stderr, "archive_write_finish_entry() failed: %s\n", archive_error_string(ext));
+ goto out20;
+ }
+ }
+
+out20:
+ archive_write_close(ext);
+ archive_write_free(ext);
+
+out10:
+ archive_read_close(a);
+ archive_read_free(a);
+
+ return ARCHIVE_OK;
+}
+
+int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
+ return remove(fpath);
+}
+
+int main(int argc, char **argv) {
+ char tmp_dirname_template[] = "/tmp/.vis-single-XXXXXX";
+ const char *tmp_dirname;
+ char *abs_path = NULL;
+ const char *term;
+ char *termenv = NULL;
+ int child_pid, statval, rc = EXIT_FAILURE;
+
+ if ((tmp_dirname = mkdtemp(tmp_dirname_template)) == NULL) {
+ perror ("mkdtemp: Could not create tmp directory");
+ goto out10;
+ }
+
+ if (extract(tmp_dirname) != ARCHIVE_OK)
+ goto out20;
+
+ if (asprintf(&abs_path, "%s/vis", tmp_dirname) == -1)
+ goto out20;
+
+ child_pid = fork();
+ if (child_pid == -1) {
+ fprintf(stderr, "could not fork!\n");
+ goto out30;
+ } else if (child_pid == 0) {
+ if ((term = getenv("TERM")) == NULL) {
+ puts("TERM is not defined!");
+ goto out30;
+ }
+
+ if (asprintf(&termenv, "TERM=%s", term) == -1)
+ goto out30;
+
+ char *env[] = { termenv, NULL };
+ execve(abs_path, argv, env);
+ }
+
+ waitpid(child_pid, &statval, WUNTRACED|WCONTINUED);
+ rc = WEXITSTATUS(statval);
+
+out30:
+ free(abs_path);
+ free(termenv);
+
+out20:
+ nftw(tmp_dirname, unlink_cb, 64, FTW_DEPTH|FTW_PHYS);
+
+out10:
+ return rc;
+}