diff options
Diffstat (limited to 'mysys/default.c')
-rw-r--r-- | mysys/default.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/mysys/default.c b/mysys/default.c index 0f33c94d17e..e38babb849d 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -50,8 +50,10 @@ const char *default_directories[MAX_DEFAULT_DIRS + 1]; #ifdef __WIN__ static const char *f_extensions[]= { ".ini", ".cnf", 0 }; +#define NEWLINE "\r\n" #else static const char *f_extensions[]= { ".cnf", 0 }; +#define NEWLINE "\n" #endif /* @@ -78,6 +80,142 @@ static void init_default_directories(); static char *remove_end_comment(char *ptr); +/* + Add/remove option to the option file section. + + SYNOPSYS + my_correct_file() + file_location The location of configuration file to edit + option option to look for + option value The value of the option we would like to set + section_name the name of the section + remove_option This is true if we want to remove the option. + False otherwise. + IMPLEMENTATION + We open the option file first, then read the file line-by-line, + looking for the section we need. At the same time we put these lines + into a buffer. Then we look for the option within this section and + change/remove it. In the end we get a buffer with modified version of the + file. Then we write it to the file, truncate it if needed and close it. + + RETURN + 0 - ok + 1 - some error has occured. Probably due to the lack of resourses + -1 - cannot open the file +*/ + +int my_correct_defaults_file(const char *file_location, const char *option, + const char *option_value, + const char *section_name, int remove_option) +{ + FILE *cnf_file; + struct stat file_stat; + char linebuff[512], *ptr; + uint optlen; + uint len; + char *file_buffer; + uint position= 0; + int is_found= FALSE; + + optlen= strlen(option); + + DBUG_ENTER("my_correct_file"); + + if (!(cnf_file= my_fopen(file_location, O_RDWR, MYF(0)))) + goto err_fopen; + + /* my_fstat doesn't use the flag parameter */ + if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) + goto err; + + /* + Reserve space to read the contents of the file and some more + for the option we want ot add. + */ + file_buffer= (char*) my_malloc(sizeof(char)* + (file_stat.st_size + /* current file size */ + optlen + /* option name len */ + 2 + /* reserve space for newline */ + 1 + /* reserve for '=' char */ + strlen(option_value)), /* option value len */ + MYF(MY_WME)); + + if (!file_buffer) + goto malloc_err; + while (fgets(linebuff, sizeof(linebuff), cnf_file)) + { + len= strlen(linebuff); + + /* if the section is found traverse it */ + if (is_found) + { + /* skip the old value of the option we are changing */ + if (strncmp(linebuff, option, optlen)) + { + /* copy all other lines */ + strmake(file_buffer + position, linebuff, len); + position+= len; + } + } + else + { + strmake(file_buffer + position, linebuff, len); + position+= len; + } + + + /* looking for appropriate section */ + for (ptr= linebuff ; my_isspace(&my_charset_latin1,*ptr) ; ptr++) + {} + + if (*ptr == '[') + { + /* copy the line to the buffer */ + if (!strncmp(++ptr, section_name, strlen(section_name))) + { + is_found= TRUE; + /* add option */ + if (!remove_option) + { + strmake(file_buffer + position, option, optlen); + position+= optlen; + if (*option_value) + { + *(file_buffer + position++)= '='; + strmake(file_buffer + position, option_value, + strlen(option_value)); + position+= strlen(option_value); + } + /* add a newline */ + strcat(file_buffer + position, NEWLINE); + position+= strlen(NEWLINE); + } + } + else + is_found= FALSE; /* mark that this section is of no interest to us */ + } + + } + + if (my_chsize(fileno(cnf_file), position, 0, MYF(MY_WME)) || + my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || + my_fwrite(cnf_file, file_buffer, position, MYF(MY_NABP)) || + my_fclose(cnf_file, MYF(MY_WME))) + goto err; + + my_free(file_buffer, MYF(0)); + + DBUG_RETURN(0); + +err: + my_free(file_buffer, MYF(0)); +malloc_err: + my_fclose(cnf_file, MYF(0)); + DBUG_RETURN(1); /* out of resources */ +err_fopen: + DBUG_RETURN(-1); /* cannot access the option file */ +} + /* Process config files in default directories. |