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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
****************************************************************************/
36
#include "mysys_priv.h"
37
#include <mystrings/m_string.h>
38
#include <mystrings/m_ctype.h>
39
#include <mysys/my_dir.h>
38
#include "drizzled/internal/my_sys.h"
39
#include "drizzled/internal/m_string.h"
40
#include "drizzled/charset_info.h"
41
#include <drizzled/configmake.h>
42
#include <drizzled/gettext.h>
44
#include "drizzled/cached_directory.h"
46
#ifdef HAVE_SYS_STAT_H
47
# include <sys/stat.h>
43
60
const char *my_defaults_file=0;
44
61
const char *my_defaults_group_suffix=0;
52
69
static const char *f_extensions[]= { ".cnf", 0 };
54
static int handle_default_option(void *in_ctx, const char *group_name,
71
int handle_default_option(void *in_ctx, const char *group_name,
58
75
This structure defines the context that we pass to callback
140
157
(char **) &my_defaults_group_suffix);
142
159
if (! my_defaults_group_suffix)
143
my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
160
my_defaults_group_suffix= getenv("DRIZZLE_GROUP_SUFFIX");
145
162
if (forced_extra_defaults)
146
163
my_defaults_extra_file= (char *) forced_extra_defaults;
148
165
if (forced_default_file)
149
166
my_defaults_file= forced_default_file;
153
170
load_defaults() as otherwise we can't know the type of 'func_ctx'
156
if (my_defaults_group_suffix && func == handle_default_option)
173
if (my_defaults_group_suffix && (func == handle_default_option))
158
175
/* Handle --defaults-group-suffix= */
160
177
const char **extra_groups;
161
const uint32_t instance_len= strlen(my_defaults_group_suffix);
178
const size_t instance_len= strlen(my_defaults_group_suffix);
162
179
struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
164
181
TYPELIB *group= ctx->group;
167
(const char**)alloc_root(ctx->alloc,
184
(const char**)ctx->alloc->alloc_root(
168
185
(2*group->count+1)*sizeof(char*))))
171
188
for (i= 0; i < group->count; i++)
174
191
extra_groups[i]= group->type_names[i]; /** copy group */
176
193
len= strlen(extra_groups[i]);
177
if (!(ptr= (char *)alloc_root(ctx->alloc, len+instance_len+1)))
194
if (!(ptr= (char *)ctx->alloc->alloc_root( len+instance_len+1)))
180
197
extra_groups[i+group->count]= ptr;
182
199
/** Construct new group */
183
200
memcpy(ptr, extra_groups[i], len);
184
201
memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
187
204
group->count*= 2;
188
205
group->type_names= extra_groups;
189
206
group->type_names[group->count]= 0;
192
209
if (forced_default_file)
194
211
if ((error= search_default_file_with_ext(func, func_ctx, "", "",
262
278
1 - error occured
265
static int handle_default_option(void *in_ctx, const char *group_name,
281
int handle_default_option(void *in_ctx, const char *group_name,
269
285
struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
274
290
if (find_type((char *)group_name, ctx->group, 3))
276
if (!(tmp= (char *)alloc_root(ctx->alloc, strlen(option) + 1)))
292
if (!(tmp= (char *)ctx->alloc->alloc_root(strlen(option) + 1)))
278
294
if (insert_dynamic(ctx->args, (unsigned char*) &tmp))
280
my_stpcpy(tmp, option);
308
324
int org_argc= argc, prev_argc= 0;
309
325
*defaults= *extra_defaults= *group_suffix= 0;
327
const std::string DEFAULTS_FILE("--defaults-file=");
328
const std::string DEFAULTS_EXTRA_FILE("--defaults-extra-file=");
329
const std::string DEFAULTS_GROUP_SUFFIX("--defaults-group-suffix=");
311
331
while (argc >= 2 && argc != prev_argc)
313
333
/* Skip program name or previously handled argument */
315
335
prev_argc= argc; /* To check if we found */
316
if (!*defaults && is_prefix(*argv,"--defaults-file="))
336
if (!*defaults && (strncmp(*argv,
337
DEFAULTS_FILE.c_str(),
338
DEFAULTS_FILE.size()) == 0))
318
*defaults= *argv + sizeof("--defaults-file=")-1;
340
*defaults= *argv + DEFAULTS_FILE.size();
322
if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
344
if (!*extra_defaults && (strncmp(*argv,
345
DEFAULTS_EXTRA_FILE.c_str(),
346
DEFAULTS_EXTRA_FILE.size()) == 0))
324
*extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
348
*extra_defaults= *argv + DEFAULTS_EXTRA_FILE.size();
328
if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
352
if (!*group_suffix && (strncmp(*argv,
353
DEFAULTS_GROUP_SUFFIX.c_str(),
354
DEFAULTS_GROUP_SUFFIX.size()) == 0))
330
*group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
357
*group_suffix= *argv + DEFAULTS_GROUP_SUFFIX.size();
373
400
DYNAMIC_ARRAY args;
375
bool found_print_defaults= 0;
376
402
uint32_t args_used= 0;
404
memory::Root alloc(512);
380
406
struct handle_option_ctx ctx;
382
408
init_default_directories();
383
init_alloc_root(&alloc,512,0);
385
410
Check if the user doesn't want any default option processing
386
411
--no-defaults is always the first option
390
415
/* remove the --no-defaults argument and return only the other arguments */
392
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
393
(*argc + 1)*sizeof(char*))))
417
if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (*argc + 1)*sizeof(char*))))
395
419
res= (char**) (ptr+sizeof(alloc));
420
memset(res,0,(*argc + 1));
396
421
res[0]= **argv; /* Copy program name */
397
for (i=2 ; i < (uint) *argc ; i++)
422
for (i=2 ; i < (uint32_t) *argc ; i++)
398
423
res[i-1]=argv[0][i];
399
424
res[i-1]=0; /* End pointer */
402
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
427
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
423
448
Here error contains <> 0 only if we have a fully specified conf_file
424
449
or a forced default file
426
if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
427
(args.elements + *argc +1) *sizeof(char*))))
451
if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (args.elements + *argc +1) *sizeof(char*))))
429
453
res= (char**) (ptr+sizeof(alloc));
439
463
Check if we wan't to see the new argument list
440
464
This options must always be the last of the default options
442
if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
444
found_print_defaults=1;
445
--*argc; ++*argv; /* skip argument */
449
467
memcpy(res+1+args.elements, *argv + 1, (*argc-1)*sizeof(char*));
450
468
res[args.elements+ *argc]=0; /* last null */
452
(*argc)+=args.elements;
454
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
470
(*argc)+=int(args.elements);
471
*argv= static_cast<char**>(res);
472
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
455
473
delete_dynamic(&args);
456
if (found_print_defaults)
459
printf("%s would have been started with the following arguments:\n",
461
for (i=1 ; i < *argc ; i++)
462
printf("%s ", (*argv)[i]);
469
478
fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
471
return 0; /* Keep compiler happy */
475
483
void free_defaults(char **argv)
478
486
memcpy(&ptr, (char*) argv - sizeof(ptr), sizeof(ptr));
479
free_root(&ptr,MYF(0));
487
ptr.free_root(MYF(0));
559
567
search_default_file_with_ext()
560
568
opt_handler Option handler function. It is used to process
561
569
every separate option.
562
handler_ctx Pointer to the structure to store actual
570
handler_ctx Pointer to the structure to store actual
563
571
parameters of the function.
564
572
dir directory to read
565
573
ext Extension for configuration file
600
605
end=convert_dirname(name, dir, NULL);
601
606
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
603
strxmov(end,config_file,ext,NULL);
608
sprintf(end,"%s%s",config_file,ext);
607
my_stpcpy(name,config_file);
612
strcpy(name,config_file);
609
614
fn_format(name,name,"","",4);
615
620
Ignore world-writable regular files.
616
621
This is mainly done to protect us to not read a file created by
617
the mysqld server, but the check is still valid in most context.
622
the mysqld server, but the check is still valid in most context.
619
624
if ((stat_info.st_mode & S_IWOTH) &&
620
625
(stat_info.st_mode & S_IFMT) == S_IFREG)
627
if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
632
if (!(fp= fopen(name, "r")))
628
633
return 1; /* Ignore wrong files */
635
memset(buff,0,sizeof(buff));
630
636
while (fgets(buff, sizeof(buff) - 1, fp))
643
649
if (recursion_level >= max_recursion_level)
645
for (end= ptr + strlen(ptr) - 1;
651
for (end= ptr + strlen(ptr) - 1;
646
652
my_isspace(&my_charset_utf8_general_ci, *(end - 1));
667
673
ptr, name, line)))
670
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
676
CachedDirectory dir_cache(ptr);
678
if (dir_cache.fail())
682
* Since clients still use this code, we use fprintf here.
683
* This fprintf needs to be turned into errmsg_printf
684
* as soon as the client programs no longer use mysys
685
* and can use the pluggable error message system.
687
fprintf(stderr, _("error: could not open directory: %s\n"), ptr);
673
for (i= 0; i < (uint) search_dir->number_off_files; i++)
691
CachedDirectory::Entries files= dir_cache.getEntries();
692
CachedDirectory::Entries::iterator file_iter= files.begin();
694
while (file_iter != files.end())
675
search_file= search_dir->dir_entry + i;
676
ext= fn_ext(search_file->name);
696
CachedDirectory::Entry *entry= *file_iter;
697
ext= fn_ext(entry->filename.c_str());
678
699
/* check extension */
679
700
for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
681
702
if (!strcmp(ext, *tmp_ext))
687
fn_format(tmp, search_file->name, ptr, "",
688
MY_UNPACK_FILENAME | MY_SAFE_PATH);
690
search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
691
recursion_level + 1);
704
fn_format(tmp, entry->filename.c_str(), ptr, "",
705
MY_UNPACK_FILENAME | MY_SAFE_PATH);
707
search_default_file_with_ext(opt_handler, handler_ctx, "", "",
708
tmp, recursion_level + 1);
695
my_dirend(search_dir);
697
715
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
698
716
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(include_keyword)-1]))
723
741
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
726
strmake(curr_gr, ptr, cmin((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
744
strncpy(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
745
curr_gr[min((size_t)(end-ptr)+1, sizeof(curr_gr)-1)] = '\0';
728
747
/* signal that a new group is found */
729
748
opt_handler(handler_ctx, curr_gr, NULL);
742
761
end= remove_end_comment(ptr);
743
762
if ((value= strchr(ptr, '=')))
744
763
end= value; /* Option without argument */
745
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
764
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) || end[-1]== '\n'; end--) ;
748
strmake(my_stpcpy(option,"--"),ptr, (size_t) (end-ptr));
767
strncpy(strcpy(option,"--")+2,ptr,strlen(ptr)+1);
749
768
if (opt_handler(handler_ctx, curr_gr, option))
756
775
for (value++ ; my_isspace(&my_charset_utf8_general_ci,*value); value++) ;
757
776
value_end= strchr(value, '\0');
759
We don't have to test for value_end >= value as we know there is
778
We don't have to test for value_end >= value as we know there is
762
781
for ( ; my_isspace(&my_charset_utf8_general_ci,value_end[-1]) ; value_end--) ;
763
782
if (value_end < value) /* Empty string */
766
785
/* remove quotes around argument */
767
786
if ((*value == '\"' || *value == '\'') && /* First char is quote */
768
787
(value + 1 < value_end ) && /* String is longer than 1 */
769
788
*value == value_end[-1] ) /* First char is equal to last char */
774
ptr=my_stpncpy(my_stpcpy(option,"--"),ptr,(size_t) (end-ptr));
794
memset(option,0,2+(size_t)(end-ptr)+1);
795
ptr= strncpy(strcpy(option,"--")+2,ptr,(size_t) (end-ptr));
777
800
for ( ; value != value_end; value++)
881
905
end= convert_dirname(name, pos, NULL);
882
906
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
884
strxmov(end, conf_file, *ext, " ", NULL);
908
sprintf(end,"%s%s ",conf_file, *ext);
885
909
fputs(name,stdout);
914
938
puts("\nThe following options may be given as the first argument:\n\
915
--print-defaults Print the program argument list and exit\n\
916
--no-defaults Don't read default options from any options file\n\
917
--defaults-file=# Only read default options from the given file #\n\
918
--defaults-extra-file=# Read this file after the global files are read");
939
--no-defaults Don't read default options from any options file\n\
940
--defaults-file=# Only read default options from the given file #\n\
941
--defaults-extra-file=# Read this file after the global files are read");
952
975
memset(default_directories, 0, sizeof(default_directories));
953
976
ADD_DIRECTORY("/etc/");
954
977
ADD_DIRECTORY("/etc/drizzle/");
955
#if defined(DEFAULT_SYSCONFDIR)
956
ADD_DIRECTORY(DEFAULT_SYSCONFDIR);
978
ADD_DIRECTORY(SYSCONFDIR);
958
979
ADD_COMMON_DIRECTORIES();
959
980
ADD_DIRECTORY("~/");
983
} /* namespace internal */
984
} /* namespace drizzled */