/* list.c - the list action --------------------------------------------*- C -*- * * This file is part of ck, the config keeper * * ----------------------------------------------------------------------------- * * Copyright (C) 2019 Anastasis Grammenos * GPLv3 (see LICENCE for the full notice) * * -------------------------------------------------------------------------- */ #include #include "dblayer.h" #include "ckerrlog.h" ERRLOG(list); static 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; } static 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 run_LIST(UserOpt *opt, Conf *conf) { DB db; if (open_DB(&db, opt)) { return -1; } cklist *the_list = list_make_new(); ListOpt listOpt = list_make_options(opt->args); if (listOpt.err) { ERR("Wrong list options."); goto error; } char tmp[STR_L] = ""; switch(listOpt._lt) { case LT_PATH: list_get_paths(&db, the_list, listOpt.bName, listOpt.attr, conf->home_dir); break; case LT_PROGRAM: list_get_programs(&db, the_list); break; case LT_TREE: list_get_path_program_tree(&db, the_list, listOpt.bName, listOpt.attr, conf->home_dir); list_print(the_list); goto close; case LT_CKCONF: strcat(tmp, "ck configuration directory path: "); strcat(tmp, opt->confDir); list_add(the_list, tmp); #define X(var, str, name, optional) \ if (conf->var) { \ strcpy(tmp, ""); \ strcat(tmp, name); \ strcat(tmp, ": "); \ strcat(tmp, conf->var); \ list_add(the_list, tmp); \ } CONFIG_VARIABLES_TABLE; #undef X list_print(the_list); goto close; case LT_PROG_CONFS: if (!program_exists(&db, listOpt.pName)) { ERR("Program %s doesn't exist in the database.", listOpt.pName); goto error; } get_program_paths(&db, the_list, listOpt.pName, listOpt.bName, listOpt.attr, conf->home_dir); break; } switch(listOpt._lst) { case LST_PLAIN: list_print(the_list); break; case LST_LISP: list_print_lisp(the_list); break; case LST_PYTHON: list_print_python(the_list); } close: close_DB(&db); list_free(the_list); return 0; error: close_DB(&db); list_free(the_list); return -1; } 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(); }