aboutsummaryrefslogblamecommitdiffstats
path: root/src/list.c
blob: 0976ac1e55ab63121a303e0f2d9b22ce54a3ffd8 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                                

                   
                    

                     


                                                
































































































































                                                                                
                                                                                                   



































































                                                                             





























                                                                                           
                                                 












































                                                                                                 
/* 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)             \
    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();
}