Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
/*
 * Write fdin to a new file in maildir/new, using an intermediate temp
 * file in maildir/tmp, return full path to the new file, or NULL on
 * errors.
 */
static char *
maildir_write_new (const void *ctx, int fdin, const char *maildir)
{
    char *cleanpath, *tmppath, *newpath, *newdir;

    tmppath = maildir_write_tmp (ctx, fdin, maildir);
    if (! tmppath)
	return NULL;
    cleanpath = tmppath;

    newpath = talloc_strdup (ctx, tmppath);
    if (! newpath) {
	fprintf (stderr, "Error: %s\n", strerror (ENOMEM));
	goto FAIL;
    }

    /* sanity checks needed? */
    memcpy (newpath + strlen (maildir) + 1, "new", 3);

    if (rename (tmppath, newpath)) {
	fprintf (stderr, "Error: rename '%s' '%s': %s\n",
		 tmppath, newpath, strerror (errno));
	goto FAIL;
    }
    cleanpath = newpath;

    newdir = talloc_asprintf (ctx, "%s/%s", maildir, "new");
    if (! newdir) {
	fprintf (stderr, "Error: %s\n", strerror (ENOMEM));
	goto FAIL;
    }

    if (! sync_dir (newdir))
	goto FAIL;

    return newpath;

FAIL:
    unlink (cleanpath);

    return NULL;
}