summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compat.h90
-rw-r--r--imbox.c7
2 files changed, 96 insertions, 1 deletions
diff --git a/compat.h b/compat.h
new file mode 100644
index 0000000..55dda53
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,90 @@
+/* Copyright (C) 2019  C. McEnroe <june@causal.agency>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef __linux__
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NO_READPASSPHRASE_H
+#define RPP_STDIN 1
+static inline char *
+readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) {
+	if (flags) {
+		if (!fgets(buf, bufsiz, stdin)) return NULL;
+		return strsep(&buf, "\n");
+	}
+	return getpass(prompt);
+}
+
+typedef int _readfn(void *, char *, int);
+typedef int _writefn(void *, const char *, int);
+typedef fpos_t _seekfn(void *, fpos_t, int);
+typedef int _closefn(void *);
+
+struct _funopen {
+	void *cookie;
+	_readfn *readfn;
+	_writefn *writefn;
+	_closefn *closefn;
+};
+
+static inline ssize_t
+_cookie_read(void *cookie, char *buf, size_t size) {
+	struct _funopen *funopen = cookie;
+	assert((size_t)(int)size == size);
+	return funopen->readfn(funopen->cookie, buf, size);
+}
+
+static inline ssize_t
+_cookie_write(void *cookie, const char *buf, size_t size) {
+	struct _funopen *funopen = cookie;
+	assert((size_t)(int)size == size);
+	return funopen->writefn(funopen->cookie, buf, size);
+}
+
+static inline int
+_cookie_close(void *cookie) {
+	struct _funopen *funopen = cookie;
+	int ret = funopen->closefn(funopen->cookie);
+	free(cookie);
+	return ret;
+}
+
+static const cookie_io_functions_t _cookie_fns = {
+	.read = _cookie_read,
+	.write = _cookie_write,
+	.close = _cookie_close,
+};
+
+static inline FILE *
+funopen(
+	const void *cookie,
+	_readfn *readfn, _writefn *writefn, _seekfn *seekfn, _closefn *closefn
+) {
+	struct _funopen *funopen = malloc(sizeof(*funopen));
+	if (!funopen) return NULL;
+	assert(!seekfn);
+	*funopen = (struct _funopen) { (void *)cookie, readfn, writefn, closefn };
+	return fopencookie(funopen, "r+", _cookie_fns);
+}
+
+#endif /* __linux__ */
diff --git a/imbox.c b/imbox.c
index a55b09f..faa7a00 100644
--- a/imbox.c
+++ b/imbox.c
@@ -14,9 +14,10 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+#include "compat.h"
+
 #include <ctype.h>
 #include <err.h>
-#include <readpassphrase.h>
 #include <regex.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -27,6 +28,10 @@
 #include <tls.h>
 #include <unistd.h>
 
+#ifndef NO_READPASSPHRASE_H
+#include <readpassphrase.h>
+#endif
+
 #if !defined(DIG_PATH) && !defined(DRILL_PATH)
 #	ifdef __FreeBSD__
 #		define DRILL_PATH "/usr/bin/drill"