/* edit.c - the edit 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(edit);
static 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;
}
static 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;
}
int run_EDIT(UserOpt *opt, Conf *conf) {
DB db;
if (open_DB(&db, opt)) {
return -1;
}
list_rewind(opt->args);
char confPath[STR_L] = "";
char confName[STR_M] = "";
int secret = 0;
/* Since we are here, args have to be 1 or 2 */
char *pName = list_get(opt->args);
if (!program_exists(&db, pName)) {
ERR("Program %s doesn't exist in the database.", pName);
goto error;
}
/* If there is no next argument */
if (!list_next(opt->args)) {
/* If there is no primary config*/
if (edit_get_prime_config_from_program(&db, pName, confName, &secret) == -1) {
/* If the program has only one config */
if (get_config_number(&db, pName) == 1) {
if (edit_get_config(&db, pName, confName, NULL, &secret)) {
ERR("Coudln't find config file for %s", pName);
goto error;
}
}
/* If the program has many configs */
else {
HELP("Ambiguous config. Please type the config name after the program.");
print_suggested_configs(&db, pName);
goto error;
}
}
}
/* If there are more arguments */
else {
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);
print_suggested_configs(&db, pName);
goto error;
}
}
close_DB(&db);
str_join_dirname_with_basename(confPath, secret ? conf->scrt_dir : conf->vc_dir, confName);
char *editor = getenv("EDITOR");
char command[STR_L] = "";
if (str_is_empty(editor)) {
if (system("which nano > /dev/null 2>&1") != 0) {
ERR("Nano not found. Please set $EDITOR to your desired editor.");
return -1;
}
strcpy(command, "nano");
} else {
strcpy(command, editor);
}
strcat(command, " ");
strcat(command, confPath);
HELP("editing...\n%s", command);
system(command);
return 0;
error:
close_DB(&db);
return -1;
}
void print_EDIT_help() {
HELP("ck edit PROGRAM_NAME [CONFIG_BASENAME]");
}