2024-11-20 09:28:20 +01:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
|
|
|
#include "sourcefs.h"
|
2024-12-03 18:10:50 +01:00
|
|
|
#include <dirent.h>
|
2024-12-15 15:41:28 +01:00
|
|
|
#include <errno.h>
|
2024-11-20 09:28:20 +01:00
|
|
|
#include <fcntl.h>
|
2024-11-20 10:32:33 +01:00
|
|
|
#include <stdio.h>
|
2024-12-15 15:41:28 +01:00
|
|
|
#include <string.h>
|
2024-11-20 10:32:33 +01:00
|
|
|
#include <sys/stat.h>
|
2024-12-15 15:41:28 +01:00
|
|
|
#include <unistd.h>
|
2024-11-20 09:28:20 +01:00
|
|
|
|
|
|
|
static struct source_files_handle {
|
|
|
|
int root_fd;
|
|
|
|
} handle;
|
|
|
|
|
2024-12-15 15:41:28 +01:00
|
|
|
const char *source_fname_translate(const char *filename) {
|
|
|
|
if (strcmp("/", filename) == 0) {
|
|
|
|
return ".";
|
|
|
|
} else {
|
|
|
|
return filename + 1;
|
|
|
|
}
|
|
|
|
}
|
2024-12-03 18:10:50 +01:00
|
|
|
|
2024-11-20 09:28:20 +01:00
|
|
|
int source_init(const char *root_path) {
|
|
|
|
int root_fd = open(root_path, O_PATH);
|
|
|
|
|
|
|
|
if (root_fd == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle.root_fd = root_fd;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2024-11-20 10:32:33 +01:00
|
|
|
|
2024-12-15 15:41:28 +01:00
|
|
|
int source_mkdir(const char *filename, mode_t mode) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return mkdirat(handle.root_fd, relative_filename, mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_unlink(const char *filename) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return unlinkat(handle.root_fd, relative_filename, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_stat(const char *restrict filename, struct stat *restrict statbuf) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return fstatat(handle.root_fd, relative_filename, statbuf, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_rmdir(const char *filename) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return unlinkat(handle.root_fd, relative_filename, AT_REMOVEDIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_symlink(const char *target, const char *linkpath) {
|
|
|
|
const char *relative_linkpath = source_fname_translate(linkpath);
|
|
|
|
return symlinkat(target, handle.root_fd, relative_linkpath);
|
2024-11-20 10:32:33 +01:00
|
|
|
}
|
2024-12-03 18:10:50 +01:00
|
|
|
|
|
|
|
DIR *source_opendir(const char *filename) {
|
2024-12-15 15:41:28 +01:00
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
int fd = openat(handle.root_fd, relative_filename, NULL);
|
|
|
|
if (fd < 0) {
|
|
|
|
perror("Openat failed");
|
|
|
|
return NULL;
|
|
|
|
}
|
2024-12-03 18:10:50 +01:00
|
|
|
DIR *dir_pointer = fdopendir(fd);
|
|
|
|
return dir_pointer;
|
|
|
|
}
|
|
|
|
|
2024-12-15 15:41:28 +01:00
|
|
|
int source_rename(const char *oldpath, const char *newpath) {
|
2024-12-17 10:11:59 +01:00
|
|
|
const char *relative_oldpath = source_fname_translate(oldpath);
|
|
|
|
const char *relative_newpath = source_fname_translate(newpath);
|
|
|
|
return renameat(handle.root_fd, relative_oldpath, handle.root_fd,
|
|
|
|
relative_newpath);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_link(const char *oldpath, const char *newpath) {
|
|
|
|
const char *relative_oldpath = source_fname_translate(oldpath);
|
|
|
|
const char *relative_newpath = source_fname_translate(newpath);
|
|
|
|
return linkat(handle.root_fd, relative_oldpath, handle.root_fd,
|
|
|
|
relative_newpath, 0);
|
|
|
|
// NOTE: perhaps the flags here need to be reevaluated.
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_chmod(const char *filename, mode_t mode) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return fchmodat(handle.root_fd, relative_filename, mode, 0);
|
|
|
|
// NOTE: perhaps the flags here need to be reevaluated.
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_chown(const char *filename, uid_t owner, gid_t group) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return fchownat(handle.root_fd, filename, owner, group, AT_SYMLINK_NOFOLLOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_truncate(const char *filename, off_t length) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
int fd = openat(handle.root_fd, relative_filename, NULL);
|
|
|
|
if (fd < 0) {
|
|
|
|
perror("Openat failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return ftruncate(fd, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_open(const char *filename, int flags) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return openat(handle.root_fd, relative_filename, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
int source_create(const char *filename, int flags, mode_t mode) {
|
|
|
|
const char *relative_filename = source_fname_translate(filename);
|
|
|
|
return openat(handle.root_fd, relative_filename, flags, mode);
|
2024-12-15 15:41:28 +01:00
|
|
|
}
|