List:Internals« Previous MessageNext Message »
From:jani Date:June 9 2005 11:52am
Subject:bk commit into 5.0 tree (jani:1.1944)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jani. When jani does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1944 05/06/09 12:52:12 jani@stripped +1 -0
  Applied locally latest default.c for Netware 5.0.7.
  Testing against latest LibC.

  mysys/default.c
    1.73 05/06/09 12:52:08 jani@stripped +404 -135
    Applied locally latest default.c for Netware 5.0.7.
    Testing against latest LibC.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jani
# Host:	a193-229-222-105.elisa-laajakaista.fi
# Root:	/home/jani/mydev/mysql-5.0.7-build-dev

--- 1.72/mysys/default.c	2005-06-09 08:41:02 +03:00
+++ 1.73/mysys/default.c	2005-06-09 12:52:08 +03:00
@@ -37,33 +37,185 @@
 #include "m_string.h"
 #include "m_ctype.h"
 #include <my_dir.h>
+#ifdef __WIN__
+#include <winbase.h>
+#endif
 
 char *defaults_extra_file=0;
 
 /* Which directories are searched for options (and in which order) */
 
-#define MAX_DEFAULT_DIRS 4
+#define MAX_DEFAULT_DIRS 5
 const char *default_directories[MAX_DEFAULT_DIRS + 1];
- 
 
 #ifdef __WIN__
 static const char *f_extensions[]= { ".ini", ".cnf", 0 };
+#define NEWLINE "\r\n"
+static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN];
 #else
 static const char *f_extensions[]= { ".cnf", 0 };
+#define NEWLINE "\n"
 #endif
 
-static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
-			       const char *dir, const char *config_file,
-			       TYPELIB *group);
+/*
+   This structure defines the context that we pass to callback
+   function 'handle_default_option' used in search_default_file
+   to process each option. This context is used if search_default_file
+   was called from load_defaults.
+*/
 
-static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
+struct handle_option_ctx
+{
+   MEM_ROOT *alloc;
+   DYNAMIC_ARRAY *args;
+   TYPELIB *group;
+};
+
+static int search_default_file(Process_option_func func, void *func_ctx,
+			       const char *dir, const char *config_file);
+static int search_default_file_with_ext(Process_option_func func,
+                                        void *func_ctx,
 					const char *dir, const char *ext,
-					const char *config_file,
-					TYPELIB *group);
+					const char *config_file, int recursion_level);
 static void init_default_directories();
+
 static char *remove_end_comment(char *ptr);
 
 
+/*
+  Process config files in default directories.
+
+  SYNOPSIS
+  my_search_option_files()
+  conf_file                   Basename for configuration file to search for.
+                              If this is a path, then only this file is read.
+  argc                        Pointer to argc of original program
+  argv                        Pointer to argv of original program
+  args_used                   Pointer to variable for storing the number of
+                              arguments used.
+  func                        Pointer to the function to process options
+  func_ctx                    It's context. Usually it is the structure to
+                              store additional options.
+  DESCRIPTION
+
+  This function looks for config files in default directories. Then it
+  travesrses each of the files and calls func to process each option.
+
+  RETURN
+    0  ok
+    1  given cinf_file doesn't exist
+*/
+
+int my_search_option_files(const char *conf_file, int *argc, char ***argv,
+                        uint *args_used, Process_option_func func,
+                        void *func_ctx)
+{
+  const char **dirs, *forced_default_file, *forced_extra_defaults;
+  int error= 0;
+  DBUG_ENTER("my_search_option_files");
+
+  /* Check if we want to force the use a specific default file */
+  get_defaults_files(*argc, *argv,
+                      (char **)&forced_default_file,
+                      (char **)&forced_extra_defaults);
+  if (forced_default_file)
+    forced_default_file= strchr(forced_default_file,'=')+1;
+  if (forced_extra_defaults)
+    defaults_extra_file= strchr(forced_extra_defaults,'=')+1;
+
+  (*args_used)+= (forced_default_file ? 1 : 0) +
+                 (forced_extra_defaults ? 1 : 0);
+
+  if (forced_default_file)
+  {
+    if ((error= search_default_file_with_ext(func, func_ctx, "", "",
+                                             forced_default_file, 0)) < 0)
+      goto err;
+    if (error > 0)
+    {
+      fprintf(stderr, "Could not open required defaults file: %s\n",
+              forced_default_file);
+      goto err;
+    }
+  }
+  else if (dirname_length(conf_file))
+  {
+    if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0)
+      goto err;
+  }
+  else
+  {
+    for (dirs= default_directories ; *dirs; dirs++)
+    {
+      if (**dirs)
+      {
+	if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
+	  goto err;
+      }
+      else if (defaults_extra_file)
+      {
+        if ((error= search_default_file_with_ext(func, func_ctx, "", "",
+                                                defaults_extra_file, 0)) < 0)
+	  goto err;				/* Fatal error */
+        if (error > 0)
+        {
+          fprintf(stderr, "Could not open required defaults file: %s\n",
+                  defaults_extra_file);
+          goto err;
+        }
+      }
+    }
+  }
+
+  DBUG_RETURN(error);
+
+err:
+  fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
+  exit(1);
+  return 0;					/* Keep compiler happy */
+}
+
+
+/*
+  The option handler for load_defaults.
+
+  SYNOPSIS
+    handle_deault_option()
+    in_ctx                  Handler context. In this case it is a
+                            handle_option_ctx structure.
+    group_name              The name of the group the option belongs to.
+    option                  The very option to be processed. It is already
+                            prepared to be used in argv (has -- prefix)
+
+  DESCRIPTION
+    This handler checks whether a group is one of the listed and adds an option
+    to the array if yes. Some other handler can record, for instance, all
+    groups and their options, not knowing in advance the names and amount of
+    groups.
+
+  RETURN
+    0 - ok
+    1 - error occured
+*/
+
+static int handle_default_option(void *in_ctx, const char *group_name,
+                                 const char *option)
+{
+  char *tmp;
+  struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
+
+  if (find_type((char *)group_name, ctx->group, 3))
+  {
+    if (!(tmp= alloc_root(ctx->alloc, (uint) strlen(option) + 1)))
+      return 1;
+    if (insert_dynamic(ctx->args, (gptr) &tmp))
+      return 1;
+    strmov(tmp, option);
+  }
+
+  return 0;
+}
+
 
 /*
   Gets --defaults-file and --defaults-extra-file options from command line.
@@ -123,7 +275,6 @@
    RETURN
      0	ok
      1	The given conf_file didn't exists
-     2	The given conf_file was not a normal readable file
 */
 
 
@@ -131,15 +282,15 @@
                   int *argc, char ***argv)
 {
   DYNAMIC_ARRAY args;
-  const char **dirs, *forced_default_file;
   TYPELIB group;
   my_bool found_print_defaults=0;
   uint args_used=0;
   int error= 0;
   MEM_ROOT alloc;
-  char *ptr, **res;
-
+  char *ptr,**res;
+  struct handle_option_ctx ctx;
   DBUG_ENTER("load_defaults");
+
   init_default_directories();
   init_alloc_root(&alloc,512,0);
   if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
@@ -160,75 +311,22 @@
     DBUG_RETURN(0);
   }
 
-  get_defaults_files(*argc, *argv,
-                      (char **)&forced_default_file, &defaults_extra_file);
-  if (forced_default_file)
-    forced_default_file= strchr(forced_default_file,'=')+1;
-  if (defaults_extra_file)
-    defaults_extra_file= strchr(defaults_extra_file,'=')+1;
-
-  args_used+= (forced_default_file ? 1 : 0) + (defaults_extra_file ? 1 : 0);
-
   group.count=0;
   group.name= "defaults";
   group.type_names= groups;
+
   for (; *groups ; groups++)
     group.count++;
 
   if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
     goto err;
-  if (forced_default_file)
-  {
-    if ((error= search_default_file_with_ext(&args, &alloc, "", "",
-					     forced_default_file, 
-					     &group)) < 0)
-      goto err;
-    if (error > 0)
-    {
-      fprintf(stderr, "Could not open required defaults file: %s\n",
-              forced_default_file);
-      goto err;
-    }
-  }
-  else if (dirname_length(conf_file))
-  {
-    if ((error= search_default_file(&args, &alloc, NullS, conf_file,
-				    &group)) < 0)
-      goto err;
-  }
-  else
-  {
-#ifdef __WIN__
-    char system_dir[FN_REFLEN];
-    GetWindowsDirectory(system_dir,sizeof(system_dir));
-    if ((search_default_file(&args, &alloc, system_dir, conf_file, &group)))
-      goto err;
-#endif
-#if defined(__EMX__) || defined(OS2)
-    {
-      const char *etc;
-      if ((etc= getenv("ETC")) &&
-	  (search_default_file(&args, &alloc, etc, conf_file, 
-			       &group)) < 0)
-      goto err;
-    }
-#endif
-    for (dirs=default_directories ; *dirs; dirs++)
-    {
-      if (**dirs)
-      {
-	if (search_default_file(&args, &alloc, *dirs, conf_file,
-				&group) < 0)
-	  goto err;
-      }
-      else if (defaults_extra_file)
-      {
-	if (search_default_file(&args, &alloc, NullS, defaults_extra_file,
-				&group) < 0)
-	  goto err;				/* Fatal error */
-      }
-    }
-  }
+
+  ctx.alloc= &alloc;
+  ctx.args= &args;
+  ctx.group= &group;
+
+  error= my_search_option_files(conf_file, argc, argv, &args_used,
+                      handle_default_option, (void *) &ctx);
   /*
     Here error contains <> 0 only if we have a fully specified conf_file
     or a forced default file
@@ -288,17 +386,22 @@
 }
 
 
-static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
+static int search_default_file(Process_option_func opt_handler,
+                               void *handler_ctx,
 			       const char *dir,
-			       const char *config_file, TYPELIB *group)
+			       const char *config_file)
 {
   char **ext;
+  const char *empty_list[]= { "", 0 };
+  my_bool have_ext= fn_ext(config_file)[0] != 0;
+  const char **exts_to_use= have_ext ? empty_list : f_extensions;
 
-  for (ext= (char**) f_extensions; *ext; *ext++)
+  for (ext= (char**) exts_to_use; *ext; *ext++)
   {
     int error;
-    if ((error= search_default_file_with_ext(args, alloc, dir, *ext,
-					     config_file, group)) < 0)
+    if ((error= search_default_file_with_ext(opt_handler, handler_ctx,
+                                             dir, *ext,
+					     config_file, 0)) < 0)
       return error;
   }
   return 0;
@@ -306,33 +409,95 @@
 
 
 /*
+  Skip over keyword and get argument after keyword
+
+  SYNOPSIS
+   get_argument()
+   keyword		Include directive keyword
+   kwlen		Length of keyword
+   ptr			Pointer to the keword in the line under process
+   line			line number
+
+  RETURN
+   0	error
+   #	Returns pointer to the argument after the keyword.
+*/
+
+static char *get_argument(const char *keyword, uint kwlen,
+                          char *ptr, char *name, uint line)
+{
+  char *end;
+
+  /* Skip over "include / includedir keyword" and following whitespace */
+
+  for (ptr+= kwlen - 1;
+       my_isspace(&my_charset_latin1, ptr[0]);
+       ptr++)
+  {}
+
+  /*
+    Trim trailing whitespace from directory name
+    The -1 below is for the newline added by fgets()
+    Note that my_isspace() is true for \r and \n
+  */
+  for (end= ptr + strlen(ptr) - 1;
+       my_isspace(&my_charset_latin1, *(end - 1));
+       end--)
+  {}
+  end[0]= 0;                                    /* Cut off end space */
+
+  /* Print error msg if there is nothing after !include* directive */
+  if (end <= ptr)
+  {
+    fprintf(stderr,
+	    "error: Wrong '!%s' directive in config file: %s at line %d\n",
+	    keyword, name, line);
+    return 0;
+  }
+  return ptr;
+}
+
+
+/*
   Open a configuration file (if exists) and read given options from it
-  
+
   SYNOPSIS
     search_default_file_with_ext()
-    args			Store pointer to found options here
-    alloc			Allocate strings in this object
+    opt_handler                 Option handler function. It is used to process
+                                every separate option.
+    handler_ctx                 Pointer to the structure to store actual 
+                                parameters of the function.
     dir				directory to read
-    config_file			Name of configuration file
     ext				Extension for configuration file
+    config_file                 Name of configuration file
     group			groups to read
+    recursion_level             the level of recursion, got while processing
+                                "!include" or "!includedir"
 
   RETURN
     0   Success
     -1	Fatal error, abort
      1	File not found (Warning)
-     2  File is not a regular file (Warning)
 */
 
-static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
-					const char *dir, const char *ext,
-					const char *config_file,
-					TYPELIB *group)
+static int search_default_file_with_ext(Process_option_func opt_handler,
+                                        void *handler_ctx,
+                                        const char *dir,
+                                        const char *ext,
+                                        const char *config_file,
+                                        int recursion_level)
 {
-  char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp;
+  char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext;
+  char *value, option[4096], tmp[FN_REFLEN];
+  static const char includedir_keyword[]= "includedir";
+  static const char include_keyword[]= "include";
+  const int max_recursion_level= 10;
   FILE *fp;
   uint line=0;
-  my_bool read_values=0,found_group=0;
+  my_bool found_group=0;
+  uint i;
+  MY_DIR *search_dir;
+  FILEINFO *search_file;
 
   if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
     return 0;					/* Ignore wrong paths */
@@ -361,22 +526,97 @@
     if ((stat_info.st_mode & S_IWOTH) &&
 	(stat_info.st_mode & S_IFMT) == S_IFREG)
     {
-      fprintf(stderr, "warning: World-writeable config file %s is ignored\n",
+      fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
               name);
       return 0;
     }
   }
 #endif
-  if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0))))
-    return 0;					/* Ignore wrong files */
+  if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
+    return 1;					/* Ignore wrong files */
 
-  while (fgets(buff,sizeof(buff)-1,fp))
+  while (fgets(buff, sizeof(buff) - 1, fp))
   {
     line++;
     /* Ignore comment and empty lines */
-    for (ptr=buff ; my_isspace(&my_charset_latin1,*ptr) ; ptr++ ) ;
+    for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
+    {}
+
     if (*ptr == '#' || *ptr == ';' || !*ptr)
       continue;
+
+    /* Configuration File Directives */
+    if ((*ptr == '!'))
+    {
+      if (recursion_level >= max_recursion_level)
+      {
+        for (end= ptr + strlen(ptr) - 1; 
+             my_isspace(&my_charset_latin1, *(end - 1));
+             end--)
+        {}
+        end[0]= 0;
+        fprintf(stderr,
+                "Warning: skipping '%s' directive as maximum include"
+                "recursion level was reached in file %s at line %d\n",
+                ptr, name, line);
+        continue;
+      }
+
+      /* skip over `!' and following whitespace */
+      for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
+      {}
+
+      if ((!strncmp(ptr, includedir_keyword,
+                    sizeof(includedir_keyword) - 1)) &&
+          my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
+      {
+	if (!(ptr= get_argument(includedir_keyword,
+                                sizeof(includedir_keyword),
+                                ptr, name, line)))
+	  goto err;
+
+        if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
+          goto err;
+
+        for (i= 0; i < (uint) search_dir->number_off_files; i++)
+        {
+          search_file= search_dir->dir_entry + i;
+          ext= fn_ext(search_file->name);
+
+          /* check extension */
+          for (tmp_ext= (char**) f_extensions; *tmp_ext; *tmp_ext++)
+          {
+            if (!strcmp(ext, *tmp_ext))
+              break;
+          }
+
+          if (*tmp_ext)
+          {
+            fn_format(tmp, search_file->name, ptr, "",
+                      MY_UNPACK_FILENAME | MY_SAFE_PATH);
+
+            search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
+                                         recursion_level + 1);
+          }
+        }
+
+        my_dirend(search_dir);
+      }
+      else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
+               my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
+      {
+	if (!(ptr= get_argument(include_keyword,
+                                sizeof(include_keyword), ptr,
+                                name, line)))
+	  goto err;
+
+        search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
+                                     recursion_level + 1);
+      }
+
+      continue;
+    }
+
     if (*ptr == '[')				/* Group name */
     {
       found_group=1;
@@ -389,7 +629,8 @@
       }
       for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;/* Remove end space */
       end[0]=0;
-      read_values=find_type(ptr,group,3) > 0;
+
+      strnmov(curr_gr, ptr, min((uint) (end-ptr)+1, 4096));
       continue;
     }
     if (!found_group)
@@ -399,19 +640,17 @@
 	      name,line);
       goto err;
     }
-    if (!read_values)
-      continue;
+    
+   
     end= remove_end_comment(ptr);
     if ((value= strchr(ptr, '=')))
       end= value;				/* Option without argument */
     for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
     if (!value)
     {
-      if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3)))
-	goto err;
-      strmake(strmov(tmp,"--"),ptr,(uint) (end-ptr));
-      if (insert_dynamic(args,(gptr) &tmp))
-	goto err;
+      strmake(strmov(option,"--"),ptr,(uint) (end-ptr));
+      if (opt_handler(handler_ctx, curr_gr, option))
+        goto err;
     }
     else
     {
@@ -433,12 +672,7 @@
 	value++;
 	value_end--;
       }
-      if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 +
-			   (uint) (value_end-value)+1)))
-	goto err;
-      if (insert_dynamic(args,(gptr) &tmp))
-	goto err;
-      ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr));
+      ptr=strnmov(strmov(option,"--"),ptr,(uint) (end-ptr));
       *ptr++= '=';
 
       for ( ; value != value_end; value++)
@@ -480,6 +714,8 @@
 	  *ptr++= *value;
       }
       *ptr=0;
+      if (opt_handler(handler_ctx, curr_gr, option))
+        goto err;
     }
   }
   my_fclose(fp,MYF(0));
@@ -518,13 +754,14 @@
 
 #include <help_start.h>
 
-void print_defaults(const char *conf_file, const char **groups)
+void my_print_default_files(const char *conf_file)
 {
-#ifdef __WIN__
+  const char *empty_list[]= { "", 0 };
   my_bool have_ext= fn_ext(conf_file)[0] != 0;
-#endif
+  const char **exts_to_use= have_ext ? empty_list : f_extensions;
   char name[FN_REFLEN], **ext;
   const char **dirs;
+
   init_default_directories();
   puts("\nDefault options are read from the following files in the given order:");
 
@@ -532,30 +769,9 @@
     fputs(conf_file,stdout);
   else
   {
-#ifdef __WIN__
-    GetWindowsDirectory(name,sizeof(name));
-    if (!have_ext)
-    {
-      for (ext= (char**) f_extensions; *ext; *ext++)
-        printf("%s\\%s%s ", name, conf_file, *ext);
-    }
-    else
-        printf("%s\\%s ", name, conf_file);
-#endif
-#if defined(__EMX__) || defined(OS2)
-    {
-      const char *etc;
-
-      if ((etc= getenv("ETC")))
-      {
-	for (ext= (char**) f_extensions; *ext; *ext++)
-	  printf("%s\\%s%s ", etc, conf_file, *ext);
-      }
-    }
-#endif
     for (dirs=default_directories ; *dirs; dirs++)
     {
-      for (ext= (char**) f_extensions; *ext; *ext++)
+      for (ext= (char**) exts_to_use; *ext; *ext++)
       {
 	const char *pos;
 	char *end;
@@ -574,6 +790,12 @@
     }
     puts("");
   }
+}
+
+void print_defaults(const char *conf_file, const char **groups)
+{
+  my_print_default_files(conf_file);
+
   fputs("The following groups are read:",stdout);
   for ( ; *groups ; groups++)
   {
@@ -586,15 +808,64 @@
 --defaults-file=#	Only read default options from the given file #\n\
 --defaults-extra-file=# Read this file after the global files are read");
 }
+
+#include <help_end.h>
+
+
+/*
+  Create the list of default directories.
+
+  On Microsoft Windows, this is:
+    1. C:/
+    2. GetWindowsDirectory()
+    3. GetSystemWindowsDirectory()
+    4. getenv(DEFAULT_HOME_ENV)
+    5. ""
+
+  On Novell NetWare, this is:
+    1. sys:/etc/
+    2. getenv(DEFAULT_HOME_ENV)
+    3. ""
+
+  On OS/2, this is:
+    1. getenv(ETC)
+    2. /etc/
+    3. getenv(DEFAULT_HOME_ENV)
+    4. ""
+    5. "~/"
+
+  Everywhere else, this is:
+    1. /etc/
+    2. getenv(DEFAULT_HOME_ENV)
+    3. ""
+    4. "~/"
+
+ */
+
 static void init_default_directories()
 {
   const char *env, **ptr= default_directories;
 
 #ifdef __WIN__
   *ptr++= "C:/";
+
+  if (GetWindowsDirectory(system_dir,sizeof(system_dir)))
+    *ptr++= (char*)&system_dir;
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+  /* Only VC7 and up */
+  /* Only add shared system directory if different from default. */
+  if (GetSystemWindowsDirectory(shared_system_dir,sizeof(shared_system_dir)) &&
+      strcmp(system_dir, shared_system_dir))
+    *ptr++= &shared_system_dir;
+#endif
+
 #elif defined(__NETWARE__)
   *ptr++= "sys:/etc/";
 #else
+#if defined(__EMX__) || defined(OS2)
+  if ((env= getenv("ETC")))
+    *ptr++= env;
+#endif
   *ptr++= "/etc/";
 #endif
   if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
@@ -605,5 +876,3 @@
 #endif
   *ptr= 0;			/* end marker */
 }
-
-#include <help_end.h>
Thread
bk commit into 5.0 tree (jani:1.1944)jani9 Jun