/* list.c - the list action --------------------------------------------*- 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 "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();
}