+ 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++;
+ }
+}
+
+/*
+ * 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 bool
+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
+ * subdirectories cur/new/tmp. Return true on success, false
+ * otherwise. Partial results are not cleaned up on errors.
+ */
+static bool
+maildir_create_folder (const void *ctx, const char *maildir)
+{
+ const char *subdirs[] = { "cur", "new", "tmp" };
+ const int mode = 0700;
+ char *subdir;
+ unsigned int i;
+
+ 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;
+ }
+
+ if (! mkdir_recursive (ctx, subdir, mode))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Generate a temporary file basename, no path, do not create an
+ * actual file. Return the basename, or NULL on errors.
+ */
+static char *
+tempfilename (const void *ctx)
+{
+ char *filename;