diff options
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 135 |
1 files changed, 86 insertions, 49 deletions
@@ -40,7 +40,8 @@ static void parse_args(int argc, const struct ftag_command *commands, int command_count); -static void __sqlite3_check(int rc, sqlite3 *db, const char *file, int line, const char *func) +static void __sqlite3_check(int rc, sqlite3 *db, + const char *file, int line, const char *func) { /* Note: "rc" stands for "return code" */ if (rc == SQLITE_OK) @@ -54,6 +55,15 @@ 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__) +static sqlite3 *ftag_db_open(void) +{ + const char *db_path = ftag_config_get(FC_DATABASE_PATH); + sqlite3 *db; + int rc = sqlite3_open(db_path, &db); + sqlite3_check(rc, db); + return db; +} + /* Convert heap-allocated *STR from C string to SQL string, essentially by * adding single quotes to escape single quotes. */ static void sanitize_sql_str(char **str) @@ -159,8 +169,7 @@ static void ftag_file_get_extension(char *out, int size, const char *file) strbuild(sql, "SELECT extension FROM files WHERE canonical_name = '%s';", file); - rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + db = ftag_db_open(); rc = sqlite3_exec(db, sql, ftag_file_get_extension_callback, &ext, NULL); sqlite3_check(rc, db); sqlite3_close(db); @@ -170,7 +179,8 @@ static void ftag_file_get_extension(char *out, int size, const char *file) static void ftag_file_get_path(char *out, int size, const char *file) { /* look for the encrypted version first */ - strbuild_with_size(out, size, "%s/files/%s.gpg", FTAG_CACHE_DIR, file); + strbuild_with_size(out, size, "%s/files/%s.gpg", + ftag_config_get(FC_CACHE_DIR), file); if (file_exists(out)) return; /* look for the clear version after */ @@ -267,21 +277,24 @@ static void ftag_export(int argc, char **argv) /* Create ftag's database and directories. */ static void ftag_init(int, char **) { - int rc = mkdir(FTAG_CACHE_DIR, 0755); + const char *cache_dir = ftag_config_get(FC_CACHE_DIR); + int rc = mkdir(cache_dir, 0755); if (rc == -1 && errno != EEXIST) { - fprintf(stderr, "mkdir: %s: ", FTAG_CACHE_DIR); + fprintf(stderr, "mkdir: %s: ", cache_dir); perror(""); exit(EXIT_FAILURE); } - rc = mkdir(FTAG_CACHE_DIR "/files", 0755); + char files_dir[512]; + strbuild(files_dir, "%s/files", cache_dir); + rc = mkdir(files_dir, 0755); if (rc == -1 && errno != EEXIST) { - fprintf(stderr, "mkdir: %s/files: ", FTAG_CACHE_DIR); + fprintf(stderr, "mkdir: %s: ", files_dir); perror(""); exit(EXIT_FAILURE); } char cmd_sqlite[1024]; strbuild(cmd_sqlite, "sqlite3 %s < %s", - DATABASE_PATH, FTAG_PREFIX "/share/ftag/sql/init.sql"); + ftag_config_get(FC_DATABASE_PATH), FTAG_PREFIX "/share/ftag/sql/init.sql"); char *cmd[] = { "sh", "-c", @@ -307,8 +320,7 @@ static void ftag_list_table(const char *table, const char *col) char sql[64]; sqlite3 *db = NULL; int rc; - rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + db = ftag_db_open(); strbuild(sql, "SELECT %s FROM %s;", col, table); rc = sqlite3_exec(db, sql, ftag_print, NULL, NULL); sqlite3_check(rc, db); @@ -343,6 +355,7 @@ ftag_add_one_file(sqlite3 *db, int *next_id, const char *file, uint32_t file_sum time_t date = time(NULL); size_t line_len = 0; ssize_t read_len; + const char *cache_dir = ftag_config_get(FC_CACHE_DIR); /* TODO: possibly be non-interactive Maybe take canonical_name, full_name, and description as @@ -436,11 +449,11 @@ ftag_add_one_file(sqlite3 *db, int *next_id, const char *file, uint32_t file_sum char new_path[512]; if (encrypt) { - strbuild(new_path, "%s/files/%s.gpg", FTAG_CACHE_DIR, canonical_name); + strbuild(new_path, "%s/files/%s.gpg", cache_dir, canonical_name); copy_file_with_encryption(file, new_path, ENCRYPT); } else { - strbuild(new_path, "%s/files/%s", FTAG_CACHE_DIR, canonical_name); + strbuild(new_path, "%s/files/%s", cache_dir, canonical_name); copy_file(file, new_path); } @@ -549,8 +562,7 @@ static void ftag_file_add(int argc, char **argv) /* step 2: retrieve sums of files already in the database */ sqlite3 *db; - rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + db = ftag_db_open(); int next_id = table_next_id(db, "files"); int file_count = next_id; /* number of files already in the database */ uint32_t known_sums_array[file_count]; @@ -658,8 +670,8 @@ static void ftag_file_tag(int argc, char **argv) const char *file = argv[0]; char sql[64]; sqlite3 *db; - int rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + int rc; + db = ftag_db_open(); int file_id = get_id_by_col(db, "files", "canonical_name", file); printf("%s: debug: file id is %d\n", __func__, file_id); for (int i = 1; i < argc; i++) { @@ -688,7 +700,10 @@ static void ftag_file(int argc, char **argv) static void ftag_help(int, char **) { - puts("Usage: ftag COMMAND [ARG]..."); + puts("Usage: ftag [OPTION]... COMMAND [ARG]..."); + puts("Available values for OPTION:"); + puts(" -c FILE use FILE as configuration file"); + puts(" -h display this help"); puts("Available values for COMMAND:"); puts(" init initialize the database"); puts(" file manage files"); @@ -698,11 +713,6 @@ static void ftag_help(int, char **) puts(" tag manage tags"); puts("Some commands also have their own help,"); puts("try \"ftag COMMAND help\" or \"ftag COMMAND -h\"."); - puts("Configuration:"); - printf(" cache %s\n", FTAG_CACHE_DIR); - printf(" config %s\n", FTAG_CONFIG_DIR); - printf(" prefix %s\n", FTAG_PREFIX); - printf(" version %s\n", FTAG_VERSION); } static void ftag_query_usage(void) @@ -815,8 +825,7 @@ static void ftag_query(int argc, char **argv) char sql[4096]; sqlite3 *db; int rc; - rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + db = ftag_db_open(); char sql_join[2048]; memset(sql_join, 0, sizeof(sql_join)); ftag_query_join(db, sql_join, sizeof(sql_join)-1, @@ -833,13 +842,16 @@ static void ftag_query(int argc, char **argv) static time_t get_remote_mtime(void) { - char *remote_path = FTAG_REMOTE_ROOT "/ftag.sqlite3"; + const char *remote_host = ftag_config_get(FC_REMOTE_HOST); + char remote_path[512]; + strbuild(remote_path, "%s/ftag.sqlite3", + ftag_config_get(FC_REMOTE_ROOT)); char cmd[1024]; strbuild(cmd, "ssh %s 'test -f %s && stat --format=%%Y %s || echo 0'", - FTAG_REMOTE_HOST, remote_path, remote_path); + remote_host, remote_path, remote_path); FILE *pipe = popen(cmd, "r"); if (!pipe) { - fprintf(stderr, "popen: ssh %s: ", FTAG_REMOTE_HOST); + fprintf(stderr, "popen: ssh %s: ", remote_host); perror(""); exit(EXIT_FAILURE); } @@ -852,7 +864,7 @@ static time_t get_remote_mtime(void) } int rc = pclose(pipe); if (rc == 1) { - fprintf(stderr, "pclose: ssh %s: ", FTAG_REMOTE_HOST); + fprintf(stderr, "pclose: ssh %s: ", remote_host); perror(""); exit(EXIT_FAILURE); } @@ -863,10 +875,11 @@ static time_t get_remote_mtime(void) static time_t get_local_mtime(void) { + const char *db_path = ftag_config_get(FC_DATABASE_PATH); struct stat st; - int rc = stat(DATABASE_PATH, &st); + int rc = stat(db_path, &st); if (rc == -1) { - fprintf(stderr, "stat: %s: ", DATABASE_PATH); + fprintf(stderr, "stat: %s: ", db_path); perror(""); exit(EXIT_FAILURE); } @@ -901,21 +914,27 @@ static void ftag_sync_help(int, char **) * non-zero, perform a push, else perform a pull. */ static void ftag_sync_run_rsync(int push) { - char remote_root[128]; - strbuild(remote_root, "%s:%s/", - FTAG_REMOTE_HOST, FTAG_REMOTE_ROOT); - char *first = remote_root; - char *second = FTAG_CACHE_DIR "/"; + const char *cache_dir = ftag_config_get(FC_CACHE_DIR); + const char *remote_host = ftag_config_get(FC_REMOTE_HOST); + const char *remote_root = ftag_config_get(FC_REMOTE_ROOT); + + char remote_path[128]; + strbuild(remote_path, "%s:%s/", remote_host, remote_root); + char local_path[128]; + strbuild(local_path, "%s/", cache_dir); + + char *src = remote_path; + char *dst = local_path; if (push) { - first = FTAG_CACHE_DIR "/"; - second = remote_root; + src = dst; + dst = src; } char *cmd[] = { "rsync", "--verbose", /* temporary */ "--archive", - first, - second, + src, + dst, NULL }; ftag_execvp(cmd, 1); @@ -977,8 +996,7 @@ static void ftag_tag_add(int argc, char **argv) sqlite3 *db; int rc; - rc = sqlite3_open(DATABASE_PATH, &db); - sqlite3_check(rc, db); + db = ftag_db_open(); strbuild(sql, "SELECT name, description FROM tags WHERE name = '%s';", new_tag_name); @@ -1050,17 +1068,10 @@ static void parse_args(int argc, int main(int argc, char *argv[]) { - if (argc == 1) { - ftag_help(0, NULL); - exit(EXIT_FAILURE); - } - const struct ftag_command toplevel_commands[] = { {.name = "export", .func = ftag_export}, {.name = "init", .func = ftag_init}, {.name = "file", .func = ftag_file}, - {.name = "-h", .func = ftag_help}, - {.name = "--help", .func = ftag_help}, {.name = "help", .func = ftag_help}, {.name = "query", .func = ftag_query}, {.name = "sync", .func = ftag_sync}, @@ -1074,6 +1085,32 @@ int main(int argc, char *argv[]) able to only transfer the new files, maybe using rsync. */ }; const int toplevel_command_count = sizeof(toplevel_commands) / sizeof(struct ftag_command); + const char* config_file = NULL; + const char *optstring = "c:h"; + int opt; + + while ((opt = getopt(argc, argv, optstring)) != -1) { + switch (opt) { + case 'h': + ftag_help(0, NULL); + exit(EXIT_SUCCESS); + case 'c': + config_file = optarg; + break; + case'?': + default: + ftag_help(0, NULL); + exit(EXIT_FAILURE); + } + } + + if (optind == argc) { + ftag_help(0, NULL); + exit(EXIT_FAILURE); + } + +#error "Resume here, read the config file before doing anything" + parse_args(argc-1, argv+1, toplevel_commands, toplevel_command_count); return EXIT_SUCCESS; } |
