aboutsummaryrefslogtreecommitdiff
path: root/src/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/system.c')
-rw-r--r--src/system.c114
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;
+}