summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile26
-rw-r--r--arg.h88
-rw-r--r--common.c146
-rw-r--r--common.h22
-rw-r--r--config.mk10
5 files changed, 292 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c7aa8fd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+.POSIX:
+
+CONFIGFILE = config.mk
+include $(CONFIGFILE)
+
+
+BIN =\
+ bff-premultiply\
+ bff-unpremultiply
+
+
+HDR =\
+ arg.h\
+ common.h
+
+all: $(BIN)
+
+$(BIN:=.o): $(HDR)
+common.o: $(HDR)
+$(BIN): common.o
+
+clean:
+ -rm -- *.o $(BIN)
+
+.PHONY: all clean
+.PRECIOUS: common.o
diff --git a/arg.h b/arg.h
new file mode 100644
index 0000000..5285d92
--- /dev/null
+++ b/arg.h
@@ -0,0 +1,88 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef ARG_H__
+#define ARG_H__
+
+extern char *argv0;
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][1];\
+ argc--, argv++) {\
+ char argc_;\
+ char **argv_;\
+ int brk_;\
+ if (argv[0][0] == '-') {\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+/* Handles obsolete -NUM syntax */
+#define ARGNUM case '0':\
+ case '1':\
+ case '2':\
+ case '3':\
+ case '4':\
+ case '5':\
+ case '6':\
+ case '7':\
+ case '8':\
+ case '9'
+
+#define ARGALT(SYMBOL) }\
+ } else if (argv[0][0] == SYMBOL) {\
+ for (brk_ = 0, argv[0]++, argv_ = argv;\
+ argv[0][0] && !brk_;\
+ argv[0]++) {\
+ if (argv_ != argv)\
+ break;\
+ argc_ = argv[0][0];\
+ switch (argc_)
+
+#define ARGEND }\
+ } else {\
+ break;\
+ }\
+ }
+
+#define ARGC() argc_
+
+#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk_ = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define UARGF() EARGF(usage())
+
+#define LNGARG() &argv[0][0]
+
+#define UNOFLAGS(...) ARGBEGIN {\
+ default:\
+ usage();\
+ } ARGEND;\
+ if (__VA_ARGS__)\
+ usage()
+
+
+#endif
diff --git a/common.c b/common.c
new file mode 100644
index 0000000..b39fbd6
--- /dev/null
+++ b/common.c
@@ -0,0 +1,146 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+char *argv0;
+
+static pid_t image_decoder_pid;
+static pid_t image_encoder_pid;
+
+
+void
+eprintf(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ if (argv0 && strncmp(fmt, "usage", strlen("usage")))
+ fprintf(stderr, "%s: ", argv0);
+
+ vfprintf(stderr, fmt, ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ }
+
+ va_end(ap);
+ exit(1);
+}
+
+
+void
+bff_begin(void)
+{
+ int rw[2];
+
+ if (pipe(rw))
+ eprintf("pipe:");
+ switch (image_decoder_pid = fork()) {
+ case -1:
+ eprintf("fork:");
+ break;
+ case 0:
+ if (prctl(PR_SET_PDEATHSIG, SIGKILL))
+ eprintf("prctl PR_SET_PDEATHSIG SIGKILL:");
+ close(rw[0]);
+ if (dup2(rw[1], STDOUT_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdout>:");
+ close(rw[1]);
+ execlp("blind-from-image", "blind-from-image", "-f", NULL);
+ eprintf("execlp blind-from-image:");
+ break;
+ default:
+ break;
+ }
+ close(rw[1]);
+ if (dup2(rw[0], STDIN_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdin>:");
+ close(rw[0]);
+
+ if (pipe(rw))
+ eprintf("pipe:");
+ switch (image_encoder_pid = fork()) {
+ case -1:
+ eprintf("fork:");
+ break;
+ case 0:
+ if (prctl(PR_SET_PDEATHSIG, SIGKILL))
+ eprintf("prctl PR_SET_PDEATHSIG SIGKILL:");
+ close(rw[1]);
+ if (dup2(rw[0], STDIN_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdin>:");
+ close(rw[0]);
+ execlp("blind-to-image", "blind-to-image", "-f", NULL);
+ eprintf("execlp blind-to-image:");
+ break;
+ default:
+ break;
+ }
+ close(rw[0]);
+ if (dup2(rw[1], STDOUT_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdout>:");
+ close(rw[1]);
+}
+
+
+void
+bff_end(void)
+{
+ int status;
+
+ if (waitpid(image_decoder_pid, &status, 0) < 0)
+ eprintf("waitpid blind-from-image:");
+ if (status)
+ exit(1);
+
+ if (waitpid(image_encoder_pid, &status, 0) < 0)
+ eprintf("waitpid blind-to-image:");
+ if (status)
+ exit(1);
+}
+
+
+pid_t
+bff_run(const char **args, int in, int out)
+{
+ pid_t pid;
+
+ switch (pid = fork()) {
+ case -1:
+ eprintf("fork:");
+ break;
+ case 0:
+ if (prctl(PR_SET_PDEATHSIG, SIGKILL))
+ eprintf("prctl PR_SET_PDEATHSIG SIGKILL:");
+ if (in != STDIN_FILENO) {
+ if (dup2(in, STDIN_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdin>:");
+ close(in);
+ }
+ if (out != STDOUT_FILENO) {
+ if (dup2(out, STDOUT_FILENO) < 0)
+ eprintf("dup2 <pipe> <stdout>:");
+ close(out);
+ }
+ execvp(*args, (void *)args);
+ eprintf("execlp %s:", *args);
+ break;
+ default:
+ break;
+ }
+ close(in);
+ close(out);
+
+ return pid;
+}
+
+
+void
+bff_wait(pid_t pid, const char *cmd)
+{
+ int status;
+ if (waitpid(pid, &status, 0) < 0)
+ eprintf("waitpid %s:", cmd);
+ if (status)
+ exit(1);
+}
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..ff9732c
--- /dev/null
+++ b/common.h
@@ -0,0 +1,22 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "arg.h"
+
+#define USAGE(SYNOPSIS)\
+ static void usage(void)\
+ { eprintf("usage: %s%s%s\n", argv0, *SYNOPSIS ? " " : "", SYNOPSIS); }
+
+void eprintf(const char *fmt, ...);
+
+void bff_begin(void);
+void bff_end(void);
+pid_t bff_run(const char **args, int in, int out);
+void bff_wait(pid_t pid, const char *cmd);
diff --git a/config.mk b/config.mk
new file mode 100644
index 0000000..4cafaa4
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,10 @@
+# BFF version
+VERSION = 1.0
+
+# Paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+CFLAGS = -std=c99 -Wall -pedantic -O2
+CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700
+LDFLAGS = -s