diff options
Diffstat (limited to 'mysys/default_modify.c')
-rw-r--r-- | mysys/default_modify.c | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/mysys/default_modify.c b/mysys/default_modify.c index add4317bb56..721ca596428 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -37,22 +37,20 @@ #define NEWLINE_LEN 1 #endif +static char *add_option(char *dst, const char *option_value, + const char *option, int remove_option); + int modify_defaults_file(const char *file_location, const char *option, const char *option_value, const char *section_name, int remove_option) { FILE *cnf_file; MY_STAT file_stat; - char linebuff[BUFF_SIZE], tmp[BUFF_SIZE], *tmp_ptr, *src_ptr, *dst_ptr, - *file_buffer; - uint optlen, optval_len, sect_len; - my_bool in_section= FALSE; + char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer; + uint optlen, optval_len, sect_len, nr_newlines= 0; + my_bool in_section= FALSE, opt_applied= 0; DBUG_ENTER("modify_defaults_file"); - optlen= strlen(option); - optval_len= strlen(option_value); - sect_len= strlen(section_name); - if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0)))) DBUG_RETURN(2); @@ -60,12 +58,15 @@ int modify_defaults_file(const char *file_location, const char *option, if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) goto err; + optlen= strlen(option); + optval_len= strlen(option_value); + /* Reserve space to read the contents of the file and some more for the option we want to add. */ - if (!(file_buffer= (char*) my_malloc(sizeof(char)* - (file_stat.st_size + + if (!(file_buffer= (char*) my_malloc(sizeof(char) * + (file_stat.st_size + /* option name len */ optlen + /* reserve space for newline */ @@ -73,35 +74,44 @@ int modify_defaults_file(const char *file_location, const char *option, /* reserve for '=' char */ 1 + /* option value len */ - optval_len), MYF(MY_WME)))) + optval_len + + /* The ending zero plus some safety */ + FN_REFLEN), MYF(MY_WME)))) goto malloc_err; - for (dst_ptr= file_buffer, tmp_ptr= 0; - fgets(linebuff, BUFF_SIZE, cnf_file); ) + sect_len= strlen(section_name); + + for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); ) { /* Skip over whitespaces */ for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} - if (in_section && !strncmp(src_ptr, option, optlen) && + if (!*src_ptr) /* Empty line */ + { + nr_newlines++; + continue; + } + + if (!opt_applied && in_section && !strncmp(src_ptr, option, optlen) && (*(src_ptr + optlen) == '=' || my_isspace(&my_charset_latin1, *(src_ptr + optlen)) || *(src_ptr + optlen) == '\0')) { - /* The option under modifying was found in this section. Apply new. */ - if (!remove_option) - dst_ptr= strmov(dst_ptr, tmp); - tmp_ptr= 0; /* To mark that we have already applied this */ + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + opt_applied= 1; } else { /* If going to new group and we have option to apply, do it now */ - if (tmp_ptr && *src_ptr == '[') + if (in_section && !opt_applied && *src_ptr == '[') { - dst_ptr= strmov(dst_ptr, tmp); - tmp_ptr= 0; + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + } + for (; nr_newlines; nr_newlines--) + dst_ptr= strmov(dst_ptr, NEWLINE); dst_ptr= strmov(dst_ptr, linebuff); } /* Look for a section */ @@ -117,43 +127,38 @@ int modify_defaults_file(const char *file_location, const char *option, if (*src_ptr != ']') continue; /* Missing closing parenthesis. Assume this was no group */ - in_section= TRUE; - /* add option */ - if (!remove_option) - { - tmp_ptr= strmov(tmp, option); - if (*option_value) - { - *tmp_ptr++= '='; - tmp_ptr= strmov(tmp_ptr, option_value); - } - /* add a newline */ - strmov(tmp_ptr, NEWLINE); - } } else in_section= FALSE; /* mark that this section is of no interest to us */ } } - /* File ended. New option still remains to apply at the end */ - if (tmp_ptr) + /* File ended. */ + if (!opt_applied && !remove_option && in_section) { + /* New option still remains to apply at the end */ if (*(dst_ptr - 1) != '\n') - *dst_ptr++= '\n'; - dst_ptr= strmov(dst_ptr, tmp); + dst_ptr= strmov(dst_ptr, NEWLINE); + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + opt_applied= 1; } + for (; nr_newlines; nr_newlines--) + dst_ptr= strmov(dst_ptr, NEWLINE); - if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, - MYF(MY_WME)) || - my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || - my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), - MYF(MY_NABP)) || - my_fclose(cnf_file, MYF(MY_WME))) - goto err; + if (opt_applied) + { + /* Don't write the file if there are no changes to be made */ + if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, + MYF(MY_WME)) || + my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || + my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), + MYF(MY_NABP))) + goto err; + } + if (my_fclose(cnf_file, MYF(MY_WME))) + goto err; my_free(file_buffer, MYF(0)); - DBUG_RETURN(0); err: @@ -162,3 +167,21 @@ malloc_err: my_fclose(cnf_file, MYF(0)); DBUG_RETURN(1); /* out of resources */ } + + +static char *add_option(char *dst, const char *option_value, + const char *option, int remove_option) +{ + if (!remove_option) + { + dst= strmov(dst, option); + if (*option_value) + { + *dst++= '='; + dst= strmov(dst, option_value); + } + /* add a newline */ + dst= strmov(dst, NEWLINE); + } + return dst; +} |