summaryrefslogtreecommitdiff
path: root/mysys/default_modify.c
diff options
context:
space:
mode:
authorunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2005-06-09 21:50:22 +0300
committerunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2005-06-09 21:50:22 +0300
commit5643df2d5846ecbc16e75a607f8d2afb4fb93090 (patch)
tree2e07574a1312c31ee8425351e2c1cbd2fb70b183 /mysys/default_modify.c
parent9227cf4254dc9e9ece41d9eabc164b05a621638a (diff)
downloadmariadb-git-5643df2d5846ecbc16e75a607f8d2afb4fb93090.tar.gz
Fixes in function modify_defaults_file():
- Removed unneccessary variables. - Made a function of that part of code, which actually changes the line under modifications. - Fixed memory overrun problem with my_malloc. Too little space was reserved. - Fixed problem in case, when new option was added at the end of the section. Before, it was added as the last line of the section, even if it left empty lines between. - Fixed so that the configuration file is not saved unneccessarily, if no modifications are done. (file timestamp remains) - This should fix (at least partially) problems described in Bug#10806
Diffstat (limited to 'mysys/default_modify.c')
-rw-r--r--mysys/default_modify.c115
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;
+}