00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include <drizzled/internal/my_sys.h>
00039 #include <drizzled/internal/m_string.h>
00040 #include <drizzled/charset_info.h>
00041 #include <drizzled/typelib.h>
00042 #include <drizzled/configmake.h>
00043 #include <drizzled/gettext.h>
00044 #include <drizzled/dynamic_array.h>
00045 #include <drizzled/cached_directory.h>
00046
00047 #ifdef HAVE_SYS_STAT_H
00048 # include <sys/stat.h>
00049 #endif
00050
00051 #include <cstdio>
00052 #include <algorithm>
00053
00054 using namespace std;
00055
00056 namespace drizzled
00057 {
00058 namespace internal
00059 {
00060
00061 const char *my_defaults_file=0;
00062 const char *my_defaults_group_suffix=0;
00063 char *my_defaults_extra_file=0;
00064
00065
00066
00067 #define MAX_DEFAULT_DIRS 6
00068 const char *default_directories[MAX_DEFAULT_DIRS + 1];
00069
00070 static const char *f_extensions[]= { ".cnf", 0 };
00071
00072 int handle_default_option(void *in_ctx, const char *group_name,
00073 const char *option);
00074
00075
00076
00077
00078
00079
00080
00081
00082 struct handle_option_ctx
00083 {
00084 memory::Root *alloc;
00085 DYNAMIC_ARRAY *args;
00086 TYPELIB *group;
00087 };
00088
00089 static int search_default_file(Process_option_func func, void *func_ctx,
00090 const char *dir, const char *config_file);
00091 static int search_default_file_with_ext(Process_option_func func,
00092 void *func_ctx,
00093 const char *dir, const char *ext,
00094 const char *config_file, int recursion_level);
00095
00096
00097
00109 static void init_default_directories(void);
00110
00111
00112 static char *remove_end_comment(char *ptr);
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 int my_search_option_files(const char *conf_file, int *argc, char ***argv,
00148 uint32_t *args_used, Process_option_func func,
00149 void *func_ctx)
00150 {
00151 const char **dirs, *forced_default_file, *forced_extra_defaults;
00152 int error= 0;
00153
00154
00155 *args_used+= get_defaults_options(*argc - *args_used, *argv + *args_used,
00156 (char **) &forced_default_file,
00157 (char **) &forced_extra_defaults,
00158 (char **) &my_defaults_group_suffix);
00159
00160 if (! my_defaults_group_suffix)
00161 my_defaults_group_suffix= getenv("DRIZZLE_GROUP_SUFFIX");
00162
00163 if (forced_extra_defaults)
00164 my_defaults_extra_file= (char *) forced_extra_defaults;
00165
00166 if (forced_default_file)
00167 my_defaults_file= forced_default_file;
00168
00169
00170
00171
00172
00173
00174 if (my_defaults_group_suffix && (func == handle_default_option))
00175 {
00176
00177 uint32_t i;
00178 const char **extra_groups;
00179 const size_t instance_len= strlen(my_defaults_group_suffix);
00180 struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
00181 char *ptr;
00182 TYPELIB *group= ctx->group;
00183
00184 if (!(extra_groups=
00185 (const char**)ctx->alloc->alloc_root(
00186 (2*group->count+1)*sizeof(char*))))
00187 goto err;
00188
00189 for (i= 0; i < group->count; i++)
00190 {
00191 size_t len;
00192 extra_groups[i]= group->type_names[i];
00194 len= strlen(extra_groups[i]);
00195 if (!(ptr= (char *)ctx->alloc->alloc_root( len+instance_len+1)))
00196 goto err;
00197
00198 extra_groups[i+group->count]= ptr;
00199
00201 memcpy(ptr, extra_groups[i], len);
00202 memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
00203 }
00204
00205 group->count*= 2;
00206 group->type_names= extra_groups;
00207 group->type_names[group->count]= 0;
00208 }
00209
00210 if (forced_default_file)
00211 {
00212 if ((error= search_default_file_with_ext(func, func_ctx, "", "",
00213 forced_default_file, 0)) < 0)
00214 goto err;
00215 if (error > 0)
00216 {
00217 fprintf(stderr, "Could not open required defaults file: %s\n",
00218 forced_default_file);
00219 goto err;
00220 }
00221 }
00222 else if (dirname_length(conf_file))
00223 {
00224 if ((error= search_default_file(func, func_ctx, NULL, conf_file)) < 0)
00225 goto err;
00226 }
00227 else
00228 {
00229 for (dirs= default_directories ; *dirs; dirs++)
00230 {
00231 if (**dirs)
00232 {
00233 if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
00234 goto err;
00235 }
00236 else if (my_defaults_extra_file)
00237 {
00238 if ((error= search_default_file_with_ext(func, func_ctx, "", "",
00239 my_defaults_extra_file, 0)) < 0)
00240 goto err;
00241 if (error > 0)
00242 {
00243 fprintf(stderr, "Could not open required defaults file: %s\n",
00244 my_defaults_extra_file);
00245 goto err;
00246 }
00247 }
00248 }
00249 }
00250
00251 return(error);
00252
00253 err:
00254 fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
00255 exit(1);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 int handle_default_option(void *in_ctx, const char *group_name,
00283 const char *option)
00284 {
00285 char *tmp;
00286 struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
00287
00288 if (!option)
00289 return 0;
00290
00291 if (ctx->group->find_type(const_cast<char*>(group_name), 3))
00292 {
00293 if (!(tmp= (char *)ctx->alloc->alloc_root(strlen(option) + 1)))
00294 return 1;
00295 ctx->args->push_back(&tmp);
00296 strcpy(tmp, option);
00297 }
00298
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 int get_defaults_options(int argc, char **argv,
00320 char **defaults,
00321 char **extra_defaults,
00322 char **group_suffix)
00323 {
00324 int org_argc= argc, prev_argc= 0;
00325 *defaults= *extra_defaults= *group_suffix= 0;
00326
00327 const std::string DEFAULTS_FILE("--defaults-file=");
00328 const std::string DEFAULTS_EXTRA_FILE("--defaults-extra-file=");
00329 const std::string DEFAULTS_GROUP_SUFFIX("--defaults-group-suffix=");
00330
00331 while (argc >= 2 && argc != prev_argc)
00332 {
00333
00334 argv++;
00335 prev_argc= argc;
00336 if (!*defaults && (strncmp(*argv,
00337 DEFAULTS_FILE.c_str(),
00338 DEFAULTS_FILE.size()) == 0))
00339 {
00340 *defaults= *argv + DEFAULTS_FILE.size();
00341 argc--;
00342 continue;
00343 }
00344 if (!*extra_defaults && (strncmp(*argv,
00345 DEFAULTS_EXTRA_FILE.c_str(),
00346 DEFAULTS_EXTRA_FILE.size()) == 0))
00347 {
00348 *extra_defaults= *argv + DEFAULTS_EXTRA_FILE.size();
00349 argc--;
00350 continue;
00351 }
00352 if (!*group_suffix && (strncmp(*argv,
00353 DEFAULTS_GROUP_SUFFIX.c_str(),
00354 DEFAULTS_GROUP_SUFFIX.size()) == 0))
00355
00356 {
00357 *group_suffix= *argv + DEFAULTS_GROUP_SUFFIX.size();
00358 argc--;
00359 continue;
00360 }
00361 }
00362 return org_argc - argc;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 int load_defaults(const char *conf_file, const char **groups,
00398 int *argc, char ***argv)
00399 {
00400 DYNAMIC_ARRAY args;
00401 TYPELIB group;
00402 uint32_t args_used= 0;
00403 int error= 0;
00404 memory::Root alloc(512);
00405 char *ptr,**res;
00406 struct handle_option_ctx ctx;
00407
00408 init_default_directories();
00409
00410
00411
00412
00413 if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
00414 {
00415
00416 uint32_t i;
00417 if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (*argc + 1)*sizeof(char*))))
00418 goto err;
00419 res= (char**) (ptr+sizeof(alloc));
00420 memset(res,0,(*argc + 1));
00421 res[0]= **argv;
00422 for (i=2 ; i < (uint32_t) *argc ; i++)
00423 res[i-1]=argv[0][i];
00424 res[i-1]=0;
00425 (*argc)--;
00426 *argv=res;
00427 *(memory::Root*) ptr= alloc;
00428 return(0);
00429 }
00430
00431 group.count=0;
00432 group.name= "defaults";
00433 group.type_names= groups;
00434
00435 for (; *groups ; groups++)
00436 group.count++;
00437
00438 if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
00439 goto err;
00440
00441 ctx.alloc= &alloc;
00442 ctx.args= &args;
00443 ctx.group= &group;
00444
00445 error= my_search_option_files(conf_file, argc, argv, &args_used,
00446 handle_default_option, (void *) &ctx);
00447
00448
00449
00450
00451 if (!(ptr=(char*) alloc.alloc_root(sizeof(alloc)+ (args.size() + *argc +1) *sizeof(char*))))
00452 goto err;
00453 res= (char**) (ptr+sizeof(alloc));
00454
00455
00456 res[0]= argv[0][0];
00457 memcpy(res+1, args.buffer, args.size()*sizeof(char*));
00458
00459 (*argc)-= args_used;
00460 (*argv)+= args_used;
00461
00462
00463
00464
00465
00466 if (*argc)
00467 memcpy(res+1+args.size(), *argv + 1, (*argc-1)*sizeof(char*));
00468 res[args.size()+ *argc]=0;
00469
00470 (*argc)+=int(args.size());
00471 *argv= static_cast<char**>(res);
00472 *(memory::Root*) ptr= alloc;
00473 delete_dynamic(&args);
00474
00475 return(error);
00476
00477 err:
00478 fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
00479 exit(1);
00480 }
00481
00482
00483 void free_defaults(char **argv)
00484 {
00485 memory::Root ptr;
00486 memcpy(&ptr, (char*) argv - sizeof(ptr), sizeof(ptr));
00487 ptr.free_root(MYF(0));
00488 }
00489
00490
00491 static int search_default_file(Process_option_func opt_handler,
00492 void *handler_ctx,
00493 const char *dir,
00494 const char *config_file)
00495 {
00496 char **ext;
00497 const char *empty_list[]= { "", 0 };
00498 bool have_ext= fn_ext(config_file)[0] != 0;
00499 const char **exts_to_use= have_ext ? empty_list : f_extensions;
00500
00501 for (ext= (char**) exts_to_use; *ext; ext++)
00502 {
00503 int error;
00504 if ((error= search_default_file_with_ext(opt_handler, handler_ctx,
00505 dir, *ext,
00506 config_file, 0)) < 0)
00507 return error;
00508 }
00509 return 0;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 static char *get_argument(const char *keyword, size_t kwlen,
00529 char *ptr, char *name, uint32_t line)
00530 {
00531 char *end;
00532
00533
00534
00535 for (ptr+= kwlen - 1;
00536 my_isspace(&my_charset_utf8_general_ci, ptr[0]);
00537 ptr++)
00538 {}
00539
00540
00541
00542
00543
00544
00545 for (end= ptr + strlen(ptr) - 1;
00546 my_isspace(&my_charset_utf8_general_ci, *(end - 1));
00547 end--)
00548 {}
00549 end[0]= 0;
00550
00551
00552 if (end <= ptr)
00553 {
00554 fprintf(stderr,
00555 "error: Wrong '!%s' directive in config file: %s at line %d\n",
00556 keyword, name, line);
00557 return 0;
00558 }
00559 return ptr;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 static int search_default_file_with_ext(Process_option_func opt_handler,
00586 void *handler_ctx,
00587 const char *dir,
00588 const char *ext,
00589 const char *config_file,
00590 int recursion_level)
00591 {
00592 char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext;
00593 char *value, option[4096], tmp[FN_REFLEN];
00594 static const char includedir_keyword[]= "includedir";
00595 static const char include_keyword[]= "include";
00596 const int max_recursion_level= 10;
00597 FILE *fp;
00598 uint32_t line=0;
00599 bool found_group=0;
00600
00601 if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
00602 return 0;
00603 if (dir)
00604 {
00605 end=convert_dirname(name, dir, NULL);
00606 if (dir[0] == FN_HOMELIB)
00607 *end++='.';
00608 sprintf(end,"%s%s",config_file,ext);
00609 }
00610 else
00611 {
00612 strcpy(name,config_file);
00613 }
00614 fn_format(name,name,"","",4);
00615 {
00616 struct stat stat_info;
00617 if (stat(name,&stat_info))
00618 return 1;
00619
00620
00621
00622
00623
00624 if ((stat_info.st_mode & S_IWOTH) &&
00625 (stat_info.st_mode & S_IFMT) == S_IFREG)
00626 {
00627 fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
00628 name);
00629 return 0;
00630 }
00631 }
00632 if (!(fp= fopen(name, "r")))
00633 return 1;
00634
00635 memset(buff,0,sizeof(buff));
00636 while (fgets(buff, sizeof(buff) - 1, fp))
00637 {
00638 line++;
00639
00640 for (ptr= buff; my_isspace(&my_charset_utf8_general_ci, *ptr); ptr++)
00641 {}
00642
00643 if (*ptr == '#' || *ptr == ';' || !*ptr)
00644 continue;
00645
00646
00647 if ((*ptr == '!'))
00648 {
00649 if (recursion_level >= max_recursion_level)
00650 {
00651 for (end= ptr + strlen(ptr) - 1;
00652 my_isspace(&my_charset_utf8_general_ci, *(end - 1));
00653 end--)
00654 {}
00655 end[0]= 0;
00656 fprintf(stderr,
00657 "Warning: skipping '%s' directive as maximum include"
00658 "recursion level was reached in file %s at line %d\n",
00659 ptr, name, line);
00660 continue;
00661 }
00662
00663
00664 for (++ptr; my_isspace(&my_charset_utf8_general_ci, ptr[0]); ptr++)
00665 {}
00666
00667 if ((!strncmp(ptr, includedir_keyword,
00668 sizeof(includedir_keyword) - 1)) &&
00669 my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(includedir_keyword) - 1]))
00670 {
00671 if (!(ptr= get_argument(includedir_keyword,
00672 sizeof(includedir_keyword),
00673 ptr, name, line)))
00674 goto err;
00675
00676 CachedDirectory dir_cache(ptr);
00677
00678 if (dir_cache.fail())
00679 {
00687 fprintf(stderr, _("error: could not open directory: %s\n"), ptr);
00688 goto err;
00689 }
00690
00691 CachedDirectory::Entries files= dir_cache.getEntries();
00692 CachedDirectory::Entries::iterator file_iter= files.begin();
00693
00694 while (file_iter != files.end())
00695 {
00696 CachedDirectory::Entry *entry= *file_iter;
00697 ext= fn_ext(entry->filename.c_str());
00698
00699
00700 for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
00701 {
00702 if (!strcmp(ext, *tmp_ext))
00703 {
00704 fn_format(tmp, entry->filename.c_str(), ptr, "",
00705 MY_UNPACK_FILENAME | MY_SAFE_PATH);
00706
00707 search_default_file_with_ext(opt_handler, handler_ctx, "", "",
00708 tmp, recursion_level + 1);
00709 }
00710 }
00711
00712 ++file_iter;
00713 }
00714 }
00715 else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
00716 my_isspace(&my_charset_utf8_general_ci, ptr[sizeof(include_keyword)-1]))
00717 {
00718 if (!(ptr= get_argument(include_keyword,
00719 sizeof(include_keyword), ptr,
00720 name, line)))
00721 goto err;
00722
00723 search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
00724 recursion_level + 1);
00725 }
00726
00727 continue;
00728 }
00729
00730 if (*ptr == '[')
00731 {
00732 found_group=1;
00733 if (!(end=(char *) strchr(++ptr,']')))
00734 {
00735 fprintf(stderr,
00736 "error: Wrong group definition in config file: %s at line %d\n",
00737 name,line);
00738 goto err;
00739 }
00740
00741 for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) ; end--) ;
00742 end[0]=0;
00743
00744 strncpy(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
00745 curr_gr[min((size_t)(end-ptr)+1, sizeof(curr_gr)-1)] = '\0';
00746
00747
00748 opt_handler(handler_ctx, curr_gr, NULL);
00749
00750 continue;
00751 }
00752 if (!found_group)
00753 {
00754 fprintf(stderr,
00755 "error: Found option without preceding group in config file: %s at line: %d\n",
00756 name,line);
00757 goto err;
00758 }
00759
00760
00761 end= remove_end_comment(ptr);
00762 if ((value= strchr(ptr, '=')))
00763 end= value;
00764 for ( ; my_isspace(&my_charset_utf8_general_ci,end[-1]) || end[-1]== '\n'; end--) ;
00765 if (!value)
00766 {
00767 strncpy(strcpy(option,"--")+2,ptr,strlen(ptr)+1);
00768 if (opt_handler(handler_ctx, curr_gr, option))
00769 goto err;
00770 }
00771 else
00772 {
00773
00774 char *value_end;
00775 for (value++ ; my_isspace(&my_charset_utf8_general_ci,*value); value++) ;
00776 value_end= strchr(value, '\0');
00777
00778
00779
00780
00781 for ( ; my_isspace(&my_charset_utf8_general_ci,value_end[-1]) ; value_end--) ;
00782 if (value_end < value)
00783 value_end=value;
00784
00785
00786 if ((*value == '\"' || *value == '\'') &&
00787 (value + 1 < value_end ) &&
00788 *value == value_end[-1] )
00789 {
00790 value++;
00791 value_end--;
00792 }
00793
00794 memset(option,0,2+(size_t)(end-ptr)+1);
00795 ptr= strncpy(strcpy(option,"--")+2,ptr,(size_t) (end-ptr));
00796 ptr[end-ptr]= '\0';
00797 ptr+= strlen(ptr);
00798 *ptr++= '=';
00799
00800 for ( ; value != value_end; value++)
00801 {
00802 if (*value == '\\' && value != value_end-1)
00803 {
00804 switch(*++value) {
00805 case 'n':
00806 *ptr++='\n';
00807 break;
00808 case 't':
00809 *ptr++= '\t';
00810 break;
00811 case 'r':
00812 *ptr++ = '\r';
00813 break;
00814 case 'b':
00815 *ptr++ = '\b';
00816 break;
00817 case 's':
00818 *ptr++= ' ';
00819 break;
00820 case '\"':
00821 *ptr++= '\"';
00822 break;
00823 case '\'':
00824 *ptr++= '\'';
00825 break;
00826 case '\\':
00827 *ptr++= '\\';
00828 break;
00829 default:
00830 *ptr++= '\\';
00831 *ptr++= *value;
00832 break;
00833 }
00834 }
00835 else
00836 *ptr++= *value;
00837 }
00838 *ptr=0;
00839 if (opt_handler(handler_ctx, curr_gr, option))
00840 goto err;
00841 }
00842 }
00843 fclose(fp);
00844 return(0);
00845
00846 err:
00847 fclose(fp);
00848
00849 return -1;
00850 }
00851
00852
00853 static char *remove_end_comment(char *ptr)
00854 {
00855 char quote= 0;
00856 char escape= 0;
00857
00858 for (; *ptr; ptr++)
00859 {
00860 if ((*ptr == '\'' || *ptr == '\"') && !escape)
00861 {
00862 if (!quote)
00863 quote= *ptr;
00864 else if (quote == *ptr)
00865 quote= 0;
00866 }
00867
00868 if (!quote && *ptr == '#')
00869 {
00870 *ptr= 0;
00871 return ptr;
00872 }
00873 escape= (quote && *ptr == '\\' && !escape);
00874 }
00875 return ptr;
00876 }
00877
00878 void my_print_default_files(const char *conf_file)
00879 {
00880 const char *empty_list[]= { "", 0 };
00881 bool have_ext= fn_ext(conf_file)[0] != 0;
00882 const char **exts_to_use= have_ext ? empty_list : f_extensions;
00883 char name[FN_REFLEN], **ext;
00884 const char **dirs;
00885
00886 init_default_directories();
00887 puts("\nDefault options are read from the following files in the given order:");
00888
00889 if (dirname_length(conf_file))
00890 fputs(conf_file,stdout);
00891 else
00892 {
00893 for (dirs=default_directories ; *dirs; dirs++)
00894 {
00895 for (ext= (char**) exts_to_use; *ext; ext++)
00896 {
00897 const char *pos;
00898 char *end;
00899 if (**dirs)
00900 pos= *dirs;
00901 else if (my_defaults_extra_file)
00902 pos= my_defaults_extra_file;
00903 else
00904 continue;
00905 end= convert_dirname(name, pos, NULL);
00906 if (name[0] == FN_HOMELIB)
00907 *end++='.';
00908 sprintf(end,"%s%s ",conf_file, *ext);
00909 fputs(name,stdout);
00910 }
00911 }
00912 }
00913 puts("");
00914 }
00915
00916 void print_defaults(const char *conf_file, const char **groups)
00917 {
00918 const char **groups_save= groups;
00919 my_print_default_files(conf_file);
00920
00921 fputs("The following groups are read:",stdout);
00922 for ( ; *groups ; groups++)
00923 {
00924 fputc(' ',stdout);
00925 fputs(*groups,stdout);
00926 }
00927
00928 if (my_defaults_group_suffix)
00929 {
00930 groups= groups_save;
00931 for ( ; *groups ; groups++)
00932 {
00933 fputc(' ',stdout);
00934 fputs(*groups,stdout);
00935 fputs(my_defaults_group_suffix,stdout);
00936 }
00937 }
00938 puts("\nThe following options may be given as the first argument:\n\
00939 --no-defaults Don't read default options from any options file\n\
00940 --defaults-file=# Only read default options from the given file #\n\
00941 --defaults-extra-file=# Read this file after the global files are read");
00942 }
00943
00944
00945
00946
00947
00948 static void add_directory(const char* dir)
00949 {
00950 array_append_string_unique(dir, default_directories, array_elements(default_directories));
00951 }
00952
00953 static void add_common_directories()
00954 {
00955 const char *env= getenv("DRIZZLE_HOME");
00956 if (env)
00957 add_directory(env);
00958
00959 add_directory("");
00960 }
00961
00974 static void init_default_directories(void)
00975 {
00976 memset(default_directories, 0, sizeof(default_directories));
00977 add_directory("/etc/");
00978 add_directory("/etc/drizzle/");
00979 add_directory(SYSCONFDIR);
00980 add_common_directories();
00981 add_directory("~/");
00982 }
00983
00984 }
00985 }