Esempio n. 1
0
static int
create_dir(struct pkg *pkg, struct pkg_dir *d)
{
	struct stat st;

	if (mkdirat(pkg->rootfd, RELATIVE_PATH(d->path), 0755) == -1)
		if (!mkdirat_p(pkg->rootfd, RELATIVE_PATH(d->path)))
			return (EPKG_FATAL);
	if (fstatat(pkg->rootfd, RELATIVE_PATH(d->path), &st, 0) == -1) {
		if (errno != ENOENT) {
			pkg_fatal_errno("Fail to stat directory %s", d->path);
		}
		if (fstatat(pkg->rootfd, RELATIVE_PATH(d->path), &st, AT_SYMLINK_NOFOLLOW) == 0) {
			unlinkat(pkg->rootfd, RELATIVE_PATH(d->path), 0);
		}
		if (mkdirat(pkg->rootfd, RELATIVE_PATH(d->path), 0755) == -1) {
			pkg_fatal_errno("Fail to create directory %s", d->path);
		}
	}

	if (st.st_uid == d->uid && st.st_gid == d->gid &&
	    (st.st_mode & ~S_IFMT) == (d->perm & ~S_IFMT)) {
		d->noattrs = true;
	}

	return (EPKG_OK);
}
Esempio n. 2
0
int
pkgdb_dump(struct pkgdb *db, const char *dest)
{
	sqlite3	*backup;
	int	 ret;

	if (eaccess(dest, W_OK)) {
		if (errno != ENOENT) {
			pkg_fatal_errno("Unable to access '%s'", dest);
		}

		/* Could we create the Sqlite DB file? */
		if (eaccess(bsd_dirname(dest), W_OK)) {
			pkg_fatal_errno("Unable to access '%s'",
			    bsd_dirname(dest));
		}
	}

	ret = sqlite3_open(dest, &backup);

	if (ret != SQLITE_OK) {
		ERROR_SQLITE(backup, "sqlite3_open");
		sqlite3_close(backup);
		return (EPKG_FATAL);
	}

	pkg_emit_backup();
	ret = copy_database(db->sqlite, backup);

	sqlite3_close(backup);

	return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
}
Esempio n. 3
0
int
pkgdb_load(struct pkgdb *db, const char *src)
{
	sqlite3	*restore;
	int	 ret;

	if (eaccess(src, R_OK)) {
		pkg_fatal_errno("Unable to access '%s'", src);
	}

	ret = sqlite3_open(src, &restore);

	if (ret != SQLITE_OK) {
		ERROR_SQLITE(restore, "sqlite3_open");
		sqlite3_close(restore);
		return (EPKG_FATAL);
	}

	pkg_emit_restore();
	ret = copy_database(restore, db->sqlite);

	sqlite3_close(restore);

	return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
}
Esempio n. 4
0
int
metalog_open(const char *metalog)
{
	metalogfp = fopen(metalog, "a");
	if (metalogfp == NULL) {
		pkg_fatal_errno("Unable to open metalog '%s'", metalog);
	} 

	return EPKG_OK;
}
Esempio n. 5
0
static int
set_attrs(int fd, char *path, mode_t perm, uid_t uid, gid_t gid,
    const struct timespec *ats, const struct timespec *mts)
{

	struct timeval tv[2];
	struct stat st;
	int fdcwd;
#ifdef HAVE_UTIMENSAT
	struct timespec times[2];

	times[0] = *ats;
	times[1] = *mts;
	if (utimensat(fd, RELATIVE_PATH(path), times,
	    AT_SYMLINK_NOFOLLOW) == -1 && errno != EOPNOTSUPP){
		pkg_fatal_errno("Fail to set time on %s", path);
	}
	if (errno == EOPNOTSUPP) {
#endif

	tv[0].tv_sec = ats->tv_sec;
	tv[0].tv_usec = ats->tv_nsec / 1000;
	tv[1].tv_sec = mts->tv_sec;
	tv[1].tv_usec = mts->tv_nsec / 1000;

	fdcwd = open(".", O_DIRECTORY|O_CLOEXEC);
	fchdir(fd);

	if (lutimes(RELATIVE_PATH(path), tv) == -1) {

		if (errno != ENOSYS) {
			pkg_fatal_errno("Fail to set time on %s", path);
		}
		else {
			/* Fallback to utimes */
			if (utimes(RELATIVE_PATH(path), tv) == -1) {
				pkg_fatal_errno("Fail to set time(fallback) on "
				    "%s", path);
			}
		}
	}
	fchdir(fdcwd);
	close(fdcwd);
#ifdef HAVE_UTIMENSAT
	}
#endif

	if (getenv("INSTALL_AS_USER") == NULL) {
		if (fchownat(fd, RELATIVE_PATH(path), uid, gid,
				AT_SYMLINK_NOFOLLOW) == -1) {
			if (errno == ENOTSUP) {
				if (fchownat(fd, RELATIVE_PATH(path), uid, gid, 0) == -1) {
					pkg_fatal_errno("Fail to chown(fallback) %s", path);
				}
			}
			else {
				pkg_fatal_errno("Fail to chown %s", path);
			}
		}
	}

	/* zfs drops the setuid on fchownat */
	if (fchmodat(fd, RELATIVE_PATH(path), perm, AT_SYMLINK_NOFOLLOW) == -1) {
		if (errno == ENOTSUP) {
			/* 
			 * Executing fchmodat on a symbolic link results in
			 * ENOENT (file not found) on platforms that do not
			 * support AT_SYMLINK_NOFOLLOW. The file mode of
			 * symlinks cannot be modified via file descriptor
			 * reference on these systems. The lchmod function is
			 * also not an option because it is not a posix
			 * standard, nor is implemented everywhere. Since
			 * symlink permissions have never been evaluated and
			 * thus cosmetic, just skip them on these systems.
			 */
			if (fstatat(fd, RELATIVE_PATH(path), &st, AT_SYMLINK_NOFOLLOW) == -1) {
				pkg_fatal_errno("Fail to get file status %s", path);
			}
			if (!S_ISLNK(st.st_mode)) {
				if (fchmodat(fd, RELATIVE_PATH(path), perm, 0) == -1) {
					pkg_fatal_errno("Fail to chmod(fallback) %s", path);
				}
			}
		}
		else {
			pkg_fatal_errno("Fail to chmod %s", path);
		}
	}

	return (EPKG_OK);
}