aboutsummaryrefslogblamecommitdiffstats
path: root/src/edit.c
blob: 5179a548f8ca6367059a2504eb41e1eeb2b2182b (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                                

                   
                    

                     


                                                                                            






















                                                                 
                                                                                               


























































                                                                                         











































































                                                                                             
/* 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]");
}