diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/actionparser.c | 18 | ||||
-rw-r--r-- | src/actionparser.h | 1 | ||||
-rw-r--r-- | src/actions.c | 1 | ||||
-rw-r--r-- | src/actions.h | 2 | ||||
-rw-r--r-- | src/argumentparser.h | 15 | ||||
-rw-r--r-- | src/ck.c | 2 | ||||
-rw-r--r-- | src/ckutil.c | 54 | ||||
-rw-r--r-- | src/ckutil.h | 29 | ||||
-rw-r--r-- | src/confparser.c | 42 | ||||
-rw-r--r-- | src/confparser.h | 16 | ||||
-rw-r--r-- | src/dblayer.c | 95 | ||||
-rw-r--r-- | src/dblayer.h | 19 |
13 files changed, 207 insertions, 89 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4be093a..c797532 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,12 +24,14 @@ set(ckLib_src ${SRC_DIR}/actions.c ${SRC_DIR}/confparser.c ${SRC_DIR}/dblayer.c + ${SRC_DIR}/ckutil.c ) set(ckLib_hdr ${SRC_DIR}/actionparser.h ${SRC_DIR}/actions.h ${SRC_DIR}/confparser.h ${SRC_DIR}/dblayer.h + ${SRC_DIR}/ckutil.h ) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RES_DIR}/cmake) diff --git a/src/actionparser.c b/src/actionparser.c index bfa4f5b..811f0c4 100644 --- a/src/actionparser.c +++ b/src/actionparser.c @@ -17,11 +17,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> #include "actionparser.h" +#include "ckutil.h" /* accepted commands */ /* [0] is the count */ @@ -125,8 +123,9 @@ int parseVals(UserOpt *opt) { return parse_##ACTION(opt); CK_ACTIONS #undef X - } - return 1; + default: + return -1; + } } CkAction determineAction() { @@ -139,7 +138,7 @@ CkAction determineAction() { } CK_ACTIONS #undef X - return -1; + return CK_WRONG_ACTION; } UserOpt make_empty_user_opt() { @@ -178,8 +177,7 @@ void getConfig(UserOpt *opt) { if (strcmp(token, ".") == 0){ printf("Dot\n"); } - struct stat st = {0}; - if (stat(token, &st) == -1) { + if (!util_is_dir(token)) { printf("%s is not a directory\n", token); exit(1); } @@ -218,7 +216,7 @@ ParseResult parseAction(int argc, char* argv[], UserOpt *opt) { // get action nextToken(); opt->action = determineAction(); - if (opt->action == -1) { + if (opt->action == CK_WRONG_ACTION) { opt->err = PERR_UNKONW_ACTION; return OPR_ERR; } @@ -260,6 +258,8 @@ void getPossibleActionNames(char * dest, CkAction ckAction) { break; CK_ACTIONS #undef X + default: + break; } strcpy(dest, buf); diff --git a/src/actionparser.h b/src/actionparser.h index be2416a..be7cf90 100644 --- a/src/actionparser.h +++ b/src/actionparser.h @@ -43,6 +43,7 @@ enum ParseErrors { typedef enum CkActions CkAction; enum CkActions { + CK_WRONG_ACTION, #define X(ACTION) \ CKA_##ACTION, CK_ACTIONS diff --git a/src/actions.c b/src/actions.c index 8941495..87c0a6c 100644 --- a/src/actions.c +++ b/src/actions.c @@ -42,6 +42,7 @@ int run_ADD(UserOpt * opt, Conf *conf) { for (int i = 0; i < opt->argc; i++) { printf("[%d]: %s\n", i, opt->argv[i]); } + add_insert_program_to_db(&db, opt->argv[1]); close_DB(&db); return 0; } diff --git a/src/actions.h b/src/actions.h index b9d2192..e7e5636 100644 --- a/src/actions.h +++ b/src/actions.h @@ -23,7 +23,7 @@ CK_ACTIONS #undef X -#define X(ACTION) \ +#define X(ACTION) \ extern void print_##ACTION##_result(int ok); CK_ACTIONS #undef X diff --git a/src/argumentparser.h b/src/argumentparser.h index 7674e52..8189b38 100644 --- a/src/argumentparser.h +++ b/src/argumentparser.h @@ -1,17 +1,4 @@ -/* 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 - * - * ------------------------------------------------------------------ */ +/* argumentparser.h - Argument parser for ck------------------------*- C -*- */ #ifndef ARGUMENTPARSER_H #define ARGUMENTPARSER_H #define INIT_ALIAS \ @@ -73,6 +73,8 @@ int main(int argc, char *argv[]) { break; CK_ACTIONS #undef X + default: + break; } free_user_opt(&opt); return 0; diff --git a/src/ckutil.c b/src/ckutil.c new file mode 100644 index 0000000..fc6d4b0 --- /dev/null +++ b/src/ckutil.c @@ -0,0 +1,54 @@ +/* ckutil.c - utility functions 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 <dirent.h> +#include <ctype.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "ckutil.h" + +int util_is_dir(const char *path) { + DIR *dir; + dir = opendir(path); + if (!dir) { + return 0; + } + closedir(dir); + return 1; +} + +int util_is_str_empty(const char *s) { + while (*s != '\0') { + if (!isspace((unsigned char)*s)) + return 0; + s++; + } + return 1; +} + +int util_file_exists(const char* path) { + struct stat st = {0}; + if (stat(path, &st) == -1) { + return 0; + } + return 1; +} + +int util_is_file_rw(const char* path) { + if (access(path, R_OK | W_OK) == 0) { + return 1; + } + return 0; +} + +void util_mkdir(const char *name) { + mkdir(name, 0755); +} diff --git a/src/ckutil.h b/src/ckutil.h new file mode 100644 index 0000000..c99798d --- /dev/null +++ b/src/ckutil.h @@ -0,0 +1,29 @@ +/* ckutil.h - utility functions for ck ---------------------------------*- C -*- + * + * This file is part of ck, the config keeper + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2018 Anastasis Grammenos + * GPLv3 (see LICENCE for the full notice) + * + * -------------------------------------------------------------------------- */ +#ifndef CKUTIL_H +#define CKUTIL_H + +/* Returns 1 if path is a directory, else returns 0. */ +extern int util_is_dir(const char *path); + +/* Returns 1 if file(or dir) exists, else returns 0. */ +extern int util_file_exists(const char *path); + +extern int util_is_file_rw(const char *path); +extern int util_is_cli_flag(); + +/* Returns 1 if str contains only whitespace, or nothing, + * else returns 0. */ +extern int util_is_str_empty(); +extern int util_remove_newlibe(); + +extern void util_mkdir(const char *path); +#endif // CKUTIL_H diff --git a/src/confparser.c b/src/confparser.c index 62cfb8f..ef1de61 100644 --- a/src/confparser.c +++ b/src/confparser.c @@ -11,11 +11,8 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> -#include <ctype.h> -#include <dirent.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> + +#include "ckutil.h" #include "confparser.h" @@ -45,17 +42,8 @@ int read_next_line(char *line, FILE *f) { return 0; } -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)) { + if (line[0] == '#' || util_is_str_empty(line)) { return CV_NO_VAL_OR_COMMENT; } #define X(var, str, name) \ @@ -67,16 +55,6 @@ ConfVar match_variables(char *line, char matched[]) { return -1; } -int is_dir(char *path) { - DIR *dir; - dir = opendir(path); - if (!dir) { - return 0; - } - closedir(dir); - return 1; -} - char *make_config_name(char * confPath) { char *db_path = strdup(confPath); @@ -99,12 +77,15 @@ ConfigParserResult parse(Conf *conf, UserOpt *opt) { char line[200]; char matched[200]; while (read_next_line(line, confPtr)) { + if (strlen(line) > 200) { + 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 (!is_dir(matched)) { \ + if (!util_is_dir(matched)) { \ free(conf->var); \ return CPR_WRONG_##var; \ } \ @@ -150,20 +131,19 @@ int config_file_parse(Conf *conf, UserOpt *opt) { } int init_create_config_file(UserOpt *opt) { - struct stat st = {0}; char tmp[200]; - if (stat(opt->argv[0], &st) == -1) { + if (!util_file_exists(opt->argv[0])) { printf("Version control directory: %s\ndoes not exist.\n", opt->argv[0]); return 1; } - if (stat(opt->argv[1], &st) == -1) { + if (!util_file_exists(opt->argv[1])) { printf("Secret directory: %s\ndoes not exist.\n", opt->argv[1]); return 1; } - if (stat(opt->confDir, &st) == -1) { - mkdir(opt->confDir, 0755); + if (!util_file_exists(opt->confDir)) { + util_mkdir(opt->confDir); } char *confName = make_config_name(opt->confDir); diff --git a/src/confparser.h b/src/confparser.h index fad65d1..076cb0f 100644 --- a/src/confparser.h +++ b/src/confparser.h @@ -24,33 +24,35 @@ typedef enum ConfingVariables ConfVar; -#define X(var, str, name) CV_##var, enum ConfingVariables { CV_NO_VAL_OR_COMMENT, +#define X(var, str, name) CV_##var, 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, +#define X(var, str, name) \ + CPR_WRONG_##var, CONFIG_VARIABLES_TABLE -}; #undef X +}; typedef struct ConfigValues Conf; -#define X(var, str, name) char* var; struct ConfigValues { ConfigParserResult result; +#define X(var, str, name) char* var; CONFIG_VARIABLES_TABLE -}; #undef X +}; +/* Parse the configuration file and fill the conf struct */ extern int config_file_parse(Conf *conf, UserOpt *opt); extern int init_create_config_file(UserOpt *opt); + #endif // CONFPARSER_H diff --git a/src/dblayer.c b/src/dblayer.c index 5ece9c0..98a4d64 100644 --- a/src/dblayer.c +++ b/src/dblayer.c @@ -15,33 +15,29 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include "dblayer.h" +#include "ckutil.h" const char * const DB_NAME = "/ckdb"; -char *make_db_name(char *confPath) { - char *db_path = strdup(confPath); - - db_path = realloc(db_path, strlen(confPath)+strlen(DB_NAME)+1); +/* figure out the database name */ +void make_db_name(char *ret, const char *confPath) { + char db_path[200]; + strcpy(db_path, confPath); strcat(db_path, DB_NAME); - return db_path; + strcpy(ret, db_path); } -int db_exists(UserOpt *opt) { - char *db_path = make_db_name(opt->confDir); - int ret; - ret = 0; - if (access(db_path, F_OK) == 0) { - ret = 1; - } - free(db_path); - return ret; +/* Check if the db file exists*/ +int db_exists(const UserOpt *opt) { + char db_path[200]; + make_db_name(db_path, opt->confDir); + return util_is_file_rw(db_path); } -// check if db has the correct tables +/* check if db has the correct tables */ int check_initialized_DB(sqlite3 *db) { char *sql = "SELECT * FROM SQLITE_MASTER WHERE type='table';"; sqlite3_stmt *stmt; @@ -84,13 +80,13 @@ void close_DB(DB *db) { sqlite3_close(db->ptr); } -DB init_make_DB(UserOpt *opt) { +DB init_make_DB(const UserOpt *opt) { sqlite3 *db; + char db_path[200]; int rc; - char *db_path = make_db_name(opt->confDir); + make_db_name(db_path, opt->confDir); rc = sqlite3_open(db_path, &db); - free(db_path); if (rc != SQLITE_OK) { return empty_DB(SQL_ERR_NO_DB_FILE); } @@ -98,13 +94,13 @@ DB init_make_DB(UserOpt *opt) { return new_DB(db); } -DB open_DB(UserOpt *opt) { +DB open_DB(const UserOpt *opt) { sqlite3 *db; int rc; + char db_path[200]; - char *db_path = make_db_name(opt->confDir); + make_db_name(db_path, opt->confDir); rc = sqlite3_open(db_path, &db); - free(db_path); if (rc) { return empty_DB(SQL_ERR_NO_DB_FILE); @@ -141,6 +137,59 @@ void init_make_tables(DB *db) { } } -int add_insert_program_to_db(DB *db, char* name) { +int get_next_valid_id_from_table(DB *db, const char* tableName) { + sqlite3_stmt *stmt; + int rc; + + char sql[100] = "SELECT id FROM "; + strcat(sql, tableName); + strcat(sql, " ORDER BY id;"); + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + return -1; + } + sqlite3_bind_text(stmt, 1, tableName, strlen(tableName), 0); + + int id = 0; + while (sqlite3_step(stmt) == SQLITE_ROW) { + int a = sqlite3_column_int(stmt, 0); + if (a != id) { + break; + } + id++; + } + sqlite3_finalize(stmt); + return id; +} + +void insert_to_program_table(DB *db, const char *name) { + sqlite3_stmt *stmt; + int rc; + + char * sql = + "INSERT INTO PROGRAM VALUES(?, ?);"; + + rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); + if (rc != SQLITE_OK) { + printf("Error\n"); + return; + } + int id = get_next_valid_id_from_table(db, "PROGRAM"); + if (id == -1) { + db->error = SQL_ERR_SQLITE; + return; + } + sqlite3_bind_int(stmt, 1, id); + sqlite3_bind_text(stmt, 2, name, strlen(name), 0); + if (sqlite3_step(stmt) != SQLITE_DONE) { + printf("Error\n"); + return; + } + sqlite3_finalize(stmt); +} + +int add_insert_program_to_db(DB *db, const char *name) { + insert_to_program_table(db,name); return 0; } diff --git a/src/dblayer.h b/src/dblayer.h index 24fdc2b..de73aac 100644 --- a/src/dblayer.h +++ b/src/dblayer.h @@ -33,14 +33,25 @@ struct DBstruct { SqlError error; }; -extern int db_exists(UserOpt *opt); -extern DB open_DB(); +extern int db_exists(const UserOpt *opt); + +/* Open the db file. On fail return null pointer to db + * and the corresponding SQL error (NO_DB_FILE | NO_TABLES)*/ +extern DB open_DB(const UserOpt *opt); + extern void close_DB(DB *DB); +/********/ /* init */ +/********/ + +/* Create the tables required for the ckdb */ extern void init_make_tables(DB *db); -extern DB init_make_DB(); +extern DB init_make_DB(const UserOpt *opt); +/*******/ /* add */ -extern int add_insert_program_to_db(DB *db, char * name); +/*******/ + +extern int add_insert_program_to_db(DB *db, const char * name); #endif /* DBLAEYR_H */ |