default.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:11k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This library is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU Library General Public
  5.    License as published by the Free Software Foundation; either
  6.    version 2 of the License, or (at your option) any later version.
  7.    
  8.    This library is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.    Library General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU Library General Public
  14.    License along with this library; if not, write to the Free
  15.    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  16.    MA 02111-1307, USA */
  17. /****************************************************************************
  18. ** Add all options from files named "group".cnf from the default_directories
  19. ** before the command line arguments.
  20. ** On Windows defaults will also search in the Windows directory for a file
  21. ** called 'group'.ini
  22. ** As long as the program uses the last argument for conflicting
  23. ** options one only have to add a call to "load_defaults" to enable
  24. ** use of default values.
  25. ** pre- and end 'blank space' are removed from options and values. The
  26. ** following escape sequences are recognized in values:  b t n r \
  27. **
  28. ** The following arguments are handled automaticly;  If used, they must be
  29. ** first argument on the command line!
  30. ** --no-defaults ; no options are read.
  31. ** --defaults-file=full-path-to-default-file ; Only this file will be read.
  32. ** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
  33. ** --print-defaults ; Print the modified command line and exit
  34. ****************************************************************************/
  35. #undef SAFEMALLOC /* safe_malloc is not yet initailized */
  36. #include "mysys_priv.h"
  37. #include "m_string.h"
  38. #include "m_ctype.h"
  39. char *defaults_extra_file=0;
  40. /* Which directories are searched for options (and in which order) */
  41. const char *default_directories[]= {
  42. #ifdef __WIN__
  43. "C:/",
  44. #else
  45. "/etc/",
  46. #endif
  47. #ifdef DATADIR
  48. DATADIR,
  49. #endif
  50. "", /* Place for defaults_extra_dir */
  51. #ifndef __WIN__
  52. "~/",
  53. #endif
  54. NullS,
  55. };
  56. #define default_ext    ".cnf" /* extension for config file */
  57. #ifdef __WIN__
  58. #include <winbase.h>
  59. #define windows_ext ".ini"
  60. #endif
  61. static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
  62.    const char *dir, const char *config_file,
  63.    const char *ext, TYPELIB *group);
  64. void load_defaults(const char *conf_file, const char **groups,
  65.    int *argc, char ***argv)
  66. {
  67.   DYNAMIC_ARRAY args;
  68.   const char **dirs, *forced_default_file;
  69.   TYPELIB group;
  70.   my_bool found_print_defaults=0;
  71.   uint args_used=0;
  72.   MEM_ROOT alloc;
  73.   char *ptr,**res;
  74.   DBUG_ENTER("load_defaults");
  75.   init_alloc_root(&alloc,128,0);
  76.   if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
  77.   {
  78.     /* remove the --no-defaults argument and return only the other arguments */
  79.     uint i;
  80.     if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
  81.  (*argc + 1)*sizeof(char*))))
  82.       goto err;
  83.     res= (char**) (ptr+sizeof(alloc));
  84.     res[0]= **argv; /* Copy program name */
  85.     for (i=2 ; i < (uint) *argc ; i++)
  86.       res[i-1]=argv[0][i];
  87.     (*argc)--;
  88.     *argv=res;
  89.     *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
  90.     DBUG_VOID_RETURN;
  91.   }
  92.   /* Check if we want to force the use a specific default file */
  93.   forced_default_file=0;
  94.   if (*argc >= 2)
  95.   {
  96.     if (is_prefix(argv[0][1],"--defaults-file="))
  97.     {
  98.       forced_default_file=strchr(argv[0][1],'=')+1;
  99.       args_used++;
  100.     }
  101.     else if (is_prefix(argv[0][1],"--defaults-extra-file="))
  102.     {
  103.       defaults_extra_file=strchr(argv[0][1],'=')+1;
  104.       args_used++;
  105.     }
  106.   }
  107.   group.count=0;
  108.   group.name= "defaults";
  109.   group.type_names= groups;
  110.   for (; *groups ; groups++)
  111.     group.count++;
  112.   if (init_dynamic_array(&args, sizeof(char*),*argc, 32))
  113.     goto err;
  114.   if (forced_default_file)
  115.   {
  116.     if (search_default_file(&args, &alloc, "", forced_default_file, "",
  117.     &group))
  118.       goto err;
  119.   }
  120.   else if (dirname_length(conf_file))
  121.   {
  122.     if (search_default_file(&args, &alloc, NullS, conf_file, default_ext,
  123.     &group))
  124.       goto err;
  125.   }
  126.   else
  127.   {
  128. #ifdef __WIN__
  129.     char system_dir[FN_REFLEN];
  130.     GetWindowsDirectory(system_dir,sizeof(system_dir));
  131.     if (search_default_file(&args, &alloc, system_dir, conf_file, windows_ext,
  132.     &group))
  133.       goto err;
  134. #endif
  135. #ifdef __EMX__
  136.     if (getenv("ETC") &&
  137.         search_default_file(&args, &alloc, getenv("ETC"), conf_file, 
  138.                             default_ext, &group))
  139.       goto err;
  140. #endif
  141.     for (dirs=default_directories ; *dirs; dirs++)
  142.     {
  143.       int error=0;
  144.       if (**dirs)
  145. error=search_default_file(&args, &alloc, *dirs, conf_file,
  146.   default_ext, &group);
  147.       else if (defaults_extra_file)
  148. error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
  149.   default_ext, &group);
  150.       if (error)
  151. goto err;
  152.     }
  153.   }
  154.   if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
  155.        (args.elements + *argc +1) *sizeof(char*))))
  156.     goto err;
  157.   res= (char**) (ptr+sizeof(alloc));
  158.   /* copy name + found arguments + command line arguments to new array */
  159.   res[0]=argv[0][0];
  160.   memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*));
  161.   /* Skipp --defaults-file and --defaults-extra-file */
  162.   (*argc)-= args_used;
  163.   (*argv)+= args_used;
  164.   /* Check if we wan't to see the new argument list */
  165.   if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
  166.   {
  167.     found_print_defaults=1;
  168.     --*argc; ++*argv; /* skipp argument */
  169.   }
  170.   memcpy((gptr) (res+1+args.elements), (char*) ((*argv)+1),
  171.  (*argc-1)*sizeof(char*));
  172.   res[args.elements+ *argc]=0; /* last null */
  173.   (*argc)+=args.elements;
  174.   *argv= (char**) res;
  175.   *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
  176.   delete_dynamic(&args);
  177.   if (found_print_defaults)
  178.   {
  179.     int i;
  180.     printf("%s would have been started with the following arguments:n",
  181.    **argv);
  182.     for (i=1 ; i < *argc ; i++)
  183.       printf("%s ", (*argv)[i]);
  184.     puts("");
  185.     exit(1);
  186.   }
  187.   DBUG_VOID_RETURN;
  188.  err:
  189.   fprintf(stderr,"Program abortedn");
  190.   exit(1);
  191. }
  192. void free_defaults(char **argv)
  193. {
  194.   MEM_ROOT ptr;
  195.   memcpy_fixed((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr));
  196.   free_root(&ptr,MYF(0));
  197. }
  198. static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
  199.    const char *dir, const char *config_file,
  200.    const char *ext, TYPELIB *group)
  201. {
  202.   char name[FN_REFLEN+10],buff[257],*ptr,*end,*value,*tmp;
  203.   FILE *fp;
  204.   uint line=0;
  205.   my_bool read_values=0,found_group=0;
  206.   if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
  207.     return 0; /* Ignore wrong paths */
  208.   if (dir)
  209.   {
  210.     strmov(name,dir);
  211.     convert_dirname(name);
  212.     if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
  213.       strcat(name,".");
  214.     strxmov(strend(name),config_file,ext,NullS);
  215.   }
  216.   else
  217.   {
  218.     strmov(name,config_file);
  219.   }
  220.   if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0))))
  221.     return 0; /* Ignore wrong files */
  222.   while (fgets(buff,sizeof(buff)-1,fp))
  223.   {
  224.     line++;
  225.     /* Ignore comment and empty lines */
  226.     for (ptr=buff ; isspace(*ptr) ; ptr++ ) ;
  227.     if (*ptr == '#' || *ptr == ';' || !*ptr)
  228.       continue;
  229.     if (*ptr == '[') /* Group name */
  230.     {
  231.       found_group=1;
  232.       if (!(end=(char *) strchr(++ptr,']')))
  233.       {
  234. fprintf(stderr,
  235. "error: Wrong group definition in config file: %s at line %dn",
  236. name,line);
  237. goto err;
  238.       }
  239.       for ( ; isspace(end[-1]) ; end--) ; /* Remove end space */
  240.       end[0]=0;
  241.       read_values=find_type(ptr,group,3) > 0;
  242.       continue;
  243.     }
  244.     if (!found_group)
  245.     {
  246.       fprintf(stderr,
  247.       "error: Found option without preceding group in config file: %s at line: %dn",
  248.       name,line);
  249.       goto err;
  250.     }
  251.     if (!read_values)
  252.       continue;
  253.     if (!(end=value=strchr(ptr,'=')))
  254.       end=strend(ptr); /* Option without argument */
  255.     for ( ; isspace(end[-1]) ; end--) ;
  256.     if (!value)
  257.     {
  258.       if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3)))
  259. goto err;
  260.       strmake(strmov(tmp,"--"),ptr,(uint) (end-ptr));
  261.       if (insert_dynamic(args,(gptr) &tmp))
  262. goto err;
  263.     }
  264.     else
  265.     {
  266.       /* Remove pre- and end space */
  267.       char *value_end;
  268.       for (value++ ; isspace(*value); value++) ;
  269.       value_end=strend(value);
  270.       for ( ; isspace(value_end[-1]) ; value_end--) ;
  271.       if (value_end < value) /* Empty string */
  272. value_end=value;
  273.       if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 +
  274.    (uint) (value_end-value)+1)))
  275. goto err;
  276.       if (insert_dynamic(args,(gptr) &tmp))
  277. goto err;
  278.       ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr));
  279.       *ptr++= '=';
  280.       for ( ; value != value_end; value++)
  281.       {
  282. if (*value == '\' && value != value_end-1)
  283. {
  284.   switch(*++value) {
  285.   case 'n':
  286.     *ptr++='n';
  287.     break;
  288.   case 't':
  289.     *ptr++= 't';
  290.     break;
  291.   case 'r':
  292.     *ptr++ = 'r';
  293.     break;
  294.   case 'b':
  295.     *ptr++ = 'b';
  296.     break;
  297.   case 's':
  298.     *ptr++= ' '; /* space */
  299.     break;
  300.   case '\':
  301.     *ptr++= '\';
  302.     break;
  303.   default: /* Unknown; Keep '' */
  304.     *ptr++= '\';
  305.     *ptr++= *value;
  306.     break;
  307.   }
  308. }
  309. else
  310.   *ptr++= *value;
  311.       }
  312.       *ptr=0;
  313.     }
  314.   }
  315.   my_fclose(fp,MYF(0));
  316.   return(0);
  317.  err:
  318.   my_fclose(fp,MYF(0));
  319.   return 1;
  320. }
  321. void print_defaults(const char *conf_file, const char **groups)
  322. {
  323. #ifdef __WIN__
  324.   bool have_ext=fn_ext(conf_file)[0] != 0;
  325. #endif
  326.   char name[FN_REFLEN];
  327.   const char **dirs;
  328.   puts("nDefault options are read from the following files in the given order:");
  329.   if (dirname_length(conf_file))
  330.     fputs(conf_file,stdout);
  331.   else
  332.   {
  333. #ifdef __WIN__
  334.     GetWindowsDirectory(name,sizeof(name));
  335.     printf("%s\%s%s ",name,conf_file,have_ext ? "" : windows_ext);
  336. #endif
  337. #ifdef __EMX__
  338.     if (getenv("ETC"))
  339.       printf("%s\%s%s ", getenv("ETC"), conf_file, default_ext);
  340. #endif
  341.     for (dirs=default_directories ; *dirs; dirs++)
  342.     {
  343.       if (**dirs)
  344. strmov(name,*dirs);
  345.       else if (defaults_extra_file)
  346. strmov(name,defaults_extra_file);
  347.       else
  348. continue;
  349.       convert_dirname(name);
  350.       if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
  351. strcat(name,".");
  352.       strxmov(strend(name),conf_file,default_ext," ",NullS);
  353.       fputs(name,stdout);
  354.     }
  355.     puts("");
  356.   }
  357.   fputs("The following groups are read:",stdout);
  358.   for ( ; *groups ; groups++)
  359.   {
  360.     fputc(' ',stdout);
  361.     fputs(*groups,stdout);
  362.   }
  363.   puts("nThe following options may be given as the first argument:n
  364. --print-defaults Print the program argument list and exitn
  365. --no-defaults Don't read default options from any options filen
  366. --defaults-file=# Only read default options from the given file #n
  367. --defaults-extra-file=# Read this file after the global files are read");
  368. }