=== modified file 'client/client_priv.h'
--- client/client_priv.h	2008-01-31 16:46:50 +0000
+++ client/client_priv.h	2009-12-11 08:41:04 +0000
@@ -79,6 +79,6 @@
   OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID,
   OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
   OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
-  OPT_WRITE_BINLOG, OPT_DUMP_DATE,
+  OPT_WRITE_BINLOG, OPT_DUMP_DATE, OPT_BACKUP_BASEDIR,
   OPT_MAX_CLIENT_OPTION
 };

=== modified file 'client/mysqldump.c'
--- client/mysqldump.c	2009-08-28 15:06:59 +0000
+++ client/mysqldump.c	2009-12-14 01:23:33 +0000
@@ -45,6 +45,7 @@
 #include <m_ctype.h>
 #include <hash.h>
 #include <stdarg.h>
+#include <my_dir.h>
 
 #include "client_priv.h"
 #include "mysql.h"
@@ -60,6 +61,7 @@
 #define EX_EOM 4
 #define EX_EOF 5 /* ferror for output file was got */
 #define EX_ILLEGAL_TABLE 6
+#define EX_FILEOP 7
 
 /* index into 'show fields from table' */
 
@@ -110,7 +112,8 @@
              *where=0, *order_by=0,
              *opt_compatible_mode_str= 0,
              *err_ptr= 0,
-             *log_error_file= NULL;
+             *log_error_file= NULL,
+             *opt_backup_basedir= NULL;
 static char **defaults_argv= 0;
 static char compatible_mode_normal_str[255];
 /* Server supports character_set_results session variable? */
@@ -126,6 +129,7 @@
 #include <sslopt-vars.h>
 FILE *md_result_file= 0;
 FILE *stderror_file=0;
+static char backup_dir[FN_REFLEN];
 
 #ifdef HAVE_SMEM
 static char *shared_memory_base_name=0;
@@ -175,7 +179,13 @@
 TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
                                   "", compatible_mode_names, NULL};
 
+typedef struct st_db_ent {
+  char *database;
+  FILE *sql_file;
+} db_entry;
+
 HASH ignore_table;
+HASH per_file_databases;
 
 static struct my_option my_long_options[] =
 {
@@ -210,6 +220,9 @@
   {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
+  {"backup-basedir", OPT_BACKUP_BASEDIR, "Create dump files under this directory instead of writing results to stdout. One dump file is created per database. This option must be combined with --[all-]databases option. Cannot be combined with --tab option. Dump files are created under directory /backup-basedir/<num>/ where num is a sequential number.",
+    (uchar**) &opt_backup_basedir, (uchar**) &opt_backup_basedir, 0, GET_STR,
+    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"character-sets-dir", OPT_CHARSETS_DIR,
    "Directory where character sets are.", (uchar**) &charsets_dir,
    (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -690,6 +703,143 @@
   return (uchar*) entry;
 }
 
+static void free_db_ent(db_entry *entry)
+{
+  if (entry->sql_file) {
+    md_result_file= entry->sql_file;
+    write_footer(entry->sql_file);
+    my_fclose(entry->sql_file, MYF(0));
+    entry->sql_file= NULL;
+  }
+  my_free(entry->database, MYF(MY_ALLOW_ZERO_PTR));
+  my_free((void*)entry, MYF(0));
+}
+
+
+uchar* get_db_key(const db_entry *entry, size_t *length,
+                     my_bool not_used __attribute__((unused)))
+{
+  *length= strlen(entry->database);
+  return (uchar*) entry->database;
+}
+
+int my_mkdir(const char *dir, int Flags, myf MyFlags __attribute__((unused)))
+{
+  DBUG_ENTER("my_dir");
+  DBUG_PRINT("enter",("dir: %s",dir));
+  
+#if  defined(__WIN__)
+  if (mkdir((char*) dir))
+#else
+  if (mkdir((char*) dir, Flags & my_umask_dir))
+#endif
+  {
+    my_errno=errno;
+    DBUG_PRINT("error",("error %d when creating direcory %s",my_errno,dir));
+    DBUG_RETURN(-1);
+  }
+  DBUG_RETURN(0);
+}
+
+static my_bool
+create_backup_dir(const char *basedir)
+{
+  MY_DIR *dirp;
+  FILEINFO *file;
+  uint i;
+  ulong seq, len;
+  
+  if (NULL == basedir) {
+    goto err; /* for safety */
+  }
+  
+  len= strlen(basedir);
+  if (len > FN_REFLEN - 8) {
+    goto err;
+  }
+  
+  if (!(dirp= my_dir(basedir, MYF(MY_WANT_STAT))))
+  {
+    fprintf(stderr, "Specified directory name for --backup-basedir is too long.\n");
+    goto err;
+  }
+  
+  for (i=0, seq=0 ; i < (uint) dirp->number_off_files  ; i++)
+  {
+    ulong current_seq;
+    file=dirp->dir_entry+i;
+    if ((file->name[0] == '.' && 
+         ((file->name[1] == '.' && file->name[2] == '\0') ||
+          file->name[1] == '\0')))
+    {
+      continue; /* current and parent directories. */
+    }
+    current_seq= (ulong)atoi(file->name);
+    seq= (current_seq > seq) ? current_seq : seq;
+  }
+  my_dirend(dirp);
+  seq++;
+  
+  convert_dirname(backup_dir,basedir,NullS);
+  my_snprintf(backup_dir+len, FN_REFLEN - len, "/%06u", seq);
+
+  if (my_mkdir(backup_dir, 0777, MYF(0)) < 0)
+  {
+    goto err;
+  }
+
+  return 0; /* SUCCESS */
+  
+err:
+  fprintf(stderr,
+          "%s: Error occured when creating a directory for --backup-basedir option.\n", my_progname);
+  return 1;
+}
+
+static FILE*
+open_sql_file_for_db(const char* db, int flags)
+{
+  FILE *res, *tmp;
+  char filename[FN_REFLEN];
+  db_entry *e;
+  
+  if((e = (db_entry*)hash_search(&per_file_databases, db, strlen(db)))) {
+    return e->sql_file;
+  }
+  
+  e= my_malloc(sizeof(db_entry), MYF(0));
+  if (NULL == e) {
+    return NULL;
+  }
+  e->database = my_strdup(db, MYF(0));
+  
+  res= my_fopen(fn_format(filename, db, backup_dir, ".sql", 4),
+                flags, MYF(MY_WME));
+  e->sql_file= res;
+  tmp= md_result_file;
+  md_result_file= res;
+  write_header(res, (char*)db);
+  check_io(res);
+  md_result_file= tmp;
+  
+  if (my_hash_insert(&per_file_databases, (uchar*)e))
+    return NULL;
+  
+  return res;
+}
+
+static void
+select_sql_file_for_db(const char *db)
+{
+  if (!opt_backup_basedir) {
+    return;
+  }
+  md_result_file= open_sql_file_for_db(db, O_WRONLY | FILE_BINARY);
+  
+  if (md_result_file == NULL) {
+    exit(EX_EOM);
+  }
+}
 
 static my_bool
 get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
@@ -853,6 +1003,7 @@
 {
   int ho_error;
   MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
+  MY_STAT stat_info;
 
   opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
   opt_net_buffer_length= *mysql_params->p_net_buffer_length;
@@ -875,10 +1026,10 @@
       my_hash_insert(&ignore_table,
                      (uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))))
     return(EX_EOM);
-
+  
   if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
     return(ho_error);
-
+  
   *mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
   *mysql_params->p_net_buffer_length= opt_net_buffer_length;
   if (debug_info_flag)
@@ -895,7 +1046,27 @@
             "%s: You must use option --tab with --fields-...\n", my_progname);
     return(EX_USAGE);
   }
+  
+  if (opt_backup_basedir) {
+    if ((!opt_alldbs && !opt_databases) || path)
+    {
+      fprintf(stderr,
+              "%s: --backup-basedir option must be used with --all-databases or --databases, mustn't used with --tab options.\n", my_progname);
+      return(EX_USAGE);
+    }
+    if (!my_stat(opt_backup_basedir, &stat_info, MYF(0)))
+    {
+      fprintf(stderr,
+              "%s: Directory '%s' doesn't exist. --backup-basedir option needs an existing directory as its argument.\n", my_progname, opt_backup_basedir);
+      return(EX_USAGE);
+    }
 
+    if (hash_init(&per_file_databases, charset_info, 16, 0, 0,
+                  (hash_get_key) get_db_key,
+                  (hash_free_key) free_db_ent, 0))
+      return(EX_EOM);
+  }
+  
   /* Ensure consistency of the set of binlog & locking options */
   if (opt_delete_master_logs && !opt_master_data)
     opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
@@ -1416,11 +1587,13 @@
 
 static void free_resources()
 {
-  if (md_result_file && md_result_file != stdout)
+  if (md_result_file && md_result_file != stdout && !opt_backup_basedir)
     my_fclose(md_result_file, MYF(0));
   my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
   if (hash_inited(&ignore_table))
     hash_free(&ignore_table);
+  if (hash_inited(&per_file_databases))
+    hash_free(&per_file_databases);
   if (extended_insert)
     dynstr_free(&extended_row);
   if (insert_pat_inited)
@@ -4005,6 +4178,8 @@
   char *afterdot;
   int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql");
   DBUG_ENTER("dump_all_tables_in_db");
+  
+  select_sql_file_for_db(database);
 
   afterdot= strmov(hash_key, database);
   *afterdot++= '.';
@@ -4106,6 +4281,8 @@
   char table_buff[NAME_LEN*2+3];
   char hash_key[2*NAME_LEN+2];  /* "db.tablename" */
   char *afterdot;
+  
+  select_sql_file_for_db(database);
 
   afterdot= strmov(hash_key, database);
   *afterdot++= '.';
@@ -5011,6 +5188,13 @@
     free_resources();
     exit(exit_code);
   }
+  
+  if (opt_backup_basedir)
+  {
+    if (create_backup_dir(opt_backup_basedir)) {
+      return(EX_FILEOP);
+    }
+  }
 
   if (log_error_file)
   {
@@ -5026,7 +5210,7 @@
     free_resources();
     exit(EX_MYSQLERR);
   }
-  if (!path)
+  if (!path && !opt_backup_basedir)
     write_header(md_result_file, *argv);
 
   if ((opt_lock_all_tables || opt_master_data) &&
@@ -5098,7 +5282,7 @@
   */
 err:
   dbDisconnect(current_host);
-  if (!path)
+  if (!path && !opt_backup_basedir)
     write_footer(md_result_file);
   free_resources();