aboutsummaryrefslogblamecommitdiffstats
path: root/src/confparser.c
blob: 64bfe34c74c94090c4569232545e8802bd111a8e (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                                


                   

                   
                       
                     
 
                   

                                         

                                      

                     











                                        
                                         

                                          
              
   
                         
           

 
                                                     
                                             










                                                  



                                                         
 
                   


                                                    

                               

                                           
                                                 


                              

                      
                                              
                               

                              


                                                 
                                                 
                                                 
                                                 

                                                 
                                                 





                              





                                                                  
     











                                                   
                                                 
                                                                 
                             

                                                                         
                                                                         




                                                                         
                                                        

                        
                         



              
 
                            

                       
   

                         


   
                                           

                                                               
                                                                                       


             

                                                               
                                                                              


             
                                              
                             

   

                                           

                                           

             
 
                
                                        
                        



                               
                        

                    
 
            

           
/* confparser.h - Configuration file parser for ck ---------------------*- C -*-
 *
 * This file is part of ck, the config keeper
 *
 * -----------------------------------------------------------------------------
 *
 * Copyright (C) 2018  Anastasis Grammenos
 * GPLv3 (see LICENCE for the full notice)
 *
 * -------------------------------------------------------------------------- */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "ckutil.h"
#include "confparser.h"
#include "ckerrlog.h"

ERRLOG(configfile);

const char * const CONFIG_NAME = "/ckrc";

void conf_values_initialize(Conf *c) {
  c->scrt_dir = NULL;
  c->vc_dir = NULL;
}

int remove_newline(char buff[]) {
  int initLength = strlen(buff);
  for (int i = 0; i < initLength; i++) {
    if (buff[i] == '\n') {
      buff[i] = ' ';
    }
  }
  return strlen(buff);
}

int read_next_line(char *line, FILE *f) {
  char nextLine[STR_L];
  if (fgets(nextLine, STR_L, f) == NULL) {
    return -1;
  }
  strcpy(line, nextLine);
  return 0;
}

ConfVar match_variables(char *line, char matched[]) {
  if (line[0] == '#' || str_is_empty(line)) {
    return CV_NO_VAL_OR_COMMENT;
  }
#define X(var, str, name)                        \
  if (sscanf(line, str, matched) == 1) {         \
    return CV_##var;                             \
  }
  CONFIG_VARIABLES_TABLE
#undef X
  return -1;
}

void make_config_name(char * ret, const char *confPath) {
  char tmp[STR_L];
  strcpy(tmp, confPath);
  strcat(tmp, CONFIG_NAME);

  strcpy(ret, tmp);
}

ConfigParserResult parse(Conf *conf, UserOpt *opt) {
  conf_values_initialize(conf);
  FILE *confPtr;
  char confName[STR_L];
  make_config_name(confName, opt->confDir);
  if ((confPtr = fopen(confName, "r")) == NULL) {
    return CPR_NO_CONFIG_FILE;
  }
  int flag = 1;
  char line[STR_L];
  char matched[STR_L];
  while (read_next_line(line, confPtr) == 0) {
    if (strlen(line) > STR_L) {
      return CPR_WRONG_CONFIG;
    }
    switch(match_variables(line, matched)) {
#define X(var, str, name)                       \
      case CV_##var:                            \
        conf->var = malloc(strlen(matched)+1);  \
        strcpy(conf->var, matched);             \
        if (!util_is_dir(matched)) {            \
          return CPR_WRONG_##var;               \
        }                                       \
        LOG("Found %s: %s", name, conf->var);   \
        break;
      CONFIG_VARIABLES_TABLE
#undef X
    case CV_NO_VAL_OR_COMMENT:
      break;
    default:
      if (line[strlen(line) - 1] == '\n') {
        ERR("Config error in line: %.*s", strlen(line) - 1, line);
      }
      else {
        ERR("Config error in line: %s", line);
      }
    }
  }
#define X(var, str)                               \
  if (conf->var == NULL) {                        \
    flag = 0;                                     \
    CONFIG_VARIABLES_TABLE
#undef X
  if (flag) {
    return CPR_OK;
  }
  return CPR_NO_CONFIG_FILE;
}

int config_file_parse(Conf *conf, UserOpt *opt) {
  LOG("Using '%s' for ck configuration directory", opt->confDir);
  switch (parse(conf, opt)) {
#define X(var,str,name)                                                 \
    case CPR_WRONG_##var:                                               \
      ERR("%s %s defined in config doesn't exist", name, conf->var);    \
      return 0;                                                         \
    break;
    CONFIG_VARIABLES_TABLE
#undef X
  case CPR_NO_CONFIG_FILE:
    ERR("The config file specified could not be found");
    return 0;
  case CPR_WRONG_CONFIG:
    ERR("Config help\n");
  case CPR_OK:
    return 1;
  }
}

void free_conf(Conf *conf) {
  if (conf->vc_dir) {
    free(conf->vc_dir);
  }
  if (conf->scrt_dir) {
    free(conf->scrt_dir);
  }
}

int init_create_config_file(UserOpt *opt) {
  char absVCdir[STR_L];
  if (!util_file_exists(list_get_at(opt->args, 0), absVCdir)) {
    ERR("Version control directory: %s\ndoes not exist.\n", list_get_at(opt->args, 0));
    return 1;
  }

  char absSRdir[STR_L];
  if (!util_file_exists(list_get_at(opt->args, 1), absSRdir)) {
    ERR("Secret directory: %s\ndoes not exist.\n", list_get_at(opt->args, 1));
    return 1;
  }
  
  if (!util_file_exists(opt->confDir, NULL)) {
    util_mkdir(opt->confDir);
  }

  char confName[STR_L];
  make_config_name(confName, opt->confDir);
  FILE *f;
  if ((f = fopen(confName, "w")) == NULL) {
    return 1;
  }

  char tmp[200];
  strcpy(tmp, "version_control_dir = ");
  strcat(tmp, absVCdir);
  strcat(tmp, "\n");
  fputs(tmp, f);

  strcpy(tmp, "secret_dir = ");
  strcat(tmp, absSRdir);
  strcat(tmp, "\n");
  fputs(tmp, f);

  fclose(f);
  return 0;
}