63
65
struct stat file_stat;
64
66
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
65
67
size_t opt_len= 0, optval_len= 0, sect_len;
66
uint nr_newlines= 0, buffer_size;
68
uint32_t nr_newlines= 0;
67
70
bool in_section= false, opt_applied= 0;
68
uint reserve_extended;
71
size_t reserve_extended;
70
73
int reserve_occupied= 0;
72
if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
75
if (!(cnf_file= my_fopen(file_location, O_RDWR, MYF(0))))
75
78
if (fstat(fileno(cnf_file), &file_stat))
90
93
NEWLINE_LEN + /* Space for newline */
91
94
RESERVE); /* Some additional space */
93
buffer_size= (file_stat.st_size +
94
1); /* The ending zero */
96
buffer_size= (size_t)cmax((uint64_t)file_stat.st_size + 1, (uint64_t)SIZE_MAX);
97
99
Reserve space to read the contents of the file and some more
98
100
for the option we want to add.
100
if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended,
102
if (!(file_buffer= (char*) malloc(cmax(buffer_size + reserve_extended,
104
106
sect_len= strlen(section_name);
106
108
for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); )
108
110
/* Skip over whitespaces */
109
for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr);
111
for (src_ptr= linebuff; my_isspace(&my_charset_utf8_general_ci, *src_ptr);
119
121
/* correct the option (if requested) */
120
122
if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
121
123
(*(src_ptr + opt_len) == '=' ||
122
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
124
my_isspace(&my_charset_utf8_general_ci, *(src_ptr + opt_len)) ||
123
125
*(src_ptr + opt_len) == '\0'))
125
127
char *old_src_ptr= src_ptr;
126
src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */
128
src_ptr= strchr(src_ptr+ opt_len, '\0'); /* Find the end of the line */
128
130
/* could be negative */
129
131
reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr);
130
132
if (reserve_occupied >= (int) reserve_extended)
132
134
reserve_extended= (uint) reserve_occupied + RESERVE;
133
if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size +
135
MYF(MY_WME|MY_FREE_ON_ERROR))))
135
if (!(file_buffer= (char*) realloc(file_buffer, buffer_size +
156
157
for (; nr_newlines; nr_newlines--)
157
dst_ptr= stpcpy(dst_ptr, NEWLINE);
158
dst_ptr= strcpy(dst_ptr, NEWLINE)+NEWLINE_LEN;
159
160
/* Skip the section if MY_REMOVE_SECTION was given */
160
161
if (!in_section || remove_option != MY_REMOVE_SECTION)
161
dst_ptr= stpcpy(dst_ptr, linebuff);
162
dst_ptr= strcpy(dst_ptr, linebuff);
163
dst_ptr+= strlen(linebuff);
163
165
/* Look for a section */
164
166
if (*src_ptr == '[')
198
200
/* New option still remains to apply at the end */
199
201
if (!remove_option && *(dst_ptr - 1) != '\n')
200
dst_ptr= stpcpy(dst_ptr, NEWLINE);
202
dst_ptr= strcpy(dst_ptr, NEWLINE)+NEWLINE_LEN;
201
203
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
204
206
for (; nr_newlines; nr_newlines--)
205
dst_ptr= stpcpy(dst_ptr, NEWLINE);
207
dst_ptr= strcpy(dst_ptr, NEWLINE)+NEWLINE_LEN;
209
211
/* Don't write the file if there are no changes to be made */
210
if (ftruncate(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer)) ||
211
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
212
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
212
if (ftruncate(fileno(cnf_file), (size_t) (dst_ptr - file_buffer)) ||
213
fseeko(cnf_file, 0, SEEK_SET) ||
214
fwrite(file_buffer, 1, (size_t) (dst_ptr - file_buffer), cnf_file))
216
217
if (my_fclose(cnf_file, MYF(MY_WME)))
219
my_free(file_buffer, MYF(0));
223
my_free(file_buffer, MYF(0));
225
226
my_fclose(cnf_file, MYF(0));
226
227
return(1); /* out of resources */
233
234
if (!remove_option)
235
dst= stpcpy(dst, option);
236
dst= strcpy(dst, option);
237
dst+= strlen(option);
236
238
if (*option_value)
239
dst= stpcpy(dst, option_value);
241
dst= strcpy(dst, option_value);
242
dst+= strlen(option_value);
241
244
/* add a newline */
242
dst= stpcpy(dst, NEWLINE);
245
dst= strcpy(dst, NEWLINE)+NEWLINE_LEN;