aboutsummaryrefslogblamecommitdiffstats
path: root/src/actions.c
blob: 990b371a1a8833f6bcebef5265a49983011cf4ba (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                                                


                                             





                                                                                
                    
                         
                    
                   
                   
                     
 

               
                                         
               
                       

                                                         

                                     
                                          
              
   
                            


                               
                        
           


                                        
                       
                       
                                        
                                                               
     
               
   
                                              



                            
                                                                 
               
                           
                                                        
               
   
                          
                                           
                                                          
               
   
                               
                  
                             
                   

                  
              
   
                
           


                                        
               
        



                                              




                                                                 
                

                                                                 
                  
              
                          
                                   

                          
                                             
   
            

 
                                        


                                        
                                                               
     
              

   
                         






















                                                                                  
                                                 

                   
     





                                                                     
                                               
                 
     

                
                                                                                             


                                  










                                                                        

                            

                                  
                  
           

                
            

 
                                        


                                        
                                                               
     
              
   
 
                                     
                                                 
 
                    
                               
               
   
                       

                       
                                                                               

                  
                                     
          
               
                                                                                           

                         


















                                                                      
                                                                                                 
          


                        
                         

                
                              

                  
                                
   
       
                
                      
           


                      
            

 
                                          


                                                                        
   
                       






                                                               
                                  
                                                                              
                
                                                 

                

                                            
                                           
                             



                                       
                  








                                                  

 
                                        
               
                  









                                                    


                                                                 

                                                                 






                                                                 
            
 







                                                               
              







                                                                               
                                                                 

















                                                              
                                       














                             
              
                  



                                      


                  
            
 
/* actions.c - ck actions ----------------------------------------------*- C -*-
 *
 * This file is part of ck, the config keeper
 *
 * -----------------------------------------------------------------------------
 *
 * Copyright (C) 2018  Anastasis Grammenos
 * GPLv3 (see LICENCE for the full notice)
 *
 * -------------------------------------------------------------------------- */
#include "actions.h"
#include "actionhelper.h"
#include "dblayer.h"
#include "ckutil.h"
#include "cklist.h"
#include "ckerrlog.h"

ERRLOG(action);

int run_INIT(UserOpt * opt, Conf *conf) {
  UNUSED(conf);
  if (db_exists(opt)) {
    ERR("ck is already initialized in %s", opt->confDir);
    return -1;
  }
  if (init_create_config_file(opt)) {
    sERR("Cound not create config file.");
    return -1;
  }
  DB db = init_make_DB(opt);
  if (db.error == SQL_NO_ERR) {
    init_make_tables(&db);
  }
  sqlite3_close(db.ptr);
  return 0;
}

int run_ADD(UserOpt * opt, Conf *conf) {
  DB db = open_DB(opt);
  if (db.ptr == NULL) {
    if (db.error == SQL_ERR_NO_TABLES) {
      ERR("The database file is currupted. Run ck init anew.");
    }
    goto error;
  }
  AddOpt addOpt = add_make_options(opt->args);
  switch (addOpt.err) {
  case ADD_NO_ERR:
    break;
  case ADD_ERR_WRONG_CONFIG:
    ERR("The config file specified doesn't exist or is a link.");
    goto error;
  case ADD_ERR_WRONG_FLAGS:
    ERR("Flags are: -s for secret and -p for primary.");
    goto error;
  }
  add_print_opts(&addOpt);
  /* Try adding the new config to the DB */
  if (add_transaction_try(&db, &addOpt, conf->home_dir)) {
    goto error;
  }
  add_make_link(&addOpt, conf);
  char err[STR_M];
  if (add_err_message(err)) {
    PRINT_ERR(err);
  error:
    close_DB(&db);
    return -1;
  }
  close_DB(&db);
  return 0;
}

int run_DEL(UserOpt * opt, Conf *conf) {
  UNUSED(conf);
  DB db;

  DelOpt delOpt = del_make_options(opt->args);
  switch(delOpt.err) {
  case DEL_NO_ERR:
    db = open_DB(opt);
    if (db.ptr == NULL) {
      if (db.error == SQL_ERR_NO_TABLES) {
        ERR("The database file is currupted. Run ck init anew.");
      }
      return -1;
    }
    int rc = del_transaction_try(&db, delOpt.arg, delOpt.isConf);
    close_DB(&db);
    return rc;
  case DEL_ERR_WRONG_ARGS:
    ERR("Wrong delete arguments.");
    break;
  case DEL_ERR_WRONG_PATH:
    ERR("Path %s doesnt exist.", delOpt.arg);
  }
  return -1;
}

int run_EDIT(UserOpt *opt, Conf *conf) {
  DB db = open_DB(opt);
  if (db.ptr == NULL) {
    if (db.error == SQL_ERR_NO_TABLES) {
      ERR("The database file is currupted. Run ck init anew.");
    }
    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.");
        edit_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);
      edit_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;
}

int run_LIST(UserOpt *opt, Conf *conf) {
  DB db = open_DB(opt);
  if (db.ptr == NULL) {
    if (db.error == SQL_ERR_NO_TABLES) {
      ERR("The database file is currupted. Run ck init anew.");
    }
    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)                       \
    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;
}

int run_SEARCH(UserOpt *opt, Conf *conf) {
  if (system("which grep > /dev/null 2>&1") != 0) {
    ERR("No grep avaliable. Please make sure you have grep installed.");
    return -1;
  }
  DB db = open_DB(opt);
  if (db.ptr == NULL) {
    if (db.error == SQL_ERR_NO_TABLES) {
      ERR("The database file is currupted. Run ck init anew.");
    }
    return -1;
  }

  cklist *paths = list_make_new();
  list_get_paths(&db, paths, 0 /*basename*/, 0/*attributes*/, conf->home_dir);
  close_DB(&db);
  if (list_size(paths) && list_size(opt->args)) {
    do {
      FILE *cmd;
      char result[STR_L] = "";
      char command[STR_L] = "grep -H -n \"";
      strcat(command, list_get(opt->args));
      strcat(command, "\" ");
      strcat(command, list_get(paths));
      cmd = popen(command, "r");
      if (cmd == NULL) {
        list_free(paths);
        return -1;
      }
      while (fgets(result, sizeof(result), cmd)) {
        printf("%s", result);
      }
      pclose(cmd);
    } while(list_next(paths));
  }
  list_free(paths);
  return 0;
}

int run_HELP(UserOpt *opt, Conf *conf) {
  UNUSED(conf);
  char tmp[STR_M];
  if (strcmp(list_get(opt->args), "config") == 0) {
    print_conf_help();
    return 0;
  }

  if (strcmp(list_get(opt->args), "verbose") == 0) {
    print_verbose_help();
    return 0;
  }

  switch(parser_get_action(list_get(opt->args), NULL)) {
#define X(ACTION)                                               \
    case CKA_##ACTION:                                          \
      get_possible_action_strings(tmp, CKA_##ACTION);           \
      HELP("%s:\n%s", #ACTION, tmp);                            \
      print_##ACTION##_help();                                  \
      return 0;
    CK_ACTIONS
#undef X
  default:
    ERR("Unknown action: %s", list_get(opt->args));
  }
  return -1;
}

int run_RESTORE(UserOpt *opt, Conf *conf) {
  UNUSED(conf);
  DB db = open_DB(opt);
  if (db.ptr == NULL) {
    if (db.error == SQL_ERR_NO_TABLES) {
      ERR("The database file is currupted. Run ck init anew.");
    }
    return -1;
  }
  cklist *from = list_make_new();
  cklist *to = list_make_new();
  int err_flag = 0;
  if (strcmp(list_get(opt->args), "-p") == 0) {
    if (list_next(opt->args)) {
      if (program_exists(&db, list_get(opt->args))) {
        if (restore_configs_exists(&db, conf, list_get(opt->args), from, to)) {
          hLOG("Restoring links for %s...", list_get(opt->args));
        }
        else {
          err_flag = 1;
        }
      }
      else {
        ERR("Program %s does not exist", list_get(opt->args));
        err_flag = 1;
      }
    }
    else {
      sERR("-p needs a program name");
      err_flag = 1;
    }
  }
  else if (strcmp(list_get(opt->args), "all") == 0) {
    if (!list_next(opt->args)) {
      if (restore_all_exist(&db, conf, from, to)) {
        hLOG("Restoring all links...");
      }
      else {
        err_flag = 1;
      }
    }
    else {
      sERR("Wrong argument");
      err_flag = 1;
    }
  }
  else {
    sERR("Wrong argument");
    err_flag = 1;
  }
  close_DB(&db);
  int rc = -1;
  if (!err_flag) {
    rc = restore_make_links(from, to);
    if (rc) {
      sERR("Restore failed.");
    }
  }
  list_free(from);
  list_free(to);
  return rc;
}