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 B0D51429E26 for ; Sat, 3 Dec 2011 19:40:26 -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 FOIjlAIUbDq0 for ; Sat, 3 Dec 2011 19:40:25 -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 A044F429E25 for ; Sat, 3 Dec 2011 19:40:25 -0800 (PST) X-AuditID: 12074422-b7ff56d00000092f-b5-4edaeba8fed2 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) by dmz-mailsec-scanner-5.mit.edu (Symantec Messaging Gateway) with SMTP id 84.91.02351.8ABEADE4; Sat, 3 Dec 2011 22:40:24 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id pB43eNjH001306; Sat, 3 Dec 2011 22:40:24 -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 pB43eM8P010210 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sat, 3 Dec 2011 22:40:23 -0500 (EST) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77) (envelope-from ) id 1RX2xu-0004PX-T8; Sat, 03 Dec 2011 22:42:10 -0500 Date: Sat, 3 Dec 2011 22:42:10 -0500 From: Austin Clements To: Jani Nikula Subject: Re: [PATCH v2 1/2] cli: introduce the concept of user defined hooks Message-ID: <20111204034210.GA16405@mit.edu> References: <7fbe6befcf31881a9bca672f55b93501249a220c.1322859389.git.jani@nikula.org> <6688b09fffa2a66b496af78008102f88ab4e9450.1322953841.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: <6688b09fffa2a66b496af78008102f88ab4e9450.1322953841.git.jani@nikula.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrOKsWRmVeSWpSXmKPExsUixG6nrrvi9S0/g2kXdSyapjtbXL85k9mB yePW/dfsHs9W3WIOYIrisklJzcksSy3St0vgymj4PIGxoF294se0PuYGxg65LkZODgkBE4n2 fS+YIGwxiQv31rN1MXJxCAnsY5SY/fApWEJIYD2jxPeH2hCJE0wSd7ceYodwljBKPP06B6yK RUBF4t71SWA2m4CGxLb9yxlBbBEBRYnNJ/eD2cwC0hLffjeD1QgL+Eh0/9zFDmLzCuhItNxb DjV0IaNE07+bLBAJQYmTM5+wQDTrSOzcegfoPg6wQcv/cUCE5SWat85mBrE5BcIk3mybCjZf FOieKSe3sU1gFJ6FZNIsJJNmIUyahWTSAkaWVYyyKblVurmJmTnFqcm6xcmJeXmpRbqmermZ JXqpKaWbGMFx4KK0g/HnQaVDjAIcjEo8vJknbvkJsSaWFVfmHmKU5GBSEuX9/QooxJeUn1KZ kVicEV9UmpNafIhRgoNZSYS36yFQjjclsbIqtSgfJiXNwaIkzsu108FPSCA9sSQ1OzW1ILUI JivDwaEkwXsSZKhgUWp6akVaZk4JQpqJgxNkOA/QcKPXIMOLCxJzizPTIfKnGHU5tr7oP8Mo xJKXn5cqJc7rC1IkAFKUUZoHNweWvl4xigO9JcxrDlLFA0x9cJNeAS1hAlqi2HgDZElJIkJK qoGxbpfF3VdzUsIqq/e+ubPbqCJcilEk6tOO43NbN33oZD0e+tDq2/UXeWE1r+0+zBVd89d7 5l7zQ17cB23FPihs4g+6s/L88SUTjBdtWHR9y2SDn27P/hq7yt7QKPU88vRP5EdTa26vW7s+ a9c4h8qHPppxkbffYtse82qurqbOrFe/tByjr7y4qcRSnJFoqMVcVJwIAJ2key86AwAA 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: Sun, 04 Dec 2011 03:40:26 -0000 I like it. See below for some nits. Quoth Jani Nikula on Dec 04 at 1:16 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 > > --- > > v2: Switch to git style hooks in a hook directory as suggested by Austin > Clements in IRC. Update manpage and add polish. > --- > Makefile.local | 1 + > notmuch-client.h | 3 ++ > notmuch-hook.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 67 insertions(+), 0 deletions(-) > create mode 100644 notmuch-hook.c > > diff --git a/Makefile.local b/Makefile.local > index c94402b..a1665e1 100644 > --- a/Makefile.local > +++ b/Makefile.local > @@ -302,6 +302,7 @@ notmuch_client_srcs = \ > notmuch-config.c \ > notmuch-count.c \ > notmuch-dump.c \ > + notmuch-hook.c \ > notmuch-new.c \ > notmuch-reply.c \ > notmuch-restore.c \ > 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); > > diff --git a/notmuch-hook.c b/notmuch-hook.c > new file mode 100644 > index 0000000..fc32044 > --- /dev/null > +++ b/notmuch-hook.c > @@ -0,0 +1,63 @@ > +/* 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" > + > +int > +notmuch_run_hook (const char *db_path, const char *hook) > +{ > + char *hook_path; > + int status = 0; You use status as both a notmuch_status_t and for generic C library results. This seems a little weird. You may or may not want to do anything about it. > + > + if (asprintf (&hook_path, "%s/%s/%s/%s", db_path, ".notmuch", "hooks", > + hook) == -1) asprintf isn't very portable. Perhaps talloc_asprintf would be better? (And more idiomatic.) > + return NOTMUCH_STATUS_OUT_OF_MEMORY; > + > + 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 = NOTMUCH_STATUS_FILE_ERROR; > + } > + goto DONE; > + } > + > + status = system (hook_path); It would probably be better to fork/execl. system is sensitive to all sorts of weird things because it invokes the shell (e.g., spaces or funny characters in db_path) and it plays funny games with signals. Really proper error handling with fork/exec is a pain, but I think you can get away with something simpler and even get rid of the access call in the process. Something like ret = fork(); if (ret < 0) ... else if (ret == 0) { ret = execl(hook_path, hook_path, NULL); if (ret != ENOENT && ret != EACCESS) print a real error message exit(0); } else { waitpid(ret, &status, 0); if (status) .. checks you do now .. } I guess this wastes a fork if there is no hook script, so maybe the access call is worth doing anyway. > + if (status) { > + if (WIFSIGNALED(status)) > + fprintf(stderr, "Error: %s hook terminated with signal %d\n", hook, > + WTERMSIG(status)); > + else > + fprintf(stderr, "Error: %s hook failed with status %d\n", hook, > + WEXITSTATUS(status)); > + > + status = NOTMUCH_STATUS_FILE_ERROR; /* Close enough */ > + } > + > + DONE: > + free (hook_path); > + > + return status; > +}