[WIP 2/3] cli/insert: move several file/directory manipulation routines into a new...
authorDavid Bremner <david@tethera.net>
Sun, 28 Sep 2014 18:28:18 +0000 (20:28 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 18:04:48 +0000 (10:04 -0800)
08/c39df99b4a585cfb7fcd4fa7dee87137150473 [new file with mode: 0644]

diff --git a/08/c39df99b4a585cfb7fcd4fa7dee87137150473 b/08/c39df99b4a585cfb7fcd4fa7dee87137150473
new file mode 100644 (file)
index 0000000..529ec6a
--- /dev/null
@@ -0,0 +1,311 @@
+Return-Path: <bremner@tesseract.cs.unb.ca>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 80ABA431FD8\r
+       for <notmuch@notmuchmail.org>; Sun, 28 Sep 2014 11:29:24 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+       autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id xS4RMl-BkY4h for <notmuch@notmuchmail.org>;\r
+       Sun, 28 Sep 2014 11:29:19 -0700 (PDT)\r
+Received: from yantan.tethera.net (yantan.tethera.net [199.188.72.155])\r
+       (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id B2600431FDC\r
+       for <notmuch@notmuchmail.org>; Sun, 28 Sep 2014 11:29:07 -0700 (PDT)\r
+Received: from remotemail by yantan.tethera.net with local (Exim 4.80)\r
+       (envelope-from <bremner@tesseract.cs.unb.ca>)\r
+       id 1XYJDX-0005gR-8c; Sun, 28 Sep 2014 15:29:07 -0300\r
+Received: (nullmailer pid 31288 invoked by uid 1000); Sun, 28 Sep 2014\r
+       18:28:49 -0000\r
+From: David Bremner <david@tethera.net>\r
+To: notmuch@notmuchmail.org\r
+Subject: [WIP 2/3] cli/insert: move several file/directory manipulation\r
+       routines into a new util file.\r
+Date: Sun, 28 Sep 2014 20:28:18 +0200\r
+Message-Id: <1411928899-29625-3-git-send-email-david@tethera.net>\r
+X-Mailer: git-send-email 2.1.0\r
+In-Reply-To: <1411928899-29625-1-git-send-email-david@tethera.net>\r
+References: <87iok8vog6.fsf@steelpick.2x.cz>\r
+       <1411928899-29625-1-git-send-email-david@tethera.net>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://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: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 28 Sep 2014 18:29:25 -0000\r
+\r
+This will promote code sharing of low level file operations.\r
+---\r
+ notmuch-insert.c    | 79 ++----------------------------------------\r
+ util/Makefile.local |  1 +\r
+ util/file-util.c    | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ util/file-util.h    | 20 +++++++++++\r
+ 4 files changed, 121 insertions(+), 77 deletions(-)\r
+ create mode 100644 util/file-util.c\r
+ create mode 100644 util/file-util.h\r
+\r
+diff --git a/notmuch-insert.c b/notmuch-insert.c\r
+index 5ef6e66..48bdd28 100644\r
+--- a/notmuch-insert.c\r
++++ b/notmuch-insert.c\r
+@@ -23,6 +23,7 @@\r
\r
+ #include "notmuch-client.h"\r
+ #include "tag-util.h"\r
++#include "file-util.h"\r
\r
+ #include <sys/types.h>\r
+ #include <sys/stat.h>\r
+@@ -63,26 +64,6 @@ safe_gethostname (char *hostname, size_t len)\r
+     }\r
+ }\r
\r
+-/* Call fsync() on a directory path. */\r
+-static notmuch_bool_t\r
+-sync_dir (const char *dir)\r
+-{\r
+-    int fd, r;\r
+-\r
+-    fd = open (dir, O_RDONLY);\r
+-    if (fd == -1) {\r
+-      fprintf (stderr, "Error: open %s: %s\n", dir, strerror (errno));\r
+-      return FALSE;\r
+-    }\r
+-\r
+-    r = fsync (fd);\r
+-    if (r)\r
+-      fprintf (stderr, "Error: fsync %s: %s\n", dir, strerror (errno));\r
+-\r
+-    close (fd);\r
+-\r
+-    return r == 0;\r
+-}\r
\r
+ /*\r
+  * Check the specified folder name does not contain a directory\r
+@@ -92,65 +73,9 @@ sync_dir (const char *dir)\r
+ static notmuch_bool_t\r
+ is_valid_folder_name (const char *folder)\r
+ {\r
+-    const char *p = folder;\r
+-\r
+-    for (;;) {\r
+-      if ((p[0] == '.') && (p[1] == '.') && (p[2] == '\0' || p[2] == '/'))\r
+-          return FALSE;\r
+-      p = strchr (p, '/');\r
+-      if (!p)\r
+-          return TRUE;\r
+-      p++;\r
+-    }\r
++    return ! has_double_dot_component (folder);\r
+ }\r
\r
+-/*\r
+- * Make the given directory and its parents as necessary, using the\r
+- * given mode. Return TRUE on success, FALSE otherwise. Partial\r
+- * results are not cleaned up on errors.\r
+- */\r
+-static notmuch_bool_t\r
+-mkdir_recursive (const void *ctx, const char *path, int mode)\r
+-{\r
+-    struct stat st;\r
+-    int r;\r
+-    char *parent = NULL, *slash;\r
+-\r
+-    /* First check the common case: directory already exists. */\r
+-    r = stat (path, &st);\r
+-    if (r == 0) {\r
+-        if (! S_ISDIR (st.st_mode)) {\r
+-          fprintf (stderr, "Error: '%s' is not a directory: %s\n",\r
+-                   path, strerror (EEXIST));\r
+-          return FALSE;\r
+-      }\r
+-\r
+-      return TRUE;\r
+-    } else if (errno != ENOENT) {\r
+-      fprintf (stderr, "Error: stat '%s': %s\n", path, strerror (errno));\r
+-      return FALSE;\r
+-    }\r
+-\r
+-    /* mkdir parents, if any */\r
+-    slash = strrchr (path, '/');\r
+-    if (slash && slash != path) {\r
+-      parent = talloc_strndup (ctx, path, slash - path);\r
+-      if (! parent) {\r
+-          fprintf (stderr, "Error: %s\n", strerror (ENOMEM));\r
+-          return FALSE;\r
+-      }\r
+-\r
+-      if (! mkdir_recursive (ctx, parent, mode))\r
+-          return FALSE;\r
+-    }\r
+-\r
+-    if (mkdir (path, mode)) {\r
+-      fprintf (stderr, "Error: mkdir '%s': %s\n", path, strerror (errno));\r
+-      return FALSE;\r
+-    }\r
+-\r
+-    return parent ? sync_dir (parent) : TRUE;\r
+-}\r
\r
+ /*\r
+  * Create the given maildir folder, i.e. maildir and its\r
+diff --git a/util/Makefile.local b/util/Makefile.local\r
+index 905f237..8749cfb 100644\r
+--- a/util/Makefile.local\r
++++ b/util/Makefile.local\r
+@@ -5,6 +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)/file-util.c \\r
+               $(dir)/util.c\r
\r
+ libutil_modules := $(libutil_c_srcs:.c=.o)\r
+diff --git a/util/file-util.c b/util/file-util.c\r
+new file mode 100644\r
+index 0000000..66c4485\r
+--- /dev/null\r
++++ b/util/file-util.c\r
+@@ -0,0 +1,98 @@\r
++#include <errno.h>\r
++#include <fcntl.h>\r
++#include <stdio.h>\r
++#include <string.h>\r
++#include <sys/stat.h>\r
++#include <sys/types.h>\r
++#include <talloc.h>\r
++#include <unistd.h>\r
++\r
++#include "file-util.h"\r
++\r
++/*\r
++ * Check whether specified path name contains a directory\r
++ * component "..". to prevent writes outside of the Maildir\r
++ */\r
++int\r
++has_double_dot_component (const char *path)\r
++{\r
++    const char *p = path;\r
++\r
++    for (;;) {\r
++      if ((p[0] == '.') && (p[1] == '.') && (p[2] == '\0' || p[2] == '/'))\r
++          return TRUE;\r
++      p = strchr (p, '/');\r
++      if (!p)\r
++          return FALSE;\r
++      p++;\r
++    }\r
++}\r
++\r
++/*\r
++ * Make the given directory and its parents as necessary, using the\r
++ * given mode. return TRUE on success, 0 otherwise. Partial\r
++ * results are not cleaned up on errors.\r
++ */\r
++int\r
++mkdir_recursive (const void *ctx, const char *path, int mode)\r
++{\r
++    struct stat st;\r
++    int r;\r
++    char *parent = NULL, *slash;\r
++\r
++    /* First check the common case: directory already exists. */\r
++    r = stat (path, &st);\r
++    if (r == 0) {\r
++        if (! S_ISDIR (st.st_mode)) {\r
++          fprintf (stderr, "Error: '%s' is not a directory: %s\n",\r
++                   path, strerror (EEXIST));\r
++          return FALSE;\r
++      }\r
++\r
++      return TRUE;\r
++    } else if (errno != ENOENT) {\r
++      fprintf (stderr, "Error: stat '%s': %s\n", path, strerror (errno));\r
++      return FALSE;\r
++    }\r
++\r
++    /* mkdir parents, if any */\r
++    slash = strrchr (path, '/');\r
++    if (slash && slash != path) {\r
++      parent = talloc_strndup (ctx, path, slash - path);\r
++      if (! parent) {\r
++          fprintf (stderr, "Error: %s\n", strerror (ENOMEM));\r
++          return FALSE;\r
++      }\r
++\r
++      if (! mkdir_recursive (ctx, parent, mode))\r
++          return FALSE;\r
++    }\r
++\r
++    if (mkdir (path, mode)) {\r
++      fprintf (stderr, "Error: mkdir '%s': %s\n", path, strerror (errno));\r
++      return FALSE;\r
++    }\r
++\r
++    return parent ? sync_dir (parent) : TRUE;\r
++}\r
++\r
++/* Call fsync() on a directory path. */\r
++int\r
++sync_dir (const char *dir)\r
++{\r
++    int fd, r;\r
++\r
++    fd = open (dir, O_RDONLY);\r
++    if (fd == -1) {\r
++      fprintf (stderr, "Error: open %s: %s\n", dir, strerror (errno));\r
++      return FALSE;\r
++    }\r
++\r
++    r = fsync (fd);\r
++    if (r)\r
++      fprintf (stderr, "Error: fsync %s: %s\n", dir, strerror (errno));\r
++\r
++    close (fd);\r
++\r
++    return r == 0;\r
++}\r
+diff --git a/util/file-util.h b/util/file-util.h\r
+new file mode 100644\r
+index 0000000..4f96957\r
+--- /dev/null\r
++++ b/util/file-util.h\r
+@@ -0,0 +1,20 @@\r
++#ifndef _FILE_UTIL_H\r
++#define _FILE_UTIL_H\r
++\r
++#ifndef FALSE \r
++#define FALSE 0\r
++#endif\r
++#ifndef TRUE\r
++#define TRUE 1\r
++#endif\r
++\r
++int\r
++has_double_dot_component (const char *path);\r
++\r
++int\r
++mkdir_recursive (const void *ctx, const char *path, int mode);\r
++\r
++int\r
++sync_dir (const char *path);\r
++\r
++#endif\r
+-- \r
+2.1.0\r
+\r