summaryrefslogtreecommitdiff
path: root/mysys/default.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/default.c')
-rw-r--r--mysys/default.c358
1 files changed, 233 insertions, 125 deletions
diff --git a/mysys/default.c b/mysys/default.c
index 9510cfb3464..bedf26a6c9c 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -37,28 +37,16 @@
#include "m_string.h"
#include "m_ctype.h"
#include <my_dir.h>
+#ifdef __WIN__
+#include <winbase.h>
+#endif
char *defaults_extra_file=0;
/* Which directories are searched for options (and in which order) */
-const char *default_directories[]= {
-#ifdef __WIN__
-"C:/",
-#elif defined(__NETWARE__)
-"sys:/etc/",
-#else
-"/etc/",
-#endif
-#ifdef DATADIR
-DATADIR,
-#endif
-"", /* Place for defaults_extra_dir */
-#if !defined(__WIN__) && !defined(__NETWARE__)
-"~/",
-#endif
-NullS,
-};
+#define MAX_DEFAULT_DIRS 4
+const char *default_directories[MAX_DEFAULT_DIRS + 1];
#ifdef __WIN__
static const char *f_extensions[]= { ".ini", ".cnf", 0 };
@@ -66,19 +54,175 @@ static const char *f_extensions[]= { ".ini", ".cnf", 0 };
static const char *f_extensions[]= { ".cnf", 0 };
#endif
-static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
- const char *dir, const char *config_file,
- TYPELIB *group);
+/*
+ This structure defines the context that we pass to callback
+ function 'handle_default_option' used in search_default_file
+ to process each option. This context is used if search_default_file
+ was called from load_defaults.
+*/
+
+struct handle_option_ctx
+{
+ MEM_ROOT *alloc;
+ DYNAMIC_ARRAY *args;
+ TYPELIB *group;
+};
-static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
+static int search_default_file(Process_option_func func, void *func_ctx,
+ const char *dir, const char *config_file);
+static int search_default_file_with_ext(Process_option_func func,
+ void *func_ctx,
const char *dir, const char *ext,
- const char *config_file,
- TYPELIB *group, int recursion_level);
+ const char *config_file, int recursion_level);
+static void init_default_directories();
static char *remove_end_comment(char *ptr);
/*
+ Process config files in default directories.
+
+ SYNOPSIS
+ my_search_option_files()
+ conf_file Basename for configuration file to search for.
+ If this is a path, then only this file is read.
+ argc Pointer to argc of original program
+ argv Pointer to argv of original program
+ args_used Pointer to variable for storing the number of
+ arguments used.
+ func Pointer to the function to process options
+ func_ctx It's context. Usually it is the structure to
+ store additional options.
+ DESCRIPTION
+
+ This function looks for config files in default directories. Then it
+ travesrses each of the files and calls func to process each option.
+
+ RETURN
+ 0 ok
+ 1 given cinf_file doesn't exist
+*/
+
+int my_search_option_files(const char *conf_file, int *argc, char ***argv,
+ uint *args_used, Process_option_func func,
+ void *func_ctx)
+{
+ const char **dirs, *forced_default_file, *forced_extra_defaults;
+ int error= 0;
+ DBUG_ENTER("my_search_option_files");
+
+ /* Check if we want to force the use a specific default file */
+ get_defaults_files(*argc, *argv,
+ (char **)&forced_default_file,
+ (char **)&forced_extra_defaults);
+ if (forced_default_file)
+ forced_default_file= strchr(forced_default_file,'=')+1;
+ if (forced_extra_defaults)
+ defaults_extra_file= strchr(forced_extra_defaults,'=')+1;
+
+ args_used+= (forced_default_file ? 1 : 0) + (forced_extra_defaults ? 1 : 0);
+
+ if (forced_default_file)
+ {
+ if ((error= search_default_file_with_ext(func, func_ctx, "", "",
+ forced_default_file, 0)) < 0)
+ goto err;
+ if (error > 0)
+ {
+ fprintf(stderr, "Could not open required defaults file: %s\n",
+ forced_default_file);
+ goto err;
+ }
+ }
+ else if (dirname_length(conf_file))
+ {
+ if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0)
+ goto err;
+ }
+ else
+ {
+#ifdef __WIN__
+ char system_dir[FN_REFLEN];
+ GetWindowsDirectory(system_dir,sizeof(system_dir));
+ if ((search_default_file(func, func_ctx, system_dir, conf_file)))
+ goto err;
+#endif
+#if defined(__EMX__) || defined(OS2)
+ {
+ const char *etc;
+ if ((etc= getenv("ETC")) &&
+ (search_default_file(func, func_ctx, etc, conf_file)) < 0)
+ goto err;
+ }
+#endif
+ for (dirs= default_directories ; *dirs; dirs++)
+ {
+ if (**dirs)
+ {
+ if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
+ goto err;
+ }
+ else if (defaults_extra_file)
+ {
+ if (search_default_file(func, func_ctx, NullS,
+ defaults_extra_file) < 0)
+ goto err; /* Fatal error */
+
+ }
+ }
+ }
+
+ DBUG_RETURN(error);
+
+err:
+ fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
+ exit(1);
+ return 0; /* Keep compiler happy */
+}
+
+
+/*
+ The option handler for load_defaults.
+
+ SYNOPSIS
+ handle_deault_option()
+ in_ctx Handler context. In this case it is a
+ handle_option_ctx structure.
+ group_name The name of the group the option belongs to.
+ option The very option to be processed. It is already
+ prepared to be used in argv (has -- prefix)
+
+ DESCRIPTION
+ This handler checks whether a group is one of the listed and adds an option
+ to the array if yes. Some other handler can record, for instance, all
+ groups and their options, not knowing in advance the names and amount of
+ groups.
+
+ RETURN
+ 0 - ok
+ 1 - error occured
+*/
+
+static int handle_default_option(void *in_ctx, const char *group_name,
+ const char *option)
+{
+ char *tmp;
+ struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
+
+ if (find_type((char *)group_name, ctx->group, 3))
+ {
+ if (!(tmp= alloc_root(ctx->alloc, (uint) strlen(option) + 1)))
+ return 1;
+ if (insert_dynamic(ctx->args, (gptr) &tmp))
+ return 1;
+ strmov(tmp, option);
+ }
+
+ return 0;
+}
+
+
+/*
Gets --defaults-file and --defaults-extra-file options from command line.
SYNOPSIS
@@ -136,7 +280,6 @@ void get_defaults_files(int argc, char **argv,
RETURN
0 ok
1 The given conf_file didn't exists
- 2 The given conf_file was not a normal readable file
*/
@@ -144,16 +287,16 @@ int load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv)
{
DYNAMIC_ARRAY args;
- const char **dirs, *forced_default_file, *forced_extra_defaults;
TYPELIB group;
my_bool found_print_defaults=0;
uint args_used=0;
int error= 0;
MEM_ROOT alloc;
- char *ptr, **res;
-
+ char *ptr,**res;
+ struct handle_option_ctx ctx;
DBUG_ENTER("load_defaults");
+ init_default_directories();
init_alloc_root(&alloc,512,0);
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
@@ -173,76 +316,22 @@ int load_defaults(const char *conf_file, const char **groups,
DBUG_RETURN(0);
}
- get_defaults_files(*argc, *argv,
- (char **)&forced_default_file,
- (char **)&forced_extra_defaults);
- if (forced_default_file)
- forced_default_file= strchr(forced_default_file,'=')+1;
- if (forced_extra_defaults)
- defaults_extra_file= strchr(forced_extra_defaults,'=')+1;
-
- args_used+= (forced_default_file ? 1 : 0) + (forced_extra_defaults ? 1 : 0);
-
group.count=0;
group.name= "defaults";
group.type_names= groups;
+
for (; *groups ; groups++)
group.count++;
if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
goto err;
- if (forced_default_file)
- {
- if ((error= search_default_file_with_ext(&args, &alloc, "", "",
- forced_default_file,
- &group, 0)) < 0)
- goto err;
- if (error > 0)
- {
- fprintf(stderr, "Could not open required defaults file: %s\n",
- forced_default_file);
- goto err;
- }
- }
- else if (dirname_length(conf_file))
- {
- if ((error= search_default_file(&args, &alloc, NullS, conf_file,
- &group)) < 0)
- goto err;
- }
- else
- {
-#ifdef __WIN__
- char system_dir[FN_REFLEN];
- GetWindowsDirectory(system_dir,sizeof(system_dir));
- if ((search_default_file(&args, &alloc, system_dir, conf_file, &group)))
- goto err;
-#endif
-#if defined(__EMX__) || defined(OS2)
- {
- const char *etc;
- if ((etc= getenv("ETC")) &&
- (search_default_file(&args, &alloc, etc, conf_file,
- &group)) < 0)
- goto err;
- }
-#endif
- for (dirs=default_directories ; *dirs; dirs++)
- {
- if (**dirs)
- {
- if (search_default_file(&args, &alloc, *dirs, conf_file,
- &group) < 0)
- goto err;
- }
- else if (defaults_extra_file)
- {
- if (search_default_file(&args, &alloc, NullS, defaults_extra_file,
- &group) < 0)
- goto err; /* Fatal error */
- }
- }
- }
+
+ ctx.alloc= &alloc;
+ ctx.args= &args;
+ ctx.group= &group;
+
+ error= my_search_option_files(conf_file, argc, argv, &args_used,
+ handle_default_option, (void *) &ctx);
/*
Here error contains <> 0 only if we have a fully specified conf_file
or a forced default file
@@ -302,17 +391,19 @@ void free_defaults(char **argv)
}
-static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
+static int search_default_file(Process_option_func opt_handler,
+ void *handler_ctx,
const char *dir,
- const char *config_file, TYPELIB *group)
+ const char *config_file)
{
char **ext;
for (ext= (char**) f_extensions; *ext; *ext++)
{
int error;
- if ((error= search_default_file_with_ext(args, alloc, dir, *ext,
- config_file, group, 0)) < 0)
+ if ((error= search_default_file_with_ext(opt_handler, handler_ctx,
+ dir, *ext,
+ config_file, 0)) < 0)
return error;
}
return 0;
@@ -374,8 +465,10 @@ static char *get_argument(const char *keyword, uint kwlen,
SYNOPSIS
search_default_file_with_ext()
- args Store pointer to found options here
- alloc Allocate strings in this object
+ opt_handler Option handler function. It is used to process
+ every separate option.
+ handler_ctx Pointer to the structure to store actual
+ parameters of the function.
dir directory to read
ext Extension for configuration file
config_file Name of configuration file
@@ -387,21 +480,23 @@ static char *get_argument(const char *keyword, uint kwlen,
0 Success
-1 Fatal error, abort
1 File not found (Warning)
- 2 File is not a regular file (Warning)
*/
-static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
- const char *dir, const char *ext,
- const char *config_file,
- TYPELIB *group, int recursion_level)
+static int search_default_file_with_ext(Process_option_func opt_handler,
+ void *handler_ctx,
+ const char *dir,
+ const char *ext,
+ const char *config_file,
+ int recursion_level)
{
- char name[FN_REFLEN + 10], buff[4096], *ptr, *end, *value, *tmp, **tmp_ext;
+ char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext;
+ char *value, option[4096], tmp[FN_REFLEN];
static const char includedir_keyword[]= "includedir";
static const char include_keyword[]= "include";
const int max_recursion_level= 10;
FILE *fp;
- uint line= 0;
- my_bool read_values= 0, found_group= 0;
+ uint line=0;
+ my_bool found_group=0;
uint i;
MY_DIR *search_dir;
FILEINFO *search_file;
@@ -433,13 +528,13 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
if ((stat_info.st_mode & S_IWOTH) &&
(stat_info.st_mode & S_IFMT) == S_IFREG)
{
- fprintf(stderr, "warning: World-writable config file %s is ignored\n",
+ fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
name);
return 0;
}
}
#endif
- if (!(fp= my_fopen(fn_format(name, name, "", "", 4), O_RDONLY, MYF(0))))
+ if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
return 0; /* Ignore wrong files */
while (fgets(buff, sizeof(buff) - 1, fp))
@@ -499,14 +594,10 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
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,
+ search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
recursion_level + 1);
}
}
@@ -521,7 +612,7 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
name, line)))
goto err;
- search_default_file_with_ext(args, alloc, "", "", ptr, group,
+ search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
recursion_level + 1);
}
@@ -540,7 +631,8 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
}
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;/* Remove end space */
end[0]=0;
- read_values=find_type(ptr,group,3) > 0;
+
+ strnmov(curr_gr, ptr, min((uint) (end-ptr)+1, 4096));
continue;
}
if (!found_group)
@@ -550,19 +642,17 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
name,line);
goto err;
}
- if (!read_values)
- continue;
+
+
end= remove_end_comment(ptr);
if ((value= strchr(ptr, '=')))
end= value; /* Option without argument */
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
if (!value)
{
- if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3)))
- goto err;
- strmake(strmov(tmp,"--"),ptr,(uint) (end-ptr));
- if (insert_dynamic(args,(gptr) &tmp))
- goto err;
+ strmake(strmov(option,"--"),ptr,(uint) (end-ptr));
+ if (opt_handler(handler_ctx, curr_gr, option))
+ goto err;
}
else
{
@@ -584,12 +674,7 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
value++;
value_end--;
}
- if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 +
- (uint) (value_end-value)+1)))
- goto err;
- if (insert_dynamic(args,(gptr) &tmp))
- goto err;
- ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr));
+ ptr=strnmov(strmov(option,"--"),ptr,(uint) (end-ptr));
*ptr++= '=';
for ( ; value != value_end; value++)
@@ -631,6 +716,8 @@ static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
*ptr++= *value;
}
*ptr=0;
+ if (opt_handler(handler_ctx, curr_gr, option))
+ goto err;
}
}
my_fclose(fp,MYF(0));
@@ -677,6 +764,7 @@ void print_defaults(const char *conf_file, const char **groups)
char name[FN_REFLEN], **ext;
const char **dirs;
+ init_default_directories();
puts("\nDefault options are read from the following files in the given order:");
if (dirname_length(conf_file))
@@ -739,3 +827,23 @@ void print_defaults(const char *conf_file, const char **groups)
}
#include <help_end.h>
+
+static void init_default_directories()
+{
+ const char *env, **ptr= default_directories;
+
+#ifdef __WIN__
+ *ptr++= "C:/";
+#elif defined(__NETWARE__)
+ *ptr++= "sys:/etc/";
+#else
+ *ptr++= "/etc/";
+#endif
+ if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
+ *ptr++= env;
+ *ptr++= ""; /* Place for defaults_extra_file */
+#if !defined(__WIN__) && !defined(__NETWARE__)
+ *ptr++= "~/";;
+#endif
+ *ptr= 0; /* end marker */
+}