aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt16
-rw-r--r--src/actionhelper.c373
-rw-r--r--src/actionhelper.h68
-rw-r--r--src/actions.c78
-rw-r--r--src/actions.h25
-rw-r--r--src/add.c287
-rw-r--r--src/ck.c3
-rw-r--r--src/ckerrlog.c2
-rw-r--r--src/ckutil.c14
-rw-r--r--src/ckutil.h6
-rw-r--r--src/clparser.c2
-rw-r--r--src/dblayer.c830
-rw-r--r--src/dblayer.h55
-rw-r--r--src/delete.c176
-rw-r--r--src/edit.c91
-rw-r--r--src/init.c62
-rw-r--r--src/list.c206
-rw-r--r--src/queries.c (renamed from src/dbhelper.c)4
-rw-r--r--src/queries.h (renamed from src/dbhelper.h)2
-rw-r--r--src/restore.c114
-rw-r--r--test/05_restore46
21 files changed, 1186 insertions, 1274 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d88de5..65490cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,7 @@ project(ck C)
# version
set(ck_MAJOR_VERSION 0)
set(ck_MINOR_VERSION 9)
-set(ck_PATCH_VERSION 1)
+set(ck_PATCH_VERSION 2)
# Feature test macros
set(FEATURE_TEST_MACROS "-D_DEFAULT_SOURCE")
@@ -57,22 +57,26 @@ set(ckUnitTest_src ${UNIT_TEST_DIR}/ck-test.c)
set(ckLib_src
${SRC_DIR}/clparser.c
${SRC_DIR}/actions.c
- ${SRC_DIR}/actionhelper.c
${SRC_DIR}/confparser.c
${SRC_DIR}/dblayer.c
- ${SRC_DIR}/dbhelper.c
+ ${SRC_DIR}/queries.c
${SRC_DIR}/ckutil.c
${SRC_DIR}/cklist.c
${SRC_DIR}/ckerrlog.c
+ ${SRC_DIR}/init.c
+ ${SRC_DIR}/add.c
+ ${SRC_DIR}/delete.c
+ ${SRC_DIR}/edit.c
+ ${SRC_DIR}/list.c
+ ${SRC_DIR}/restore.c
)
set(ckLib_hdr
${SRC_DIR}/clparser.h
${SRC_DIR}/actions.h
- ${SRC_DIR}/actionhelper.h
${SRC_DIR}/confparser.h
${SRC_DIR}/dblayer.h
- ${SRC_DIR}/dbhelper.h
+ ${SRC_DIR}/queries.h
${SRC_DIR}/ckutil.h
${SRC_DIR}/cklist.h
${SRC_DIR}/ckinfo.h
@@ -123,8 +127,8 @@ if (CK_TESTS)
configure_file(${TEST_DIR}/01_add ${BIN_TEST_DIR}/01_add @ONLY)
configure_file(${TEST_DIR}/02_list ${BIN_TEST_DIR}/02_list @ONLY)
configure_file(${TEST_DIR}/03_delete ${BIN_TEST_DIR}/03_delete @ONLY)
- configure_file(${TEST_DIR}/03_delete ${BIN_TEST_DIR}/03_delete @ONLY)
configure_file(${TEST_DIR}/04_search ${BIN_TEST_DIR}/04_search @ONLY)
+ configure_file(${TEST_DIR}/05_restore ${BIN_TEST_DIR}/05_restore @ONLY)
# test-ck
configure_file(${RES_DIR}/test-ck test-ck @ONLY)
endif()
diff --git a/src/actionhelper.c b/src/actionhelper.c
deleted file mode 100644
index 6cc37bd..0000000
--- a/src/actionhelper.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* actionhelper.c - helper routines for ck actions --------------------*- C -*-
- *
- * This file is part of ck, the config keeper
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2018 Anastasis Grammenos
- * GPLv3 (see LICENCE for the full notice)
- *
- * -------------------------------------------------------------------------- */
-#include <libgen.h>
-
-#include "actionhelper.h"
-#include "confparser.h"
-#include "ckerrlog.h"
-
-ERRLOG(action);
-
-char add_err[STR_M] = "";
-
-int add_err_message(char *err) {
- if (!str_is_empty(add_err)) {
- if (err) {
- strcpy(err, add_err);
- }
- return 1;
- }
- return 0;
-}
-
-void link_config(const AddOpt *opt, const char* newPath) {
- printf("Linking %s -> %s\n", newPath, opt->confPath);
- if (util_symlink_file(newPath, opt->confPath) != 0) {
- strcpy(add_err, "Could not link file.");
- }
-}
-
-int move_config(const AddOpt *opt, char *progDir, char *ret) {
- char newPath[STR_L] = "";
- char *tmp = strdup(opt->confPath);
- str_join_dirname_with_basename(newPath, progDir, basename(tmp));
- free(tmp);
- if (util_file_exists(newPath, NULL)) {
- strcpy(add_err, "File already exists");\
- return -1;
- }
- strcpy(ret, newPath);
- printf("Moving %s -> %s\n", opt->confPath, newPath);
- if (util_move_file(opt->confPath, newPath) != 0) {
- strcpy(add_err, "Could not move file.");
- return -1;
- }
- return 0;
-}
-
-AddOpt add_make_options(cklist *args) {
- list_rewind(args);
- /* since we are here, the first two arguments must exist */
- AddOpt addOpt = {
- .progName = list_get(args),
- .secret = 0,
- .prime = 0,
- .err = ADD_NO_ERR
- };
-
- list_next(args);
- if (!util_is_file_rw(list_get(args))
- || !util_is_file_link(list_get(args))) {
- addOpt.err = ADD_ERR_WRONG_CONFIG;
- return addOpt;
- }
- realpath(list_get(args), addOpt.confPath);
-
- while (list_next(args)) {
- if (strcmp(list_get(args), "-s") == 0 && addOpt.secret == 0) {
- addOpt.secret = 1;
- } else if (strcmp(list_get(args), "-p") == 0 && addOpt.prime == 0) {
- addOpt.prime = 1;
- } else {
- addOpt.err = ADD_ERR_WRONG_FLAGS;
- return addOpt;
- }
- }
- list_rewind(args);
- return addOpt;
-}
-
-void add_print_opts(AddOpt *opt) {
- printf("Program:\t%s\nConfig:\t\t%s\n", opt->progName, opt->confPath);
- if (opt->prime && opt->secret) {
- printf("Options:\tsecret, primary\n");
- } else if (opt->prime) {
- printf("Options:\tprimary\n");
- } else if (opt->secret) {
- printf("Options:\tsecret\n");
- }
-}
-
-void get_or_make_program_dir(const AddOpt *opt, const Conf *conf, char *ret) {
- char tmp[STR_L] = "";
- str_join_dirname_with_basename(tmp, opt->secret ? conf->scrt_dir : conf->vc_dir, opt->progName);
- if (!util_file_exists(tmp, NULL)) {
- util_mkdir(tmp);
- }
- strcpy(ret, tmp);
-}
-
-void add_make_link(const AddOpt *opt, const Conf *conf) {
- char progDir[STR_L] = "";
- get_or_make_program_dir(opt, conf, progDir);
- char newPath[STR_L] = "";
- move_config(opt, progDir, newPath);
- if (add_err_message(NULL)) {
- return;
- }
- link_config(opt, newPath);
- if (add_err_message(NULL)) {
- return;
- }
-}
-
-void edit_print_suggested_configs(DB *db, const char *pName) {
- char name[STR_M] = "";
- strcat(name, pName);
- strcat(name, ":");
- cklist *paths = list_make_and_add(name);
- get_program_paths(db, paths, pName, 1, 0, NULL);
- list_print(paths);
- list_free(paths);
-}
-
-int init_create_config_file(UserOpt *opt) {
- char absVCdir[STR_L] = "";
- if (!util_file_exists(list_get_at(opt->args, 0), absVCdir)) {
- ERR("Version control directory: %s does not exist.", list_get_at(opt->args, 0));
- return 1;
- }
-
- char absSRdir[STR_L] = "";
- if (!util_file_exists(list_get_at(opt->args, 1), absSRdir)) {
- ERR("Secret directory: %s does not exist.", list_get_at(opt->args, 1));
- return 1;
- }
-
- if (!util_file_exists(opt->confDir, NULL)) {
- util_mkdir(opt->confDir);
- }
-
- char confName[STR_L] = "";
- make_config_name(confName, opt->confDir);
- FILE *f;
- if ((f = fopen(confName, "w")) == NULL) {
- return 1;
- }
-
- char tmp[STR_L] = "";
- strcpy(tmp, "version_control_dir = ");
- strcat(tmp, absVCdir);
- strcat(tmp, "\n");
- fputs(tmp, f);
-
- strcpy(tmp, "secret_dir = ");
- strcat(tmp, absSRdir);
- strcat(tmp, "\n");
- fputs(tmp, f);
-
- strcpy(tmp, "home_dir = ");
- strcat(tmp, getenv("HOME"));
- strcat(tmp, "\n");
- fputs(tmp, f);
-
- fclose(f);
- return 0;
-}
-
-ListOpt list_make_options(cklist *args) {
- list_rewind(args);
- ListOpt listOpt = {
- ._lt = LT_TREE,
- ._lst = LST_PLAIN,
- .pName = NULL,
- .attr = 0,
- .bName = 0,
- .err = 0
- };
-
- if (list_size(args)) {
- do {
- if (strcmp(list_get(args), "-a") == 0) {
- listOpt.attr = 1;
- continue;
- }
- if (strcmp(list_get(args), "-b") == 0) {
- listOpt.bName = 1;
- continue;
- }
- if (strcmp(list_get(args), "-t") == 0) {
- if (!list_next(args)) {
- listOpt.err = 1;
- break;
- }
- if (strcmp(list_get(args), "plain") == 0) {
- listOpt._lst = LST_PLAIN;
- }
- else if (strcmp(list_get(args), "lisp") == 0) {
- listOpt._lst = LST_LISP;
- }
- else if (strcmp(list_get(args), "python") == 0) {
- listOpt._lst = LST_PYTHON;
- }
- else {
- listOpt.err = 1;
- }
- }
- else if (strcmp(list_get(args), "paths") == 0) {
- listOpt._lt = LT_PATH;
- }
- else if (strcmp(list_get(args), "programs") == 0) {
- listOpt._lt = LT_PROGRAM;
- }
- else if (strcmp(list_get(args), "tree") == 0) {
- listOpt._lt = LT_TREE;
- }
- else if (strcmp(list_get(args), "ckconf") == 0) {
- listOpt._lt = LT_CKCONF;
- }
- else if (strcmp(list_get(args), "-p") == 0) {
- if (list_next(args)) {
- listOpt._lt = LT_PROG_CONFS;
- listOpt.pName = list_get(args);
- }
- else {
- listOpt.err = 1;
- break;
- }
- }
- else {
- listOpt.err = 1;
- }
- } while(list_next(args));
- }
- list_rewind(args);
- return listOpt;
-}
-
-int restore_make_links(cklist *from, cklist *to) {
- list_rewind(from);
- list_rewind(to);
- if (list_size(from) > 0
- && list_size(to) > 0
- && list_size(from) == list_size(to)) {
- do {
- if (util_file_exists(list_get(to), NULL)
- || !util_is_file_link(list_get(to))) {
- ERR("File %s already exists.", list_get(to));
- sERR("No links were created.");
- return -1;
- }
- } while (list_next(to));
- list_rewind(to);
- while (1) {
- if (util_symlink_file(list_get(from), list_get(to))) {
- ERR("FATAL could not link %s -> %s", list_get(from), list_get(to));
- sERR("Process stopping.");
- return -1;
- }
- hLOG("Linking: %s -> %s", list_get(from), list_get(to));
- if (util_own_grp_copy(list_get(to), list_get(from))) {
- return -1;
- }
- if (!list_next(from)) {
- break;
- }
- if (!list_next(to)) {
- break;
- }
- }
- }
- return 0;
-}
-
-/*****************/
-/* PRINT RESULTS */
-/*****************/
-
-void print_INIT_result(int err) {
- if (!err) {
- hLOG("Initialized empty ckdb.");
- }
-}
-
-void print_ADD_result(int err) {
- if (!err) {
- hLOG("ckdb updated succesfully.");
- return;
- }
- sERR("Could not complete add transaction.");
-}
-
-void print_DEL_result(int err) {
- if (!err) {
- hLOG("ckdb updated succesfully.");
- return;
- }
- sERR("Could not complete delete transaction.");
-}
-
-void print_EDIT_result(int err) {
- UNUSED(err);
-}
-
-void print_LIST_result(int err) {
- UNUSED(err);
-}
-
-void print_SEARCH_result(int err) {
- UNUSED(err);
-}
-
-void print_HELP_result(int err) {
- UNUSED(err);
-}
-
-void print_RESTORE_result(int err) {
- UNUSED(err);
-}
-
-void print_INIT_help() {
- HELP("ck init VERSION_CONTROL_DIR SECRET_DIR");
-}
-
-void print_ADD_help() {
- HELP("ck add PROGRAM_NAME CONFIG_PATH [-p] [-s]");
-}
-
-void print_DEL_help() {
- HELP("ck delete PROGRAM_NAME [CONFIG_BASENAME]");
-}
-
-void print_EDIT_help() {
- HELP("ck edit PROGRAM_NAME [CONFIG_BASENAME]");
-}
-
-void print_LIST_help() {
- ckhelp("ck list tree [-a] [-b]");
- ckhelp("ck list -p PROGRAM_NAME [-t list-type] [-a] [-b]");
- ckhelp("ck list programs [-t list-type] [-a] [-b]");
- ckhelp("ck list paths [-t list-type] [-a] [-b]");
- ckhelp("ck list ckconf");
- report_help();
-}
-
-void print_SEARCH_help() {
- HELP("ck search SEARCH_TERM");
-}
-
-void print_HELP_help() {
- HELP("ck help action");
-}
-
-void print_RESTORE_help() {
- ckhelp("ck restore -p PROGRAM_NAME");
- ckhelp("ck restore all");
- report_help();
-}
-
-void print_conf_help(void) {
- HELP("ck [-v|--verbose] [-c|--config DIR] action [...]");
-}
-
-void print_verbose_help(void) {
- HELP("ck [-v|--verbose] [-c|--config DIR] action [...]");
-}
diff --git a/src/actionhelper.h b/src/actionhelper.h
deleted file mode 100644
index f7da0dd..0000000
--- a/src/actionhelper.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* actionhelper.h - helper routines for ck actions --------------------*- C -*-
- *
- * This file is part of ck, the config keeper
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2018 Anastasis Grammenos
- * GPLv3 (see LICENCE for the full notice)
- *
- * -----------------------------------------------------------------------------
- *
- * Here reside helper routines for the actions.
- *
- * -------------------------------------------------------------------------- */
-#ifndef ACTIONHELPER_H
-#define ACTIONHELPER_H
-
-#include "actions.h"
-#include "ckutil.h"
-#include "cklist.h"
-#include "dblayer.h"
-
-/********/
-/* INIT */
-/********/
-
-int init_create_config_file(UserOpt *opt);
-
-/*******/
-/* ADD */
-/*******/
-
-/* if add_err is set, return true
- * along with a copy of the error message.
- * Pass NULL if you don't care about the message */
-int add_err_message(char *err);
-AddOpt add_make_options(cklist *args);
-void add_print_opts(AddOpt *opt);
-void add_make_link(const AddOpt *opt, const Conf *conf);
-
-/********/
-/* EDIT */
-/********/
-void edit_print_suggested_configs(DB *db, const char *pName);
-
-/********/
-/* LIST */
-/********/
-ListOpt list_make_options(cklist *args);
-
-/***********/
-/* RESTORE */
-/***********/
-int restore_make_links(cklist *from, cklist *to);
-
-/************************/
-/* PRINT RESULTS & HELP */
-/************************/
-#define X(ACTION) \
- void print_##ACTION##_result(int err); \
- void print_##ACTION##_help(void);
-CK_ACTIONS
-#undef X
-
-void print_conf_help(void);
-void print_verbose_help(void);
-
-#endif /* ACTIONHELPER_H */
diff --git a/src/actions.c b/src/actions.c
index 882fa30..c977aee 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -8,10 +8,7 @@
* GPLv3 (see LICENCE for the full notice)
*
* -------------------------------------------------------------------------- */
-#include "actions.h"
-#include "actionhelper.h"
#include "dblayer.h"
-#include "ckutil.h"
#include "cklist.h"
#include "ckerrlog.h"
@@ -28,10 +25,12 @@ int run_INIT(UserOpt * opt, Conf *conf) {
return -1;
}
DB db;
- if (!init_make_DB(&db, opt)) {
- init_make_tables(&db);
+ if (open_DB(&db, opt)) {
+ return -1;
}
+ init_make_tables(&db);
sqlite3_close(db.ptr);
+ hLOG("Initialized empty ckdb.");
return 0;
}
@@ -56,15 +55,14 @@ int run_ADD(UserOpt * opt, Conf *conf) {
if (add_transaction_try(&db, &addOpt, conf->home_dir)) {
goto error;
}
- add_make_link(&addOpt, conf);
- char err[STR_M] = "";
- if (add_err_message(err)) {
- PRINT_ERR(err);
+ if (add_make_link(&addOpt, conf)) {
error:
close_DB(&db);
+ sERR("Could not complete add transaction.");
return -1;
}
close_DB(&db);
+ hLOG("ckdb updated succesfully.");
return 0;
}
@@ -93,11 +91,16 @@ int run_DEL(UserOpt * opt, Conf *conf) {
rc = del_transaction_try(&db, pName, cName);
if (rc) {
HELP("Program %s doesn't have a config named %s", pName, cName);
- edit_print_suggested_configs(&db, pName);
+ print_suggested_configs(&db, pName);
}
}
error:
close_DB(&db);
+ if (!rc) {
+ hLOG("ckdb updated succesfully.");
+ } else {
+ sERR("Could not complete delete transaction.");
+ }
return rc;
}
@@ -131,7 +134,7 @@ int run_EDIT(UserOpt *opt, Conf *conf) {
/* If the program has many configs */
else {
HELP("Ambiguous config. Please type the config name after the program.");
- edit_print_suggested_configs(&db, pName);
+ print_suggested_configs(&db, pName);
goto error;
}
}
@@ -141,7 +144,7 @@ int run_EDIT(UserOpt *opt, Conf *conf) {
char *cName = list_get(opt->args);
if (edit_get_config(&db, pName, confName, cName, &secret)) {
ERR("Program %s doesn't have a config named %s", pName, cName);
- edit_print_suggested_configs(&db, pName);
+ print_suggested_configs(&db, pName);
goto error;
}
}
@@ -360,3 +363,54 @@ int run_RESTORE(UserOpt *opt, Conf *conf) {
list_free(to);
return rc;
}
+
+/**************/
+/* PRINT HELP */
+/**************/
+
+void print_INIT_help() {
+ HELP("ck init VERSION_CONTROL_DIR SECRET_DIR");
+}
+
+void print_ADD_help() {
+ HELP("ck add PROGRAM_NAME CONFIG_PATH [-p] [-s]");
+}
+
+void print_DEL_help() {
+ HELP("ck delete PROGRAM_NAME [CONFIG_BASENAME]");
+}
+
+void print_EDIT_help() {
+ HELP("ck edit PROGRAM_NAME [CONFIG_BASENAME]");
+}
+
+void print_LIST_help() {
+ ckhelp("ck list tree [-a] [-b]");
+ ckhelp("ck list -p PROGRAM_NAME [-t list-type] [-a] [-b]");
+ ckhelp("ck list programs [-t list-type] [-a] [-b]");
+ ckhelp("ck list paths [-t list-type] [-a] [-b]");
+ ckhelp("ck list ckconf");
+ report_help();
+}
+
+void print_SEARCH_help() {
+ HELP("ck search SEARCH_TERM");
+}
+
+void print_HELP_help() {
+ HELP("ck help action");
+}
+
+void print_RESTORE_help() {
+ ckhelp("ck restore -p PROGRAM_NAME");
+ ckhelp("ck restore all");
+ report_help();
+}
+
+void print_conf_help(void) {
+ HELP("ck [-v|--verbose] [-c|--config DIR] action [...]");
+}
+
+void print_verbose_help(void) {
+ HELP("ck [-v|--verbose] [-c|--config DIR] action [...]");
+}
diff --git a/src/actions.h b/src/actions.h
index d261cc6..2015538 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -67,4 +67,29 @@ struct ListOptions {
int err;
};
+/* init.c */
+int init_create_config_file(UserOpt *opt);
+
+/* add.c */
+AddOpt add_make_options(cklist *args);
+void add_print_opts(AddOpt *opt);
+int add_make_link(const AddOpt *opt, const Conf *conf);
+
+/* list.c */
+ListOpt list_make_options(cklist *args);
+
+/* restore.c */
+int restore_make_links(cklist *from, cklist *to);
+
+/************************/
+/* PRINT RESULTS & HELP */
+/************************/
+#define X(ACTION) \
+ void print_##ACTION##_help(void);
+CK_ACTIONS
+#undef X
+
+void print_conf_help(void);
+void print_verbose_help(void);
+
#endif /* ACTIONS_H */
diff --git a/src/add.c b/src/add.c
new file mode 100644
index 0000000..f7a49bf
--- /dev/null
+++ b/src/add.c
@@ -0,0 +1,287 @@
+#include <libgen.h>
+
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+ERRLOG(add);
+
+static int get_next_valid_id_from_table(DB *db, const char* tableName) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_select_id_from(sql, tableName);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+ sqlite3_bind_text(stmt, 1, tableName, (int)strlen(tableName), 0);
+
+ int id = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ int a = sqlite3_column_int(stmt, 0);
+ if (a != id) {
+ break;
+ }
+ id++;
+ }
+ sqlite3_finalize(stmt);
+ return id;
+}
+
+static int insert_to_program_table(DB *db, const char *name) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_L] = "";
+ dbh_form_query_insert_program(sql);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ ERR("while preparing insert to program sql.");
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ int id = get_next_valid_id_from_table(db, TBL_PROGRAM);
+ if (id == -1) {
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, id);
+ sqlite3_bind_text(stmt, 2, name, (int)strlen(name), 0);
+ if (sqlite3_step(stmt) != SQLITE_DONE) {
+ ERR("while excecuting insert to program sql.");
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ sqlite3_finalize(stmt);
+ return id;
+}
+
+static int insert_to_config_table(DB *db, const char *path, const int secret, const int prime) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_L] = "";
+ dbh_form_query_insert_config(sql);
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ ERR("Error while preparing insert to config sql.");
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ int id = get_next_valid_id_from_table(db, TBL_CONFIG);
+ if (id == -1) {
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, id);
+ sqlite3_bind_text(stmt, 2, path, (int)strlen(path), 0);
+ sqlite3_bind_int(stmt, 3, secret);
+ sqlite3_bind_int(stmt, 4, prime);
+ if (sqlite3_step(stmt) != SQLITE_DONE) {
+ ERR("Error while excecuting insert to config sql.");
+ db->error = SQL_ERR_SQLITE;
+ return-1;
+ }
+ sqlite3_finalize(stmt);
+ return id;
+}
+
+static int add_get_or_insert_config_to_db(DB *db, const int pid, const char *path, const int secret, const int prime, const char *home) {
+ char tpath[STR_L] = "";
+ if (!swap_home_with_tilde(tpath, path, home)) {
+ strcpy(tpath, path);
+ }
+ int cid = get_config_id(db, tpath);
+ if (cid == -2) {
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ /* If config doesnt exist insert it and return it's cid */
+ if (cid == -1) {
+ if (program_has_primary_config(db, pid, NULL, NULL) && prime) {
+ db->error = SQL_ERR_PRIMARY_REDEFINITION;
+ return -1;
+ }
+ return insert_to_config_table(db, tpath, secret, prime);
+ }
+
+ /* If it exist it means the user has inserted the same path twice */
+ db->error = SQL_CONFIG_PATH_EXISTS;
+ return -1;
+}
+
+static int add_get_or_insert_program_to_db(DB *db, const char *name) {
+ int pid = get_program_id(db, name);
+ if (pid == -2) {
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+ if (pid == -1) {
+ return insert_to_program_table(db, name);
+ }
+ return pid;
+}
+
+static int add_basename_exists(DB *db, const char *pName, const char *path) {
+ cklist *baseNames = list_make_new();
+ get_program_paths(db, baseNames, pName, 1 /*basename */, 0, NULL);
+ char *tmp = strdup(path);
+ int rc = list_exists(baseNames, basename(tmp));
+ free(tmp);
+ list_free(baseNames);
+ return rc;
+}
+
+static int add_insert_relationship(DB *db, const int pid, const int cid) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dhb_form_query_insert_relationship(sql);
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ db->error = SQL_ERR_SQLITE;
+ ERR("while preparing insert to rel sql.");
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, pid);
+ sqlite3_bind_int(stmt, 2, cid);
+ if (sqlite3_step(stmt) != SQLITE_DONE) {
+ db->error = SQL_ERR_SQLITE;
+ ERR("while excecuting insert to rel sql.");
+ return-1;
+ }
+ sqlite3_finalize(stmt);
+ return 1;
+}
+
+int add_transaction_try(DB *db, const AddOpt * const opt, const char *home) {
+ __BEGIN_TRANSACTION__
+ int pid = add_get_or_insert_program_to_db(db, opt->progName);
+ if (db->error == SQL_ERR_SQLITE) {
+ ERR("Could not insert program to db.");
+ return 1;
+ }
+ if (add_basename_exists(db, opt->progName, opt->confPath)) {
+ ERR("Cannot have two configs with the same basename, for the same program.");
+ return 1;
+ }
+ int cid = add_get_or_insert_config_to_db(db, pid, opt->confPath, opt->secret, opt->prime, home);
+ if (db->error == SQL_ERR_SQLITE) {
+ ERR("Could not insert config to db.");
+ return 1;
+ }
+ else if (db->error == SQL_CONFIG_PATH_EXISTS) {
+ ERR("This config already exists in the database.");
+ return 1;
+ }
+ else if (db->error == SQL_ERR_PRIMARY_REDEFINITION) {
+ ERR("This program already has a primary config.");
+ return 1;
+ }
+ add_insert_relationship(db, pid, cid);
+ if (db->error == SQL_ERR_SQLITE) {
+ ERR("rel update failed\n");
+ return 1;
+ }
+ __END_TRANSACTION__
+
+ return 0;
+}
+
+static int link_config(const AddOpt *opt, const char* newPath) {
+ hLOG("Linking %s -> %s\n", newPath, opt->confPath);
+ if (util_symlink_file(newPath, opt->confPath) != 0) {
+ ERR("Could not link file.");
+ return -1;
+ }
+ return 0;
+}
+
+static int move_config(const AddOpt *opt, char *progDir, char *ret) {
+ char newPath[STR_L] = "";
+ char *tmp = strdup(opt->confPath);
+ str_join_dirname_with_basename(newPath, progDir, basename(tmp));
+ free(tmp);
+ if (util_file_exists(newPath, NULL)) {
+ ERR("File already exists");
+ return -1;
+ }
+ strcpy(ret, newPath);
+ hLOG("Moving %s -> %s\n", opt->confPath, newPath);
+ if (util_move_file(opt->confPath, newPath) != 0) {
+ ERR("Could not move file.");
+ return -1;
+ }
+ return 0;
+}
+
+AddOpt add_make_options(cklist *args) {
+ list_rewind(args);
+ /* since we are here, the first two arguments must exist */
+ AddOpt addOpt = {
+ .progName = list_get(args),
+ .secret = 0,
+ .prime = 0,
+ .err = ADD_NO_ERR
+ };
+
+ list_next(args);
+ if (!util_is_file_rw(list_get(args))
+ || !util_is_file_link(list_get(args))) {
+ addOpt.err = ADD_ERR_WRONG_CONFIG;
+ return addOpt;
+ }
+ realpath(list_get(args), addOpt.confPath);
+
+ while (list_next(args)) {
+ if (strcmp(list_get(args), "-s") == 0 && addOpt.secret == 0) {
+ addOpt.secret = 1;
+ } else if (strcmp(list_get(args), "-p") == 0 && addOpt.prime == 0) {
+ addOpt.prime = 1;
+ } else {
+ addOpt.err = ADD_ERR_WRONG_FLAGS;
+ return addOpt;
+ }
+ }
+ list_rewind(args);
+ return addOpt;
+}
+
+void add_print_opts(AddOpt *opt) {
+ printf("Program:\t%s\nConfig:\t\t%s\n", opt->progName, opt->confPath);
+ if (opt->prime && opt->secret) {
+ printf("Options:\tsecret, primary\n");
+ } else if (opt->prime) {
+ printf("Options:\tprimary\n");
+ } else if (opt->secret) {
+ printf("Options:\tsecret\n");
+ }
+}
+
+static void get_or_make_program_dir(const AddOpt *opt, const Conf *conf, char *ret) {
+ char tmp[STR_L] = "";
+ str_join_dirname_with_basename(tmp, opt->secret ? conf->scrt_dir : conf->vc_dir, opt->progName);
+ if (!util_file_exists(tmp, NULL)) {
+ util_mkdir(tmp);
+ }
+ strcpy(ret, tmp);
+}
+
+int add_make_link(const AddOpt *opt, const Conf *conf) {
+ char progDir[STR_L] = "";
+ get_or_make_program_dir(opt, conf, progDir);
+ char newPath[STR_L] = "";
+ if (move_config(opt, progDir, newPath)) {
+ return -1;
+ }
+ if (link_config(opt, newPath)) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/ck.c b/src/ck.c
index 1370008..1be7298 100644
--- a/src/ck.c
+++ b/src/ck.c
@@ -28,7 +28,7 @@
*
* -------------------------------------------------------------------------- */
-#include "actionhelper.h"
+#include "actions.h"
#include "dblayer.h"
#include "cklist.h"
#include "ckutil.h"
@@ -68,7 +68,6 @@ int main(int argc, const char **argv) {
#define X(ACTION) \
case CKA_##ACTION: \
rc = run_##ACTION(&opt, &conf); \
- print_##ACTION##_result(rc); \
break;
CK_ACTIONS
#undef X
diff --git a/src/ckerrlog.c b/src/ckerrlog.c
index fab18b0..cf5a6e8 100644
--- a/src/ckerrlog.c
+++ b/src/ckerrlog.c
@@ -44,7 +44,7 @@ void log_command(int argc,const char* argv[]) {
void add_ ## stream ## _with_delim(const char *delim, \
const char *txt, \
va_list args) { \
- char tmp[STR_L] = ""; \
+ char tmp[STR_L] = ""; \
vsprintf(tmp, txt, args); \
if (stream) { \
list_add(stream, tmp); \
diff --git a/src/ckutil.c b/src/ckutil.c
index fde5e24..2b807de 100644
--- a/src/ckutil.c
+++ b/src/ckutil.c
@@ -228,3 +228,17 @@ int y_or_n_prompt() {
}
return 0;
}
+
+void decorate_entry(char *entry, int secret, int primary, const char *path) {
+ if (primary) {
+ strcat(entry, " [p]");
+ }
+
+ if (secret) {
+ strcat(entry, " [s]");
+ }
+ /* root */
+ if (util_is_link_owned_by_root(path)) {
+ strcat(entry, " [root]");
+ }
+}
diff --git a/src/ckutil.h b/src/ckutil.h
index d29b302..60d715f 100644
--- a/src/ckutil.h
+++ b/src/ckutil.h
@@ -49,11 +49,11 @@
/* Create the config name to be used when storing a new config to
* the VC or SCRT dir */
void str_make_ck_config_name(char *ret, const char *path,
- const char *progName);
+ const char *progName);
/* Joins the two strings into ret, with a '/' in between */
void str_join_dirname_with_basename(char *ret, const char *path,
- const char *progName);
+ const char *progName);
/* Returns 1 if str contains only whitespace, or nothing,
* else returns 0. */
@@ -99,4 +99,6 @@ int util_is_link_owned_by_root(const char *link);
/* yes is 1, no is 0 */
int y_or_n_prompt();
+
+void decorate_entry(char *entry, int secret, int primary, const char *path);
#endif // CKUTIL_H
diff --git a/src/clparser.c b/src/clparser.c
index 6dbd62a..ba73db0 100644
--- a/src/clparser.c
+++ b/src/clparser.c
@@ -13,7 +13,7 @@
#include "confparser.h"
#include "ckinfo.h"
#include "ckerrlog.h"
-#include "actionhelper.h"
+#include "actions.h"
ERRLOG(parser);
diff --git a/src/dblayer.c b/src/dblayer.c
index a6e6193..12be997 100644
--- a/src/dblayer.c
+++ b/src/dblayer.c
@@ -11,16 +11,16 @@
#include <libgen.h>
#include "dblayer.h"
-#include "dbhelper.h"
+#include "queries.h"
#include "ckutil.h"
#include "ckerrlog.h"
ERRLOG(ckdb);
-const char * const DB_FILE_NAME = "/ckdb";
+static const char * const DB_FILE_NAME = "/ckdb";
/* figure out the database name */
-void make_db_name(char *ret, const char *confPath) {
+static void make_db_name(char *ret, const char *confPath) {
char db_path[STR_L] = "";
strcpy(db_path, confPath);
strcat(db_path, DB_FILE_NAME);
@@ -36,7 +36,7 @@ int db_exists(const UserOpt *opt) {
}
/* check if db has the correct tables */
-int check_initialized_DB(sqlite3 *db) {
+static int check_initialized_DB(sqlite3 *db) {
char sql[STR_M] = "";
dbh_form_query_select_all_tables(sql);
sqlite3_stmt *stmt;
@@ -67,14 +67,6 @@ int check_initialized_DB(sqlite3 *db) {
return 0;
}
-DB empty_DB(SqlError err) {
- return (DB){ .ptr = NULL, .error = err };
-}
-
-DB new_DB(sqlite3 *db) {
- return (DB){ .ptr = db, .error = SQL_NO_ERR };
-}
-
void close_DB(DB *db) {
sqlite3_close(db->ptr);
}
@@ -94,149 +86,17 @@ int open_DB(DB *db, const UserOpt *opt) {
return -1;
}
- if (check_initialized_DB(db->ptr)) {
- ERR("The database file is currupted. Run ck init anew.");
- return -1;
+ if (opt->action != CKA_INIT) {
+ if (check_initialized_DB(db->ptr)) {
+ ERR("The database file is currupted. Run ck init anew.");
+ return -1;
+ }
}
LOG("Opened %s", db_path);
return 0;
}
-int init_make_DB(DB *db, const UserOpt *opt) {
- char db_path[STR_L] = "";
- int rc;
-
- make_db_name(db_path, opt->confDir);
- rc = sqlite3_open(db_path, &db->ptr);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- return 0;
-}
-
-void init_make_tables(DB *db) {
- char sql[STR_L] = "";
- dbh_form_query_make_tables(sql);
-
- int rc = sqlite3_exec(db->ptr, sql, 0, 0, 0);
- if (rc != SQLITE_OK ) {
- PRINT_ERR("Could not create empty db.");
- db->error = SQL_ERR_SQLITE;
- return;
- }
-}
-
-int get_next_valid_id_from_table(DB *db, const char* tableName) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_select_id_from(sql, tableName);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_bind_text(stmt, 1, tableName, (int)strlen(tableName), 0);
-
- int id = 0;
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- int a = sqlite3_column_int(stmt, 0);
- if (a != id) {
- break;
- }
- id++;
- }
- sqlite3_finalize(stmt);
- return id;
-}
-
-int insert_to_program_table(DB *db, const char *name) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_L] = "";
- dbh_form_query_insert_program(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- PRINT_ERR("while preparing insert to program sql.");
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- int id = get_next_valid_id_from_table(db, TBL_PROGRAM);
- if (id == -1) {
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- sqlite3_bind_int(stmt, 1, id);
- sqlite3_bind_text(stmt, 2, name, (int)strlen(name), 0);
- if (sqlite3_step(stmt) != SQLITE_DONE) {
- PRINT_ERR("while excecuting insert to program sql.");
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- sqlite3_finalize(stmt);
- return id;
-}
-
-int insert_to_config_table(DB *db, const char *path, const int secret, const int prime) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_L] = "";
- dbh_form_query_insert_config(sql);
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- PRINT_ERR("Error while preparing insert to config sql.");
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- int id = get_next_valid_id_from_table(db, TBL_CONFIG);
- if (id == -1) {
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- sqlite3_bind_int(stmt, 1, id);
- sqlite3_bind_text(stmt, 2, path, (int)strlen(path), 0);
- sqlite3_bind_int(stmt, 3, secret);
- sqlite3_bind_int(stmt, 4, prime);
- if (sqlite3_step(stmt) != SQLITE_DONE) {
- PRINT_ERR("Error while excecuting insert to config sql.");
- db->error = SQL_ERR_SQLITE;
- return-1;
- }
- sqlite3_finalize(stmt);
- return id;
-}
-
-int insert_to_rel_table(DB *db, const int pid, const int cid) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dhb_form_query_insert_relationship(sql);
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- db->error = SQL_ERR_SQLITE;
- PRINT_ERR("while preparing insert to rel sql.");
- return -1;
- }
- sqlite3_bind_int(stmt, 1, pid);
- sqlite3_bind_int(stmt, 2, cid);
- if (sqlite3_step(stmt) != SQLITE_DONE) {
- db->error = SQL_ERR_SQLITE;
- PRINT_ERR("while excecuting insert to rel sql.");
- return-1;
- }
- sqlite3_finalize(stmt);
- return 1;
-}
-
-/* Returns -2 or error, -1 if program doesn't exist
- * else the program ID */
int get_program_id(DB *db, const char* name) {
sqlite3_stmt *stmt;
int rc;
@@ -288,12 +148,6 @@ int get_config_id(DB *db, const char* path) {
return id;
}
-int add_insert_relationship(DB *db, const int pid, const int cid) {
- // do checks
- return insert_to_rel_table(db, pid, cid);
-}
-
-/* Returns the path of the found config via *ret */
int program_has_primary_config(DB *db, const int pid, char *ret, int *sec) {
sqlite3_stmt *stmt;
int rc;
@@ -335,185 +189,75 @@ int program_has_primary_config(DB *db, const int pid, char *ret, int *sec) {
return 0;
}
-int add_get_or_insert_config_to_db(DB *db, const int pid, const char *path, const int secret, const int prime, const char *home) {
- char tpath[STR_L] = "";
- if (!swap_home_with_tilde(tpath, path, home)) {
- strcpy(tpath, path);
- }
- int cid = get_config_id(db, tpath);
- if (cid == -2) {
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
- /* If config doesnt exist insert it and return it's cid */
- if (cid == -1) {
- if (program_has_primary_config(db, pid, NULL, NULL) && prime) {
- db->error = SQL_ERR_PRIMARY_REDEFINITION;
- return -1;
- }
- return insert_to_config_table(db, tpath, secret, prime);
- }
+int get_program_relations(DB *db, int pid) {
+ int count = -1;
+ sqlite3_stmt *stmt;
+ int rc;
- /* If it exist it means the user has inserted the same path twice */
- db->error = SQL_CONFIG_PATH_EXISTS;
- return -1;
-}
+ char sql[STR_M] = "";
+ dbh_form_query_count_program_relations(sql);
-int add_get_or_insert_program_to_db(DB *db, const char *name) {
- int pid = get_program_id(db, name);
- if (pid == -2) {
- db->error = SQL_ERR_SQLITE;
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
return -1;
}
- if (pid == -1) {
- return insert_to_program_table(db, name);
- }
- return pid;
-}
-int add_basename_exists(DB *db, const char *pName, const char *path) {
- cklist *baseNames = list_make_new();
- get_program_paths(db, baseNames, pName, 1 /*basename */, 0, NULL);
- char *tmp = strdup(path);
- int rc = list_exists(baseNames, basename(tmp));
- free(tmp);
- list_free(baseNames);
- return rc;
-}
-
-int add_transaction_try(DB *db, const AddOpt * const opt, const char *home) {
- __BEGIN_TRANSACTION__
- int pid = add_get_or_insert_program_to_db(db, opt->progName);
- if (db->error == SQL_ERR_SQLITE) {
- PRINT_ERR("Could not insert program to db.\n");
- return 1;
- }
- if (add_basename_exists(db, opt->progName, opt->confPath)) {
- ERR("Cannot have two configs with the same basename, for the same program.");
- return 1;
- }
- int cid = add_get_or_insert_config_to_db(db, pid, opt->confPath, opt->secret, opt->prime, home);
- if (db->error == SQL_ERR_SQLITE) {
- PRINT_ERR("Could not insert config to db.\n");
- return 1;
- }
- else if (db->error == SQL_CONFIG_PATH_EXISTS) {
- PRINT_ERR("This config already exists in the database.\n");
- return 1;
- }
- else if (db->error == SQL_ERR_PRIMARY_REDEFINITION) {
- PRINT_ERR("This program already has a primary config.\n");
- return 1;
- }
- add_insert_relationship(db, pid, cid);
- if (db->error == SQL_ERR_SQLITE) {
- PRINT_ERR("rel update failed\n");
- return 1;
+ sqlite3_bind_int(stmt, 1, pid);
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ count = sqlite3_column_int(stmt, 0);
}
- __END_TRANSACTION__
- return 0;
-}
-
-int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secret) {
- int pid = get_program_id(db, pName);
- /* error */
- if (pid == -2) {
+ if (rc != SQLITE_OK) {
return -1;
}
+ sqlite3_finalize(stmt);
+ return count;
+}
+int get_config_number(DB *db, char* pName) {
+ int pid = get_program_id(db, pName);
/* program exists */
if (pid > -1) {
- char path[STR_M] = "";
- if (program_has_primary_config(db, pid, path, secret) == 1) {
- if (!str_is_empty(path)) {
- if (ret) {
- str_make_ck_config_name(ret, path, pName);
- }
- return 0;
- }
- }
+ return get_program_relations(db, pid);
}
-
- /* No prime config found */
return -1;
}
-int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec) {
- int pid = get_program_id(db, pName);
- /* error */
- if (pid == -2) {
- return -1;
- }
-
- /* program exists */
- if (pid > -1) {
- sqlite3_stmt *stmt;
- int rc;
-
- char selection[STR_M] = COL_CONFIG_PATH;
- strcat(selection, ", ");
- strcat(selection, COL_CONFIG_SECRET);
- char condition[STR_M] = TBL_PROGRAM;
- strcat(condition, ".");
- strcat(condition, COL_PROGRAM_ID);
-
- char sql[STR_L] = "";
- dbh_form_query_select_from_joined_eq(sql, selection, condition);
+int get_pid_from_cid(DB *db, int cid) {
+ int pid = -1;
+ sqlite3_stmt *stmt;
+ int rc;
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- sqlite3_bind_int(stmt, 1, pid);
- if (rc != SQLITE_OK) {
- return -2;
- }
+ char sql[STR_M] = "";
+ dbh_form_query_get_pid_from_cid(sql);
- int flag = -1;
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- char confName[STR_M] = "";
- if (cName) {
- char *tmp = strdup((char *)sqlite3_column_text(stmt, 0));
- if (strcmp(cName, basename(tmp)) == 0) {
- flag = 0;
- str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName);
- strcpy(ret, confName);
- if (sec) {
- *sec = sqlite3_column_int(stmt, 1);
- }
- }
- free(tmp);
- break;
- }
- else {
- /* Since we are here, it means there is only 1 config for the selected program */
- flag = 0;
- str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName);
- strcpy(ret, confName);
- if (sec) {
- *sec = sqlite3_column_int(stmt, 1);
- }
- break;
- }
- }
- sqlite3_finalize(stmt);
- return flag;
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -1;
}
- return -1;
-}
-static void decorate_entry(char *entry, int secret, int primary, const char *path) {
- if (primary) {
- strcat(entry, " [p]");
- }
+ sqlite3_bind_int(stmt, 1, cid);
- if (secret) {
- strcat(entry, " [s]");
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ pid = sqlite3_column_int(stmt, 0);
}
- /* root */
- if (util_is_link_owned_by_root(path)) {
- strcat(entry, " [root]");
+
+ if (rc != SQLITE_OK) {
+ return -1;
}
+ sqlite3_finalize(stmt);
+ return pid;
}
+void print_suggested_configs(DB *db, const char *pName) {
+ char name[STR_M] = "";
+ strcat(name, pName);
+ strcat(name, ":");
+ cklist *paths = list_make_and_add(name);
+ get_program_paths(db, paths, pName, 1, 0, NULL);
+ list_print(paths);
+ list_free(paths);
+}
int get_program_paths(DB *db, cklist *ckl, const char* pName, int bname, int attr, const char *home) {
int pid = get_program_id(db, pName);
@@ -573,471 +317,3 @@ int get_program_paths(DB *db, cklist *ckl, const char* pName, int bname, int att
}
return -1;
}
-
-int list_get_paths(DB *db, cklist *ckl, int bName, int attr, const char *home) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_select_paths_with_attributes(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -2;
- }
-
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- char *tmp = strdup((char *)sqlite3_column_text(stmt, 0));
- char path[STR_L] = "";
- if (bName) {
- strcat(path, basename(tmp));
- }
- else {
- char tpath[STR_L] = "";
- if (swap_tilde_with_home(tpath, tmp, home)) {
- strcat(path, tpath);
- }
- else {
- strcat(path, tmp);
- }
- }
- free(tmp);
- if (attr) {
- decorate_entry(path, sqlite3_column_int(stmt, 1),
- sqlite3_column_int(stmt, 2),
- (char *)sqlite3_column_text(stmt, 0));
- }
- list_add(ckl, path);
- }
- sqlite3_finalize(stmt);
-
- return 1;
-}
-
-int list_get_programs(DB *db, cklist *ckl) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_select_programs(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -2;
- }
-
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- list_add(ckl, (char *)sqlite3_column_text(stmt, 0));
- }
- sqlite3_finalize(stmt);
-
- return 1;
-}
-
-int list_get_path_program_tree(DB *db, cklist *ckl, int bName, int attr, const char *home) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_select_programs(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -2;
- }
-
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- char programName[STR_M] = "";
- strcat(programName, (char *)sqlite3_column_text(stmt, 0));
- strcat(programName, ":");
- list_add(ckl, programName);
- sqlite3_stmt *stmt2;
- int rc2;
-
- char sql2[STR_L] = "";
-
- char selection[STR_M] = COL_CONFIG_PATH;
- strcat(selection, ",");
- strcat(selection, COL_CONFIG_SECRET);
- strcat(selection, ",");
- strcat(selection, COL_CONFIG_PRIMARY);
-
- char condition[STR_M] = TBL_PROGRAM;
- strcat(condition, ".");
- strcat(condition, COL_PROGRAM_NAME);
-
- dbh_form_query_select_from_joined_eq(sql2, selection, condition);
-
- rc2 = sqlite3_prepare_v2(db->ptr, sql2, -1, &stmt2, 0);
- if (rc2 != SQLITE_OK) {
- return -2;
- }
-
- sqlite3_bind_text(stmt2, 1, (char *)sqlite3_column_text(stmt, 0), -1, 0);
- while (sqlite3_step(stmt2) == SQLITE_ROW) {
- char treePath[STR_L] = "|- ";
- char *tmp = strdup((char *)sqlite3_column_text(stmt2, 0));
- if (bName) {
- strcat(treePath, basename(tmp));
- }
- else {
- char tpath[STR_L] = "";
- if (swap_tilde_with_home(tpath, tmp, home)) {
- strcat(treePath, tpath);
- }
- else {
- strcat(treePath, tmp);
- }
- }
- free(tmp);
- if (attr) {
- decorate_entry(treePath, sqlite3_column_int(stmt2, 1),
- sqlite3_column_int(stmt2, 2),
- (char *)sqlite3_column_text(stmt2, 0));
- }
- list_add(ckl, treePath);
- }
- sqlite3_finalize(stmt2);
- }
- sqlite3_finalize(stmt);
-
- return 1;
-}
-
-int delete_prog(DB *db, int pid) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_delete_x_from_y(sql, COL_PROGRAM_ID, TBL_PROGRAM);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_bind_int(stmt, 1, pid);
- sqlite3_step(stmt);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- sqlite3_finalize(stmt);
- return 0;
-}
-
-int delete_conf(DB *db, int cid) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_delete_x_from_y(sql, COL_CONFIG_ID, TBL_CONFIG);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_bind_int(stmt, 1, cid);
- sqlite3_step(stmt);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- sqlite3_finalize(stmt);
- return 0;
-}
-
-int get_pid_from_cid(DB *db, int cid) {
- int pid = -1;
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_get_pid_from_cid(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- sqlite3_bind_int(stmt, 1, cid);
-
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- pid = sqlite3_column_int(stmt, 0);
- }
-
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_finalize(stmt);
- return pid;
-}
-
-int get_program_relations(DB *db, int pid) {
- int count = -1;
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_count_program_relations(sql);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- sqlite3_bind_int(stmt, 1, pid);
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- count = sqlite3_column_int(stmt, 0);
- }
-
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_finalize(stmt);
- return count;
-}
-
-int get_config_number(DB *db, char* pName) {
- int pid = get_program_id(db, pName);
- /* program exists */
- if (pid > -1) {
- return get_program_relations(db, pid);
- }
- return -1;
-}
-
-/* Removes the relationship of `cid` with the corresponding program.
- * Returns the program's pid on succes, negative integer otherwise.
- */
-int remove_conf_rel(DB *db, int cid) {
- sqlite3_stmt *stmt;
- int rc;
-
- int pid = get_pid_from_cid(db, cid);
-
- char sql[STR_M] = "";
- dbh_form_query_delete_x_from_y(sql, COL_REL_CONFIG_ID, TBL_REL);
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -1;
- }
- sqlite3_bind_int(stmt, 1, cid);
- sqlite3_step(stmt);
- if (rc != SQLITE_OK) {
- return -1;
- }
-
- sqlite3_finalize(stmt);
-
- return pid;
-}
-
-int remove_all_configs(DB *db, int pid) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_M] = "";
- dbh_form_query_select_from_joined_eq(sql, COL_REL_CONFIG_ID, COL_REL_PROGRAM_ID);
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return -2;
- }
-
- sqlite3_bind_int(stmt, 1, pid);
-
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- delete_conf(db, sqlite3_column_int(stmt, 0));
- remove_conf_rel(db, sqlite3_column_int(stmt, 0));
- }
- sqlite3_finalize(stmt);
-
- return 0;
-}
-
-int get_cid_from_pname_and_basename(DB *db, const char *pName, const char *cBaseName) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_L] = "";
- char selection[STR_M] = TBL_CONFIG;
- strcat(selection, ".");
- strcat(selection, COL_CONFIG_ID);
- strcat(selection, ", ");
- strcat(selection, COL_CONFIG_PATH);
-
- char condition[STR_M] = TBL_PROGRAM;
- strcat(condition, ".");
- strcat(condition, COL_PROGRAM_NAME);
-
- dbh_form_query_select_from_joined_eq(sql, selection, condition);
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- ERR("while preparing get_cid_from_pname_and_basename");
- db->error = SQL_ERR_SQLITE;
- return -1;
- }
-
- sqlite3_bind_text(stmt, 1, pName, -1, 0);
- int _cid = -1;
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- if (strcmp(cBaseName, basename((char *)sqlite3_column_text(stmt, 1))) == 0) {
- _cid = sqlite3_column_int(stmt, 0);
- break;
- }
- }
- sqlite3_finalize(stmt);
- return _cid;
-}
-
-int del_transaction_try(DB *db, const char *pName, const char *cBaseName) {
- __BEGIN_TRANSACTION__
- int pid = -1;
- if (cBaseName) {
- // del conf
- int cid = get_cid_from_pname_and_basename(db, pName, cBaseName);
- if (cid < 0) {
- ERR("Config %s doesn't exist in the database.", cBaseName);
- return -1;
- }
- if (delete_conf(db, cid)) {
- ERR("Could not delete config %s from db.", cBaseName);
- return -1;
- }
- // handle relations
- pid = remove_conf_rel(db, cid);
- HELP("Deleted %s config: %s", pName, cBaseName);
- if (get_program_relations(db, pid) > 0) {
- goto end;
- }
- }
- else {
- pid = get_program_id(db, pName);
- }
- if (pid < 0) {
- ERR("Program not found in the db.");
- return -1;
- }
- /* If we are deleting a program we should delete everything that
- * refferences it (configs and relationships) */
- if (!cBaseName) {
- remove_all_configs(db, pid);
- }
- if(delete_prog(db, pid)) {
- ERR("Could not delete program %s from db.", pName);
- return -1;
- }
- HELP("Deleted program %s", pName);
- end:
- __END_TRANSACTION__
- return 0;
-}
-
-int restore_program(DB *db, Conf *conf, const char *pName) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_L] = "";
-
- char selection[STR_M] = COL_CONFIG_PATH;
- strcat(selection, ",");
- strcat(selection, COL_CONFIG_SECRET);
-
- char condition[STR_M] = TBL_PROGRAM;
- strcat(condition, ".");
- strcat(condition, COL_PROGRAM_NAME);
-
- dbh_form_query_select_from_joined_eq(sql, selection, condition);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return 0;
- }
-
- sqlite3_bind_text(stmt, 1, pName, -1, 0);
- int err_flag = 0;
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- int secret = sqlite3_column_int(stmt, 1);
- char filePath[STR_L] = "";
- strcpy(filePath, secret ? conf->scrt_dir : conf->vc_dir);
- strcat(filePath, "/");
- strcat(filePath, pName);
- strcat(filePath, "/");
- strcat(filePath, basename((char *)sqlite3_column_text(stmt, 0)));
- if (!util_is_file_rw(filePath)) {
- sERR("%s does not exist or is not accessible.", filePath);
- err_flag = 1;
- }
- }
- sqlite3_finalize(stmt);
- return err_flag;
-}
-
-int restore_configs_exists(DB *db, Conf *conf, const char *pName, cklist *from, cklist *to) {
- sqlite3_stmt *stmt;
- int rc;
-
- char sql[STR_L] = "";
-
- char selection[STR_M] = COL_CONFIG_PATH;
- strcat(selection, ",");
- strcat(selection, COL_CONFIG_SECRET);
-
- char condition[STR_M] = TBL_PROGRAM;
- strcat(condition, ".");
- strcat(condition, COL_PROGRAM_NAME);
-
- dbh_form_query_select_from_joined_eq(sql, selection, condition);
-
- rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
- if (rc != SQLITE_OK) {
- return 0;
- }
-
- sqlite3_bind_text(stmt, 1, pName, -1, 0);
- int err_flag = 0;
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- char filePath[STR_L] = "";
- strcpy(filePath, /*secret*/ sqlite3_column_int(stmt, 1) ? conf->scrt_dir : conf->vc_dir);
- strcat(filePath, "/");
- strcat(filePath, pName);
- if (!util_is_dir(filePath)) {
- sERR("%s is not a directory.", filePath);
- err_flag = 1;
- break;
- }
- strcat(filePath, "/");
- strcat(filePath, basename(/*path*/ (char *)sqlite3_column_text(stmt, 0)));
- if (!util_is_file_rw(filePath)) {
- sERR("%s does not exist or is not accessible.", filePath);
- err_flag = 1;
- break;
- }
- list_add(from, filePath);
- char tpath[STR_L] = "";
- if (!swap_tilde_with_home(tpath, (char *)sqlite3_column_text(stmt, 0), conf->home_dir)) {
- strcpy(tpath, (char *)sqlite3_column_text(stmt, 0));
- }
- list_add(to, tpath);
- }
- sqlite3_finalize(stmt);
- return !err_flag;
-}
-
-int restore_all_exist(DB *db, Conf *conf, cklist *from, cklist *to) {
- cklist *programs = list_make_new();
- if (list_get_programs(db, programs) != 1) {
- ERR("No programs in ckdb");
- list_free(programs);
- return 0;
- }
- int err_flag = 0;
- if (list_size(programs) > 0) {
- do {
- if (!restore_configs_exists(db, conf, list_get(programs), from, to)) {
- err_flag = 1;
- }
- } while(list_next(programs));
- }
- list_free(programs);
- return !err_flag;
-}
diff --git a/src/dblayer.h b/src/dblayer.h
index 2e42ad0..c830a94 100644
--- a/src/dblayer.h
+++ b/src/dblayer.h
@@ -35,57 +35,54 @@ struct DBstruct {
SqlError error;
};
-int db_exists(const UserOpt *opt);
-
/* Open the db file. On fail return null pointer to db->ptr
* and the corresponding SQL error (NO_DB_FILE | NO_TABLES)*/
int open_DB(DB *db, const UserOpt *opt);
-
void close_DB(DB *db);
+int db_exists(const UserOpt *opt);
+
+
+/**********************************/
int program_exists(DB *db, const char *pName);
int get_program_paths(DB *db, cklist *ckl, const char* pName, int bName, int attr, const char *home);
+int get_config_number(DB *db, char *pName);
+int get_program_relations(DB *db, int pid);
+/* Returns the path of the found config via *ret */
+int program_has_primary_config(DB *db, const int pid, char *ret, int *sec);
-/********/
-/* init */
-/********/
+/* Returns -2 or error, -1 if program doesn't exist
+ * else the program ID */
+int get_config_id(DB *db, const char* path);
-/* Create the tables required for the ckdb */
-void init_make_tables(DB *db);
-int init_make_DB(DB *db, const UserOpt *opt);
+/* Returns -2 or error, -1 if program doesn't exist
+ * else the config ID */
+int get_program_id(DB *db, const char* name);
+
+int get_pid_from_cid(DB *db, int cid);
-/*******/
-/* add */
-/*******/
+void print_suggested_configs(DB *db, const char *pName);
+/* init.c */
+void init_make_tables(DB *db);
+
+/* add.c */
/* Returns 1 in error, 0 otherwise */
int add_transaction_try(DB *db, const AddOpt * const opt, const char *home);
-/********/
-/* edit */
-/********/
-
+/* edit.c */
int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secret);
-int get_config_number(DB *db, char *pName);
int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec);
-/********/
-/* list */
-/********/
-
+/* list.c */
int list_get_paths(DB *db, cklist *ckl, int bName, int attr, const char *home);
int list_get_programs(DB *db, cklist *ckl);
int list_get_path_program_tree(DB *db, cklist *ckl, int bName, int attr, const char *home);
-/*******/
-/* del */
-/*******/
-
+/* delete.c */
int del_transaction_try(DB *db, const char *pName, const char *cBaseName);
-/***********/
-/* restore */
-/***********/
-
+/* restore.c */
int restore_configs_exists(DB *db, Conf *conf, const char *pName, cklist *from, cklist *to);
int restore_all_exist(DB *db, Conf *conf, cklist *from, cklist *to);
+
#endif /* DBLAYER_H */
diff --git a/src/delete.c b/src/delete.c
new file mode 100644
index 0000000..ce7017f
--- /dev/null
+++ b/src/delete.c
@@ -0,0 +1,176 @@
+#include <libgen.h>
+
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+ERRLOG(delete);
+
+static int delete_prog(DB *db, int pid) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_delete_x_from_y(sql, COL_PROGRAM_ID, TBL_PROGRAM);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, pid);
+ sqlite3_step(stmt);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+
+ sqlite3_finalize(stmt);
+ return 0;
+}
+
+static int delete_conf(DB *db, int cid) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_delete_x_from_y(sql, COL_CONFIG_ID, TBL_CONFIG);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, cid);
+ sqlite3_step(stmt);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+
+ sqlite3_finalize(stmt);
+ return 0;
+}
+
+/* Removes the relationship of `cid` with the corresponding program.
+ * Returns the program's pid on succes, negative integer otherwise.
+ */
+static int remove_conf_rel(DB *db, int cid) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ int pid = get_pid_from_cid(db, cid);
+
+ char sql[STR_M] = "";
+ dbh_form_query_delete_x_from_y(sql, COL_REL_CONFIG_ID, TBL_REL);
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+ sqlite3_bind_int(stmt, 1, cid);
+ sqlite3_step(stmt);
+ if (rc != SQLITE_OK) {
+ return -1;
+ }
+
+ sqlite3_finalize(stmt);
+
+ return pid;
+}
+
+static int remove_all_configs(DB *db, int pid) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_select_from_joined_eq(sql, COL_REL_CONFIG_ID, COL_REL_PROGRAM_ID);
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -2;
+ }
+
+ sqlite3_bind_int(stmt, 1, pid);
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ delete_conf(db, sqlite3_column_int(stmt, 0));
+ remove_conf_rel(db, sqlite3_column_int(stmt, 0));
+ }
+ sqlite3_finalize(stmt);
+
+ return 0;
+}
+
+static int get_cid_from_pname_and_basename(DB *db, const char *pName, const char *cBaseName) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_L] = "";
+ char selection[STR_M] = TBL_CONFIG;
+ strcat(selection, ".");
+ strcat(selection, COL_CONFIG_ID);
+ strcat(selection, ", ");
+ strcat(selection, COL_CONFIG_PATH);
+
+ char condition[STR_M] = TBL_PROGRAM;
+ strcat(condition, ".");
+ strcat(condition, COL_PROGRAM_NAME);
+
+ dbh_form_query_select_from_joined_eq(sql, selection, condition);
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ ERR("while preparing get_cid_from_pname_and_basename");
+ db->error = SQL_ERR_SQLITE;
+ return -1;
+ }
+
+ sqlite3_bind_text(stmt, 1, pName, -1, 0);
+ int _cid = -1;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ if (strcmp(cBaseName, basename((char *)sqlite3_column_text(stmt, 1))) == 0) {
+ _cid = sqlite3_column_int(stmt, 0);
+ break;
+ }
+ }
+ sqlite3_finalize(stmt);
+ return _cid;
+}
+
+int del_transaction_try(DB *db, const char *pName, const char *cBaseName) {
+ __BEGIN_TRANSACTION__
+ int pid = -1;
+ if (cBaseName) {
+ // del conf
+ int cid = get_cid_from_pname_and_basename(db, pName, cBaseName);
+ if (cid < 0) {
+ ERR("Config %s doesn't exist in the database.", cBaseName);
+ return -1;
+ }
+ if (delete_conf(db, cid)) {
+ ERR("Could not delete config %s from db.", cBaseName);
+ return -1;
+ }
+ // handle relations
+ pid = remove_conf_rel(db, cid);
+ HELP("Deleted %s config: %s", pName, cBaseName);
+ if (get_program_relations(db, pid) > 0) {
+ goto end;
+ }
+ }
+ else {
+ pid = get_program_id(db, pName);
+ }
+ if (pid < 0) {
+ ERR("Program not found in the db.");
+ return -1;
+ }
+ /* If we are deleting a program we should delete everything that
+ * refferences it (configs and relationships) */
+ if (!cBaseName) {
+ remove_all_configs(db, pid);
+ }
+ if(delete_prog(db, pid)) {
+ ERR("Could not delete program %s from db.", pName);
+ return -1;
+ }
+ HELP("Deleted program %s", pName);
+ end:
+ __END_TRANSACTION__
+ return 0;
+}
diff --git a/src/edit.c b/src/edit.c
new file mode 100644
index 0000000..1058d45
--- /dev/null
+++ b/src/edit.c
@@ -0,0 +1,91 @@
+#include <libgen.h>
+
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+int edit_get_prime_config_from_program(DB *db, char *pName, char *ret, int *secret) {
+ int pid = get_program_id(db, pName);
+ /* error */
+ if (pid == -2) {
+ return -1;
+ }
+
+ /* program exists */
+ if (pid > -1) {
+ char path[STR_M] = "";
+ if (program_has_primary_config(db, pid, path, secret) == 1) {
+ if (!str_is_empty(path)) {
+ if (ret) {
+ str_make_ck_config_name(ret, path, pName);
+ }
+ return 0;
+ }
+ }
+ }
+
+ /* No prime config found */
+ return -1;
+}
+
+int edit_get_config(DB *db, const char *pName, char *ret, const char *cName, int *sec) {
+ int pid = get_program_id(db, pName);
+ /* error */
+ if (pid == -2) {
+ return -1;
+ }
+
+ /* program exists */
+ if (pid > -1) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char selection[STR_M] = COL_CONFIG_PATH;
+ strcat(selection, ", ");
+ strcat(selection, COL_CONFIG_SECRET);
+ char condition[STR_M] = TBL_PROGRAM;
+ strcat(condition, ".");
+ strcat(condition, COL_PROGRAM_ID);
+
+ char sql[STR_L] = "";
+ dbh_form_query_select_from_joined_eq(sql, selection, condition);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ sqlite3_bind_int(stmt, 1, pid);
+ if (rc != SQLITE_OK) {
+ return -2;
+ }
+
+ int flag = -1;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ char confName[STR_M] = "";
+ if (cName) {
+ char *tmp = strdup((char *)sqlite3_column_text(stmt, 0));
+ if (strcmp(cName, basename(tmp)) == 0) {
+ flag = 0;
+ str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName);
+ strcpy(ret, confName);
+ if (sec) {
+ *sec = sqlite3_column_int(stmt, 1);
+ }
+ }
+ free(tmp);
+ break;
+ }
+ else {
+ /* Since we are here, it means there is only 1 config for the selected program */
+ flag = 0;
+ str_make_ck_config_name(confName, (char *)sqlite3_column_text(stmt, 0), pName);
+ strcpy(ret, confName);
+ if (sec) {
+ *sec = sqlite3_column_int(stmt, 1);
+ }
+ break;
+ }
+ }
+ sqlite3_finalize(stmt);
+ return flag;
+ }
+ return -1;
+}
diff --git a/src/init.c b/src/init.c
new file mode 100644
index 0000000..e38a6f5
--- /dev/null
+++ b/src/init.c
@@ -0,0 +1,62 @@
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+ERRLOG(init);
+
+int init_create_config_file(UserOpt *opt) {
+ char absVCdir[STR_L] = "";
+ if (!util_file_exists(list_get_at(opt->args, 0), absVCdir)) {
+ ERR("Version control directory: %s does not exist.", list_get_at(opt->args, 0));
+ return 1;
+ }
+
+ char absSRdir[STR_L] = "";
+ if (!util_file_exists(list_get_at(opt->args, 1), absSRdir)) {
+ ERR("Secret directory: %s does not exist.", list_get_at(opt->args, 1));
+ return 1;
+ }
+
+ if (!util_file_exists(opt->confDir, NULL)) {
+ util_mkdir(opt->confDir);
+ }
+
+ char confName[STR_L] = "";
+ make_config_name(confName, opt->confDir);
+ FILE *f;
+ if ((f = fopen(confName, "w")) == NULL) {
+ return 1;
+ }
+
+ char tmp[STR_L] = "";
+ strcpy(tmp, "version_control_dir = ");
+ strcat(tmp, absVCdir);
+ strcat(tmp, "\n");
+ fputs(tmp, f);
+
+ strcpy(tmp, "secret_dir = ");
+ strcat(tmp, absSRdir);
+ strcat(tmp, "\n");
+ fputs(tmp, f);
+
+ strcpy(tmp, "home_dir = ");
+ strcat(tmp, getenv("HOME"));
+ strcat(tmp, "\n");
+ fputs(tmp, f);
+
+ fclose(f);
+ return 0;
+}
+
+void init_make_tables(DB *db) {
+ char sql[STR_L] = "";
+ dbh_form_query_make_tables(sql);
+
+ int rc = sqlite3_exec(db->ptr, sql, 0, 0, 0);
+ if (rc != SQLITE_OK ) {
+ PRINT_ERR("Could not create empty db.");
+ db->error = SQL_ERR_SQLITE;
+ return;
+ }
+}
diff --git a/src/list.c b/src/list.c
new file mode 100644
index 0000000..105c101
--- /dev/null
+++ b/src/list.c
@@ -0,0 +1,206 @@
+#include <libgen.h>
+
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+ListOpt list_make_options(cklist *args) {
+ list_rewind(args);
+ ListOpt listOpt = {
+ ._lt = LT_TREE,
+ ._lst = LST_PLAIN,
+ .pName = NULL,
+ .attr = 0,
+ .bName = 0,
+ .err = 0
+ };
+
+ if (list_size(args)) {
+ do {
+ if (strcmp(list_get(args), "-a") == 0) {
+ listOpt.attr = 1;
+ continue;
+ }
+ if (strcmp(list_get(args), "-b") == 0) {
+ listOpt.bName = 1;
+ continue;
+ }
+ if (strcmp(list_get(args), "-t") == 0) {
+ if (!list_next(args)) {
+ listOpt.err = 1;
+ break;
+ }
+ if (strcmp(list_get(args), "plain") == 0) {
+ listOpt._lst = LST_PLAIN;
+ }
+ else if (strcmp(list_get(args), "lisp") == 0) {
+ listOpt._lst = LST_LISP;
+ }
+ else if (strcmp(list_get(args), "python") == 0) {
+ listOpt._lst = LST_PYTHON;
+ }
+ else {
+ listOpt.err = 1;
+ }
+ }
+ else if (strcmp(list_get(args), "paths") == 0) {
+ listOpt._lt = LT_PATH;
+ }
+ else if (strcmp(list_get(args), "programs") == 0) {
+ listOpt._lt = LT_PROGRAM;
+ }
+ else if (strcmp(list_get(args), "tree") == 0) {
+ listOpt._lt = LT_TREE;
+ }
+ else if (strcmp(list_get(args), "ckconf") == 0) {
+ listOpt._lt = LT_CKCONF;
+ }
+ else if (strcmp(list_get(args), "-p") == 0) {
+ if (list_next(args)) {
+ listOpt._lt = LT_PROG_CONFS;
+ listOpt.pName = list_get(args);
+ }
+ else {
+ listOpt.err = 1;
+ break;
+ }
+ }
+ else {
+ listOpt.err = 1;
+ }
+ } while(list_next(args));
+ }
+ list_rewind(args);
+ return listOpt;
+}
+
+int list_get_paths(DB *db, cklist *ckl, int bName, int attr, const char *home) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_select_paths_with_attributes(sql);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -2;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ char *tmp = strdup((char *)sqlite3_column_text(stmt, 0));
+ char path[STR_L] = "";
+ if (bName) {
+ strcat(path, basename(tmp));
+ }
+ else {
+ char tpath[STR_L] = "";
+ if (swap_tilde_with_home(tpath, tmp, home)) {
+ strcat(path, tpath);
+ }
+ else {
+ strcat(path, tmp);
+ }
+ }
+ free(tmp);
+ if (attr) {
+ decorate_entry(path, sqlite3_column_int(stmt, 1),
+ sqlite3_column_int(stmt, 2),
+ (char *)sqlite3_column_text(stmt, 0));
+ }
+ list_add(ckl, path);
+ }
+ sqlite3_finalize(stmt);
+
+ return 1;
+}
+
+int list_get_programs(DB *db, cklist *ckl) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_select_programs(sql);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -2;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ list_add(ckl, (char *)sqlite3_column_text(stmt, 0));
+ }
+ sqlite3_finalize(stmt);
+
+ return 1;
+}
+
+int list_get_path_program_tree(DB *db, cklist *ckl, int bName, int attr, const char *home) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_M] = "";
+ dbh_form_query_select_programs(sql);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return -2;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ char programName[STR_M] = "";
+ strcat(programName, (char *)sqlite3_column_text(stmt, 0));
+ strcat(programName, ":");
+ list_add(ckl, programName);
+ sqlite3_stmt *stmt2;
+ int rc2;
+
+ char sql2[STR_L] = "";
+
+ char selection[STR_M] = COL_CONFIG_PATH;
+ strcat(selection, ",");
+ strcat(selection, COL_CONFIG_SECRET);
+ strcat(selection, ",");
+ strcat(selection, COL_CONFIG_PRIMARY);
+
+ char condition[STR_M] = TBL_PROGRAM;
+ strcat(condition, ".");
+ strcat(condition, COL_PROGRAM_NAME);
+
+ dbh_form_query_select_from_joined_eq(sql2, selection, condition);
+
+ rc2 = sqlite3_prepare_v2(db->ptr, sql2, -1, &stmt2, 0);
+ if (rc2 != SQLITE_OK) {
+ return -2;
+ }
+
+ sqlite3_bind_text(stmt2, 1, (char *)sqlite3_column_text(stmt, 0), -1, 0);
+ while (sqlite3_step(stmt2) == SQLITE_ROW) {
+ char treePath[STR_L] = "|- ";
+ char *tmp = strdup((char *)sqlite3_column_text(stmt2, 0));
+ if (bName) {
+ strcat(treePath, basename(tmp));
+ }
+ else {
+ char tpath[STR_L] = "";
+ if (swap_tilde_with_home(tpath, tmp, home)) {
+ strcat(treePath, tpath);
+ }
+ else {
+ strcat(treePath, tmp);
+ }
+ }
+ free(tmp);
+ if (attr) {
+ decorate_entry(treePath, sqlite3_column_int(stmt2, 1),
+ sqlite3_column_int(stmt2, 2),
+ (char *)sqlite3_column_text(stmt2, 0));
+ }
+ list_add(ckl, treePath);
+ }
+ sqlite3_finalize(stmt2);
+ }
+ sqlite3_finalize(stmt);
+
+ return 1;
+}
diff --git a/src/dbhelper.c b/src/queries.c
index 9de780e..0c56cc1 100644
--- a/src/dbhelper.c
+++ b/src/queries.c
@@ -1,4 +1,4 @@
-/* dbhelper.c - Database layer for ck -----------------------------------*- C -*-
+/* queries.c - Database stuff for ck -----------------------------------*- C -*-
*
* This file is part of ck, the config keeper
*
@@ -8,7 +8,7 @@
* GPLv3 (see LICENCE for the full notice)
*
* -------------------------------------------------------------------------- */
-#include "dbhelper.h"
+#include "queries.h"
void dbh_form_query_make_tables(char *query) {
char tmp[STR_L] = "CREATE TABLE ";
diff --git a/src/dbhelper.h b/src/queries.h
index 31559cc..d4c3ae0 100644
--- a/src/dbhelper.h
+++ b/src/queries.h
@@ -1,4 +1,4 @@
-/* dbhelper.h - Database layer for ck ----------------------------------*- C -*-
+/* queries.h - Database stuff for ck -----------------------------------*- C -*-
*
* This file is part of ck, the config keeper
*
diff --git a/src/restore.c b/src/restore.c
new file mode 100644
index 0000000..c90cb82
--- /dev/null
+++ b/src/restore.c
@@ -0,0 +1,114 @@
+#include <libgen.h>
+
+#include "actions.h"
+#include "dblayer.h"
+#include "queries.h"
+#include "ckerrlog.h"
+
+ERRLOG(restore);
+
+int restore_make_links(cklist *from, cklist *to) {
+ list_rewind(from);
+ list_rewind(to);
+ if (list_size(from) > 0
+ && list_size(to) > 0
+ && list_size(from) == list_size(to)) {
+ do {
+ if (util_file_exists(list_get(to), NULL)
+ || !util_is_file_link(list_get(to))) {
+ ERR("File %s already exists.", list_get(to));
+ sERR("No links were created.");
+ return -1;
+ }
+ } while (list_next(to));
+ list_rewind(to);
+ while (1) {
+ if (util_symlink_file(list_get(from), list_get(to))) {
+ ERR("FATAL could not link %s -> %s", list_get(from), list_get(to));
+ sERR("Process stopping.");
+ return -1;
+ }
+ hLOG("Linking: %s -> %s", list_get(from), list_get(to));
+ if (util_own_grp_copy(list_get(to), list_get(from))) {
+ return -1;
+ }
+ if (!list_next(from)) {
+ break;
+ }
+ if (!list_next(to)) {
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+int restore_configs_exists(DB *db, Conf *conf, const char *pName, cklist *from, cklist *to) {
+ sqlite3_stmt *stmt;
+ int rc;
+
+ char sql[STR_L] = "";
+
+ char selection[STR_M] = COL_CONFIG_PATH;
+ strcat(selection, ",");
+ strcat(selection, COL_CONFIG_SECRET);
+
+ char condition[STR_M] = TBL_PROGRAM;
+ strcat(condition, ".");
+ strcat(condition, COL_PROGRAM_NAME);
+
+ dbh_form_query_select_from_joined_eq(sql, selection, condition);
+
+ rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0);
+ if (rc != SQLITE_OK) {
+ return 0;
+ }
+
+ sqlite3_bind_text(stmt, 1, pName, -1, 0);
+ int err_flag = 0;
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ char filePath[STR_L] = "";
+ strcpy(filePath, /*secret*/ sqlite3_column_int(stmt, 1) ? conf->scrt_dir : conf->vc_dir);
+ strcat(filePath, "/");
+ strcat(filePath, pName);
+ if (!util_is_dir(filePath)) {
+ sERR("%s is not a directory.", filePath);
+ err_flag = 1;
+ break;
+ }
+ strcat(filePath, "/");
+ strcat(filePath, basename(/*path*/ (char *)sqlite3_column_text(stmt, 0)));
+ if (!util_is_file_rw(filePath)) {
+ sERR("%s does not exist or is not accessible.", filePath);
+ err_flag = 1;
+ break;
+ }
+ list_add(from, filePath);
+ char tpath[STR_L] = "";
+ if (!swap_tilde_with_home(tpath, (char *)sqlite3_column_text(stmt, 0), conf->home_dir)) {
+ strcpy(tpath, (char *)sqlite3_column_text(stmt, 0));
+ }
+ list_add(to, tpath);
+ }
+ sqlite3_finalize(stmt);
+ return !err_flag;
+}
+
+int restore_all_exist(DB *db, Conf *conf, cklist *from, cklist *to) {
+ cklist *programs = list_make_new();
+ if (list_get_programs(db, programs) != 1) {
+ ERR("No programs in ckdb");
+ list_free(programs);
+ return 0;
+ }
+ int err_flag = 0;
+ if (list_size(programs) > 0) {
+ do {
+ if (!restore_configs_exists(db, conf, list_get(programs), from, to)) {
+ err_flag = 1;
+ }
+ } while(list_next(programs));
+ }
+ list_free(programs);
+ return !err_flag;
+}
diff --git a/test/05_restore b/test/05_restore
new file mode 100644
index 0000000..b27ed35
--- /dev/null
+++ b/test/05_restore
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+init restore
+
+# setup test configs
+path1=$BIN/test1.conf
+path2=$BIN/test2.conf
+path3=$BIN/test3.conf
+path4=$BIN/test4.conf
+
+add_config prog1 $path1
+add_config prog1 $path2
+
+add_config prog2 $path3
+add_config prog2 $path4
+
+# delete prog1 links
+rm $path1 $path2
+
+# restore them
+exec $BIN/ck -c $BIN restore -p prog1 > /dev/null &
+wait $!
+
+for i in $($BIN/ck -c $BIN list -p prog1); do
+ if [[ ! -L "$i" ]]; then
+ err "Couldn't restore path $i"
+ exit 1
+ fi
+done
+
+## delete all links
+rm $path1 $path2 $path3 $path4
+
+# restore all
+exec $BIN/ck -c $BIN restore all > /dev/null &
+wait $!
+
+for i in $($BIN/ck -c $BIN list paths); do
+ if [[ ! -L "$i" ]]; then
+ err "Couldn't restore path $i"
+ exit 1
+ fi
+done
+
+clear_tests
+echo -e $PASS