Hi,
  Here is the updated diff, which removes table_proc and adds table_procexec as 
the default backend when no backend name matches.

With this diff, I have the following configuration for smtpd:

#       $OpenBSD: smtpd.conf,v 1.14 2019/11/26 20:14:38 gilles Exp $

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

table aliases aliases:root.t...@bsd.ac
listen on socket

# To accept external mail, replace with: listen on all
#
listen on lo0

action "local_mail" mbox alias <aliases>
action "outbound" relay
action "bsd.ac" relay host smtp://10.7.0.1

# Uncomment the following to accept external mail for domain "example.org"
#
# match from any for domain "example.org" action "local_mail"
match from local for local action "local_mail"
match from local for domain "bsd.ac" action "bsd.ac"
match from local for any action "outbound"


where my /usr/local/libexec/smtpd/table-aliases contains:

#!/bin/ksh

user="${1:-r...@bsd.ac}"

while read line
do
  reqid="$(echo $line | awk -F'|' '{ print $5; }')"
  reply="TABLE-RESULT|$reqid|FOUND|$user"
  echo $reply
done < /dev/stdin
exit 0


This should hopefully satisfy the requirements for transparency and sanity.
I will work on the opensmtpd-extras and make a PR in the github separately, if 
that sounds fine.

Cheers,
Aisha

diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 011e306ac61..1b0ee5ad38f 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -2557,13 +2557,6 @@ table            : TABLE STRING STRING   {
                                        config  = p+1;
                                }
                        }
-                       if (config != NULL && *config != '/') {
-                               yyerror("invalid backend parameter for table: 
%s",
-                                   $2);
-                               free($2);
-                               free($3);
-                               YYERROR;
-                       }
                        table = table_create(conf, backend, $2, config);
                        if (!table_config(table)) {
                                yyerror("invalid configuration file %s for 
table %s",
diff --git a/usr.sbin/smtpd/smtpctl/Makefile b/usr.sbin/smtpd/smtpctl/Makefile
index ef8148be8c9..46831d647dc 100644
--- a/usr.sbin/smtpd/smtpctl/Makefile
+++ b/usr.sbin/smtpd/smtpctl/Makefile
@@ -47,7 +47,7 @@ SRCS+=        table.c
 SRCS+= table_static.c
 SRCS+= table_db.c
 SRCS+= table_getpwnam.c
-SRCS+= table_proc.c
+SRCS+= table_procexec.c
 SRCS+= unpack_dns.c
 SRCS+= spfwalk.c
 
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index be934112103..221f24fbdc4 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1656,6 +1656,7 @@ int table_regex_match(const char *, const char *);
 void   table_open_all(struct smtpd *);
 void   table_dump_all(struct smtpd *);
 void   table_close_all(struct smtpd *);
+const char *table_service_name(enum table_service );
 
 
 /* to.c */
diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile
index b31d4e42224..64e73c3bb70 100644
--- a/usr.sbin/smtpd/smtpd/Makefile
+++ b/usr.sbin/smtpd/smtpd/Makefile
@@ -62,7 +62,7 @@ SRCS+=                compress_gzip.c
 
 SRCS+=         table_db.c
 SRCS+=         table_getpwnam.c
-SRCS+=         table_proc.c
+SRCS+=         table_procexec.c
 SRCS+=         table_static.c
 
 SRCS+=         queue_fs.c
diff --git a/usr.sbin/smtpd/table.c b/usr.sbin/smtpd/table.c
index 1d82d88b81a..a09229ca174 100644
--- a/usr.sbin/smtpd/table.c
+++ b/usr.sbin/smtpd/table.c
@@ -45,9 +45,8 @@ struct table_backend *table_backend_lookup(const char *);
 extern struct table_backend table_backend_static;
 extern struct table_backend table_backend_db;
 extern struct table_backend table_backend_getpwnam;
-extern struct table_backend table_backend_proc;
+extern struct table_backend table_backend_procexec;
 
-static const char * table_service_name(enum table_service);
 static int table_parse_lookup(enum table_service, const char *, const char *,
     union lookup *);
 static int parse_sockaddr(struct sockaddr *, int, const char *);
@@ -58,7 +57,7 @@ static struct table_backend *backends[] = {
        &table_backend_static,
        &table_backend_db,
        &table_backend_getpwnam,
-       &table_backend_proc,
+       &table_backend_procexec,
        NULL
 };
 
@@ -77,7 +76,7 @@ table_backend_lookup(const char *backend)
        return NULL;
 }
 
-static const char *
+const char *
 table_service_name(enum table_service s)
 {
        switch (s) {
@@ -208,10 +207,9 @@ table_create(struct smtpd *conf, const char *backend, 
const char *name,
                            PATH_LIBEXEC"/table-%s\"", backend);
                }
                if (stat(path, &sb) == 0) {
-                       tb = table_backend_lookup("proc");
-                       (void)strlcpy(path, backend, sizeof(path));
+                       tb = table_backend_lookup("proc-exec");
                        if (config) {
-                               (void)strlcat(path, ":", sizeof(path));
+                               (void)strlcat(path, " ", sizeof(path));
                                if (strlcat(path, config, sizeof(path))
                                    >= sizeof(path))
                                        fatalx("table_create: config file path 
too long");
diff --git a/usr.sbin/smtpd/table_proc.c b/usr.sbin/smtpd/table_proc.c
deleted file mode 100644
index dad041a47c3..00000000000
--- a/usr.sbin/smtpd/table_proc.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*     $OpenBSD: table_proc.c,v 1.16 2019/10/03 04:51:15 gilles Exp $  */
-
-/*
- * Copyright (c) 2013 Eric Faurot <e...@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <imsg.h>
-#include <paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-
-#include "smtpd.h"
-#include "log.h"
-
-struct table_proc_priv {
-       pid_t           pid;
-       struct imsgbuf  ibuf;
-};
-
-static struct imsg      imsg;
-static size_t           rlen;
-static char            *rdata;
-
-extern char    **environ;
-
-static void
-table_proc_call(struct table_proc_priv *p)
-{
-       ssize_t n;
-
-       if (imsg_flush(&p->ibuf) == -1) {
-               log_warn("warn: table-proc: imsg_flush");
-               fatalx("table-proc: exiting");
-       }
-
-       while (1) {
-               if ((n = imsg_get(&p->ibuf, &imsg)) == -1) {
-                       log_warn("warn: table-proc: imsg_get");
-                       break;
-               }
-               if (n) {
-                       rlen = imsg.hdr.len - IMSG_HEADER_SIZE;
-                       rdata = imsg.data;
-
-                       if (imsg.hdr.type != PROC_TABLE_OK) {
-                               log_warnx("warn: table-proc: bad response");
-                               break;
-                       }
-                       return;
-               }
-
-               if ((n = imsg_read(&p->ibuf)) == -1 && errno != EAGAIN) {
-                       log_warn("warn: table-proc: imsg_read");
-                       break;
-               }
-
-               if (n == 0) {
-                       log_warnx("warn: table-proc: pipe closed");
-                       break;
-               }
-       }
-
-       fatalx("table-proc: exiting");
-}
-
-static void
-table_proc_read(void *dst, size_t len)
-{
-       if (len > rlen) {
-               log_warnx("warn: table-proc: bad msg len");
-               fatalx("table-proc: exiting");
-       }
-
-       if (dst)
-               memmove(dst, rdata, len);
-
-       rlen -= len;
-       rdata += len;
-}
-
-static void
-table_proc_end(void)
-{
-       if (rlen) {
-               log_warnx("warn: table-proc: bogus data");
-               fatalx("table-proc: exiting");
-       }
-       imsg_free(&imsg);
-}
-
-/*
- * API
- */
-
-static int
-table_proc_open(struct table *table)
-{
-       struct table_proc_priv  *priv;
-       struct table_open_params op;
-       int                      fd;
-
-       priv = xcalloc(1, sizeof(*priv));
-
-       fd = fork_proc_backend("table", table->t_config, table->t_name);
-       if (fd == -1)
-               fatalx("table-proc: exiting");
-
-       imsg_init(&priv->ibuf, fd);
-
-       memset(&op, 0, sizeof op);
-       op.version = PROC_TABLE_API_VERSION;
-       (void)strlcpy(op.name, table->t_name, sizeof op.name);
-       imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);
-
-       table_proc_call(priv);
-       table_proc_end();
-
-       table->t_handle = priv;
-
-       return (1);
-}
-
-static int
-table_proc_update(struct table *table)
-{
-       struct table_proc_priv  *priv = table->t_handle;
-       int r;
-
-       imsg_compose(&priv->ibuf, PROC_TABLE_UPDATE, 0, 0, -1, NULL, 0);
-
-       table_proc_call(priv);
-       table_proc_read(&r, sizeof(r));
-       table_proc_end();
-
-       return (r);
-}
-
-static void
-table_proc_close(struct table *table)
-{
-       struct table_proc_priv  *priv = table->t_handle;
-
-       imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0);
-       if (imsg_flush(&priv->ibuf) == -1)
-               fatal("imsg_flush");
-
-       table->t_handle = NULL;
-}
-
-static int
-imsg_add_params(struct ibuf *buf)
-{
-       size_t count = 0;
-
-       if (imsg_add(buf, &count, sizeof(count)) == -1)
-               return (-1);
-
-       return (0);
-}
-
-static int
-table_proc_lookup(struct table *table, enum table_service s, const char *k, 
char **dst)
-{
-       struct table_proc_priv  *priv = table->t_handle;
-       struct ibuf             *buf;
-       int                      r;
-
-       buf = imsg_create(&priv->ibuf,
-           dst ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0,
-           sizeof(s) + strlen(k) + 1);
-
-       if (buf == NULL)
-               return (-1);
-       if (imsg_add(buf, &s, sizeof(s)) == -1)
-               return (-1);
-       if (imsg_add_params(buf) == -1)
-               return (-1);
-       if (imsg_add(buf, k, strlen(k) + 1) == -1)
-               return (-1);
-       imsg_close(&priv->ibuf, buf);
-
-       table_proc_call(priv);
-       table_proc_read(&r, sizeof(r));
-
-       if (r == 1 && dst) {
-               if (rlen == 0) {
-                       log_warnx("warn: table-proc: empty response");
-                       fatalx("table-proc: exiting");
-               }
-               if (rdata[rlen - 1] != '\0') {
-                       log_warnx("warn: table-proc: not NUL-terminated");
-                       fatalx("table-proc: exiting");
-               }
-               *dst = strdup(rdata);
-               if (*dst == NULL)
-                       r = -1;
-               table_proc_read(NULL, rlen);
-       }
-
-       table_proc_end();
-
-       return (r);
-}
-
-static int
-table_proc_fetch(struct table *table, enum table_service s, char **dst)
-{
-       struct table_proc_priv  *priv = table->t_handle;
-       struct ibuf             *buf;
-       int                      r;
-
-       buf = imsg_create(&priv->ibuf, PROC_TABLE_FETCH, 0, 0, sizeof(s));
-       if (buf == NULL)
-               return (-1);
-       if (imsg_add(buf, &s, sizeof(s)) == -1)
-               return (-1);
-       if (imsg_add_params(buf) == -1)
-               return (-1);
-       imsg_close(&priv->ibuf, buf);
-
-       table_proc_call(priv);
-       table_proc_read(&r, sizeof(r));
-
-       if (r == 1) {
-               if (rlen == 0) {
-                       log_warnx("warn: table-proc: empty response");
-                       fatalx("table-proc: exiting");
-               }
-               if (rdata[rlen - 1] != '\0') {
-                       log_warnx("warn: table-proc: not NUL-terminated");
-                       fatalx("table-proc: exiting");
-               }
-               *dst = strdup(rdata);
-               if (*dst == NULL)
-                       r = -1;
-               table_proc_read(NULL, rlen);
-       }
-
-       table_proc_end();
-
-       return (r);
-}
-
-struct table_backend table_backend_proc = {
-       "proc",
-       K_ANY,
-       NULL,
-       NULL,
-       NULL,
-       table_proc_open,
-       table_proc_update,
-       table_proc_close,
-       table_proc_lookup,
-       table_proc_fetch,
-};
diff --git a/usr.sbin/smtpd/table_procexec.c b/usr.sbin/smtpd/table_procexec.c
new file mode 100644
index 00000000000..66f1d50ca26
--- /dev/null
+++ b/usr.sbin/smtpd/table_procexec.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2020 Gilles Chehade <gil...@poolp.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <event.h>
+#include <fcntl.h>
+#include <imsg.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <err.h>
+#include <inttypes.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+#define PROTOCOL_VERSION "1"
+
+static int table_procexec_open(struct table *);
+static int table_procexec_update(struct table *);
+static void table_procexec_close(struct table *);
+static int table_procexec_lookup(struct table *, enum table_service, const 
char *, char **);
+static int table_procexec_fetch(struct table *, enum table_service, char **);
+
+struct table_backend table_backend_procexec = {
+       "proc-exec",
+       K_ANY,
+       NULL,
+       NULL,
+       NULL,
+       table_procexec_open,
+       table_procexec_update,
+       table_procexec_close,
+       table_procexec_lookup,
+       table_procexec_fetch,
+};
+
+struct procexec_handle {
+       FILE    *backend_w;
+       FILE    *backend_r;
+       pid_t   pid;
+};
+
+static int
+table_procexec_open(struct table *t) {
+       struct procexec_handle *pe_handle;
+       pid_t pid;
+       int sp[2];
+       int execr;
+       char exec[_POSIX_ARG_MAX];
+
+       if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1){
+               fatalx("procexec - socket pair: %s", t->t_name);
+       }
+
+       pe_handle = xcalloc(1, sizeof(*pe_handle));
+
+       if ((pid = fork()) == -1) {
+               fatalx("procexec - fork: %s", t->t_name);
+       }
+
+       if (pid > 0) {
+               close(sp[0]);
+               FILE *backend_w, *backend_r;
+               if ((backend_w = fdopen(sp[1], "w")) == NULL)
+                       fatalx("procexec - backend_w: %s", t->t_name);
+
+               if ((backend_r = fdopen(sp[1], "r")) == NULL)
+                       fatalx("procexec - backend_r: %s", t->t_name);
+
+               pe_handle->pid = pid;
+               pe_handle->backend_w = backend_w;
+               pe_handle->backend_r = backend_r;
+               t->t_handle = pe_handle;
+               return 1;
+       }
+       else {
+               close(sp[1]);
+               dup2(sp[0], STDIN_FILENO);
+               dup2(sp[0], STDOUT_FILENO);
+
+               execr = snprintf(exec, sizeof(exec), "exec %s" , t->t_config);
+               if (execr >= (int) sizeof(exec))
+                       fatalx("procexec - execr: %s", t->t_name);
+               execl("/bin/sh", "/bin/sh", "-c", exec, (char *)NULL);
+               fatalx("procexec: %s", t->t_name);
+       }
+}
+
+static void
+table_procexec_close(struct table *t){
+       if(t->t_handle == NULL)
+               return;
+       kill(((struct procexec_handle *)t->t_handle)->pid, SIGTERM);
+       free(t->t_handle);
+       t->t_handle = NULL;
+}
+
+static int
+table_procexec_update(struct table *t)
+{
+       struct timeval tv;
+       uint64_t reqid;
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       uint64_t reqid_res;
+       char *qid = NULL;
+       char *ep = NULL;
+
+       reqid = generate_uid();
+       gettimeofday(&tv, NULL);
+
+       FILE* backend_w = ((struct procexec_handle *)t->t_handle)->backend_w;
+       FILE* backend_r = ((struct procexec_handle *)t->t_handle)->backend_r;
+
+       fprintf(backend_w, "TABLE|%s|%lld.%06ld|UPDATE|%016"PRIx64"\n",
+               PROTOCOL_VERSION,
+               tv.tv_sec, tv.tv_usec, reqid);
+       fflush(backend_w);
+
+       linelen = getline(&line, &linecap, backend_r);
+       if (linelen == 0)
+               return 0;
+       line[strcspn(line, "\n")] = '\0';
+
+       if (strncmp(line, "TABLE-RESULT|", 13) != 0)
+               return -1;
+       line += 13;
+
+       qid = line;
+       reqid_res = strtoull(qid, &ep, 16);
+       if (qid[0] == '\0' || *ep != '|')
+               return -1;
+       if (errno == ERANGE && reqid_res == ULLONG_MAX)
+               return -1;
+       if (reqid != reqid_res)
+               return -1;
+
+       line = ep+1;
+
+       return strcmp(line, "UPDATED") == 0;
+}
+
+/*
+static int
+table_procexec_check(int service, struct dict *params, const char *key)
+{
+       struct timeval tv;
+       uint64_t reqid;
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       uint64_t reqid_res;
+       char *qid = NULL;
+       char *ep = NULL;
+
+       reqid = generate_uid();
+       gettimeofday(&tv, NULL);
+
+       fprintf(backend_w, "TABLE|%s|%lld.%06ld|CHECK|%016"PRIx64"|%s|%s\n",
+               PROTOCOL_VERSION,
+               tv.tv_sec, tv.tv_usec, reqid, service_to_name(service), key);
+       fflush(backend_w);
+
+       linelen = getline(&line, &linecap, backend_r);
+       if (linelen == 0)
+               return 0;
+       line[strcspn(line, "\n")] = '\0';
+
+       if (strncmp(line, "TABLE-RESULT|", 13) != 0)
+               return -1;
+       line += 13;
+
+       qid = line;
+       reqid_res = strtoull(qid, &ep, 16);
+       if (qid[0] == '\0' || *ep != '|')
+               return -1;
+       if (errno == ERANGE && reqid_res == ULLONG_MAX)
+               return -1;
+       if (reqid != reqid_res)
+               return -1;
+
+       line = ep+1;
+
+       if (strcmp(line, "FAILURE") == 0)
+               return -1;
+
+       if (strcmp(line, "NOT-FOUND") == 0)
+               return 0;
+
+       if (strcmp(line, "FOUND") == 0)
+               return 1;
+
+       return -1;
+}
+*/
+
+static int
+table_procexec_lookup(struct table *t, enum table_service service, const char 
*key, char **dst) {
+       struct timeval tv;
+       uint64_t reqid;
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       uint64_t reqid_res;
+       char *qid = NULL;
+       char *ep = NULL;
+       size_t sz = 0;
+
+       FILE* backend_w = ((struct procexec_handle *)t->t_handle)->backend_w;
+       FILE* backend_r = ((struct procexec_handle *)t->t_handle)->backend_r;
+
+       reqid = generate_uid();
+       gettimeofday(&tv, NULL);
+
+       fprintf(backend_w, "TABLE|%s|%lld.%06ld|LOOKUP|%016"PRIx64"|%s|%s\n",
+               PROTOCOL_VERSION,
+               tv.tv_sec, tv.tv_usec, reqid, table_service_name(service), key);
+       fflush(backend_w);
+
+       linelen = getline(&line, &linecap, backend_r);
+       if (linelen == 0)
+               return 0;
+       line[strcspn(line, "\n")] = '\0';
+
+       if (strncmp(line, "TABLE-RESULT|", 13) != 0)
+               return -1;
+       line += 13;
+
+       qid = line;
+       reqid_res = strtoull(qid, &ep, 16);
+       if (qid[0] == '\0' || *ep != '|')
+               return -1;
+       if (errno == ERANGE && reqid_res == ULLONG_MAX)
+               return -1;
+       if (reqid != reqid_res)
+               return -1;
+
+       line = ep+1;
+
+       if (strcmp(line, "FAILURE") == 0)
+               return -1;
+
+       if (strcmp(line, "NOT-FOUND") == 0)
+               return 0;
+
+       if (strncmp(line, "FOUND|", 6) == 0) {
+               line = line + 6;
+               sz = strlen(line) + 1;
+               *dst = xcalloc(sz, sizeof(*dst));
+               if (strlcpy(*dst, line, sz) >= sz){
+                       free(*dst);
+                       return -1;
+               }
+               return 1;
+       }
+       return -1;
+}
+
+static int
+table_procexec_fetch(struct table *t, enum table_service service, char **dst){
+       struct timeval tv;
+       uint64_t reqid;
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       uint64_t reqid_res;
+       char *qid = NULL;
+       char *ep = NULL;
+       size_t sz = 0;
+
+       FILE* backend_w = ((struct procexec_handle *)t->t_handle)->backend_w;
+       FILE* backend_r = ((struct procexec_handle *)t->t_handle)->backend_r;
+
+       reqid = generate_uid();
+       gettimeofday(&tv, NULL);
+
+       fprintf(backend_w, "TABLE|%s|%lld.%06ld|FETCH|%016"PRIx64"|%s\n",
+               PROTOCOL_VERSION,
+               tv.tv_sec, tv.tv_usec, reqid, table_service_name(service));
+       fflush(backend_w);
+
+       linelen = getline(&line, &linecap, backend_r);
+       if (linelen == 0)
+               return 0;
+       line[strcspn(line, "\n")] = '\0';
+
+       if (strncmp(line, "TABLE-RESULT|", 13) != 0)
+               return -1;
+       line += 13;
+
+       qid = line;
+       reqid_res = strtoull(qid, &ep, 16);
+       if (qid[0] == '\0' || *ep != '|')
+               return -1;
+       if (errno == ERANGE && reqid_res == ULLONG_MAX)
+               return -1;
+       if (reqid != reqid_res)
+               return -1;
+
+       line = ep+1;
+
+       if (strcmp(line, "FAILURE") == 0)
+               return -1;
+
+       if (strcmp(line, "NOT-FOUND") == 0)
+               return 0;
+
+       if (strncmp(line, "FOUND|", 6) == 0) {
+               sz = strlen(line) + 1;
+               *dst = xcalloc(sz, sizeof(*dst));
+               if (strlcpy(*dst, line+6, sz) >= sz){
+                       free(*dst);
+                       return -1;
+               }
+               return 1;
+       }
+       return -1;
+}

Reply via email to