aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actionhelper.c43
-rw-r--r--src/actionhelper.h5
-rw-r--r--src/actionparser.c22
-rw-r--r--src/actionparser.h1
-rw-r--r--src/actions.c63
-rw-r--r--src/dblayer.c105
-rw-r--r--src/dblayer.h7
7 files changed, 244 insertions, 2 deletions
diff --git a/src/actionhelper.c b/src/actionhelper.c
index ad259a2..0269470 100644
--- a/src/actionhelper.c
+++ b/src/actionhelper.c
@@ -260,6 +260,36 @@ ListOpt list_make_options(cklist *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)) {
+ while (1) {
+ HELP("%s %d %d", list_get(to), util_file_exists(list_get(to), NULL), !util_is_file_link(list_get(to)));
+ if (util_file_exists(list_get(to), NULL)
+ || !util_is_file_link(list_get(to))) {
+ sERR("File %s already exists. Terminating.", list_get(to));
+ return -1;
+ }
+ if (util_symlink_file(list_get(from), list_get(to))) {
+ sERR("Failed: %s -> %s", list_get(from), list_get(to));
+ return -1;
+ }
+ LOG("Linking: %s -> %s", list_get(from), list_get(to));
+ HELP("Linking: %s -> %s", list_get(from), list_get(to));
+ if (!list_next(from)) {
+ break;
+ }
+ if (!list_next(to)) {
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
/*****************/
/* PRINT RESULTS */
/*****************/
@@ -317,6 +347,14 @@ void print_HELP_result(int err) {
}
}
+void print_RESTORE_result(int err) {
+ if (!err) {
+ HELP("restore OK");
+ return;
+ }
+ sERR("restore NOT OK");
+}
+
void print_INIT_help() {
ckhelp("Initialize the database and create the file that holds");
ckhelp("the paths where configurations will be stored.");
@@ -406,6 +444,11 @@ void print_HELP_help() {
report_help();
}
+void print_RESTORE_help() {
+ ckhelp("Restore help");
+ report_help();
+}
+
void print_conf_help(void) {
ckhelp("Set a different ck configuration directory.\n");
ckhelp("This has to be passed before any action or action argument");
diff --git a/src/actionhelper.h b/src/actionhelper.h
index bfe0b85..4265691 100644
--- a/src/actionhelper.h
+++ b/src/actionhelper.h
@@ -53,6 +53,11 @@ extern void edit_print_suggested_configs(DB *db, const char *pName);
/********/
extern ListOpt list_make_options(cklist *args);
+/***********/
+/* RESTORE */
+/***********/
+extern int restore_make_links(cklist *from, cklist *to);
+
/************************/
/* PRINT RESULTS & HELP */
/************************/
diff --git a/src/actionparser.c b/src/actionparser.c
index 529876e..c4bfbc5 100644
--- a/src/actionparser.c
+++ b/src/actionparser.c
@@ -24,6 +24,7 @@ const char* const strEDIT[] = {"3", "edit", "e", "-e"};
const char* const strLIST[] = {"5", "list", "ls", "l", "-l", "-ls"};
const char* const strSEARCH[] = {"4", "search", "grep", "s", "-s"};
const char* const strHELP[] = {"5", "help", "h", "-?", "-h", "--help"};
+const char* const strRESTORE[] = {"3", "restore","r", "-r"};
const char* const strConfDir[] = {"2", "config", "-c"};
const char* const strVersion[] = {"2", "version", "--version"};
const char* const strVerbose1[] = {"2", "--verbose", "-v"};
@@ -160,6 +161,18 @@ int parse_HELP(UserOpt *opt) {
return 0;
}
+int parse_RESTORE(UserOpt *opt) {
+ /* Restore expects 1 to 2 arguments */
+ if (optNum < pos + 1
+ || optNum > pos + 2) {
+ opt->err = PERR_RESTORE_WRONG;
+ return -1;
+ }
+
+ int arg_num = optNum - pos;
+ fill_args_list(arg_num, opt);
+ return 0;
+}
int parse_vals(UserOpt *opt) {
switch (opt->action) {
@@ -354,6 +367,9 @@ void print_parser_error(UserOpt *opt) {
break;
case PERR_HELP_WRONG:
sprintf(errStr, "Get help for a ck action.\nUsage: %s action", names);
+ break;
+ case PERR_RESTORE_WRONG:
+ sprintf(errStr, "Restore links of programs.\nUsage: %s {all} | {-p programName}", names);
}
HELP("%s", errStr);
}
@@ -373,9 +389,11 @@ void print_parser_help() {
get_possible_action_strings(names, CKA_LIST);
ckhelp("List configs: \t%s", names);
get_possible_action_strings(names, CKA_SEARCH);
- ckhelp("Search: \t%s", names);
+ ckhelp("Search configs: \t%s", names);
+ get_possible_action_strings(names, CKA_RESTORE);
+ ckhelp("Restore links: \t%s", names);
get_possible_action_strings(names, CKA_HELP);
- ckhelp("Actions Help: \t%s", names);
+ ckhelp("Help: \t%s", names);
report_help();
}
diff --git a/src/actionparser.h b/src/actionparser.h
index d3c97c4..0a28511 100644
--- a/src/actionparser.h
+++ b/src/actionparser.h
@@ -27,6 +27,7 @@
X(EDIT) \
X(LIST) \
X(SEARCH) \
+ X(RESTORE) \
X(HELP)
enum ParseErrors {
diff --git a/src/actions.c b/src/actions.c
index 48a4066..5220864 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -300,3 +300,66 @@ int run_HELP(UserOpt *opt, Conf *conf) {
}
return 1;
}
+
+int run_RESTORE(UserOpt *opt, Conf *conf) {
+ UNUSED(conf);
+ DB db = open_DB(opt);
+ if (db.ptr == NULL) {
+ if (db.error == SQL_ERR_NO_TABLES) {
+ ERR("The database file is currupted. Run ck init anew.");
+ }
+ return 1;
+ }
+ cklist *from = list_make_new();
+ cklist *to = list_make_new();
+ int err_flag = 0;
+ if (strcmp(list_get(opt->args), "-p") == 0) {
+ if (list_next(opt->args)) {
+ if (program_exists(&db, list_get(opt->args))) {
+ if (restore_configs_exists(&db, conf, list_get(opt->args), from, to)) {
+ HELP("Making links for %s", list_get(opt->args));
+ }
+ else {
+ err_flag = 1;
+ }
+ }
+ else {
+ ERR("Program %s does not exist", list_get(opt->args));
+ err_flag = 1;
+ }
+ }
+ else {
+ sERR("-p needs a program name");
+ err_flag = 1;
+ }
+ }
+ else if (strcmp(list_get(opt->args), "all") == 0) {
+ if (!list_next(opt->args)) {
+ if (restore_all_exist(&db, conf, from, to)) {
+ HELP("Make all links");
+ }
+ else {
+ err_flag = 1;
+ }
+ }
+ else {
+ sERR("Wrong argument");
+ err_flag = 1;
+ }
+ }
+ else {
+ sERR("Wrong argument");
+ err_flag = 1;
+ }
+ close_DB(&db);
+ if (!err_flag) {
+ HELP("LINKS");
+ int rc = restore_make_links(from, to);
+ list_free(from);
+ list_free(to);
+ return rc;
+ }
+ list_free(from);
+ list_free(to);
+ return 1;
+}
diff --git a/src/dblayer.c b/src/dblayer.c
index acdf339..33e1682 100644
--- a/src/dblayer.c
+++ b/src/dblayer.c
@@ -842,3 +842,108 @@ int del_transaction_try(DB *db, char *arg, int conf) {
__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;
+ }
+ list_add(from, filePath);
+ list_add(to, /*path*/ (char *)sqlite3_column_text(stmt, 0));
+ }
+ 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 94ef7ea..13ac187 100644
--- a/src/dblayer.h
+++ b/src/dblayer.h
@@ -81,4 +81,11 @@ extern int list_get_path_program_tree(DB *db, cklist *ckl, int attr);
/*******/
extern int del_transaction_try(DB *db, char *arg, int conf);
+
+/***********/
+/* restore */
+/***********/
+
+extern int restore_configs_exists(DB *db, Conf *conf, const char *pName, cklist *from, cklist *to);
+extern int restore_all_exist(DB *db, Conf *conf, cklist *from, cklist *to);
#endif /* DBLAYER_H */