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/configmake.h>
42
#include <drizzled/gettext.h>
44
#include "drizzled/cached_directory.h"
46
#ifdef HAVE_SYS_STAT_H
47
# include <sys/stat.h>
36
#include "mysys_priv.h"
37
#include <mystrings/m_string.h>
38
#include <mystrings/m_ctype.h>
60
41
const char *my_defaults_file=0;
61
42
const char *my_defaults_group_suffix=0;
146
128
int my_search_option_files(const char *conf_file, int *argc, char ***argv,
147
uint32_t *args_used, Process_option_func func,
129
uint *args_used, Process_option_func func,
150
132
const char **dirs, *forced_default_file, *forced_extra_defaults;
170
152
load_defaults() as otherwise we can't know the type of 'func_ctx'
173
if (my_defaults_group_suffix && (func == handle_default_option))
155
if (my_defaults_group_suffix && func == handle_default_option)
175
157
/* Handle --defaults-group-suffix= */
177
159
const char **extra_groups;
178
const size_t instance_len= strlen(my_defaults_group_suffix);
160
const uint instance_len= strlen(my_defaults_group_suffix);
179
161
struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
181
163
TYPELIB *group= ctx->group;
184
(const char**)ctx->alloc->alloc_root(
166
(const char**)alloc_root(ctx->alloc,
185
167
(2*group->count+1)*sizeof(char*))))
188
170
for (i= 0; i < group->count; i++)
191
173
extra_groups[i]= group->type_names[i]; /** copy group */
193
175
len= strlen(extra_groups[i]);
194
if (!(ptr= (char *)ctx->alloc->alloc_root( len+instance_len+1)))
176
if (!(ptr= alloc_root(ctx->alloc, len+instance_len+1)))
197
179
extra_groups[i+group->count]= ptr;
199
181
/** Construct new group */
200
182
memcpy(ptr, extra_groups[i], len);
201
183
memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
204
186
group->count*= 2;
205
187
group->type_names= extra_groups;
206
188
group->type_names[group->count]= 0;
209
191
if (forced_default_file)
211
193
if ((error= search_default_file_with_ext(func, func_ctx, "", "",
324
307
int org_argc= argc, prev_argc= 0;
325
308
*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=");
331
310
while (argc >= 2 && argc != prev_argc)
333
312
/* Skip program name or previously handled argument */
335
314
prev_argc= argc; /* To check if we found */
336
if (!*defaults && (strncmp(*argv,
337
DEFAULTS_FILE.c_str(),
338
DEFAULTS_FILE.size()) == 0))
315
if (!*defaults && is_prefix(*argv,"--defaults-file="))
340
*defaults= *argv + DEFAULTS_FILE.size();
317
*defaults= *argv + sizeof("--defaults-file=")-1;
344
if (!*extra_defaults && (strncmp(*argv,
345
DEFAULTS_EXTRA_FILE.c_str(),
346
DEFAULTS_EXTRA_FILE.size()) == 0))
321
if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
348
*extra_defaults= *argv + DEFAULTS_EXTRA_FILE.size();
323
*extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
352
if (!*group_suffix && (strncmp(*argv,
353
DEFAULTS_GROUP_SUFFIX.c_str(),
354
DEFAULTS_GROUP_SUFFIX.size()) == 0))
327
if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
357
*group_suffix= *argv + DEFAULTS_GROUP_SUFFIX.size();
329
*group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
413
387
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
415
389
/* remove the --no-defaults argument and return only the other arguments */
417
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*))))
419
394
res= (char**) (ptr+sizeof(alloc));
420
memset(res,0,(*argc + 1));
421
395
res[0]= **argv; /* Copy program name */
422
for (i=2 ; i < (uint32_t) *argc ; i++)
396
for (i=2 ; i < (uint) *argc ; i++)
423
397
res[i-1]=argv[0][i];
424
398
res[i-1]=0; /* End pointer */
427
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
401
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
448
422
Here error contains <> 0 only if we have a fully specified conf_file
449
423
or a forced default file
451
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*))))
453
428
res= (char**) (ptr+sizeof(alloc));
455
430
/* copy name + found arguments + command line arguments to new array */
456
431
res[0]= argv[0][0]; /* Name MUST be set, even by embedded library */
457
memcpy(res+1, args.buffer, args.elements*sizeof(char*));
432
memcpy((uchar*) (res+1), args.buffer, args.elements*sizeof(char*));
458
433
/* Skip --defaults-xxx options */
459
434
(*argc)-= args_used;
460
435
(*argv)+= args_used;
463
438
Check if we wan't to see the new argument list
464
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 */
467
memcpy(res+1+args.elements, *argv + 1, (*argc-1)*sizeof(char*));
448
memcpy((uchar*) (res+1+args.elements), (char*) ((*argv)+1),
449
(*argc-1)*sizeof(char*));
468
450
res[args.elements+ *argc]=0; /* last null */
470
(*argc)+=int(args.elements);
471
*argv= static_cast<char**>(res);
472
*(memory::Root*) ptr= alloc; /* Save alloc root for free */
452
(*argc)+=args.elements;
454
*(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
473
455
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]);
478
469
fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
471
return 0; /* Keep compiler happy */
483
475
void free_defaults(char **argv)
486
memcpy(&ptr, (char*) argv - sizeof(ptr), sizeof(ptr));
487
ptr.free_root(MYF(0));
478
memcpy((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr));
479
free_root(&ptr,MYF(0));
528
520
static char *get_argument(const char *keyword, size_t kwlen,
529
char *ptr, char *name, uint32_t line)
521
char *ptr, char *name, uint line)
533
525
/* Skip over "include / includedir keyword" and following whitespace */
535
527
for (ptr+= kwlen - 1;
536
my_isspace(&my_charset_utf8_general_ci, ptr[0]);
528
my_isspace(&my_charset_latin1, ptr[0]);
595
587
static const char include_keyword[]= "include";
596
588
const int max_recursion_level= 10;
599
591
bool found_group=0;
594
FILEINFO *search_file;
601
596
if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
602
597
return 0; /* Ignore wrong paths */
605
end=convert_dirname(name, dir, NULL);
600
end=convert_dirname(name, dir, NullS);
606
601
if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
608
sprintf(end,"%s%s",config_file,ext);
603
strxmov(end,config_file,ext,NullS);
612
strcpy(name,config_file);
607
strmov(name,config_file);
614
609
fn_format(name,name,"","",4);
632
if (!(fp= fopen(name, "r")))
627
if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
633
628
return 1; /* Ignore wrong files */
635
memset(buff,0,sizeof(buff));
636
630
while (fgets(buff, sizeof(buff) - 1, fp))
639
633
/* Ignore comment and empty lines */
640
for (ptr= buff; my_isspace(&my_charset_utf8_general_ci, *ptr); ptr++)
634
for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
643
637
if (*ptr == '#' || *ptr == ';' || !*ptr)
663
657
/* skip over `!' and following whitespace */
664
for (++ptr; my_isspace(&my_charset_utf8_general_ci, ptr[0]); ptr++)
658
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
667
661
if ((!strncmp(ptr, includedir_keyword,
668
662
sizeof(includedir_keyword) - 1)) &&
669
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(includedir_keyword) - 1]))
663
my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
671
665
if (!(ptr= get_argument(includedir_keyword,
672
666
sizeof(includedir_keyword),
673
667
ptr, name, line)))
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);
670
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
691
CachedDirectory::Entries files= dir_cache.getEntries();
692
CachedDirectory::Entries::iterator file_iter= files.begin();
694
while (file_iter != files.end())
673
for (i= 0; i < (uint) search_dir->number_off_files; i++)
696
CachedDirectory::Entry *entry= *file_iter;
697
ext= fn_ext(entry->filename.c_str());
675
search_file= search_dir->dir_entry + i;
676
ext= fn_ext(search_file->name);
699
678
/* check extension */
700
679
for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
702
681
if (!strcmp(ext, *tmp_ext))
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);
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);
695
my_dirend(search_dir);
715
697
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
716
my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(include_keyword)-1]))
698
my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
718
700
if (!(ptr= get_argument(include_keyword,
719
701
sizeof(include_keyword), ptr,
740
722
/* Remove end space */
741
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
723
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
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';
726
strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
747
728
/* signal that a new group is found */
748
729
opt_handler(handler_ctx, curr_gr, NULL);
761
742
end= remove_end_comment(ptr);
762
743
if ((value= strchr(ptr, '=')))
763
744
end= value; /* Option without argument */
764
for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) || end[-1]== '\n'; end--) ;
745
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
767
strncpy(strcpy(option,"--")+2,ptr,strlen(ptr)+1);
748
strmake(strmov(option,"--"),ptr, (size_t) (end-ptr));
768
749
if (opt_handler(handler_ctx, curr_gr, option))
773
754
/* Remove pre- and end space */
775
for (value++ ; my_isspace(&my_charset_utf8_general_ci,*value); value++) ;
776
value_end= strchr(value, '\0');
756
for (value++ ; my_isspace(&my_charset_latin1,*value); value++) ;
757
value_end=strend(value);
778
We don't have to test for value_end >= value as we know there is
759
We don't have to test for value_end >= value as we know there is
781
for ( ; my_isspace(&my_charset_utf8_general_ci,value_end[-1]) ; value_end--) ;
762
for ( ; my_isspace(&my_charset_latin1,value_end[-1]) ; value_end--) ;
782
763
if (value_end < value) /* Empty string */
785
766
/* remove quotes around argument */
786
767
if ((*value == '\"' || *value == '\'') && /* First char is quote */
787
768
(value + 1 < value_end ) && /* String is longer than 1 */
788
769
*value == value_end[-1] ) /* First char is equal to last char */
794
memset(option,0,2+(size_t)(end-ptr)+1);
795
ptr= strncpy(strcpy(option,"--")+2,ptr,(size_t) (end-ptr));
774
ptr=strnmov(strmov(option,"--"),ptr,(size_t) (end-ptr));
800
777
for ( ; value != value_end; value++)
902
878
pos= my_defaults_extra_file;
905
end= convert_dirname(name, pos, NULL);
881
end= convert_dirname(name, pos, NullS);
906
882
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
908
sprintf(end,"%s%s ",conf_file, *ext);
884
strxmov(end, conf_file, *ext, " ", NullS);
909
885
fputs(name,stdout);
938
914
puts("\nThe following options may be given as the first argument:\n\
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");
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");
967
944
3. --sysconfdir=<path> (compile-time option)
968
4. getenv("DRIZZLE_HOME")
945
4. getenv(DEFAULT_HOME_ENV)
969
946
5. --defaults-extra-file=<path> (run-time option)
973
950
static void init_default_directories(void)
975
memset(default_directories, 0, sizeof(default_directories));
952
memset((char *) default_directories, 0, sizeof(default_directories));
976
953
ADD_DIRECTORY("/etc/");
977
ADD_DIRECTORY("/etc/drizzle/");
978
ADD_DIRECTORY(SYSCONFDIR);
954
ADD_DIRECTORY("/etc/mysql/");
955
#if defined(DEFAULT_SYSCONFDIR)
956
ADD_DIRECTORY(DEFAULT_SYSCONFDIR);
979
958
ADD_COMMON_DIRECTORIES();
980
959
ADD_DIRECTORY("~/");
983
} /* namespace internal */
984
} /* namespace drizzled */