#include #include #include #include #include #include #include "config.h" struct config_item ci[] = { { "device", CFG_TYPE_STR, offsetof(struct config, device) }, { "repeat", CFG_TYPE_BOOL, offsetof(struct config, repeat) }, { "show_shifted", CFG_TYPE_BOOL, offsetof(struct config, show_shifted) }, { "time", CFG_TYPE_BOOL, offsetof(struct config, time) } }; void fix_config_file_owner(const char *config_path) { char *sudo_uid_str = getenv("SUDO_UID"); char *sudo_gid_str = getenv("SUDO_GID"); if (sudo_uid_str && sudo_gid_str) { uid_t original_uid = atoi(sudo_uid_str); gid_t original_gid = atoi(sudo_gid_str); chown(config_path, original_uid, original_gid); } } struct config *prepare_config_file() { struct config *cfg = malloc(sizeof(struct config)); if (!cfg) { return NULL; } char *sudo_user = getenv("SUDO_USER"); cfg->home = malloc(PATH_MAX); if (!cfg->home) { return NULL; } snprintf(cfg->home, PATH_MAX, "/home/%s", sudo_user); cfg->config_file_path = malloc(strlen(cfg->home) + strlen("/.klrc")); snprintf(cfg->config_file_path, PATH_MAX, "%s/.klrc", cfg->home); if (access(cfg->config_file_path, F_OK) == -1) { FILE *fp = fopen(cfg->config_file_path, "a"); if (!fp) { return NULL; } fputs(CFG_FILE_COMMENT, fp); printf("Config file was generated: %s\n", cfg->config_file_path); printf("Warning: There is no device which is defined in config, see README for details.\n"); fix_config_file_owner(cfg->config_file_path); printf("%s\n", cfg->config_file_path); fclose(fp); } return cfg; } void cmp_str(char** cfg, const char* val) { } void parse_bool(const char* val, bool* member_ptr) { if (strcmp(val, "true") == 0) { *member_ptr = true; } else { *member_ptr = false; } } void parse_str(const char* val, char* member_ptr, size_t max_len) { strncpy(member_ptr, val, max_len - 1); member_ptr[max_len - 1] = '\0'; } struct config *parese_config(struct config *cfg){ if (!cfg) { return NULL; } FILE* fp = fopen(cfg->config_file_path, "r"); if (!fp) { return NULL; } int line_count = 0; char line[128]; char key[128] = ""; char val[128] = ""; while (fgets(line, sizeof(line), fp)) { line_count++; if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') continue; int count = sscanf(line, "%s = %s", key, val); if (count < 2) { fprintf(stderr, "%s:%d: Invalid config\n", cfg->config_file_path, line_count); fclose(fp); return NULL; } for (int i = 0; i < CI_SIZE; i++) { if (strcmp(key, ci[i].key) == 0) { if (ci[i].type == CFG_TYPE_BOOL) { parse_bool(val,(bool*)((char*)cfg + ci[i].offset)); } if (ci[i].type == CFG_TYPE_STR) { printf("key:%s\nval:%s\n", key, val); parse_str(val, (char*)cfg + ci[i].offset, sizeof(cfg->device)); } break; } } } fclose(fp); return cfg; } /* struct config *parese_config(struct config *cfg) */ /* { */ /* if (!cfg) { */ /* /* } */ /* FILE *fp = fopen(cfg->config_file_path, "r"); */ /* if (!fp) { */ /* return NULL; */ /* } */ /* int line_count = 0; */ /* char line[128]; */ /* char key[64] = { 0 }; */ /* char val[64] = { 0 }; */ /* while (fgets(line, sizeof(line), fp)) { */ /* line_count++; */ /* /\* Skip comment and blank lines *\/ */ /* if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') { */ /* continue; */ /* } */ /* int count = sscanf(line, "%s = %s", key, val); */ /* if (count != 2) { */ /* printf("Error at %s:%d\n invalid token: %s", */ /* cfg->config_file_path, line_count, line); */ /* return NULL; */ /* } */ /* if (CFG_COMPLETE(key, "device")) { */ /* strncpy(cfg->device, val, sizeof(cfg->device) - 1); */ /* cfg->device[sizeof(cfg) - 1] = '\0'; */ /* } else if (CFG_COMPLETE(key, "time")) { */ /* if (CFG_COMPLETE(val, "true")) { */ /* cfg->time = true; */ /* } else { */ /* cfg->time = false; */ /* } */ /* } else if (CFG_COMPLETE(key, "key_counter")) { */ /* if (CFG_COMPLETE(val, "true")) { */ /* cfg->keys_counter = true; */ /* } else { */ /* cfg->keys_counter = false; */ /* } */ /* } else if (CFG_COMPLETE(key, "repeat")) { */ /* if (CFG_COMPLETE(val, "true")) { */ /* cfg->repeat = true; */ /* } else { */ /* cfg->repeat = false; */ /* } */ /* } */ /* } */ /* fclose(fp); */ /* return cfg; */ /* } */ struct config *config_init() { struct config *cfg = prepare_config_file(); if (!cfg) { return NULL; } if (parese_config(cfg) == NULL) { return NULL; } return cfg; }