diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 11 | ||||
| -rw-r--r-- | src/main.c | 122 | ||||
| -rw-r--r-- | src/system.c | 114 | ||||
| -rw-r--r-- | src/system.h | 30 |
4 files changed, 146 insertions, 131 deletions
diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 0c8782d..0000000 --- a/src/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -$(PROG): main.o - $(CC) -o $@ $^ $(__LIBS) $(LDFLAGS) $(LIBS) - -main.o: main.c -.c.o: - $(CC) $(__CFLAGS) $(CFLAGS) -c $< - -clean: - rm -f main.o $(PROG) - -.PHONY: clean @@ -6,12 +6,12 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <sys/sendfile.h> #include <sys/stat.h> -#include <sys/wait.h> #include <time.h> #include <unistd.h> +#include "system.h" + #ifndef FTAG_REMOTE_HOST #define FTAG_REMOTE_HOST "localhost" #endif @@ -23,13 +23,6 @@ #define DATABASE_PATH FTAG_CACHE_DIR "/ftag.sqlite3" -/* Used when encrypting or decrpyting a file, see the copy_encrypted_file - * function. */ -enum encrypt { - ENCRYPT, - DECRYPT, -}; - /* TODO: read the configuration from a file This would allow working with different databases with the same ftag @@ -69,21 +62,6 @@ static void __sqlite3_check(int rc, sqlite3 *db, const char *file, int line, con #define sqlite3_check(RC, DB) \ __sqlite3_check(RC, DB, __FILE__, __LINE__, __func__) -/* Return whether PATH exists in the file system. Exit if any non-"file not - * fount" error occurs. */ -static 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); -} - static void assert_db_exists(void) { if (file_exists(DATABASE_PATH)) @@ -101,102 +79,6 @@ static void assert_db_exists(void) exit(EXIT_FAILURE); } -/* Execute command in a child process, then wait for the child to exit before - * returning. If any error occurs, including in the child process, then if EXIT - * is non-zero, exit, else return -1. Return 0 on success. */ -static 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; -} - -/* Copy the file whose path is IN at path OUT. OUT is created or overwritten if - * needed. */ -static 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); -} - -/* Like copy_file, but OUT is an encrypted version of IN. Encryption is done - * using GPG. */ -static 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); -} - /* Prompt the user for yes or no (default is yes). Before calling, a prompt * should be printed to stdout, eventually not with an ending newline. */ static int prompt_yes_no(void) 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; +} diff --git a/src/system.h b/src/system.h new file mode 100644 index 0000000..950a82a --- /dev/null +++ b/src/system.h @@ -0,0 +1,30 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + +/* Routines for interacting with the system, mainly executing processes and + * dealing with the file system. */ + +/* Used when encrypting or decrypting a file, see the copy_file_with_encryption + * function. */ +enum encrypt { + ENCRYPT, + DECRYPT +}; + +/* Return whether PATH exists in the file system. Exit if any non-"file not + * fount" error occurs. */ +int file_exists(const char *path); + +/* Copy the file whose path is IN at path OUT. OUT is created or overwritten if + * needed. */ +void copy_file(const char *in, const char *out); + +/* Like copy_file but with encryption, which is managed using GPG. */ +void copy_file_with_encryption(const char *in, const char *out, enum encrypt encrypt); + +/* Execute command in a child process, then wait for the child to exit before + * returning. If any error occurs, including in the child process, then if EXIT + * is non-zero, exit, else return -1. Return 0 on success. */ +int ftag_execvp(char *const *cmd, int can_exit); + +#endif |
