From f17f882b5e748c71d9365d8769711d8ff8af015f Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Thu, 29 Oct 2020 11:34:56 -0400 Subject: Rewrite compat and add configure script --- Makefile | 17 +++++------ compat.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ compat.h | 102 -------------------------------------------------------------- configure | 50 ++++++++++++++++++++++++++++++ imap.c | 10 ++++-- imbox.c | 19 +++++------- 6 files changed, 162 insertions(+), 125 deletions(-) create mode 100644 compat.c delete mode 100644 compat.h create mode 100755 configure diff --git a/Makefile b/Makefile index a22cd7c..925b713 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,7 @@ -PREFIX = /usr/local -MANDIR = ${PREFIX}/share/man -LIBRESSL_PREFIX = /usr/local +PREFIX ?= /usr/local +MANDIR ?= ${PREFIX}/share/man CFLAGS += -std=c11 -Wall -Wextra -Wpedantic -CFLAGS += ${LIBRESSL_PREFIX:%=-I%/include} -LDFLAGS += ${LIBRESSL_PREFIX:%=-L%/lib} LDLIBS = -ltls BINS = imbox git-fetch-email @@ -20,15 +17,15 @@ all: ${BINS} imbox: ${OBJS} ${CC} ${LDFLAGS} ${OBJS} ${LDLIBS} -o $@ -${OBJS}: compat.h imap.h +${OBJS}: imap.h clean: rm -f ${BINS} ${OBJS} install: ${BINS} ${MANS} - install -d ${PREFIX}/bin ${MANDIR}/man1 - install ${BINS} ${PREFIX}/bin - for man in ${MANS}; do gzip -c $$man > ${MANDIR}/man1/$$man.gz; done + install -d ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANDIR}/man1 + install ${BINS} ${DESTDIR}${PREFIX}/bin + install -m 644 ${MANS} ${DESTDIR}${MANDIR}/man1 uninstall: - rm -f ${BINS:%=${PREFIX}/bin/%} ${MANS:%=${MANDIR}/man1/%.gz} + rm -f ${BINS:%=${PREFIX}/bin/%} ${MANS:%=${MANDIR}/man1/%} diff --git a/compat.c b/compat.c new file mode 100644 index 0000000..347536d --- /dev/null +++ b/compat.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2019 C. McEnroe + * + * 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 . + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this Program, or any covered work, by linking or + * combining it with LibreSSL (or a modified version of that library), + * containing parts covered by the terms of the OpenSSL License and the + * original SSLeay license, the licensors of this Program grant you + * additional permission to convey the resulting work. Corresponding + * Source for a non-source form of such a combination shall include the + * source code for the parts of LibreSSL used as well as that of the + * covered work. + */ + +#include +#include +#include +#include +#include + +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 Read(void *, char *, int); +typedef int Write(void *, const char *, int); +typedef fpos_t Seek(void *, fpos_t, int); +typedef int Close(void *); + +struct Funopen { + void *cookie; + Read *readfn; + Write *writefn; + Close *closefn; +}; + +static ssize_t cookieRead(void *cookie, char *buf, size_t size) { + struct Funopen *funopen = cookie; + return funopen->readfn(funopen->cookie, buf, size); +} + +static ssize_t cookieWrite(void *cookie, const char *buf, size_t size) { + struct Funopen *funopen = cookie; + return funopen->writefn(funopen->cookie, buf, size); +} + +static int cookieClose(void *cookie) { + struct Funopen *funopen = cookie; + int ret = 0; + if (funopen->closefn) ret = funopen->closefn(funopen->cookie); + free(cookie); + return ret; +} + +FILE *funopen( + const void *cookie, + Read *readfn, Write *writefn, Seek *seekfn, Close *closefn +) { + struct Funopen *funopen = malloc(sizeof(*funopen)); + if (!funopen) return NULL; + funopen->cookie = (void *)cookie; + funopen->readfn = readfn; + funopen->writefn = writefn; + assert(!seekfn); + funopen->closefn = closefn; + cookie_io_functions_t fns = { + .read = (readfn ? cookieRead : NULL), + .write = (writefn ? cookieWrite : NULL), + .close = cookieClose, + }; + return fopencookie(funopen, (!readfn ? "w" : !writefn ? "r" : "r+"), fns); +} diff --git a/compat.h b/compat.h deleted file mode 100644 index a40b732..0000000 --- a/compat.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (C) 2019 C. McEnroe - * - * 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 . - * - * Additional permission under GNU GPL version 3 section 7: - * - * If you modify this Program, or any covered work, by linking or - * combining it with LibreSSL (or a modified version of that library), - * containing parts covered by the terms of the OpenSSL License and the - * original SSLeay license, the licensors of this Program grant you - * additional permission to convey the resulting work. Corresponding - * Source for a non-source form of such a combination shall include the - * source code for the parts of LibreSSL used as well as that of the - * covered work. - */ - -#ifdef __linux__ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include - -#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->closefn(funopen->cookie) : 0); - 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 }; - const char *mode = (!readfn ? "w" : !writefn ? "r" : "r+"); - return fopencookie(funopen, mode, _cookie_fns); -} - -#endif /* __linux__ */ diff --git a/configure b/configure new file mode 100755 index 0000000..ccea81d --- /dev/null +++ b/configure @@ -0,0 +1,50 @@ +#!/bin/sh +set -eu + +cflags() { + echo "CFLAGS += $*" +} +ldlibs() { + echo "LDLIBS ${o:-}= $*" + o=+ +} +config() { + pkg-config --print-errors "$@" + cflags $(pkg-config --cflags "$@") + ldlibs $(pkg-config --libs "$@") +} +defstr() { + cflags "-D'$1=\"$2\"'" +} +defvar() { + defstr "$1" "$(pkg-config --variable=$3 $2)${4:-}" +} + +exec >config.mk + +for opt; do + case "${opt}" in + (--prefix=*) echo "PREFIX = ${opt#*=}" ;; + (--mandir=*) echo "MANDIR = ${opt#*=}" ;; + (*) echo "warning: unsupported option ${opt}" >&2 ;; + esac +done + +case "$(uname)" in + (FreeBSD) + config libtls + defstr DRILL_PATH /usr/bin/drill + ;; + (OpenBSD) + ldlibs -ltls + defstr DIG_PATH /usr/bin/dig + ;; + (Linux) + cflags -D_GNU_SOURCE -DDECLARE_RPP + config libtls + echo 'OBJS += compat.o' + ;; + (*) + config libtls + ;; +esac diff --git a/imap.c b/imap.c index 77381f7..8437a2c 100644 --- a/imap.c +++ b/imap.c @@ -25,8 +25,6 @@ * covered work. */ -#include "compat.h" - #include #include #include @@ -35,6 +33,14 @@ #include #include +FILE *funopen( + const void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *) +); + #include "imap.h" const char *Atoms[AtomCap] = { diff --git a/imbox.c b/imbox.c index e58663e..7e2233d 100644 --- a/imbox.c +++ b/imbox.c @@ -25,8 +25,6 @@ * covered work. */ -#include "compat.h" - #include #include #include @@ -36,18 +34,17 @@ #include #include -#ifndef NO_READPASSPHRASE_H +#ifdef DECLARE_RPP +#define RPP_STDIN 1 +char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags); +#else #include #endif #include "imap.h" -#if !defined(DIG_PATH) && !defined(DRILL_PATH) -# ifdef __FreeBSD__ -# define DRILL_PATH "/usr/bin/drill" -# else -# define DIG_PATH "dig" -# endif +#ifndef DIG_PATH +#define DIG_PATH "dig" #endif #define FETCH_HEADERS \ @@ -91,10 +88,10 @@ static void lookup(const char **host, const char **port, const char *domain) { dup2(rw[1], STDERR_FILENO); close(rw[1]); #ifdef DRILL_PATH - execlp(DRILL_PATH, DRILL_PATH, buf, "SRV", NULL); + execlp(DRILL_PATH, "drill", buf, "SRV", NULL); err(EX_CONFIG, "%s", DRILL_PATH); #else - execlp(DIG_PATH, DIG_PATH, "-t", "SRV", "-q", buf, "+short", NULL); + execlp(DIG_PATH, "dig", "-t", "SRV", "-q", buf, "+short", NULL); err(EX_CONFIG, "%s", DIG_PATH); #endif } -- cgit 1.4.1