diff options
-rw-r--r-- | CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/actionparser.c | 241 | ||||
-rw-r--r-- | src/actionparser.h | 70 | ||||
-rw-r--r-- | src/actions.c | 115 | ||||
-rw-r--r-- | src/actions.h | 20 | ||||
-rw-r--r-- | src/argumentparser.h | 27 | ||||
-rw-r--r-- | src/checks.c | 133 | ||||
-rw-r--r-- | src/checks.h | 31 | ||||
-rw-r--r-- | src/ck.c | 44 | ||||
-rw-r--r-- | src/confparser.c | 127 | ||||
-rw-r--r-- | src/confparser.h | 45 | ||||
-rw-r--r-- | src/dblayer.c | 112 | ||||
-rw-r--r-- | src/dblayer.h | 35 | ||||
-rw-r--r-- | src/main.c | 85 |
14 files changed, 1012 insertions, 88 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1471290..508dd3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,12 +5,21 @@ project(ck C) # Set project directories set(PROJECT_SOURCE_DIR ./src) # Set source code locations -set(ckBin_src ${PROJECT_SOURCE_DIR}/main.c) +set(ckBin_src ${PROJECT_SOURCE_DIR}/ck.c) set(ckLib_src - ${PROJECT_SOURCE_DIR}/main.c + ${PROJECT_SOURCE_DIR}/ck.c + ${PROJECT_SOURCE_DIR}/actionparser.c + ${PROJECT_SOURCE_DIR}/actions.c + ${PROJECT_SOURCE_DIR}/confparser.c + ${PROJECT_SOURCE_DIR}/checks.c + ${PROJECT_SOURCE_DIR}/dblayer.c ) set(ckLib_hdr -# ${PROJECT_SOURCE_DIR}/tui.hpp + ${PROJECT_SOURCE_DIR}/actionparser.h + ${PROJECT_SOURCE_DIR}/actions.h + ${PROJECT_SOURCE_DIR}/confparser.h + ${PROJECT_SOURCE_DIR}/checks.h + ${PROJECT_SOURCE_DIR}/dblayer.h ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) diff --git a/src/actionparser.c b/src/actionparser.c new file mode 100644 index 0000000..33e8ccc --- /dev/null +++ b/src/actionparser.c @@ -0,0 +1,241 @@ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "actionparser.h" + +/* -------------------------------------------------------------------------- + * The following code is resposinble for parsing the command line arguments + * and report any errors that might come up. + * -------------------------------------------------------------------------- */ + +/* accepted commands */ +/* [0] is the count */ +const char* const strINIT[] = {"2", "init", "-i"}; +const char* const strADD[] = {"2", "add", "-a"}; +const char* const strDEL[] = {"2", "del", "-d"}; +const char* const strEDIT[] = {"3", "edit", "e", "-e"}; +const char* const strLIST[] = {"3", "list", "ls", "-ls"}; +const char* const strSEARCH[] = {"3", "search", "s", "-s"}; +const char* const strHELP[] = {"4", "help", "?", "-h", "--help"}; + +/* Number of opts */ +static int optNum; +/* holds the list of the opts + as given by the user */ +static char **opts; +/* points to the current token */ +static char *token; +/* points to the position + * to be read */ +static int pos = 0; + +/* Reads the next token and returns it's position + * Returns -1 otherwise */ +int nextToken() { + if (pos < optNum) { + token = opts[pos]; + return pos++; + } + else { + token = ""; + return -1; + } +} + +void getOpt(int position, UserOpt *opt) { + // get arg + nextToken(); + + // allocate memory + opt->argv[position] = (char *)malloc((strlen(token)+1)*sizeof(char)); + strcpy(opt->argv[position], token); +} + +/* When starting to parse the action, + * `pos` should be at 2 + * like so "ck ACTION ..." + * ^ */ +int parseINIT(UserOpt *opt) { + // if db exists init should fail before checking for args + + // INIT expects 2 arguments + // starting from 0 + opt->argc = 2; + if (optNum != pos /* already consumed */ + opt->argc) { + opt->err = PERR_INIT_WRONG; + return -1; + } + + for (int i = 0; i < opt->argc; i++) { + getOpt(i, opt); + } + return 1; +} + +int parseADD(UserOpt *opt) { + // ADD expects 2 to 4 arguments + if (optNum <= pos + 1 + || optNum > pos + 4) { + opt->err = PERR_ADD_WRONG; + return -1; + } + return 1; +} + +int parseDEL(UserOpt *opt) { +} +int parseEDIT(UserOpt *opt) { +} +int parseLIST(UserOpt *opt) { +} +int parseSEARCH(UserOpt *opt) { +} +int parseHELP(UserOpt *opt) { +} + + +int parseVals(UserOpt *opt) { + switch (opt->action) { +#define X(ACTION) \ + case CKA_##ACTION: \ + return parse##ACTION(opt); + CK_ACTIONS +#undef X + default: + // can't end up here, but it prevents a compiler warning + opt->err = PERR_UNKONW_ACTION; + return -1; + break; + } + return 1; +} + +CkAction determineAction() { + int i = 0; +#define X(ACTION) \ + for (i = 1; i < atoi(str##ACTION[0]) + 1; i++) { \ + if (strcmp(token, str##ACTION[i]) == 0) { \ + return CKA_##ACTION; \ + } \ + } + CK_ACTIONS +#undef X + return -1; +} + +UserOpt initUserOpt() { + UserOpt uo; + uo.action = -1; + uo.err = PERR_NOERR; + uo.argc = 0; + for (int i = 0; i < 10; i++) { + uo.argv[i] = NULL; + } + return uo; +} + +ParseResult parseAction(int argc, char* argv[], UserOpt *opt) { + *opt = initUserOpt(); + if (argc < 2) { + return OPR_HELP; + } + opts = argv; + optNum = argc; + + // skip the program nake + nextToken(); + + // get action + nextToken(); + opt->action = determineAction(); + if (opt->action == -1) { + opt->err = PERR_UNKONW_ACTION; + return OPR_ERR; + } + if (opt->action == CKA_HELP) { + return OPR_HELP; + } + + // parse values + if (!parseVals(opt)) { + return OPR_ERR; + } + + if (opt->err == PERR_NOERR) { + return OPR_OK; + } + else { + return OPR_ERR; + } +} + +const char * getPossibleActionName(const char* const strAction[]) { + char *names; + size_t size = 2; // first chars "{ " + for (int i = 1; i < atoi(strAction[0]) + 1; i++) { + size += strlen(strAction[i]) + 2; // comma and space for each entry and " }" for the last one + } + if ((names = malloc(size)) != NULL) { + strcpy(names, "{ "); + int i = 1; + for (; i < atoi(strAction[0]); i++) { + strcat(names, strAction[i]); + strcat(names, ", "); + } + // last one + strcat(names, strAction[atoi(strAction[0])]); + strcat(names, " }"); + return names; + } + return NULL; +} + +void printParserError(UserOpt *opt) { + char *errStr = NULL; + switch (opt->err) { + case PERR_NOERR: + return; + case PERR_UNKONW_ACTION: + asprintf(&errStr, "Unknown action: %s", token); + break; + case PERR_INIT_WRONG: + asprintf(&errStr, "Initialize database\nUsage: %s VC_dir SCRT_dir DB_dir", getPossibleActionName(strINIT)); + break; + case PERR_ADD_WRONG: + asprintf(&errStr, "Add config (new or existing)\nUsage: %s ProgramName ConfigPath [-s](secret) [-p](primary)", getPossibleActionName(strADD)); + break; + case PERR_DEL_WRONG: + asprintf(&errStr, "Delete config or program\nUsage: %s ProgramName ConfigPath [-s](secret) [-p](primary)", getPossibleActionName(strDEL)); + break; + case PERR_EDIT_WRONG: + asprintf(&errStr, "Edit config\nUsage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_LIST_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_SEARCH_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + case PERR_HELP_WRONG: + asprintf(&errStr, "Usage: add ProgramName ConfigPath [-s](secret) [-p](primary)"); + break; + } + printf("Parsing error\n%s\n", errStr); + exit(1); +} + +void printParserHelp() { + printf("ck - the config keeper"); + printf("\n----------------------"); + printf("\n----------------------\n"); + printf("Usage:\n"); + printf("Initialize: \t%s\n", getPossibleActionName(strINIT)); + printf("Add config: \t%s\n", getPossibleActionName(strADD)); + printf("Delete config: \t%s\n", getPossibleActionName(strDEL)); + printf("Edit config: \t%s\n", getPossibleActionName(strEDIT)); + printf("List configs: \t%s\n", getPossibleActionName(strLIST)); + printf("Search: \t%s\n", getPossibleActionName(strSEARCH)); + printf("Print this: \t%s\n", getPossibleActionName(strHELP)); + exit(0); +} diff --git a/src/actionparser.h b/src/actionparser.h new file mode 100644 index 0000000..97d9d52 --- /dev/null +++ b/src/actionparser.h @@ -0,0 +1,70 @@ +/* actionparser.h - Action parser for ck------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * + * The code here and in actionparser.c is responsible for parsing + * the user's input from the command line and return a struct + * of the user's options ready to be handled by the rest of the + * procedures. + * + * Keeps track of what error occured where and provides + * printParserHelp() and printParserError() functions + * to notify the user + * + * ------------------------------------------------------------------ */ +#ifndef ACTIONPARSER_H +#define ACTIONPARSER_H + +#define CK_ACTIONS \ + X(INIT) \ + X(ADD) \ + X(DEL) \ + X(EDIT) \ + X(LIST) \ + X(SEARCH) \ + X(HELP) + +typedef enum ParseErrors ParseError; +enum ParseErrors { + PERR_NOERR = 0, +#define X(ACTION) \ + PERR_##ACTION##_WRONG, + CK_ACTIONS +#undef X + PERR_UNKONW_ACTION, +}; + +typedef enum CkActions CkAction; +enum CkActions { + CKA_INIT, + CKA_ADD, // program, path, primary, secret + CKA_DEL, // program regexp, if only programm, delete everything related + CKA_EDIT, // program regexp, if only program, edit primary + CKA_LIST, // list_type{tree,paths,programs} + CKA_SEARCH, // search_mode, regexp + CKA_HELP // help +}; + +typedef enum OptParserResults ParseResult; +enum OptParserResults { + OPR_OK, + OPR_ERR, + OPR_HELP +}; + +typedef struct UserOptions UserOpt; +struct UserOptions { + ParseError err; + CkAction action; + int argc; + char *argv[10]; // action's options +}; + + +extern ParseResult parseAction(int argc, char* argv[], UserOpt *opt); +extern void printParserError(); +extern void printParserHelp(); + +#endif // ACTIONPARSER_H diff --git a/src/actions.c b/src/actions.c new file mode 100644 index 0000000..9840722 --- /dev/null +++ b/src/actions.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "actions.h" +#include "dblayer.h" + +int init_create_config_file(UserOpt *opt) { + struct stat st = {0}; + if (stat("/home/gramanas/.ck", &st) == -1) { + mkdir("/home/gramanas/.ck", 0755); + } + + FILE *f; + if ((f = fopen("/home/gramanas/.ck/ckrc", "w")) == NULL) { + return 1; + } + char tmp[200]; + if (stat(opt->argv[0], &st) == -1) { + printf("Version control directory: %s\ndoes not exist.\n", opt->argv[0]); + return 1; + } + strcpy(tmp, "version_control_dir = "); + strcat(tmp, opt->argv[0]); + strcat(tmp, "\n"); + fputs(tmp, f); + if (stat(opt->argv[1], &st) == -1) { + printf("Secret directory: %s\ndoes not exist.\n", opt->argv[1]); + return 1; + } + strcpy(tmp, "secret_dir = "); + strcat(tmp, opt->argv[1]); + strcat(tmp, "\n"); + fputs(tmp, f); + fclose(f); + return 0; +} + +int run_INIT(UserOpt * opt, Conf *conf) { + if (db_exists()) { + printf("ck is already initialized.\n"); + return 0; + } + if (init_create_config_file(opt)) { + return 0; + } + DB db = init_make_DB(); + if (db.error == SQL_NO_ERR) { + init_make_tables(&db); + } + sqlite3_close(db.get); + return 1; +} + +int run_ADD(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "add"); + DB db = open_DB(); + if (db.get == NULL) { + if (db.error == SQL_ERR_NO_TABLES) { + printf("no tables\n"); + } + } + return 0; +} + +int run_DEL(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "del"); + return 0; +} + +int run_EDIT(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "edit"); + return 0; +} + +int run_LIST(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "list"); + return 0; +} + +int run_SEARCH(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "search"); + return 0; +} + +int run_HELP(UserOpt * opt, Conf *conf) { + if (!db_exists()) { + printf("ck is not initialized.\nRun ck init first."); + return 0; + } + printf("Running %s\n", "help"); + return 0; +} diff --git a/src/actions.h b/src/actions.h new file mode 100644 index 0000000..9fc0f45 --- /dev/null +++ b/src/actions.h @@ -0,0 +1,20 @@ +/* actions.h - Action parser for ck ----------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * + * + * ------------------------------------------------------------------ */ +#ifndef ACTIONS_H +#define ACTIONS_H + +#include "actionparser.h" +#include "confparser.h" + +#define X(ACTION) \ + extern int run_##ACTION(UserOpt *, Conf *); +CK_ACTIONS +#undef X + +#endif /* ACTIONS_H */ diff --git a/src/argumentparser.h b/src/argumentparser.h new file mode 100644 index 0000000..7674e52 --- /dev/null +++ b/src/argumentparser.h @@ -0,0 +1,27 @@ +/* argumentparser.h - Argument parser for ck------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * + * The code here and in argumentparser.c is responsible for parsing + * the user's input from the command line + * + * Keeps track of what error occured where and provides + * printParserHelp() and printParserError() functions + * to notify the user + * + * ------------------------------------------------------------------ */ +#ifndef ARGUMENTPARSER_H +#define ARGUMENTPARSER_H +#define INIT_ALIAS \ + + +#define ARGUMENT_TABLE \ + X(init, ) + +typedef enum ParseResults ParseResult; + +extern ParseResult parse(int argc, char *argv[]); + +#endif // ARGUMENTPARSER_H diff --git a/src/checks.c b/src/checks.c new file mode 100644 index 0000000..80b1954 --- /dev/null +++ b/src/checks.c @@ -0,0 +1,133 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <dirent.h> + +#include "checks.h" + + + +/* const char* const matchVCDirName = " version_control_dir = %s"; */ +/* const char* const matchSCRTDirName = " secret_dir = %s"; */ +/* const char* const matchDBDirName = " database_dir = %s"; */ + +/* ConfigParserResult parseConfigFile(FILE *f, Conf *c) { */ +/* char *vc_dir, *scrt_dir, *db_dir; */ +/* DIR *dir; */ + +/* char * buffer = 0; */ +/* long length; */ +/* if (f) { */ +/* fseek(f, 0, SEEK_END); */ +/* length = ftell (f); */ +/* fseek(f, 0, SEEK_SET); */ +/* buffer = malloc (length); */ +/* if (buffer) { */ +/* fread (buffer, 1, length, f); */ +/* for (int i = 0; i < length; i++) { */ +/* if (buffer[i] == '\n') { */ +/* buffer[i] = ' '; */ +/* } */ +/* } */ +/* } */ +/* fclose (f); */ +/* } */ + + /* if (buffer) { */ + /* // VC dir */ + /* vc_dir = malloc(sizeof(char)*100); */ + /* if (sscanf(buffer, matchVCDirName, vc_dir) != 1) { */ + /* return CPR_NO_VC_DIR; */ + /* } */ + /* dir = opendir(vc_dir); */ + /* if (!dir) { */ + /* return CPR_WRONG_VC_DIR; */ + /* } */ + /* closedir(dir); */ + /* c->VC_dir = vc_dir; */ + +/* /\* printf("%s", buffer); *\/ */ + +/* // SCRT_dir */ +/* scrt_dir = malloc(sizeof(char)*100); */ +/* if(sscanf(buffer, matchSCRTDirName, scrt_dir) != 1) { */ +/* return CPR_NO_SCRT_DIR; */ +/* } */ +/* dir = opendir(scrt_dir); */ +/* if (!dir) { */ +/* return CPR_WRONG_SCRT_DIR; */ +/* } */ +/* c->SCRT_dir = scrt_dir; */ + +/* // DB_dir */ +/* db_dir = malloc(sizeof(char)*100); */ +/* if (sscanf(buffer, matchDBDirName, db_dir) != 1) { */ +/* return CPR_NO_DB_DIR; */ +/* } */ +/* dir = opendir(db_dir); */ +/* if (!dir) { */ +/* return CPR_WRONG_DB_DIR; */ +/* } */ +/* c->DB_dir = db_dir; */ +/* } */ +/* return CPR_OK; */ +/* } */ + + +/* char *getConfigPath() { */ +/* char *home = getenv("HOME"); */ +/* char *path; */ +/* if (home == NULL) { */ +/* printf("HOME variable is not set. Can't find config."); */ + +/* } */ +/* if ((path = malloc(strlen(home)+strlen(configFilename)+1 /\* for the slash *\/))) { */ +/* strcat(path, home); */ +/* strcat(path, "/"); */ +/* strcat(path, configFilename); */ +/* } */ +/* return path; */ +/* } */ + +// -1 config file problem +// 0 config content problem +// 1 all good +/* int doConfigCheck(Conf *conf) { */ +/* char* ckConfigPath = getConfigPath(); */ +/* if (ckConfigPath == NULL) { */ +/* return -1; */ +/* } */ +/* FILE *confPtr; */ +/* if ((confPtr = fopen(ckConfigPath, "r")) == NULL){ */ +/* return -1; */ +/* } */ +/* return 2; */ +/* } */ + +/* /\* CheckResult doInitCheck(Conf *conf) { */ + /* switch (doConfigCheck(conf)) { */ + /* case CPR_NO_VC_DIR: */ + /* printf("There is no VersionControl directory defined in the configuration file.\n"); */ + /* return CR_NO_CONFIG; */ + /* case CPR_WRONG_VC_DIR: */ + /* printf("The VersionControl directory defined in the configuration file is wrong.\n"); */ + /* return CR_WRONG_CONFIG; */ + /* case CPR_NO_SCRT_DIR: */ + /* printf("There is no Secret directory defined in the configuration file.\n"); */ + /* return CR_NO_CONFIG; */ + /* case CPR_WRONG_SCRT_DIR: */ + /* printf("The Secret directory defined in the configuration file is wrong.\n"); */ + /* return CR_WRONG_CONFIG; */ + /* case CPR_NO_DB_DIR: */ + /* printf("There is no Database directory defined in the configuration file.\n"); */ + /* return CR_NO_CONFIG; */ + /* case CPR_WRONG_DB_DIR: */ + /* printf("The Database directory defined in the configuration file is wrong.\n"); */ + /* return CR_WRONG_CONFIG; */ + /* case CPR_OK: */ + /* break; */ + /* } */ +// return 0; + //doDbCheck(); +//} diff --git a/src/checks.h b/src/checks.h new file mode 100644 index 0000000..c165c95 --- /dev/null +++ b/src/checks.h @@ -0,0 +1,31 @@ +/* optparser.h - Opt parser for ck -----------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * + * The code here and in checks.c is responsible for checking + * if a database file is present and if the user has initialized + * ck before with correct VC_dir and SCRT_dir paths. + * + * It is called before the parsing of the user's arguments + * in order to make sure that everything is setup properly + * for the later operations. + * + * ------------------------------------------------------------------ */ +#ifndef CHECKS_H +#define CHECKS_H + +typedef enum CheckResults CheckResult; +enum CheckResults { + CR_OK, + CR_NO_CONFIG, + CR_WRONG_CONFIG, + CR_NO_DB +}; + + + +CheckResult doInitCheck(); + +#endif // CHECKS_H diff --git a/src/ck.c b/src/ck.c new file mode 100644 index 0000000..56dec2e --- /dev/null +++ b/src/ck.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <string.h> +#include <sqlite3.h> + +#include "actionparser.h" +#include "actions.h" +#include "confparser.h" +#include "dblayer.h" + + int main(int argc, char *argv[]) { + sqlite3 *db; + int rc; + + Conf conf; + config_file_parse(&conf); + //return 1; + +#define X(var, str, name) \ + printf("%s: %s\n", name, conf.var); + CONFIG_VARIABLES_TABLE +#undef X + UserOpt opt; + switch(parseAction(argc, argv, &opt)) { + case OPR_HELP: + printParserHelp(); + case OPR_ERR: + printParserError(&opt); + case OPR_OK: + break; + // + } + + switch(opt.action) { +#define X(ACTION) \ + case CKA_##ACTION: \ + run_##ACTION(&opt, &conf); \ + break; + CK_ACTIONS +#undef X + + } + + return 0; +} diff --git a/src/confparser.c b/src/confparser.c new file mode 100644 index 0000000..d4d33f5 --- /dev/null +++ b/src/confparser.c @@ -0,0 +1,127 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <dirent.h> +#include <ctype.h> +#include "confparser.h" + +const char* const configFilename = ".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); +} + +char* read_next_line(FILE *f) { + char nextLine[200]; + char *line; + if (fgets(nextLine, 200, f) == NULL) { + return NULL; + } + line = malloc(remove_newline(nextLine)); + strcpy(line, nextLine); + return line; +} + +int is_empty(const char *s) { + while (*s != '\0') { + if (!isspace((unsigned char)*s)) + return 0; + s++; + } + return 1; +} + +ConfVar match_variables(char *line, char matched[]) { + if (line[0] == '#' || 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; +} + +int is_dir(char *path) { + DIR *dir; + dir = opendir(path); + if (!dir) { + return 0; + } + closedir(dir); + return 1; +} + +ConfigParserResult parse(Conf *conf) { + conf_values_initialize(conf); + FILE *confPtr; + if ((confPtr = fopen("/home/gramanas/.ck/ckrc", "r")) == NULL) { + return CPR_NO_CONFIG_FILE; + } + int flag = 1; + char *line = read_next_line(confPtr); + char matched[200]; + while (line != NULL) { + switch(match_variables(line, matched)) { +#define X(var, str, name) \ + case CV_##var: \ + conf->var = malloc(strlen(matched)); \ + strcpy(conf->var, matched); \ + if (!is_dir(matched)) { \ + return CPR_WRONG_##var; \ + } \ + break; + CONFIG_VARIABLES_TABLE +#undef X + case CV_NO_VAL_OR_COMMENT: + break; + default: + printf("%s:\n%s\n", "Config error in line", line); + } + free(line); + line=read_next_line(confPtr); + } +#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) { + switch (parse(conf)) { +#define X(var,str,name) \ + case CPR_WRONG_##var: \ + printf("Config error:\n" \ + "%s: %s\n" \ + "defined in config does not exist\n", name, conf->var); \ + return 0; \ + break; + CONFIG_VARIABLES_TABLE +#undef X + case CPR_NO_CONFIG_FILE: + printf("The config file specified could not be found\n"); + return 0; + case CPR_WRONG_CONFIG: + printf("Config help\n"); + case CPR_OK: + return 1; + } +} diff --git a/src/confparser.h b/src/confparser.h new file mode 100644 index 0000000..2ed8f82 --- /dev/null +++ b/src/confparser.h @@ -0,0 +1,45 @@ +/* confparser.h - Configuration file parser for ck -------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * The code here and in confparser.c is responsible parsing + * the configuration and get the values set there + * ------------------------------------------------------------------ */ +#ifndef CONFPARSER_H +#define CONFPARSER_H +#define CONFIG_VARIABLES_TABLE \ + X(VC_dir, " version_control_dir = %s ", "Version Control directory") \ + X(SCRT_dir, " secret_dir = %s " , "Secret directory") + + +typedef enum ConfingVariables ConfVar; +#define X(var, str, name) CV_##var, +enum ConfingVariables { + CV_NO_VAL_OR_COMMENT, + CONFIG_VARIABLES_TABLE +}; +#undef X + +typedef enum ConfigParserResults ConfigParserResult; +#define X(var, str, name) \ + CPR_WRONG_##var, +enum ConfigParserResults { + CPR_OK, + CPR_NO_CONFIG_FILE, + CPR_WRONG_CONFIG, + CONFIG_VARIABLES_TABLE +}; +#undef X + +typedef struct ConfigValues Conf; +#define X(var, str, name) char* var; +struct ConfigValues { + ConfigParserResult result; + CONFIG_VARIABLES_TABLE +}; +#undef X + +extern int config_file_parse(Conf *conf); + +#endif // CONFPARSER_H diff --git a/src/dblayer.c b/src/dblayer.c new file mode 100644 index 0000000..eee60a6 --- /dev/null +++ b/src/dblayer.c @@ -0,0 +1,112 @@ +/* dblayer.c - Database layer for ck ---------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * ------------------------------------------------------------------ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dblayer.h" + +int db_exists() { + FILE *db_file; + + if ((db_file = fopen("/home/gramanas/.ck/ckdb", "rb")) == NULL) { + return 0; + } + fclose(db_file); + return 1; +} + +// check if db has the correct tables +int check_initialized_DB(sqlite3 *db) { + char *sql = "SELECT * FROM SQLITE_MASTER;"; + sqlite3_stmt *stmt; + + int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); + + int program_table_ok, config_table_ok, rel_table_ok = 0; + while (sqlite3_step(stmt) != SQLITE_DONE) { + const unsigned char *tmpbuf = sqlite3_column_text(stmt, 1); + if (strcmp((char *)tmpbuf, "PROGRAM") == 0) { + program_table_ok = 1; + } + if (strcmp((char *)tmpbuf, "CONFIG") == 0) { + config_table_ok = 1; + } + if (strcmp((char *)tmpbuf, "REL") == 0) { + rel_table_ok = 1; + } + } + + if (!program_table_ok + || !config_table_ok + || !rel_table_ok ) { + return 1; + } + + sqlite3_finalize(stmt); + return 0; +} + +DB empty_DB(SqlError err) { + return (DB){ .get = NULL, .error = err }; +} + +DB new_DB(sqlite3 *db) { + return (DB){ .get = db, .error = SQL_NO_ERR }; +} + +DB init_make_DB() { + sqlite3 *db; + int rc; + + rc = sqlite3_open("/home/gramanas/.ck/ckdb", &db); + + if (rc) { + return empty_DB(SQL_ERR_NO_DB_FILE); + } + + return new_DB(db); +} + +DB open_DB() { + sqlite3 *db; + int rc; + + rc = sqlite3_open("/home/gramanas/.ck/ckdb", &db); + + if (rc) { + return empty_DB(SQL_ERR_NO_DB_FILE); + } + + if (check_initialized_DB(db)) { + return empty_DB(SQL_ERR_NO_TABLES); + } + + return new_DB(db); +} + +void init_make_tables(DB *db) { + char * sql = "CREATE TABLE REL(" + "pId INT NOT NULL," + "cId INT NOT NULL);" + "CREATE TABLE PROGRAM(" + "id INT PRIMARY KEY NOT NULL," + "name TEXT NOT NULL);" + "CREATE TABLE CONFIG(" + "id INT PRIMARY KEY NOT NULL," + "path TEXT NOT NULL," + "secret INT NOT NULL," + "prime INT NOT NULL);"; + + char *err_msg = NULL; + int rc = sqlite3_exec(db->get, sql, 0, 0, &err_msg); + if (rc != SQLITE_OK ) { + printf("SQL error: %s\n", err_msg); + sqlite3_free(err_msg); + db->error = SQL_ERR_SQLITE; + return; + } +} diff --git a/src/dblayer.h b/src/dblayer.h new file mode 100644 index 0000000..4fe4d99 --- /dev/null +++ b/src/dblayer.h @@ -0,0 +1,35 @@ +/* dblayer.h - Database layer for ck ---------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * --------------------------------------------------------------------- + * + * + * ------------------------------------------------------------------ */ +#ifndef DBLAYER_H +#define DBLAYER_H + +#include <sqlite3.h> + +typedef enum SqlErrors SqlError; +enum SqlErrors { + SQL_NO_ERR = 0, + SQL_ERR_NO_DB_FILE, + SQL_ERR_NO_TABLES, + SQL_ERR_SQLITE +}; + +typedef struct DBstruct DB; +struct DBstruct { + sqlite3 *get; + SqlError error; +}; + +extern int db_exists(); +extern DB open_DB(); + +/* init */ +extern void init_make_tables(DB *db); +extern DB init_make_DB(); + +#endif /* DBLAEYR_H */ diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 6de5b43..0000000 --- a/src/main.c +++ /dev/null @@ -1,85 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sqlite3.h> - -static int callback(void *NotUsed, int argc, char **argv, char **azColName) { - int i; - for(i = 0; i<argc; i++) { - printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); - } - printf("\n"); - return 0; -} - -void initDb(sqlite3 *db) { - char *zErrMsg = 0; - char *sql; - int rc; - - /* Create SQL statement */ - sql = "CREATE TABLE PROGRAM(" \ - "id INT PRIMARY KEY NOT NULL," \ - "name TEXT NOT NULL);"; - - /* Execute SQL statement */ - rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); - - if( rc != SQLITE_OK ){ - fprintf(stderr, "SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } else { - fprintf(stdout, "Table created successfully\n"); - } - sql = "CREATE TABLE CONFIG(" \ - "id INT PRIMARY KEY NOT NULL," \ - "path TEXT NOT NULL," \ - "secret INT NOT NULL," \ - "prime INT NOT NULL);"; - - /* Execute SQL statement */ - rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); - - if( rc != SQLITE_OK ){ - fprintf(stderr, "SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } else { - fprintf(stdout, "Table created successfully\n"); - } - sql = "CREATE TABLE REL(" \ - "pId INT NOT NULL," \ - "cId INT NOT NULL);"; - - /* Execute SQL statement */ - rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); - - if( rc != SQLITE_OK ){ - fprintf(stderr, "SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } else { - fprintf(stdout, "Table created successfully\n"); - } -} - - int main(int argc, char* argv[]) { - sqlite3 *db; - int rc; - - /* Open database */ - rc = sqlite3_open("ckdb", &db); - - if (rc) { - fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); - return(0); - } - else { - fprintf(stdout, "Opened database successfully\n"); - } - - if (strcmp("init", argv[1]) == 0) { - initDb(db); - } - - sqlite3_close(db); - return 0; -} |