145 lines
No EOL
4 KiB
C
145 lines
No EOL
4 KiB
C
#include "config.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
|
|
char *klist_config_key_to_string(KLIST_CONFIG_KEY key) {
|
|
switch (key) {
|
|
case CONFIG_DATABASE_NAME:
|
|
return "database";
|
|
case _CONFIG_KEY_COUNT:
|
|
return "";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
KLIST_CONFIG_KEY klist_config_string_to_key(char *key) {
|
|
if (!strcmp(key, klist_config_key_to_string(CONFIG_DATABASE_NAME)))
|
|
return CONFIG_DATABASE_NAME;
|
|
return _CONFIG_KEY_COUNT;
|
|
}
|
|
|
|
char *klist_config_name(char *name) {
|
|
char *config_home = getenv("XDG_CONFIG_HOME");
|
|
bool config_home_a = false;
|
|
if (!config_home) {
|
|
config_home_a = true;
|
|
char *home = getenv("HOME");
|
|
const char *config_home_format = "%s/.config";
|
|
int config_home_len = snprintf(name, 0, config_home_format, home);
|
|
config_home = malloc(++config_home_len * sizeof(char));
|
|
snprintf(config_home, config_home_len, config_home_format, home, name);
|
|
}
|
|
|
|
int config_dir_len = snprintf(NULL, 0, "%s/%s", config_home, name);
|
|
char *config_dir = malloc(++config_dir_len * sizeof(char));
|
|
snprintf(config_dir, config_dir_len, "%s/%s", config_home, name);
|
|
|
|
struct stat st;
|
|
if (stat(config_dir, &st) == -1)
|
|
mkdir(config_dir, 0755);
|
|
|
|
int config_file_len = snprintf(NULL, 0, "%s/%s/config", config_home, name);
|
|
char *config_file_name = malloc(++config_file_len * sizeof(char));
|
|
snprintf(config_file_name, config_file_len, "%s/%s/config", config_home,
|
|
name);
|
|
|
|
if (config_home_a)
|
|
free(config_home);
|
|
free(config_dir);
|
|
|
|
return config_file_name;
|
|
}
|
|
|
|
void klist_config_parse(klist_config *ctx, FILE *config) {
|
|
fseek(config, 0, SEEK_END);
|
|
int c;
|
|
char *key = NULL, *val = NULL;
|
|
bool found_key = false, ignore_line = false;
|
|
while ((c = fgetc(config)) != EOF) {
|
|
switch (c) {
|
|
case '\n':
|
|
ignore_line = true;
|
|
if (!key)
|
|
continue;
|
|
if (!val) {
|
|
fprintf(stderr, "ignoring key '%s'", key);
|
|
}
|
|
if (!strcmp(key, "database")) {
|
|
ctx->db_file = malloc(strlen(val));
|
|
strcpy(ctx->db_file, val);
|
|
} else {
|
|
fprintf(stderr, "ignoring unknown key '%s'", key);
|
|
}
|
|
free(key);
|
|
free(val);
|
|
key = NULL;
|
|
val = NULL;
|
|
break;
|
|
case '=':
|
|
if (!found_key)
|
|
found_key = true;
|
|
else {
|
|
printf("config file is screwed, please review\n");
|
|
exit(1);
|
|
}
|
|
break;
|
|
default:
|
|
if (!key && !val && c == '#')
|
|
ignore_line = true;
|
|
if (ignore_line)
|
|
continue;
|
|
if (found_key) {
|
|
char *_val = val ? realloc(val, (strlen(val) + 2) * sizeof(char))
|
|
: malloc(2 * sizeof(char));
|
|
if (_val) {
|
|
val = _val;
|
|
val[strlen(val) - 2] = (char)c;
|
|
val[strlen(val) - 1] = '\0';
|
|
}
|
|
} else {
|
|
char *_key = key ? realloc(key, (strlen(key) + 2) * sizeof(char))
|
|
: malloc(2 * sizeof(char));
|
|
if (_key) {
|
|
key = _key;
|
|
key[strlen(key) - 2] = (char)c;
|
|
key[strlen(key) - 1] = '\0';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void klist_config_setup(char *name, FILE *config) {
|
|
char *data_home = getenv("XDG_DATA_HOME");
|
|
bool data_home_a = false;
|
|
if (!data_home) {
|
|
data_home_a = true;
|
|
char *home = getenv("HOME");
|
|
const char *data_home_format = "%s/.local/state";
|
|
int data_home_len = snprintf(name, 0, data_home_format, home);
|
|
data_home = malloc(++data_home_len * sizeof(char));
|
|
snprintf(data_home, data_home_len, data_home_format, home, name);
|
|
}
|
|
|
|
int db_file_len = snprintf(NULL, 0, "%s/%s", data_home, name);
|
|
char *db_file = malloc(++db_file_len * sizeof(char));
|
|
snprintf(db_file, db_file_len, "%s/%s", data_home, name);
|
|
|
|
struct stat st;
|
|
if (stat(db_file, &st) == -1)
|
|
mkdir(db_file, 0755);
|
|
|
|
if (data_home_a)
|
|
free(data_home);
|
|
|
|
// fseek(config, 0, SEEK_END);
|
|
fprintf(config, "%s=%s/tasks.db\n",
|
|
klist_config_key_to_string(CONFIG_DATABASE_NAME), db_file);
|
|
fclose(config);
|
|
|
|
if (db_file)
|
|
free(db_file);
|
|
} |