Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id B14F1431FD0 for ; Thu, 8 Dec 2011 15:32:53 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AXyrIMwp6E6T for ; Thu, 8 Dec 2011 15:32:52 -0800 (PST) Received: from dmz-mailsec-scanner-5.mit.edu (DMZ-MAILSEC-SCANNER-5.MIT.EDU [18.7.68.34]) by olra.theworths.org (Postfix) with ESMTP id B6876431FB6 for ; Thu, 8 Dec 2011 15:32:52 -0800 (PST) X-AuditID: 12074422-b7ff56d00000092f-d0-4ee149235038 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43]) by dmz-mailsec-scanner-5.mit.edu (Symantec Messaging Gateway) with SMTP id 76.95.02351.32941EE4; Thu, 8 Dec 2011 18:32:51 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id pB8NWoa0016951; Thu, 8 Dec 2011 18:32:50 -0500 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id pB8NWl4T017194 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Thu, 8 Dec 2011 18:32:49 -0500 (EST) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77) (envelope-from ) id 1RYnTy-0001EP-3J; Thu, 08 Dec 2011 18:34:30 -0500 Date: Thu, 8 Dec 2011 18:34:29 -0500 From: Austin Clements To: Jani Nikula Subject: Re: [PATCH v4 1/3] cli: introduce the concept of user defined hooks Message-ID: <20111208233429.GA3190@mit.edu> References: <1e4ddb5e3a6b980e47418f67e16709a42e63bc47.1323384304.git.jani@nikula.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1e4ddb5e3a6b980e47418f67e16709a42e63bc47.1323384304.git.jani@nikula.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrKKsWRmVeSWpSXmKPExsUixCmqravs+dDP4OcTdoum6c4W12/OZHZg 8rh1/zW7x7NVt5gDmKK4bFJSczLLUov07RK4Mq7/WspSsFutYtm3FcwNjL2yXYycHBICJhJd i38wQ9hiEhfurWfrYuTiEBLYxyhxrGEKM4SznlFixdz5rBDOCSaJyxvuQGWWMErMOLsAqIeD g0VAReLRXWeQUWwCGhLb9i9nBLFFBBQlNp/cD2YzC0hLfPvdzARiCwv4SOw4OY8NxOYV0JZo WfWdHWSMkECdxMMdFRBhQYmTM5+wQLTqSOzcegdsE8iY5f84IMLyEs1bZ4M9wCkQJvHq+RRW EFsU6JgpJ7exTWAUnoVk0iwkk2YhTJqFZNICRpZVjLIpuVW6uYmZOcWpybrFyYl5ealFuqZ6 uZkleqkppZsYQTHA7qK0g/HnQaVDjAIcjEo8vJ3cD/2EWBPLiitzDzFKcjApifLe9gAK8SXl p1RmJBZnxBeV5qQWH2KU4GBWEuEVYAXK8aYkVlalFuXDpKQ5WJTEebl2OvgJCaQnlqRmp6YW pBbBZGU4OJQkeD3cgRoFi1LTUyvSMnNKENJMHJwgw3mAhueALOYtLkjMLc5Mh8ifYtTluDH5 wBlGIZa8/LxUKXHegyBFAiBFGaV5cHNgqesVozjQW8K8Wo5AVTzAtAc36RXQEiagJV+yH4As KUlESEk1MJpNz5bR7Dl3ReZdKP+cH+LvmsJbd02Ze1g+/76n+l/lE1dVArey+1hu6IysnJgy 5bL064WWiftmvkqqb7y25fnNr/Ui1zlXff/27c732Iwf5Wf60qT9ug8+fG6vNivdMuC6XD9b xl+pW85hfurxhvfC/P88Devk3lCW2st6uqfnwbsyzSLdEiWW4oxEQy3mouJEAEPzmnU4AwAA Cc: notmuch@notmuchmail.org X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Dec 2011 23:32:53 -0000 Quoth Jani Nikula on Dec 09 at 12:48 am: > Add mechanism for running user defined hooks. Hooks are executables or > symlinks to executables stored under the new notmuch hooks directory, > /.notmuch/hooks. > > No hooks are introduced here, but adding support for a hook is now a simple > matter of calling the new notmuch_run_hook() function at an appropriate > location with the hook name. > > Signed-off-by: Jani Nikula > --- > Makefile.local | 1 + > hooks.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > notmuch-client.h | 3 ++ > 3 files changed, 97 insertions(+), 0 deletions(-) > create mode 100644 hooks.c > > diff --git a/Makefile.local b/Makefile.local > index 15e6d88..88365da 100644 > --- a/Makefile.local > +++ b/Makefile.local > @@ -298,6 +298,7 @@ notmuch_client_srcs = \ > debugger.c \ > gmime-filter-reply.c \ > gmime-filter-headers.c \ > + hooks.c \ > notmuch.c \ > notmuch-config.c \ > notmuch-count.c \ > diff --git a/hooks.c b/hooks.c > new file mode 100644 > index 0000000..44ee419 > --- /dev/null > +++ b/hooks.c > @@ -0,0 +1,93 @@ > +/* notmuch - Not much of an email program, (just index and search) > + * > + * This file is part of notmuch. > + * > + * Copyright © 2011 Jani Nikula > + * > + * 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 http://www.gnu.org/licenses/ . > + * > + * Author: Jani Nikula > + */ > + > +#include "notmuch-client.h" > +#include > + > +int > +notmuch_run_hook (const char *db_path, const char *hook) > +{ > + char *hook_path; > + int status = 0; > + pid_t pid; > + > + hook_path = talloc_asprintf (NULL, "%s/%s/%s/%s", db_path, ".notmuch", > + "hooks", hook); > + if (hook_path == NULL) { > + fprintf (stderr, "Out of memory\n"); > + return 1; > + } > + > + /* Check access before fork() for speed and simplicity of error handling. */ > + if (access (hook_path, X_OK) == -1) { > + /* Ignore ENOENT. It's okay not to have a hook, hook dir, or even > + * notmuch dir. Dangling symbolic links also result in ENOENT, but > + * we'll ignore that too for simplicity. */ > + if (errno != ENOENT) { > + fprintf (stderr, "Error: %s hook access failed: %s\n", hook, > + strerror (errno)); > + status = 1; > + } Is it the intent that a present but non-executable hook (errno == EACCES) will print the above error message and return with a failure? I'm pretty sure this differs from the behavior of git hooks. Other than this, this patch looks good to me. > + goto DONE; > + } > + > + pid = fork(); > + if (pid == -1) { > + fprintf (stderr, "Error: %s hook fork failed: %s\n", hook, > + strerror (errno)); > + status = 1; > + goto DONE; > + } else if (pid == 0) { > + execl (hook_path, hook_path, NULL); > + /* Same as above for ENOENT, but unlikely now. Indicate all other errors > + * to parent through non-zero exit status. */ > + if (errno != ENOENT) { > + fprintf (stderr, "Error: %s hook execution failed: %s\n", hook, > + strerror (errno)); > + status = 1; > + } > + exit (status); > + } > + > + if (waitpid (pid, &status, 0) == -1) { > + fprintf (stderr, "Error: %s hook wait failed: %s\n", hook, > + strerror (errno)); > + status = 1; > + goto DONE; > + } > + > + if (!WIFEXITED (status) || WEXITSTATUS (status)) { > + if (WIFEXITED (status)) { > + fprintf (stderr, "Error: %s hook failed with status %d\n", > + hook, WEXITSTATUS (status)); > + } else if (WIFSIGNALED (status)) { > + fprintf (stderr, "Error: %s hook terminated with signal %d\n", > + hook, WTERMSIG (status)); > + } > + status = 1; > + } > + > + DONE: > + talloc_free (hook_path); > + > + return status; > +} > diff --git a/notmuch-client.h b/notmuch-client.h > index b50cb38..a91ad6c 100644 > --- a/notmuch-client.h > +++ b/notmuch-client.h > @@ -235,6 +235,9 @@ void > notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, > notmuch_bool_t synchronize_flags); > > +int > +notmuch_run_hook (const char *db_path, const char *hook); > + > notmuch_bool_t > debugger_is_active (void);