예제 #1
0
int
mkdirhier(char *path, mode_t mask)
{
	struct fattr *fa;
	size_t i, last, len;
	int error, finish, rv;

	finish = 0;
	last = 0;
	len = strlen(path);
	for (i = len - 1; i > 0; i--) {
		if (path[i] == '/') {
			path[i] = '\0';
			if (access(path, F_OK) == 0) {
				path[i] = '/';
				break;
			}
			if (errno != ENOENT) {
				path[i] = '/';
				if (last == 0)
					return (-1);
				finish = 1;
				break;
			}
			last = i;
		}
	}
	if (last == 0)
		return (0);

	i = strlen(path);
	fa = fattr_new(FT_DIRECTORY, -1);
	fattr_mergedefault(fa);
	fattr_umask(fa, mask);
	while (i < len) {
		if (!finish) {
			rv = 0;
			error = fattr_makenode(fa, path);
			if (!error)
				rv = fattr_install(fa, path, NULL);
			if (error || rv == -1)
				finish = 1;
		}
		path[i] = '/';
		i += strlen(path + i);
        }
	assert(i == len);
	if (finish)
		return (-1);
        return (0);
}
예제 #2
0
/*
 * Open the status file.  If scantime is not -1, the file is opened
 * for updating, otherwise, it is opened read-only. If the status file
 * couldn't be opened, NULL is returned and errmsg is set to the error
 * message.
 */
struct status *
status_open(struct coll *coll, time_t scantime, char **errmsg)
{
	struct status *st;
	struct stream *file;
	struct fattr *fa;
	char *destpath, *path;
	int error, rv;

	path = coll_statuspath(coll);
	file = stream_open_file(path, O_RDONLY);
	if (file == NULL) {
		if (errno != ENOENT) {
			xasprintf(errmsg, "Could not open \"%s\": %s\n",
			    path, strerror(errno));
			free(path);
			return (NULL);
		}
		st = status_fromnull(path);
	} else {
		st = status_fromrd(path, file);
		if (st == NULL) {
			xasprintf(errmsg, "Error in \"%s\": Bad header line",
			    path);
			free(path);
			return (NULL);
		}
	}

	if (scantime != -1) {
		/* Open for writing too. */
		xasprintf(&destpath, "%s/%s/%s/", coll->co_base,
		    coll->co_colldir, coll->co_name);
		st->tempfile = tempname(destpath);
		if (mkdirhier(destpath, coll->co_umask) != 0) {
			xasprintf(errmsg, "Cannot create directories leading "
			    "to \"%s\": %s", destpath, strerror(errno));
			free(destpath);
			status_free(st);
			return (NULL);
		}
		free(destpath);
		st->wr = stream_open_file(st->tempfile,
		    O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if (st->wr == NULL) {
			xasprintf(errmsg, "Cannot create \"%s\": %s",
			    st->tempfile, strerror(errno));
			status_free(st);
			return (NULL);
		}
		fa = fattr_new(FT_FILE, -1);
		fattr_mergedefault(fa);
		fattr_umask(fa, coll->co_umask);
		rv = fattr_install(fa, st->tempfile, NULL);
		fattr_free(fa);
		if (rv == -1) {
			xasprintf(errmsg,
			    "Cannot set attributes for \"%s\": %s",
			    st->tempfile, strerror(errno));
			status_free(st);
			return (NULL);
		}
		if (scantime != st->scantime)
			st->dirty = 1;
		error = proto_printf(st->wr, "F %d %t\n", STATUS_VERSION,
		    scantime);
		if (error) {
			st->error = STATUS_ERR_WRITE;
			st->suberror = errno;
			*errmsg = status_errmsg(st);
			status_free(st);
			return (NULL);
		}
	}
	return (st);
}