aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actionparser.c241
-rw-r--r--src/actionparser.h70
-rw-r--r--src/actions.c115
-rw-r--r--src/actions.h20
-rw-r--r--src/argumentparser.h27
-rw-r--r--src/checks.c133
-rw-r--r--src/checks.h31
-rw-r--r--src/ck.c44
-rw-r--r--src/confparser.c127
-rw-r--r--src/confparser.h45
-rw-r--r--src/dblayer.c112
-rw-r--r--src/dblayer.h35
-rw-r--r--src/main.c85
13 files changed, 1000 insertions, 85 deletions
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;
-}