aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c78
1 files changed, 68 insertions, 10 deletions
diff --git a/src/main.c b/src/main.c
index 9581d6e..8501ec2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);