Skip to content

Instantly share code, notes, and snippets.

@ticchen
Created October 7, 2016 06:03
Show Gist options
  • Save ticchen/220afe4672021c280c6660840fea64e6 to your computer and use it in GitHub Desktop.
Save ticchen/220afe4672021c280c6660840fea64e6 to your computer and use it in GitHub Desktop.
void create_new_cofg(char *usr_conf, char *def_conf)
{
int done = 0;
FILE *usr_fp = NULL, *def_fp = NULL, *temp_fp = NULL;
char buf[CONFIG_BUFFER] = {0};
//get currect sep by config name
char *fname = get_fname(usr_conf);
char *sep = find_file_sep(fname);
//save current setting in binary tree for searching
void *conf_root = NULL;
create_binary_tree(usr_conf, &conf_root);
//prepare a temp file
char temp_conf[NAME_MAX] = {0};
snprintf(temp_conf, sizeof(temp_conf), "%s/merge.temp", dirname(strdupa(usr_conf)));
fprintf(stderr, "temp_conf: %s\n", temp_conf);
temp_fp = fopen(temp_conf, "w+");
if(temp_fp == NULL) {
fprintf(stderr, "Error: fail to create temp file: %s\n", temp_conf);
goto error;
}
//prepare def_conf
def_fp = fopen(def_conf, "r");
if(def_fp == NULL) {
fprintf(stderr, "Error: fail to open default config: %s\n", def_conf);
goto error;
}
//prepare usr_conf
usr_fp = fopen(usr_conf, "r");
if(usr_fp == NULL) {
fprintf(stderr, "Error: fail to open user config: %s\n", usr_conf);
goto error;
}
//copy def_conf's version to temp
while(fgets(buf, sizeof(buf), def_fp) != NULL) {
if(strncmp(buf, VERSION_TAG, strlen(VERSION_TAG)) == 0) {
del_str_brackets(buf);
rm_blank(buf);
fprintf(temp_fp, "%s\n", buf);
break;
}
}
//copy usr_conf to temp exclude version
while(fgets(buf, sizeof(buf), usr_fp) != NULL) {
if(strncmp(buf, VERSION_TAG, strlen(VERSION_TAG)) == 0) {
continue; //skip version line
}
fprintf(temp_fp, "%s", buf);
}
//copy def_conf to temp exclude existing in binary tree
while(fgets(buf, sizeof(buf), def_fp) != NULL) {
if(strncmp(buf, VERSION_TAG, strlen(VERSION_TAG)) == 0) {
continue; //skip version line
}
char pbuf[CONFIG_BUFFER] = {0};
strcpy(pbuf, buf);
del_str_comment_LF(pbuf);
if(strlen(pbuf) < 1) {
continue;
}
//prepare tree key
CONF_NODE *newNode = read_key_value(pbuf, sep);
if(newNode == NULL) {
continue;
}
if(tfind(newNode, &conf_root, func_name_compare) == NULL) {
//buf in not in tree, copy it into temp
fprintf(temp_fp, "%s", buf);
}
free_conf_node(newNode);
}
done = 1;
error:
if(usr_fp != NULL) {
fclose(usr_fp);
}
if(def_fp != NULL) {
fclose(def_fp);
}
if(temp_fp != NULL) {
int temp_fd = fileno(temp_fp);
if(temp_fd != -1) {
fsync(temp_fd); //synchronize to storage device
}
fclose(temp_fp);
}
if(conf_root != NULL) {
twalk(conf_root, free_tree);
}
if(done) {
rename(temp_conf, usr_conf);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment