diff options
| author | Tristan Riehs <tristan.riehs@inria.fr> | 2025-11-11 22:07:29 +0100 |
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@inria.fr> | 2025-11-11 22:07:29 +0100 |
| commit | d1421b18f095c04c16123cde0e0799426b2944e1 (patch) | |
| tree | 6227ac6084c24107ab28280fb77709d7fc40df07 /src/main.c | |
| parent | a8d819e1f6b66b04503c1c12687245d88e435d91 (diff) | |
Make some more progress on "ftag file add"
The ID of added files has to be properly managed.
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 78 |
1 files changed, 68 insertions, 10 deletions
@@ -1,10 +1,13 @@ #include <assert.h> #include <errno.h> +#include <fcntl.h> #include <sqlite3.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/sendfile.h> #include <sys/stat.h> +#include <time.h> #include <unistd.h> #define DATABASE_PATH (FTAG_ROOT "/ftag.sqlite3") @@ -69,6 +72,11 @@ static void assert_no_single_quote(const char *str) static void ftag_init(int, char **) { + int rc = mkdir(FTAG_ROOT "/files", 0755); + if (rc == -1) { + perror(FTAG_ROOT "/files"); + exit(EXIT_FAILURE); + } char cmd[1024]; memset(cmd, 0, sizeof(cmd)); snprintf(cmd, sizeof(cmd)-1, @@ -101,11 +109,13 @@ static void ftag_list_table(const char *table, const char *col) sqlite3_close(db); } +/* Write to OUT a version of IN that does not contain any blank or uppercase + * letter. */ static void canonicalize(char *out, const char *in) { int i; for (i = 0; i < strlen(in)-1; i++) { - if (in[i] > 'A' && in[i] < 'Z') + if (in[i] >= 'A' && in[i] <= 'Z') out[i] = in[i] - 'A' + 'a'; else if (in[i] == ' ') out[i] = '_'; @@ -124,6 +134,7 @@ static void ftag_add_one_file(sqlite3 *db, char *full_name = NULL; char *canonical_name = NULL; char *description = NULL; + char *date = NULL; size_t line_len = 0; ssize_t read_len; @@ -150,37 +161,83 @@ static void ftag_add_one_file(sqlite3 *db, printf("Enter the canonical name, a version of the name that\n" "ideally contains no blank and, if possible, no upper\n" "case letters and no symbols. If no input is given,\n" - "canonical name will be \"%s\".", canonical_name); + "canonical name will be \"%s\".\n", canonical_name); read_len = getline(&canonical_name, &line_len, stdin); if (read_len == -1) { perror("getline"); exit(EXIT_FAILURE); } + if (canonical_name[0] == '\n') + canonicalize(canonical_name, full_name); assert_no_single_quote(canonical_name); - printf("Enter the description."); + printf("Enter the description.\n"); line_len = 0; read_len = getline(&description, &line_len, stdin); if (read_len == -1) { perror("getline"); exit(EXIT_FAILURE); } + if (!description) + description = strdup(""); assert_no_single_quote(description); + line_len = 32; + date = malloc(line_len); + time_t now = time(NULL); + struct tm *now_tm = localtime(&now); + strftime(date, line_len-1, "%Y-%m-%d", now_tm); + printf("Enter the date in the format YYYY-MM-DD. If no input is\n" + "given, date will be \"%s\".\n", date); + read_len = getline(&date, &line_len, stdin); + if (read_len == -1) { + perror("getline"); + exit(EXIT_FAILURE); + } + if (date[0] == '\n') + strftime(date, line_len-1, "%Y-%m-%d", now_tm); + memset(sql, 0, sizeof(sql)); snprintf(sql, sizeof(sql)-1, - "INSERT INTO files VALUES(%d, '%s', '%s', '%s')", - *last_id, - canonical_name, - full_name, - description); + "INSERT INTO files VALUES(%d, '%s', '%s', '%s', '%s')", + *last_id, canonical_name, full_name, description, date); rc = sqlite3_exec(db, sql, NULL, NULL, NULL); sqlite3_check(rc, db); (*last_id)++; + + char new_path[512]; + memset(new_path, 0, sizeof(new_path)); + snprintf(new_path, sizeof(new_path)-1, + "%s/files/%s", FTAG_ROOT, canonical_name); + int out_fd = open(new_path, O_WRONLY | O_CREAT, 0644); + + if (out_fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + + int in_fd = open(file, O_RDONLY); + + if (in_fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + + ssize_t written_bytes; + while ((written_bytes = sendfile(out_fd, in_fd, NULL, 4096)) == 4096) + ; + + if (written_bytes == -1) { + perror("sendfile"); + exit(EXIT_FAILURE); + } + + free(now_tm); + close(in_fd); + close(out_fd); free(full_name); free(canonical_name); - if(description) - free(description); + free(description); } /* Add new files to the database. */ @@ -195,6 +252,7 @@ static void ftag_file_add(int argc, char **argv) int last_id; rc = sqlite3_open(DATABASE_PATH, &db); sqlite3_check(rc, db); + /* TODO: set last_id properly */ for (int i = 0; i < argc; i++) ftag_add_one_file(db, &last_id, argv[i]); sqlite3_close(db); |
