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