From bb1ca85ecf3309837c684ec2e9fcf5c088beec21 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 22 Sep 2014 11:54:57 +0200 Subject: [PATCH] [PATCH 06/11] cli/insert: use a single recursive mkdir function --- c1/4b25b43eecee75fc01c40a602572ed223ef1cf | 248 ++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 c1/4b25b43eecee75fc01c40a602572ed223ef1cf diff --git a/c1/4b25b43eecee75fc01c40a602572ed223ef1cf b/c1/4b25b43eecee75fc01c40a602572ed223ef1cf new file mode 100644 index 000000000..e8af73f59 --- /dev/null +++ b/c1/4b25b43eecee75fc01c40a602572ed223ef1cf @@ -0,0 +1,248 @@ +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 CD2EA431FC0 + for ; Mon, 22 Sep 2014 02:55:11 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" +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 Xs7z0sPjbAyE for ; + Mon, 22 Sep 2014 02:55:07 -0700 (PDT) +Received: from mail-wi0-f170.google.com (mail-wi0-f170.google.com + [209.85.212.170]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) + (No client certificate requested) + by olra.theworths.org (Postfix) with ESMTPS id C50C0431FDE + for ; Mon, 22 Sep 2014 02:54:56 -0700 (PDT) +Received: by mail-wi0-f170.google.com with SMTP id fb4so2486823wid.3 + for ; Mon, 22 Sep 2014 02:54:55 -0700 (PDT) +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20130820; + h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to + :references:in-reply-to:references; + bh=+eJmjEEFeki5WtosF6F2YBxONWtxesmKdqnnEpOzjBk=; + b=V7RyB2D9NOHfx7axwrDe1aqhWmgpfBAbEhV8kJBNWu3NbUHnMpgO/owi1o5Rh1dRKR + p2o5F41oFfucEM665JBfKmw/61YOU1QGvXOXxUnHEJ01myngkxvwbPJ3SAnkWLXmG3Ad + nx8tnqMh6U6UYCaU1NtaxsiFwfunPI0mR9U5RrOcTl+UZLWb1e3uGEuGP4PrAnxJG9UU + GdtCZaF7MCftKJ/ziLR+sr5Z3jE8ddhZO6LTv6/lrLDApCFSlpHOdAxXckROyqx1zQGz + WA+NrDR6vCbIOt+SFQgGqKXzZp7abV4HLDmnjCAlrHvJt/obxKbwORmPjsewvS9TTOWk + Q+AQ== +X-Gm-Message-State: + ALoCoQlzw4D32NBOxTVZciiM1YX08srcr/bLmrCMk09EjNkT0Nukcy8L8zWiuh841xBB2kBFDwa7 +X-Received: by 10.180.75.143 with SMTP id c15mr14512427wiw.31.1411379695711; + Mon, 22 Sep 2014 02:54:55 -0700 (PDT) +Received: from localhost ([2001:4b98:dc0:43:216:3eff:fe1b:25f3]) + by mx.google.com with ESMTPSA id + ky3sm11695685wjb.39.2014.09.22.02.54.55 for + (version=TLSv1.1 cipher=RC4-SHA bits=128/128); + Mon, 22 Sep 2014 02:54:55 -0700 (PDT) +From: Jani Nikula +To: notmuch@notmuchmail.org +Subject: [PATCH 06/11] cli/insert: use a single recursive mkdir function +Date: Mon, 22 Sep 2014 11:54:57 +0200 +Message-Id: + <3059bb1ef1dede24e28d9827082ca36c8e6c5996.1411379395.git.jani@nikula.org> +X-Mailer: git-send-email 1.7.2.5 +In-Reply-To: +References: +In-Reply-To: +References: +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: Mon, 22 Sep 2014 09:55:12 -0000 + +Combine make_directory() and make_directory_and_parents() into a +single recursive mkdir_recursive() function. Clarify the code and +improve error handling. Improve error messages. Switch to using the +new function in maildir_create_folder(). Constify talloc context. +--- + notmuch-insert.c | 131 +++++++++++++++++++++++------------------------------- + 1 files changed, 55 insertions(+), 76 deletions(-) + +diff --git a/notmuch-insert.c b/notmuch-insert.c +index 7375c54..cdeeb41 100644 +--- a/notmuch-insert.c ++++ b/notmuch-insert.c +@@ -104,96 +104,78 @@ is_valid_folder_name (const char *folder) + } + } + +-/* Make the given directory, succeeding if it already exists. */ ++/* ++ * 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 +-make_directory (char *path, int mode) ++mkdir_recursive (const void *ctx, const char *path, int mode) + { +- notmuch_bool_t ret; +- char *slash; ++ struct stat st; ++ int r; ++ char *parent = NULL, *slash; + +- if (mkdir (path, mode) != 0) +- return (errno == EEXIST); ++ /* 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; ++ } + +- /* Sync the parent directory for durability. */ +- ret = TRUE; +- slash = strrchr (path, '/'); +- if (slash) { +- *slash = '\0'; +- ret = sync_dir (path); +- *slash = '/'; ++ return TRUE; ++ } else if (errno != ENOENT) { ++ fprintf (stderr, "Error: stat '%s': %s\n", path, strerror (errno)); ++ return FALSE; + } +- return ret; +-} +- +-/* Make the given directory including its parent directories as necessary. +- * Return TRUE on success, FALSE on error. */ +-static notmuch_bool_t +-make_directory_and_parents (char *path, int mode) +-{ +- struct stat st; +- char *start; +- char *end; +- notmuch_bool_t ret; + +- /* First check the common case: directory already exists. */ +- if (stat (path, &st) == 0) +- return S_ISDIR (st.st_mode) ? TRUE : FALSE; +- +- for (start = path; *start != '\0'; start = end + 1) { +- /* start points to the first unprocessed character. +- * Find the next slash from start onwards. */ +- end = strchr (start, '/'); +- +- /* If there are no more slashes then all the parent directories +- * have been made. Now attempt to make the whole path. */ +- if (end == NULL) +- return make_directory (path, mode); +- +- /* Make the path up to the next slash, unless the current +- * directory component is actually empty. */ +- if (end > start) { +- *end = '\0'; +- ret = make_directory (path, mode); +- *end = '/'; +- if (! ret) +- 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; + } + +- return TRUE; ++ 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. dir and its subdirectories +- * 'cur', 'new', 'tmp'. */ ++/* ++ * Create the given maildir folder, i.e. maildir and its ++ * subdirectories cur/new/tmp. Return TRUE on success, FALSE ++ * otherwise. Partial results are not cleaned up on errors. ++ */ + static notmuch_bool_t +-maildir_create_folder (void *ctx, const char *dir) ++maildir_create_folder (const void *ctx, const char *maildir) + { ++ const char *subdirs[] = { "cur", "new", "tmp" }; + const int mode = 0700; + char *subdir; +- char *tail; +- +- /* Create 'cur' directory, including parent directories. */ +- subdir = talloc_asprintf (ctx, "%s/cur", dir); +- if (! subdir) { +- fprintf (stderr, "Out of memory.\n"); +- return FALSE; +- } +- if (! make_directory_and_parents (subdir, mode)) +- return FALSE; +- +- tail = subdir + strlen (subdir) - 3; ++ unsigned int i; + +- /* Create 'new' directory. */ +- strcpy (tail, "new"); +- if (! make_directory (subdir, mode)) +- return FALSE; ++ for (i = 0; i < ARRAY_SIZE (subdirs); i++) { ++ subdir = talloc_asprintf (ctx, "%s/%s", maildir, subdirs[i]); ++ if (! subdir) { ++ fprintf (stderr, "Error: %s\n", strerror (ENOMEM)); ++ return FALSE; ++ } + +- /* Create 'tmp' directory. */ +- strcpy (tail, "tmp"); +- if (! make_directory (subdir, mode)) +- return FALSE; ++ if (! mkdir_recursive (ctx, subdir, mode)) ++ return FALSE; ++ } + +- talloc_free (subdir); + return TRUE; + } + +@@ -463,11 +445,8 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) + fprintf (stderr, "Out of memory\n"); + return EXIT_FAILURE; + } +- if (create_folder && ! maildir_create_folder (config, maildir)) { +- fprintf (stderr, "Error: creating maildir %s: %s\n", +- maildir, strerror (errno)); ++ if (create_folder && ! maildir_create_folder (config, maildir)) + return EXIT_FAILURE; +- } + } + + /* Setup our handler for SIGINT. We do not set SA_RESTART so that copying +-- +1.7.2.5 + -- 2.26.2