diff options
| author | Tristan Riehs <tristan.riehs@inria.fr> | 2026-04-26 11:51:56 +0200 |
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@inria.fr> | 2026-04-26 11:53:41 +0200 |
| commit | d2fb6a8aac6abe5bfe4b4ea7f2528d119afbc8c6 (patch) | |
| tree | 611f03f03044f8f1210984d03b1cd28cd52016f2 /src/system.c | |
| parent | 34d935265e65b6b2a5c5dbdaf0c2cbcb97c205e1 (diff) | |
Create a "system" module
Also unify makefiles, otherwise dependencies are not properly resolved.
Diffstat (limited to 'src/system.c')
| -rw-r--r-- | src/system.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/system.c b/src/system.c new file mode 100644 index 0000000..df53e99 --- /dev/null +++ b/src/system.c @@ -0,0 +1,114 @@ +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/sendfile.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "system.h" + +int file_exists(const char *path) +{ + struct stat statbuf __attribute__((unused)); + int rc = stat(path, &statbuf); + if (rc == 0) + return 1; + else if ((rc == -1) && (errno == ENOENT)) + return 0; + fprintf(stderr, "stat: \"%s\": ", path); + perror(""); + exit(EXIT_FAILURE); +} + +void copy_file(const char *in, const char *out) +{ + int in_fd; + int out_fd; + int rc; + ssize_t written_bytes; + in_fd = open(in, O_RDONLY); + if (in_fd == -1) { + fprintf(stderr, "open: %s:", in); + perror(""); + exit(EXIT_FAILURE); + } + out_fd = open(out, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (out_fd == -1) { + fprintf(stderr, "open: %s:", out); + perror(""); + exit(EXIT_FAILURE); + } + while ((written_bytes = sendfile(out_fd, in_fd, NULL, 4096)) == 4096) + ; + if (written_bytes == -1) { + perror("sendfile"); + exit(EXIT_FAILURE); + } + rc = fchmod(out_fd, 0400); + if (rc == -1) { + fprintf(stderr, "chmod: %s: ", out); + perror(""); + exit(EXIT_FAILURE); + } + close(in_fd); + close(out_fd); +} + +void +copy_file_with_encryption(const char *in, const char *out, enum encrypt encrypt) +{ + char *crypt_param; + assert(encrypt == ENCRYPT || encrypt == DECRYPT); + if (encrypt == ENCRYPT) + crypt_param = "--encrypt"; + else + crypt_param = "--decrypt"; + /* use dups to suppress "discards const qualifier" warnings */ + char *in_dup = strdup(in); + char *out_dup = strdup(out); + char *cmd[] = { + "gpg", + "--output", out_dup, + "--yes", + crypt_param, in_dup, + NULL + }; + ftag_execvp(cmd, 1); + free(in_dup); + free(out_dup); +} + +int ftag_execvp(char *const *cmd, int can_exit) +{ + int status = 0; + int rc = fork(); + if (rc == 0) { + execvp(cmd[0], cmd); + fprintf(stderr, "exec: %s: ", cmd[0]); + perror(""); + } + else if (rc > 0) { + int status; + wait(&status); + if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { + fprintf(stderr, + "ftag: child process exited abnormally\n"); + if (can_exit) + exit(EXIT_FAILURE); + else + status = -1; + } + } + else { + perror("fork"); + if (can_exit) + exit(EXIT_FAILURE); + else + status = -1; + } + return status; +} |
