1 Return-Path: <bremner@tesseract.cs.unb.ca>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 80ABA431FD8
\r
6 for <notmuch@notmuchmail.org>; Sun, 28 Sep 2014 11:29:24 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id xS4RMl-BkY4h for <notmuch@notmuchmail.org>;
\r
16 Sun, 28 Sep 2014 11:29:19 -0700 (PDT)
\r
17 Received: from yantan.tethera.net (yantan.tethera.net [199.188.72.155])
\r
18 (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))
\r
19 (No client certificate requested)
\r
20 by olra.theworths.org (Postfix) with ESMTPS id B2600431FDC
\r
21 for <notmuch@notmuchmail.org>; Sun, 28 Sep 2014 11:29:07 -0700 (PDT)
\r
22 Received: from remotemail by yantan.tethera.net with local (Exim 4.80)
\r
23 (envelope-from <bremner@tesseract.cs.unb.ca>)
\r
24 id 1XYJDX-0005gR-8c; Sun, 28 Sep 2014 15:29:07 -0300
\r
25 Received: (nullmailer pid 31288 invoked by uid 1000); Sun, 28 Sep 2014
\r
27 From: David Bremner <david@tethera.net>
\r
28 To: notmuch@notmuchmail.org
\r
29 Subject: [WIP 2/3] cli/insert: move several file/directory manipulation
\r
30 routines into a new util file.
\r
31 Date: Sun, 28 Sep 2014 20:28:18 +0200
\r
32 Message-Id: <1411928899-29625-3-git-send-email-david@tethera.net>
\r
33 X-Mailer: git-send-email 2.1.0
\r
34 In-Reply-To: <1411928899-29625-1-git-send-email-david@tethera.net>
\r
35 References: <87iok8vog6.fsf@steelpick.2x.cz>
\r
36 <1411928899-29625-1-git-send-email-david@tethera.net>
\r
37 X-BeenThere: notmuch@notmuchmail.org
\r
38 X-Mailman-Version: 2.1.13
\r
40 List-Id: "Use and development of the notmuch mail system."
\r
41 <notmuch.notmuchmail.org>
\r
42 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
43 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
44 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
45 List-Post: <mailto:notmuch@notmuchmail.org>
\r
46 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
47 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
48 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
49 X-List-Received-Date: Sun, 28 Sep 2014 18:29:25 -0000
\r
51 This will promote code sharing of low level file operations.
\r
53 notmuch-insert.c | 79 ++----------------------------------------
\r
54 util/Makefile.local | 1 +
\r
55 util/file-util.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++
\r
56 util/file-util.h | 20 +++++++++++
\r
57 4 files changed, 121 insertions(+), 77 deletions(-)
\r
58 create mode 100644 util/file-util.c
\r
59 create mode 100644 util/file-util.h
\r
61 diff --git a/notmuch-insert.c b/notmuch-insert.c
\r
62 index 5ef6e66..48bdd28 100644
\r
63 --- a/notmuch-insert.c
\r
64 +++ b/notmuch-insert.c
\r
67 #include "notmuch-client.h"
\r
68 #include "tag-util.h"
\r
69 +#include "file-util.h"
\r
71 #include <sys/types.h>
\r
72 #include <sys/stat.h>
\r
73 @@ -63,26 +64,6 @@ safe_gethostname (char *hostname, size_t len)
\r
77 -/* Call fsync() on a directory path. */
\r
78 -static notmuch_bool_t
\r
79 -sync_dir (const char *dir)
\r
83 - fd = open (dir, O_RDONLY);
\r
85 - fprintf (stderr, "Error: open %s: %s\n", dir, strerror (errno));
\r
91 - fprintf (stderr, "Error: fsync %s: %s\n", dir, strerror (errno));
\r
99 * Check the specified folder name does not contain a directory
\r
100 @@ -92,65 +73,9 @@ sync_dir (const char *dir)
\r
101 static notmuch_bool_t
\r
102 is_valid_folder_name (const char *folder)
\r
104 - const char *p = folder;
\r
107 - if ((p[0] == '.') && (p[1] == '.') && (p[2] == '\0' || p[2] == '/'))
\r
109 - p = strchr (p, '/');
\r
114 + return ! has_double_dot_component (folder);
\r
118 - * Make the given directory and its parents as necessary, using the
\r
119 - * given mode. Return TRUE on success, FALSE otherwise. Partial
\r
120 - * results are not cleaned up on errors.
\r
122 -static notmuch_bool_t
\r
123 -mkdir_recursive (const void *ctx, const char *path, int mode)
\r
127 - char *parent = NULL, *slash;
\r
129 - /* First check the common case: directory already exists. */
\r
130 - r = stat (path, &st);
\r
132 - if (! S_ISDIR (st.st_mode)) {
\r
133 - fprintf (stderr, "Error: '%s' is not a directory: %s\n",
\r
134 - path, strerror (EEXIST));
\r
139 - } else if (errno != ENOENT) {
\r
140 - fprintf (stderr, "Error: stat '%s': %s\n", path, strerror (errno));
\r
144 - /* mkdir parents, if any */
\r
145 - slash = strrchr (path, '/');
\r
146 - if (slash && slash != path) {
\r
147 - parent = talloc_strndup (ctx, path, slash - path);
\r
149 - fprintf (stderr, "Error: %s\n", strerror (ENOMEM));
\r
153 - if (! mkdir_recursive (ctx, parent, mode))
\r
157 - if (mkdir (path, mode)) {
\r
158 - fprintf (stderr, "Error: mkdir '%s': %s\n", path, strerror (errno));
\r
162 - return parent ? sync_dir (parent) : TRUE;
\r
166 * Create the given maildir folder, i.e. maildir and its
\r
167 diff --git a/util/Makefile.local b/util/Makefile.local
\r
168 index 905f237..8749cfb 100644
\r
169 --- a/util/Makefile.local
\r
170 +++ b/util/Makefile.local
\r
171 @@ -5,6 +5,7 @@ extra_cflags += -I$(srcdir)/$(dir)
\r
173 libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \
\r
174 $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c \
\r
175 + $(dir)/file-util.c \
\r
178 libutil_modules := $(libutil_c_srcs:.c=.o)
\r
179 diff --git a/util/file-util.c b/util/file-util.c
\r
180 new file mode 100644
\r
181 index 0000000..66c4485
\r
183 +++ b/util/file-util.c
\r
185 +#include <errno.h>
\r
186 +#include <fcntl.h>
\r
187 +#include <stdio.h>
\r
188 +#include <string.h>
\r
189 +#include <sys/stat.h>
\r
190 +#include <sys/types.h>
\r
191 +#include <talloc.h>
\r
192 +#include <unistd.h>
\r
194 +#include "file-util.h"
\r
197 + * Check whether specified path name contains a directory
\r
198 + * component "..". to prevent writes outside of the Maildir
\r
201 +has_double_dot_component (const char *path)
\r
203 + const char *p = path;
\r
206 + if ((p[0] == '.') && (p[1] == '.') && (p[2] == '\0' || p[2] == '/'))
\r
208 + p = strchr (p, '/');
\r
216 + * Make the given directory and its parents as necessary, using the
\r
217 + * given mode. return TRUE on success, 0 otherwise. Partial
\r
218 + * results are not cleaned up on errors.
\r
221 +mkdir_recursive (const void *ctx, const char *path, int mode)
\r
225 + char *parent = NULL, *slash;
\r
227 + /* First check the common case: directory already exists. */
\r
228 + r = stat (path, &st);
\r
230 + if (! S_ISDIR (st.st_mode)) {
\r
231 + fprintf (stderr, "Error: '%s' is not a directory: %s\n",
\r
232 + path, strerror (EEXIST));
\r
237 + } else if (errno != ENOENT) {
\r
238 + fprintf (stderr, "Error: stat '%s': %s\n", path, strerror (errno));
\r
242 + /* mkdir parents, if any */
\r
243 + slash = strrchr (path, '/');
\r
244 + if (slash && slash != path) {
\r
245 + parent = talloc_strndup (ctx, path, slash - path);
\r
247 + fprintf (stderr, "Error: %s\n", strerror (ENOMEM));
\r
251 + if (! mkdir_recursive (ctx, parent, mode))
\r
255 + if (mkdir (path, mode)) {
\r
256 + fprintf (stderr, "Error: mkdir '%s': %s\n", path, strerror (errno));
\r
260 + return parent ? sync_dir (parent) : TRUE;
\r
263 +/* Call fsync() on a directory path. */
\r
265 +sync_dir (const char *dir)
\r
269 + fd = open (dir, O_RDONLY);
\r
271 + fprintf (stderr, "Error: open %s: %s\n", dir, strerror (errno));
\r
277 + fprintf (stderr, "Error: fsync %s: %s\n", dir, strerror (errno));
\r
283 diff --git a/util/file-util.h b/util/file-util.h
\r
284 new file mode 100644
\r
285 index 0000000..4f96957
\r
287 +++ b/util/file-util.h
\r
289 +#ifndef _FILE_UTIL_H
\r
290 +#define _FILE_UTIL_H
\r
300 +has_double_dot_component (const char *path);
\r
303 +mkdir_recursive (const void *ctx, const char *path, int mode);
\r
306 +sync_dir (const char *path);
\r