--- /dev/null
+Return-Path: <dkg@fifthhorseman.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 23DCC6DE0943\r
+ for <notmuch@notmuchmail.org>; Fri, 8 Jul 2016 03:13:32 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at cworth.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0.135\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0.135 tagged_above=-999 required=5 tests=[AWL=0.135]\r
+ autolearn=disabled\r
+Received: from arlo.cworth.org ([127.0.0.1])\r
+ by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id c9fRaG2bnxFs for <notmuch@notmuchmail.org>;\r
+ Fri, 8 Jul 2016 03:13:24 -0700 (PDT)\r
+Received: from che.mayfirst.org (che.mayfirst.org [162.247.75.118])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 8F11E6DE02AC\r
+ for <notmuch@notmuchmail.org>; Fri, 8 Jul 2016 03:13:09 -0700 (PDT)\r
+Received: from fifthhorseman.net (unknown [88.128.80.54])\r
+ by che.mayfirst.org (Postfix) with ESMTPSA id A5144F98B\r
+ for <notmuch@notmuchmail.org>; Fri, 8 Jul 2016 06:13:08 -0400 (EDT)\r
+Received: by fifthhorseman.net (Postfix, from userid 1000)\r
+ id 7F87D205C3; Fri, 8 Jul 2016 11:27:34 +0200 (CEST)\r
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
+To: Notmuch Mail <notmuch@notmuchmail.org>\r
+Subject: [PATCH v4 01/16] add util/search-path.{c,\r
+ h} to test for executables in $PATH\r
+Date: Fri, 8 Jul 2016 11:27:12 +0200\r
+Message-Id: <1467970047-8013-2-git-send-email-dkg@fifthhorseman.net>\r
+X-Mailer: git-send-email 2.8.1\r
+In-Reply-To: <1467970047-8013-1-git-send-email-dkg@fifthhorseman.net>\r
+References: <1467970047-8013-1-git-send-email-dkg@fifthhorseman.net>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.20\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 08 Jul 2016 10:13:32 -0000\r
+\r
+This is a utility function we can use to see whether an executable is\r
+available.\r
+---\r
+ util/Makefile.local | 2 +-\r
+ util/search-path.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ util/search-path.h | 24 ++++++++++++++++++++++++\r
+ 3 files changed, 75 insertions(+), 1 deletion(-)\r
+ create mode 100644 util/search-path.c\r
+ create mode 100644 util/search-path.h\r
+\r
+diff --git a/util/Makefile.local b/util/Makefile.local\r
+index 905f237..8b2b91b 100644\r
+--- a/util/Makefile.local\r
++++ b/util/Makefile.local\r
+@@ -5,7 +5,7 @@ extra_cflags += -I$(srcdir)/$(dir)\r
+ \r
+ libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
+ $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c \\r
+- $(dir)/util.c\r
++ $(dir)/util.c $(dir)/search-path.c\r
+ \r
+ libutil_modules := $(libutil_c_srcs:.c=.o)\r
+ \r
+diff --git a/util/search-path.c b/util/search-path.c\r
+new file mode 100644\r
+index 0000000..9da21cb\r
+--- /dev/null\r
++++ b/util/search-path.c\r
+@@ -0,0 +1,50 @@\r
++#include "search-path.h"\r
++#include <stdlib.h>\r
++#include <unistd.h>\r
++#include <string.h>\r
++#include <sys/types.h>\r
++#include <sys/stat.h>\r
++#include <fcntl.h>\r
++\r
++\r
++notmuch_bool_t\r
++test_for_executable (const char *exename)\r
++{\r
++ char *path = NULL, *save = NULL, *tok;\r
++ notmuch_bool_t ret = FALSE;\r
++\r
++ if (strchr (exename, '/')) {\r
++ if (0 == access (exename, X_OK))\r
++ return TRUE;\r
++ else\r
++ return FALSE;\r
++ }\r
++\r
++ path = getenv ("PATH");\r
++ if (path)\r
++ path = strdup (path);\r
++ else {\r
++ size_t n = confstr (_CS_PATH, NULL, 0);\r
++ path = (char *) malloc (n);\r
++ if (! path)\r
++ return FALSE;\r
++ confstr (_CS_PATH, path, n);\r
++ }\r
++\r
++ tok = strtok_r (path, ":", &save);\r
++ while (tok) {\r
++ int dir_fd = open (tok, O_DIRECTORY | O_RDONLY);\r
++ if (dir_fd != -1) {\r
++ int access = faccessat (dir_fd, exename, X_OK, 0);\r
++ close (dir_fd);\r
++ if (access == 0) {\r
++ ret = TRUE;\r
++ break;\r
++ }\r
++ }\r
++ tok = strtok_r (NULL, ":", &save);\r
++ }\r
++ if (path)\r
++ free (path);\r
++ return ret;\r
++}\r
+diff --git a/util/search-path.h b/util/search-path.h\r
+new file mode 100644\r
+index 0000000..14c4d14\r
+--- /dev/null\r
++++ b/util/search-path.h\r
+@@ -0,0 +1,24 @@\r
++#ifndef _SEARCH_PATH_H\r
++#define _SEARCH_PATH_H\r
++\r
++#include "notmuch.h"\r
++\r
++/* can an executable be found with the given name?\r
++ *\r
++ * Return TRUE only if we can find something to execute with the\r
++ * associated name.\r
++ *\r
++ * if the name has a '/' in it, we look for it directly with\r
++ * access(exename, X_OK).\r
++ *\r
++ * otherwise, we look for it in $PATH (or in confstr(_CS_PATH), if\r
++ * $PATH is unset).\r
++ *\r
++ * This should match the logic for execvp (as well as matching user\r
++ * expectations, hopefully).\r
++ */\r
++\r
++notmuch_bool_t\r
++test_for_executable (const char *exename);\r
++\r
++#endif\r
+-- \r
+2.8.1\r
+\r