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); }
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); }
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); }
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; }
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); }