12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/****************************************************************************
17
17
Add all options from files named "group".cnf from the default_directories
33
33
--print-defaults ; Print the modified command line and exit
34
34
****************************************************************************/
38
#include "drizzled/internal/my_sys.h"
39
#include "drizzled/internal/m_string.h"
40
#include "drizzled/charset_info.h"
41
#include "drizzled/typelib.h"
42
#include <drizzled/configmake.h>
43
#include <drizzled/gettext.h>
45
#include "drizzled/cached_directory.h"
47
#ifdef HAVE_SYS_STAT_H
48
# include <sys/stat.h>
36
#include "mysys_priv.h"
37
#include <mystrings/m_string.h>
38
#include <mystrings/m_ctype.h>
61
41
const char *my_defaults_file=0;
62
42
const char *my_defaults_group_suffix=0;
68
48
const char *default_directories[MAX_DEFAULT_DIRS + 1];
70
50
static const char *f_extensions[]= { ".cnf", 0 };
72
int handle_default_option(void *in_ctx, const char *group_name,
53
static int handle_default_option(void *in_ctx, const char *group_name,
76
57
This structure defines the context that we pass to callback
158
139
(char **) &my_defaults_group_suffix);
160
141
if (! my_defaults_group_suffix)
161
my_defaults_group_suffix= getenv("DRIZZLE_GROUP_SUFFIX");
142
my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
163
144
if (forced_extra_defaults)
164
145
my_defaults_extra_file= (char *) forced_extra_defaults;
166
147
if (forced_default_file)
167
148
my_defaults_file= forced_default_file;
171
152
load_defaults() as otherwise we can't know the type of 'func_ctx'
174
if (my_defaults_group_suffix && (func == handle_default_option))
155
if (my_defaults_group_suffix && func == handle_default_option)
176
157
/* Handle --defaults-group-suffix= */
178
159
const char **extra_groups;
179
const size_t instance_len= strlen(my_defaults_group_suffix);
160
const uint32_t instance_len= strlen(my_defaults_group_suffix);
180
161
struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
182
163
TYPELIB *group= ctx->group;
185
(const char**)ctx->alloc->alloc_root(
166
(const char**)alloc_root(ctx->alloc,
186
167
(2*group->count+1)*sizeof(char*))))
189
170
for (i= 0; i < group->count; i++)
192
173
extra_groups[i]= group->type_names[i]; /** copy group */
194
175
len= strlen(extra_groups[i]);
195
if (!(ptr= (char *)ctx->alloc->alloc_root( len+instance_len+1)))
176
if (!(ptr= alloc_root(ctx->alloc, len+instance_len+1)))
198
179
extra_groups[i+group->count]= ptr;
200
181
/** Construct new group */
201
182
memcpy(ptr, extra_groups[i], len);
202
183
memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
205
186
group->count*= 2;
206
187
group->type_names= extra_groups;
207
188
group->type_names[group->count]= 0;
210
191
if (forced_default_file)
212
193
if ((error= search_default_file_with_ext(func, func_ctx, "", "",
279
261
1 - error occured
282
int handle_default_option(void *in_ctx, const char *group_name,
264
static int handle_default_option(void *in_ctx, const char *group_name,
286
268
struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
291
if (ctx->group->find_type(const_cast<char*>(group_name), 3))
273
if (find_type((char *)group_name, ctx->group, 3))
293
if (!(tmp= (char *)ctx->alloc->alloc_root(strlen(option) + 1)))
275
if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
295
277
if (insert_dynamic(ctx->args, (unsigned char*) &tmp))
279
my_stpcpy(tmp, option);
325
307
int org_argc= argc, prev_argc= 0;
326
308
*defaults= *extra_defaults= *group_suffix= 0;
328
const std::string DEFAULTS_FILE("--defaults-file=");
329
const std::string DEFAULTS_EXTRA_FILE("--defaults-extra-file=");
330
const std::string DEFAULTS_GROUP_SUFFIX("--defaults-group-suffix=");
332
310
while (argc >= 2 && argc != prev_argc)
334
312
/* Skip program name or previously handled argument */
336
314
prev_argc= argc; /* To check if we found */
337
if (!*defaults && (strncmp(*argv,
338
DEFAULTS_FILE.c_str(),
339
DEFAULTS_FILE.size()) == 0))
315
if (!*defaults && is_prefix(*argv,"--defaults-file="))
341
*defaults= *argv + DEFAULTS_FILE.size();
317
*defaults= *argv + sizeof("--defaults-file=")-1;
345
if (!*extra_defaults && (strncmp(*argv,
346
DEFAULTS_EXTRA_FILE.c_str(),
347
DEFAULTS_EXTRA_FILE.size()) == 0))
321
if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
349
*extra_defaults= *argv + DEFAULTS_EXTRA_FILE.size();
323
*extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
353
if (!*group_suffix && (strncmp(*argv,
354
DEFAULTS_GROUP_SUFFIX.c_str(),
355
DEFAULTS_GROUP_SUFFIX.size()) == 0))
327
if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
358
*group_suffix= *argv + DEFAULTS_GROUP_SUFFIX.size();
329
*group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
401
372
DYNAMIC_ARRAY args;
374
bool found_print_defaults= 0;
403
375
uint32_t args_used= 0;
405
memory::Root alloc(512);
407
379
struct handle_option_ctx ctx;
409
381
init_default_directories();
382
init_alloc_root(&alloc,512,0);
411
384
Check if the user doesn't want any default option processing
412
385
--no-defaults is always the first option
416
389
/* remove the --no-defaults argument and return only the other arguments */
418
if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (*argc + 1)*sizeof(char*))))
391
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
392
(*argc + 1)*sizeof(char*))))
420
394
res= (char**) (ptr+sizeof(alloc));
421
memset(res,0,(*argc + 1));
422
395
res[0]= **argv; /* Copy program name */
423
for (i=2 ; i < (uint32_t) *argc ; i++)
396
for (i=2 ; i < (uint) *argc ; i++)
424
397
res[i-1]=argv[0][i];
425
398
res[i-1]=0; /* End pointer */
428
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
401
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
449
422
Here error contains <> 0 only if we have a fully specified conf_file
450
423
or a forced default file
452
if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (args.elements + *argc +1) *sizeof(char*))))
425
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
426
(args.elements + *argc +1) *sizeof(char*))))
454
428
res= (char**) (ptr+sizeof(alloc));
464
438
Check if we wan't to see the new argument list
465
439
This options must always be the last of the default options
441
if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
443
found_print_defaults=1;
444
--*argc; ++*argv; /* skip argument */
468
448
memcpy(res+1+args.elements, *argv + 1, (*argc-1)*sizeof(char*));
469
449
res[args.elements+ *argc]=0; /* last null */
471
(*argc)+=int(args.elements);
472
*argv= static_cast<char**>(res);
473
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
451
(*argc)+=args.elements;
453
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
474
454
delete_dynamic(&args);
455
if (found_print_defaults)
458
printf("%s would have been started with the following arguments:\n",
460
for (i=1 ; i < *argc ; i++)
461
printf("%s ", (*argv)[i]);
479
468
fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
470
return 0; /* Keep compiler happy */
484
474
void free_defaults(char **argv)
487
477
memcpy(&ptr, (char*) argv - sizeof(ptr), sizeof(ptr));
488
ptr.free_root(MYF(0));
478
free_root(&ptr,MYF(0));
568
558
search_default_file_with_ext()
569
559
opt_handler Option handler function. It is used to process
570
560
every separate option.
571
handler_ctx Pointer to the structure to store actual
561
handler_ctx Pointer to the structure to store actual
572
562
parameters of the function.
573
563
dir directory to read
574
564
ext Extension for configuration file
606
599
end=convert_dirname(name, dir, NULL);
607
600
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
609
sprintf(end,"%s%s",config_file,ext);
602
strxmov(end,config_file,ext,NULL);
613
strcpy(name,config_file);
606
my_stpcpy(name,config_file);
615
608
fn_format(name,name,"","",4);
621
614
Ignore world-writable regular files.
622
615
This is mainly done to protect us to not read a file created by
623
the mysqld server, but the check is still valid in most context.
616
the mysqld server, but the check is still valid in most context.
625
618
if ((stat_info.st_mode & S_IWOTH) &&
626
619
(stat_info.st_mode & S_IFMT) == S_IFREG)
633
if (!(fp= fopen(name, "r")))
626
if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
634
627
return 1; /* Ignore wrong files */
636
memset(buff,0,sizeof(buff));
637
629
while (fgets(buff, sizeof(buff) - 1, fp))
650
642
if (recursion_level >= max_recursion_level)
652
for (end= ptr + strlen(ptr) - 1;
644
for (end= ptr + strlen(ptr) - 1;
653
645
my_isspace(&my_charset_utf8_general_ci, *(end - 1));
674
666
ptr, name, line)))
677
CachedDirectory dir_cache(ptr);
679
if (dir_cache.fail())
683
* Since clients still use this code, we use fprintf here.
684
* This fprintf needs to be turned into errmsg_printf
685
* as soon as the client programs no longer use mysys
686
* and can use the pluggable error message system.
688
fprintf(stderr, _("error: could not open directory: %s\n"), ptr);
669
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
692
CachedDirectory::Entries files= dir_cache.getEntries();
693
CachedDirectory::Entries::iterator file_iter= files.begin();
695
while (file_iter != files.end())
672
for (i= 0; i < (uint) search_dir->number_off_files; i++)
697
CachedDirectory::Entry *entry= *file_iter;
698
ext= fn_ext(entry->filename.c_str());
674
search_file= search_dir->dir_entry + i;
675
ext= fn_ext(search_file->name);
700
677
/* check extension */
701
678
for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
703
680
if (!strcmp(ext, *tmp_ext))
705
fn_format(tmp, entry->filename.c_str(), ptr, "",
706
MY_UNPACK_FILENAME | MY_SAFE_PATH);
708
search_default_file_with_ext(opt_handler, handler_ctx, "", "",
709
tmp, recursion_level + 1);
686
fn_format(tmp, search_file->name, ptr, "",
687
MY_UNPACK_FILENAME | MY_SAFE_PATH);
689
search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
690
recursion_level + 1);
694
my_dirend(search_dir);
716
696
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
717
697
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(include_keyword)-1]))
742
722
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
745
strncpy(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
746
curr_gr[min((size_t)(end-ptr)+1, sizeof(curr_gr)-1)] = '\0';
725
strmake(curr_gr, ptr, cmin((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
748
727
/* signal that a new group is found */
749
728
opt_handler(handler_ctx, curr_gr, NULL);
762
741
end= remove_end_comment(ptr);
763
742
if ((value= strchr(ptr, '=')))
764
743
end= value; /* Option without argument */
765
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) || end[-1]== '\n'; end--) ;
744
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
768
strncpy(strcpy(option,"--")+2,ptr,strlen(ptr)+1);
747
strmake(my_stpcpy(option,"--"),ptr, (size_t) (end-ptr));
769
748
if (opt_handler(handler_ctx, curr_gr, option))
776
755
for (value++ ; my_isspace(&my_charset_utf8_general_ci,*value); value++) ;
777
756
value_end= strchr(value, '\0');
779
We don't have to test for value_end >= value as we know there is
758
We don't have to test for value_end >= value as we know there is
782
761
for ( ; my_isspace(&my_charset_utf8_general_ci,value_end[-1]) ; value_end--) ;
783
762
if (value_end < value) /* Empty string */
786
765
/* remove quotes around argument */
787
766
if ((*value == '\"' || *value == '\'') && /* First char is quote */
788
767
(value + 1 < value_end ) && /* String is longer than 1 */
789
768
*value == value_end[-1] ) /* First char is equal to last char */
795
memset(option,0,2+(size_t)(end-ptr)+1);
796
ptr= strncpy(strcpy(option,"--")+2,ptr,(size_t) (end-ptr));
773
ptr=my_stpncpy(my_stpcpy(option,"--"),ptr,(size_t) (end-ptr));
801
776
for ( ; value != value_end; value++)
906
880
end= convert_dirname(name, pos, NULL);
907
881
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
909
sprintf(end,"%s%s ",conf_file, *ext);
883
strxmov(end, conf_file, *ext, " ", NULL);
910
884
fputs(name,stdout);
939
913
puts("\nThe following options may be given as the first argument:\n\
940
--no-defaults Don't read default options from any options file\n\
941
--defaults-file=# Only read default options from the given file #\n\
942
--defaults-extra-file=# Read this file after the global files are read");
914
--print-defaults Print the program argument list and exit\n\
915
--no-defaults Don't read default options from any options file\n\
916
--defaults-file=# Only read default options from the given file #\n\
917
--defaults-extra-file=# Read this file after the global files are read");
946
921
This extra complexity is to avoid declaring 'rc' if it won't be
949
static void add_directory(const char* dir)
951
array_append_string_unique(dir, default_directories, array_elements(default_directories));
954
static void add_common_directories()
956
const char *env= getenv("DRIZZLE_HOME");
959
// Placeholder for --defaults-extra-file=<path>
924
#define ADD_DIRECTORY(DIR) (void) array_append_string_unique((DIR), default_directories, \
925
array_elements(default_directories))
927
#define ADD_COMMON_DIRECTORIES() \
930
if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV)))) \
931
ADD_DIRECTORY(env); \
932
/* Placeholder for --defaults-extra-file=<path> */ \
964
938
Initialize default directories for Unix
969
943
3. --sysconfdir=<path> (compile-time option)
970
4. getenv("DRIZZLE_HOME")
944
4. getenv(DEFAULT_HOME_ENV)
971
945
5. --defaults-extra-file=<path> (run-time option)
975
949
static void init_default_directories(void)
977
951
memset(default_directories, 0, sizeof(default_directories));
978
add_directory("/etc/");
979
add_directory("/etc/drizzle/");
980
add_directory(SYSCONFDIR);
981
add_common_directories();
952
ADD_DIRECTORY("/etc/");
953
ADD_DIRECTORY("/etc/mysql/");
954
#if defined(DEFAULT_SYSCONFDIR)
955
ADD_DIRECTORY(DEFAULT_SYSCONFDIR);
957
ADD_COMMON_DIRECTORIES();
985
} /* namespace internal */
986
} /* namespace drizzled */