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;
147
128
int my_search_option_files(const char *conf_file, int *argc, char ***argv,
148
uint32_t *args_used, Process_option_func func,
129
uint *args_used, Process_option_func func,
151
132
const char **dirs, *forced_default_file, *forced_extra_defaults;
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 uint 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, "", "",
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)))
295
if (insert_dynamic(ctx->args, (unsigned char*) &tmp))
275
if (!(tmp= alloc_root(ctx->alloc, strlen(option) + 1)))
277
if (insert_dynamic(ctx->args, (uchar*) &tmp))
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;
414
387
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
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 */
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));
529
519
static char *get_argument(const char *keyword, size_t kwlen,
530
char *ptr, char *name, uint32_t line)
520
char *ptr, char *name, uint line)
534
524
/* Skip over "include / includedir keyword" and following whitespace */
536
526
for (ptr+= kwlen - 1;
537
my_isspace(&my_charset_utf8_general_ci, ptr[0]);
527
my_isspace(&my_charset_latin1, ptr[0]);
596
586
static const char include_keyword[]= "include";
597
587
const int max_recursion_level= 10;
600
590
bool found_group=0;
593
FILEINFO *search_file;
602
595
if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
603
596
return 0; /* Ignore wrong paths */
606
end=convert_dirname(name, dir, NULL);
599
end=convert_dirname(name, dir, NullS);
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,NullS);
613
strcpy(name,config_file);
606
stpcpy(name,config_file);
615
608
fn_format(name,name,"","",4);
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))
640
632
/* Ignore comment and empty lines */
641
for (ptr= buff; my_isspace(&my_charset_utf8_general_ci, *ptr); ptr++)
633
for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
644
636
if (*ptr == '#' || *ptr == ';' || !*ptr)
664
656
/* skip over `!' and following whitespace */
665
for (++ptr; my_isspace(&my_charset_utf8_general_ci, ptr[0]); ptr++)
657
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
668
660
if ((!strncmp(ptr, includedir_keyword,
669
661
sizeof(includedir_keyword) - 1)) &&
670
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(includedir_keyword) - 1]))
662
my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
672
664
if (!(ptr= get_argument(includedir_keyword,
673
665
sizeof(includedir_keyword),
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
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(include_keyword)-1]))
697
my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
719
699
if (!(ptr= get_argument(include_keyword,
720
700
sizeof(include_keyword), ptr,
741
721
/* Remove end space */
742
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
722
for ( ; my_isspace(&my_charset_latin1,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, min((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_latin1,end[-1]) ; end--) ;
768
strncpy(strcpy(option,"--")+2,ptr,strlen(ptr)+1);
747
strmake(stpcpy(option,"--"),ptr, (size_t) (end-ptr));
769
748
if (opt_handler(handler_ctx, curr_gr, option))
774
753
/* Remove pre- and end space */
776
for (value++ ; my_isspace(&my_charset_utf8_general_ci,*value); value++) ;
755
for (value++ ; my_isspace(&my_charset_latin1,*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
for ( ; my_isspace(&my_charset_utf8_general_ci,value_end[-1]) ; value_end--) ;
761
for ( ; my_isspace(&my_charset_latin1,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=stpncpy(stpcpy(option,"--"),ptr,(size_t) (end-ptr));
801
776
for ( ; value != value_end; value++)
903
877
pos= my_defaults_extra_file;
906
end= convert_dirname(name, pos, NULL);
880
end= convert_dirname(name, pos, NullS);
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, " ", NullS);
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 */