Commit 8139af18 authored by petr@mysql.com's avatar petr@mysql.com

Post-review fixes for "!include" patch originating from Yahoo! (the whole patch is recommitted)

parent 7e8e0332
...@@ -73,7 +73,7 @@ static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc, ...@@ -73,7 +73,7 @@ static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
const char *dir, const char *ext, const char *dir, const char *ext,
const char *config_file, const char *config_file,
TYPELIB *group); TYPELIB *group, int recursion_level);
static char *remove_end_comment(char *ptr); static char *remove_end_comment(char *ptr);
...@@ -193,8 +193,8 @@ int load_defaults(const char *conf_file, const char **groups, ...@@ -193,8 +193,8 @@ int load_defaults(const char *conf_file, const char **groups,
if (forced_default_file) if (forced_default_file)
{ {
if ((error= search_default_file_with_ext(&args, &alloc, "", "", if ((error= search_default_file_with_ext(&args, &alloc, "", "",
forced_default_file, forced_default_file,
&group)) < 0) &group, 0)) < 0)
goto err; goto err;
if (error > 0) if (error > 0)
{ {
...@@ -311,7 +311,7 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, ...@@ -311,7 +311,7 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
{ {
int error; int error;
if ((error= search_default_file_with_ext(args, alloc, dir, *ext, if ((error= search_default_file_with_ext(args, alloc, dir, *ext,
config_file, group)) < 0) config_file, group, 0)) < 0)
return error; return error;
} }
return 0; return 0;
...@@ -320,15 +320,17 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, ...@@ -320,15 +320,17 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
/* /*
Open a configuration file (if exists) and read given options from it Open a configuration file (if exists) and read given options from it
SYNOPSIS SYNOPSIS
search_default_file_with_ext() search_default_file_with_ext()
args Store pointer to found options here args Store pointer to found options here
alloc Allocate strings in this object alloc Allocate strings in this object
dir directory to read dir directory to read
config_file Name of configuration file
ext Extension for configuration file ext Extension for configuration file
config_file Name of configuration file
group groups to read group groups to read
recursion_level the level of recursion, got while processing
"!include" or "!includedir"
RETURN RETURN
0 Success 0 Success
...@@ -340,12 +342,18 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, ...@@ -340,12 +342,18 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
const char *dir, const char *ext, const char *dir, const char *ext,
const char *config_file, const char *config_file,
TYPELIB *group) TYPELIB *group, int recursion_level)
{ {
char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp; char name[FN_REFLEN + 10], buff[4096], *ptr, *end, *value, *tmp, **tmp_ext;
static const char includedir_keyword[]= "includedir";
static const char include_keyword[]= "include";
const int max_recursion_level= 10;
FILE *fp; FILE *fp;
uint line=0; uint line= 0;
my_bool read_values=0,found_group=0; my_bool read_values= 0, found_group= 0;
uint i;
MY_DIR *search_dir;
FILEINFO *search_file;
if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3) if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
return 0; /* Ignore wrong paths */ return 0; /* Ignore wrong paths */
...@@ -374,22 +382,121 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, ...@@ -374,22 +382,121 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
if ((stat_info.st_mode & S_IWOTH) && if ((stat_info.st_mode & S_IWOTH) &&
(stat_info.st_mode & S_IFMT) == S_IFREG) (stat_info.st_mode & S_IFMT) == S_IFREG)
{ {
fprintf(stderr, "warning: World-writeable config file %s is ignored\n", fprintf(stderr, "warning: World-writable config file %s is ignored\n",
name); name);
return 0; return 0;
} }
} }
#endif #endif
if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0)))) if (!(fp= my_fopen(fn_format(name, name, "", "", 4), O_RDONLY, MYF(0))))
return 0; /* Ignore wrong files */ return 0; /* Ignore wrong files */
while (fgets(buff,sizeof(buff)-1,fp)) while (fgets(buff, sizeof(buff) - 1, fp))
{ {
line++; line++;
/* Ignore comment and empty lines */ /* Ignore comment and empty lines */
for (ptr=buff ; my_isspace(&my_charset_latin1,*ptr) ; ptr++ ) ; for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
{}
if (*ptr == '#' || *ptr == ';' || !*ptr) if (*ptr == '#' || *ptr == ';' || !*ptr)
continue; continue;
/* Configuration File Directives */
if ((*ptr == '!') && (recursion_level < max_recursion_level))
{
/* skip over `!' and following whitespace */
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
if ((!strncmp(ptr, includedir_keyword, sizeof(includedir_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
{
/* skip over "includedir" and following whitespace */
for (ptr+= sizeof(includedir_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from directory name */
end= ptr + strlen(ptr) - 1;
/*
This would work fine even if no whitespaces are met
since fgets() stores the newline character in the buffer
*/
for (; my_isspace(&my_charset_latin1, *(end - 1)); end--)
{}
end[0]= 0;
/* print error msg if there is nothing after !inludedir directive */
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !includedir directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
goto err;
for (i= 0; i < (uint) search_dir->number_off_files; i++)
{
search_file= search_dir->dir_entry + i;
ext= fn_ext(search_file->name);
/* check extenstion */
for (tmp_ext= (char**) f_extensions; *tmp_ext; *tmp_ext++)
{
if (!strcmp(ext, *tmp_ext))
break;
}
if (*tmp_ext)
{
if (!(tmp= alloc_root(alloc, 2 + strlen(search_file->name)
+ strlen(ptr))))
goto err;
fn_format(tmp, search_file->name, ptr, "",
MY_UNPACK_FILENAME | MY_SAFE_PATH);
search_default_file_with_ext(args, alloc, "", "", tmp, group,
recursion_level + 1);
}
}
my_dirend(search_dir);
}
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword) - 1]))
{
/* skip over `include' and following whitespace */
for (ptr+= sizeof(include_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from filename */
end= ptr + strlen(ptr) - 1;
for (; my_isspace(&my_charset_latin1, *(end - 1)) ; end--)
{}
end[0]= 0;
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !include directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
search_default_file_with_ext(args, alloc, "", "", ptr, group,
recursion_level + 1);
}
continue;
}
if (*ptr == '[') /* Group name */ if (*ptr == '[') /* Group name */
{ {
found_group=1; found_group=1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment