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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* mysqldump.c  - Dump a tables contents and format to an ASCII file
  14. **
  15. ** The author's original notes follow :-
  16. **
  17. ** ******************************************************
  18. ** *      *
  19. ** * AUTHOR: Igor Romanenko (igor@frog.kiev.ua)      *
  20. ** * DATE:   December 3, 1994      *
  21. ** * WARRANTY: None, expressed, impressed, implied      *
  22. ** *     or other      *
  23. ** * STATUS: Public domain      *
  24. ** * Adapted and optimized for MySQL by      *
  25. ** * Michael Widenius, Sinisa Milivojevic, Jani Tolonen *
  26. ** * -w --where added 9/10/98 by Jim Faucette      *
  27. ** * slave code by David Saez Padros <david@ols.es>     *
  28. ** *      *
  29. ** ******************************************************
  30. */
  31. /* SSL by
  32. **   Andrei Errapart <andreie@no.spam.ee>
  33. **   T鮪u Samuel  <tonu@please.do.not.remove.this.spam.ee>
  34. **/
  35. #define DUMP_VERSION "8.13"
  36. #include <global.h>
  37. #include <my_sys.h>
  38. #include <m_string.h>
  39. #include <m_ctype.h>
  40. #include "mysql.h"
  41. #include "mysql_version.h"
  42. #include "mysqld_error.h"
  43. #include <getopt.h>
  44. /* Exit codes */
  45. #define EX_USAGE 1
  46. #define EX_MYSQLERR 2
  47. #define EX_CONSCHECK 3
  48. #define EX_EOM 4
  49. /* index into 'show fields from table' */
  50. #define SHOW_FIELDNAME  0
  51. #define SHOW_TYPE  1
  52. #define SHOW_NULL  2
  53. #define SHOW_DEFAULT  4
  54. #define SHOW_EXTRA  5
  55. #define QUOTE_CHAR '`'
  56. static char *add_load_option(char *ptr, const char *object,
  57.      const char *statement);
  58. static char *field_escape(char *to,const char *from,uint length);
  59. static my_bool  verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
  60. lock_tables=0,ignore_errors=0,flush_logs=0,replace=0,
  61. ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0,
  62.                 opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
  63.                 opt_alldbs=0,opt_create_db=0,opt_first_slave=0;
  64. static MYSQL  mysql_connection,*sock=0;
  65. static char  insert_pat[12 * 1024],*opt_password=0,*current_user=0,
  66.              *current_host=0,*path=0,*fields_terminated=0,
  67.              *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
  68.              *where=0, *default_charset;
  69. static uint     opt_mysql_port=0;
  70. static my_string opt_mysql_unix_port=0;
  71. static int   first_error=0;
  72. extern ulong net_buffer_length;
  73. static DYNAMIC_STRING extended_row;
  74. #include "sslopt-vars.h"
  75. enum options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_KEYWORDS,
  76.       OPT_LOCKS, OPT_DROP, OPT_OPTIMIZE, OPT_DELAYED, OPT_TABLES,
  77.               OPT_CHARSETS_DIR, OPT_DEFAULT_CHARSET};
  78. static struct option long_options[] =
  79. {
  80.   {"all-databases",     no_argument,    0,      'A'},
  81.   {"all", no_argument,    0,  'a'},
  82.   {"add-drop-table", no_argument,    0,  OPT_DROP},
  83.   {"add-locks",     no_argument,    0, OPT_LOCKS},
  84.   {"allow-keywords", no_argument,    0,  OPT_KEYWORDS},
  85.   {"character-sets-dir",required_argument,0,    OPT_CHARSETS_DIR},
  86.   {"complete-insert", no_argument,    0,  'c'},
  87.   {"compress",          no_argument,    0,  'C'},
  88.   {"databases",         no_argument,    0,      'B'},
  89.   {"debug", optional_argument,  0, '#'},
  90.   {"default-character-set", required_argument,  0, OPT_DEFAULT_CHARSET},
  91.   {"delayed-insert", no_argument,    0,  OPT_DELAYED},
  92.   {"extended-insert",   no_argument,    0,  'e'},
  93.   {"fields-terminated-by", required_argument,   0, (int) OPT_FTB},
  94.   {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC},
  95.   {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC},
  96.   {"fields-escaped-by", required_argument, 0, (int) OPT_ESC},
  97.   {"first-slave", no_argument,    0, 'x'},
  98.   {"flush-logs", no_argument,    0, 'F'},
  99.   {"force",     no_argument,    0, 'f'},
  100.   {"help",    no_argument,    0, '?'},
  101.   {"host",     required_argument, 0, 'h'},
  102.   {"lines-terminated-by", required_argument,    0, (int) OPT_LTB},
  103.   {"lock-tables",   no_argument,    0,  'l'},
  104.   {"no-create-db",      no_argument,    0,      'n'},
  105.   {"no-create-info",  no_argument,    0,  't'},
  106.   {"no-data",   no_argument,    0,  'd'},
  107.   {"opt",    no_argument,    0,  OPT_OPTIMIZE},
  108.   {"password",   optional_argument,  0, 'p'},
  109. #ifdef __WIN__
  110.   {"pipe", no_argument,     0, 'W'},
  111. #endif
  112.   {"port",     required_argument, 0, 'P'},
  113.   {"quick",     no_argument, 0, 'q'},
  114.   {"quote-names", no_argument, 0, 'Q'},
  115.   {"set-variable", required_argument, 0, 'O'},
  116.   {"socket",    required_argument, 0, 'S'},
  117. #include "sslopt-longopts.h"
  118.   {"tab",     required_argument, 0, 'T'},
  119.   {"tables",            no_argument,            0, OPT_TABLES},
  120. #ifndef DONT_ALLOW_USER_CHANGE
  121.   {"user",     required_argument, 0, 'u'},
  122. #endif
  123.   {"verbose",     no_argument, 0, 'v'},
  124.   {"version",     no_argument,     0, 'V'},
  125.   {"where", required_argument,  0, 'w'},
  126.   {0, 0, 0, 0}
  127. };
  128. static const char *load_default_groups[]= { "mysqldump","client",0 };
  129. CHANGEABLE_VAR changeable_vars[] = {
  130.   { "max_allowed_packet", (long*) &max_allowed_packet,24*1024*1024,4096,
  131.     24*1024L*1024L,MALLOC_OVERHEAD,1024},
  132.   { "net_buffer_length", (long*) &net_buffer_length,1024*1024L-1025,4096,
  133.     24*1024L*1024L,MALLOC_OVERHEAD,1024},
  134.   { 0, 0, 0, 0, 0, 0, 0}
  135. };
  136. static void safe_exit(int error);
  137. static void write_heder(FILE *sql_file, char *db_name);
  138. static void print_value(FILE *file, MYSQL_RES  *result, MYSQL_ROW row,
  139. const char *prefix,const char *name,
  140. int string_value);
  141. static int dump_selected_tables(char *db, char **table_names, int tables);
  142. static int dump_all_tables_in_db(char *db);
  143. static int init_dumping(char *);
  144. static int dump_databases(char **);
  145. static int dump_all_databases();
  146. static char *quote_name(char *name, char *buff);
  147. static void print_version(void)
  148. {
  149.   printf("%s  Ver %s Distrib %s, for %s (%s)n",my_progname,DUMP_VERSION,
  150.    MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
  151. } /* print_version */
  152. static void usage(void)
  153. {
  154.   uint i;
  155.   print_version();
  156.   puts("By Igor Romanenko, Monty, Jani & Sinisa");
  157.   puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,nand you are welcome to modify and redistribute it under the GPL licensen");
  158.   puts("Dumping definition and data mysql database or table");
  159.   printf("Usage: %s [OPTIONS] database [tables]n", my_progname);
  160.   printf("OR     %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]n",
  161.  my_progname);
  162.   printf("OR     %s [OPTIONS] --all-databases [OPTIONS]n", my_progname);
  163.   printf("n
  164.   -A, --all-databases   Dump all the databases. This will be same asn
  165.         --databases with all databases selected.n
  166.   -a, --all Include all MySQL specific create options.n
  167.   -#, --debug=...       Output debug log. Often this is 'd:t:o,filename`.n
  168.   --character-sets-dir=...n
  169.                         Directory where character sets aren
  170.   -?, --help Display this help message and exit.n
  171.   -B, --databases       To dump several databases. Note the difference inn
  172. usage; In this case no tables are given. All namen
  173. arguments are regarded as databasenames.n
  174. 'USE db_name;' will be included in the outputn
  175.   -c, --complete-insert Use complete insert statements.n
  176.   -C, --compress        Use compression in server/client protocol.n
  177.   --default-character-set=...n
  178.                         Set the default character setn
  179.   -e, --extended-insert Allows utilization of the new, much fastern
  180.                         INSERT syntax.n
  181.   --add-drop-table Add a 'drop table' before each create.n
  182.   --add-locks Add locks around insert statements.n
  183.   --allow-keywords Allow creation of column names that are keywords.n
  184.   --delayed-insert      Insert rows with INSERT DELAYED.n
  185.   -F, --flush-logs Flush logs file in server before starting dump.n
  186.   -f, --force Continue even if we get an sql-error.n
  187.   -h, --host=... Connect to host.n");
  188. puts("
  189.   -l, --lock-tables     Lock all tables for read.n
  190.   -n, --no-create-db    'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'n
  191.                         will not be put in the output. The above line willn
  192.                         be added otherwise, if --databases orn
  193.                         --all-databases option was given.n
  194.   -t, --no-create-info Don't write table creation info.n
  195.   -d, --no-data No row information.n
  196.   -O, --set-variable var=optionn
  197.                         give a variable a value. --help lists variablesn
  198.   --opt Same as --add-drop-table --add-locks --alln
  199.                         --extended-insert --quick --lock-tablesn
  200.   -p, --password[=...] Password to use when connecting to server.n
  201.                         If password is not given it's solicited on the tty.n");
  202. #ifdef __WIN__
  203.   puts("-W, --pipe Use named pipes to connect to server");
  204. #endif
  205.   printf("
  206.   -P, --port=... Port number to use for connection.n
  207.   -q, --quick Don't buffer query, dump directly to stdout.n
  208.   -Q, --quote-names Quote table and column names with `n
  209.   -S, --socket=... Socket file to use for connection.n
  210.   --tables              Overrides option --databases (-B).n");
  211. #include "sslopt-usage.h"
  212.   printf("
  213.   -T, --tab=...         Creates tab separated textfile for each table ton
  214.                         given path. (creates .sql and .txt files).n
  215.                         NOTE: This only works if mysqldump is run onn
  216.                               the same machine as the mysqld daemon.n");
  217. #ifndef DONT_ALLOW_USER_CHANGE
  218.   printf("
  219.   -u, --user=# User for login if not current user.n");
  220. #endif
  221.   printf("
  222.   -v, --verbose Print info about the various stages.n
  223.   -V, --version Output version information and exit.n
  224.   -w, --where= dump only selected records; QUOTES mandatory!n
  225.   EXAMPLES: "--where=user='jimf'" "-wuserid>1" "-wuserid<1"n
  226.   Use -T (--tab=...) with --fields-...n
  227.   --fields-terminated-by=...n
  228.                         Fields in the textfile are terminated by ...n
  229.   --fields-enclosed-by=...n
  230.                         Fields in the importfile are enclosed by ...n
  231.   --fields-optionally-enclosed-by=...n
  232.                         Fields in the i.file are opt. enclosed by ...n
  233.   --fields-escaped-by=...n
  234.                         Fields in the i.file are escaped by ...n
  235.   --lines-terminated-by=...n
  236.                         Lines in the i.file are terminated by ...n
  237. ");
  238.   print_defaults("my",load_default_groups);
  239.   printf("nPossible variables for option --set-variable (-O) are:n");
  240.   for (i=0 ; changeable_vars[i].name ; i++)
  241.     printf("%-20s  current value: %lun",
  242.      changeable_vars[i].name,
  243.      (ulong) *changeable_vars[i].varptr);
  244. } /* usage */
  245. static void write_heder(FILE *sql_file, char *db_name)
  246. {
  247.   fprintf(sql_file, "# MySQL dump %sn#n", DUMP_VERSION);
  248.   fprintf(sql_file, "# Host: %s    Database: %sn",
  249.   current_host ? current_host : "localhost", db_name ? db_name : "");
  250.   fputs("#--------------------------------------------------------n",
  251.   sql_file);
  252.   fprintf(sql_file, "# Server versiont%sn",
  253.   mysql_get_server_info(&mysql_connection));
  254.   return;
  255. } /* write_heder */
  256. static int get_options(int *argc,char ***argv)
  257. {
  258.   int c,option_index;
  259.   my_bool tty_password=0;
  260.   load_defaults("my",load_default_groups,argc,argv);
  261.   set_all_changeable_vars(changeable_vars);
  262.   while ((c=getopt_long(*argc,*argv,"#::p::h:u:O:P:S:T:EBaAcCdefFlnqtvVw:?Ix",
  263. long_options, &option_index)) != EOF)
  264.   {
  265.     switch(c) {
  266.     case 'a':
  267.       create_options=1;
  268.       break;
  269.     case 'e':
  270.       extended_insert=1;
  271.       break;
  272.     case 'A':
  273.       opt_alldbs=1;
  274.       break;
  275.     case OPT_DEFAULT_CHARSET:
  276.       default_charset= optarg;
  277.       break;
  278.     case OPT_CHARSETS_DIR:
  279.       charsets_dir= optarg;
  280.       break;
  281.     case 'f':
  282.       ignore_errors=1;
  283.       break;
  284.     case 'F':
  285.       flush_logs=1;
  286.       break;
  287.     case 'h':
  288.       my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
  289.       current_host=my_strdup(optarg,MYF(MY_WME));
  290.       break;
  291.     case 'n':
  292.       opt_create_db = 1;
  293.       break;
  294. #ifndef DONT_ALLOW_USER_CHANGE
  295.     case 'u':
  296.       current_user=optarg;
  297.       break;
  298. #endif
  299.     case 'O':
  300.       if (set_changeable_var(optarg, changeable_vars))
  301.       {
  302. usage();
  303. return(1);
  304.       }
  305.       break;
  306.     case 'p':
  307.       if (optarg)
  308.       {
  309. char *start=optarg;
  310. my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
  311. opt_password=my_strdup(optarg,MYF(MY_FAE));
  312. while (*optarg) *optarg++= 'x'; /* Destroy argument */
  313. if (*start)
  314.   start[1]=0; /* Cut length of argument */
  315.       }
  316.       else
  317. tty_password=1;
  318.       break;
  319.     case 'P':
  320.       opt_mysql_port= (unsigned int) atoi(optarg);
  321.       break;
  322.     case 'S':
  323.       opt_mysql_unix_port= optarg;
  324.       break;
  325.     case 'W':
  326. #ifdef __WIN__
  327.       opt_mysql_unix_port=MYSQL_NAMEDPIPE;
  328. #endif
  329.       break;
  330.     case 'T':
  331.       path= optarg;
  332.       break;
  333.     case 'B':
  334.       opt_databases = 1;
  335.       break;
  336.     case '#':
  337.       DBUG_PUSH(optarg ? optarg : "d:t:o");
  338.       break;
  339.     case 'c': cFlag=1; break;
  340.     case 'C':
  341.       opt_compress=1;
  342.       break;
  343.     case 'd': dFlag=1; break;
  344.     case 'l': lock_tables=1; break;
  345.     case 'q': quick=1; break;
  346.     case 'Q': opt_quoted=1; break;
  347.     case 't': tFlag=1;  break;
  348.     case 'v': verbose=1; break;
  349.     case 'V': print_version(); exit(0);
  350.     case 'w':
  351.       where=optarg;
  352.       break;
  353.     case 'x':
  354.       opt_first_slave=1;
  355.       break;
  356.     default:
  357.       fprintf(stderr,"%s: Illegal option character '%c'n",my_progname,opterr);
  358.       /* Fall throught */
  359.     case 'I':
  360.     case '?':
  361.       usage();
  362.       exit(0);
  363.     case (int) OPT_FTB:
  364.       fields_terminated= optarg;
  365.       break;
  366.     case (int) OPT_LTB:
  367.       lines_terminated= optarg;
  368.       break;
  369.     case (int) OPT_ENC:
  370.       enclosed= optarg;
  371.       break;
  372.     case (int) OPT_O_ENC:
  373.       opt_enclosed= optarg;
  374.       break;
  375.     case (int) OPT_ESC:
  376.       escaped= optarg;
  377.       break;
  378.     case (int) OPT_DROP:
  379.       opt_drop=1;
  380.       break;
  381.     case (int) OPT_KEYWORDS:
  382.       opt_keywords=1;
  383.       break;
  384.     case (int) OPT_LOCKS:
  385.       opt_lock=1;
  386.       break;
  387.     case (int) OPT_OPTIMIZE:
  388.       extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=1;
  389.       break;
  390.     case (int) OPT_DELAYED:
  391.       opt_delayed=1;
  392.       break;
  393.     case (int) OPT_TABLES:
  394.       opt_databases=0;
  395.       break;
  396. #include "sslopt-case.h"
  397.     }
  398.   }
  399.   if (opt_delayed)
  400.     opt_lock=0; /* Can't have lock with delayed */
  401.   if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
  402. fields_terminated))
  403.   {
  404.     fprintf(stderr, "%s: You must use option --tab with --fields-...n", my_progname);
  405.     return(1);
  406.   }
  407.   if (enclosed && opt_enclosed)
  408.   {
  409.     fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.n", my_progname);
  410.     return(1);
  411.   }
  412.   if (replace && ignore)
  413.   {
  414.     fprintf(stderr, "%s: You can't use --ignore (-i) and --replace (-r) at the same time.n",my_progname);
  415.     return(1);
  416.   }
  417.   if ((opt_databases || opt_alldbs) && path)
  418.   {
  419.     fprintf(stderr,
  420.     "%s: --databases or --all-databases can't be used with --tab.n",
  421.     my_progname);
  422.     return(1);
  423.   }
  424.   if (default_charset)
  425.   {
  426.     if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
  427.       exit(1);
  428.   }
  429.   (*argc)-=optind;
  430.   (*argv)+=optind;
  431.   if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
  432.   {
  433.     usage();
  434.     return 1;
  435.   }
  436.   if (tty_password)
  437.     opt_password=get_tty_password(NullS);
  438.   return(0);
  439. } /* get_options */
  440. /*
  441. ** DBerror -- prints mysql error message and exits the program.
  442. */
  443. static void DBerror(MYSQL *mysql, const char *when)
  444. {
  445.   DBUG_ENTER("DBerror");
  446.   my_printf_error(0,"Got error: %d: %s %s", MYF(0),
  447.   mysql_errno(mysql), mysql_error(mysql), when);
  448.   safe_exit(EX_MYSQLERR);
  449.   DBUG_VOID_RETURN;
  450. } /* DBerror */
  451. static void safe_exit(int error)
  452. {
  453.   if (!first_error)
  454.     first_error= error;
  455.   if (ignore_errors)
  456.     return;
  457.   if (sock)
  458.     mysql_close(sock);
  459.   exit(error);
  460. }
  461. /* safe_exit */
  462. /*
  463. ** dbConnect -- connects to the host and selects DB.
  464. **        Also checks whether the tablename is a valid table name.
  465. */
  466. static int dbConnect(char *host, char *user,char *passwd)
  467. {
  468.   DBUG_ENTER("dbConnect");
  469.   if (verbose)
  470.   {
  471.     fprintf(stderr, "# Connecting to %s...n", host ? host : "localhost");
  472.   }
  473.   mysql_init(&mysql_connection);
  474.   if (opt_compress)
  475.     mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
  476. #ifdef HAVE_OPENSSL
  477.   if (opt_use_ssl)
  478.     mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
  479.   opt_ssl_capath);
  480. #endif
  481.   if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
  482.          NULL,opt_mysql_port,opt_mysql_unix_port,
  483.          0)))
  484.   {
  485.     DBerror(&mysql_connection, "when trying to connect");
  486.     return 1;
  487.   }
  488.   return 0;
  489. } /* dbConnect */
  490. /*
  491. ** dbDisconnect -- disconnects from the host.
  492. */
  493. static void dbDisconnect(char *host)
  494. {
  495.   if (verbose)
  496.     fprintf(stderr, "# Disconnecting from %s...n", host ? host : "localhost");
  497.   mysql_close(sock);
  498. } /* dbDisconnect */
  499. static void unescape(FILE *file,char *pos,uint length)
  500. {
  501.   char *tmp;
  502.   DBUG_ENTER("unescape");
  503.   if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
  504.   {
  505.     ignore_errors=0; /* Fatal error */
  506.     safe_exit(EX_MYSQLERR); /* Force exit */
  507.   }
  508.   mysql_real_escape_string(&mysql_connection,tmp, pos, length);
  509.   fputc(''', file);
  510.   fputs(tmp, file);
  511.   fputc(''', file);
  512.   my_free(tmp, MYF(MY_WME));
  513.   DBUG_VOID_RETURN;
  514. } /* unescape */
  515. static my_bool test_if_special_chars(const char *str)
  516. {
  517. #if MYSQL_VERSION_ID >= 32300
  518.   for ( ; *str ; str++)
  519.     if (!isvar(*str) && *str != '$')
  520.       return 1;
  521. #endif
  522.   return 0;
  523. } /* test_if_special_chars */
  524. static char *quote_name(char *name, char *buff)
  525. {
  526.   char *end;
  527.   if (!opt_quoted && !test_if_special_chars(name))
  528.     return name;
  529.   buff[0]=QUOTE_CHAR;
  530.   end=strmov(buff+1,name);
  531.   end[0]=QUOTE_CHAR;
  532.   end[1]=0;
  533.   return buff;
  534. } /* quote_name */
  535. /*
  536. ** getStructure -- retrievs database structure, prints out corresponding
  537. **       CREATE statement and fills out insert_pat.
  538. ** Return values:  number of fields in table, 0 if error
  539. */
  540. static uint getTableStructure(char *table, char* db)
  541. {
  542.   MYSQL_RES  *tableRes;
  543.   MYSQL_ROW  row;
  544.   my_bool    init=0;
  545.   uint       numFields;
  546.   char       *strpos, *table_name;
  547.   const char *delayed;
  548.   char       name_buff[NAME_LEN+3],table_buff[NAME_LEN+3];
  549.   FILE       *sql_file = stdout;
  550.   DBUG_ENTER("getTableStructure");
  551.   delayed= opt_delayed ? " DELAYED " : "";
  552.   if (verbose)
  553.     fprintf(stderr, "# Retrieving table structure for table %s...n", table);
  554.   sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted);
  555.   table_name=quote_name(table,table_buff);
  556.   if (!mysql_query(sock,insert_pat))
  557.   {
  558.     /* using SHOW CREATE statement */
  559.     if (!tFlag)
  560.     {
  561.       /* Make an sql-file, if path was given iow. option -T was given */
  562.       char buff[20+FN_REFLEN];
  563.       sprintf(buff,"show create table %s",table_name);
  564.       if (mysql_query(sock, buff))
  565.       {
  566.         fprintf(stderr, "%s: Can't get CREATE TABLE for table '%s' (%s)n",
  567.          my_progname, table, mysql_error(sock));
  568.         safe_exit(EX_MYSQLERR);
  569.         DBUG_RETURN(0);
  570.       }
  571.       if (path)
  572.       {
  573.         char filename[FN_REFLEN], tmp_path[FN_REFLEN];
  574.         strmov(tmp_path,path);
  575.         convert_dirname(tmp_path);
  576.         sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
  577.     O_WRONLY, MYF(MY_WME));
  578.         if (!sql_file) /* If file couldn't be opened */
  579.         {
  580.    safe_exit(EX_MYSQLERR);
  581.    DBUG_RETURN(0);
  582.         }
  583.         write_heder(sql_file, db);
  584.       }
  585.       fprintf(sql_file, "n#n# Table structure for table '%s'n#nn", table);
  586.       if (opt_drop)
  587.         fprintf(sql_file, "DROP TABLE IF EXISTS %s;n",table_name);
  588.       tableRes=mysql_store_result(sock);
  589.       row=mysql_fetch_row(tableRes);
  590.       fprintf(sql_file, "%s;n", row[1]);
  591.       mysql_free_result(tableRes);
  592.     }
  593.     sprintf(insert_pat,"show fields from %s",table_name);
  594.     if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock)))
  595.     {
  596.       fprintf(stderr, "%s: Can't get info about table: '%s'nerror: %sn",
  597.        my_progname, table, mysql_error(sock));
  598.       safe_exit(EX_MYSQLERR);
  599.       DBUG_RETURN(0);
  600.     }
  601.     if (cFlag)
  602.       sprintf(insert_pat, "INSERT %sINTO %s (", delayed, table_name);
  603.     else
  604.     {
  605.       sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, table_name);
  606.       if (!extended_insert)
  607.         strcat(insert_pat,"(");
  608.     }
  609.     strpos=strend(insert_pat);
  610.     while ((row=mysql_fetch_row(tableRes)))
  611.     {
  612.       if (init)
  613.       {
  614.         if (cFlag)
  615.   strpos=strmov(strpos,", ");
  616.       }
  617.       init=1;
  618.       if (cFlag)
  619.         strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME],name_buff));
  620.     }
  621.     numFields = (uint) mysql_num_rows(tableRes);
  622.     mysql_free_result(tableRes);
  623.   }
  624.   else
  625.   {
  626.   /*  fprintf(stderr, "%s: Can't set SQL_QUOTE_SHOW_CREATE option (%s)n",
  627.       my_progname, mysql_error(sock)); */
  628.     sprintf(insert_pat,"show fields from %s",table_name);
  629.     if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock)))
  630.     {
  631.       fprintf(stderr, "%s: Can't get info about table: '%s'nerror: %sn",
  632.     my_progname, table, mysql_error(sock));
  633.       safe_exit(EX_MYSQLERR);
  634.       DBUG_RETURN(0);
  635.     }
  636.     /* Make an sql-file, if path was given iow. option -T was given */
  637.     if (!tFlag)
  638.     {
  639.       if (path)
  640.       {
  641.         char filename[FN_REFLEN], tmp_path[FN_REFLEN];
  642.         strmov(tmp_path,path);
  643.         convert_dirname(tmp_path);
  644.         sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
  645.  O_WRONLY, MYF(MY_WME));
  646.         if (!sql_file) /* If file couldn't be opened */
  647.         {
  648. safe_exit(EX_MYSQLERR);
  649. DBUG_RETURN(0);
  650.         }
  651.         write_heder(sql_file, db);
  652.       }
  653.       fprintf(sql_file, "n#n# Table structure for table '%s'n#nn", table);
  654.       if (opt_drop)
  655.         fprintf(sql_file, "DROP TABLE IF EXISTS %s;n",table_name);
  656.       fprintf(sql_file, "CREATE TABLE %s (n", table_name);
  657.     }
  658.     if (cFlag)
  659.       sprintf(insert_pat, "INSERT %sINTO %s (", delayed, table_name);
  660.     else
  661.     {
  662.       sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, table_name);
  663.       if (!extended_insert)
  664.         strcat(insert_pat,"(");
  665.     }
  666.     strpos=strend(insert_pat);
  667.     while ((row=mysql_fetch_row(tableRes)))
  668.     {
  669.       ulong *lengths=mysql_fetch_lengths(tableRes);
  670.       if (init)
  671.       {
  672.         if (!tFlag)
  673. fputs(",n",sql_file);
  674.         if (cFlag)
  675. strpos=strmov(strpos,", ");
  676.       }
  677.       init=1;
  678.       if (cFlag)
  679.         strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME],name_buff));
  680.       if (!tFlag)
  681.       {
  682.         if (opt_keywords)
  683. fprintf(sql_file, "  %s.%s %s", table_name,
  684. quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]);
  685.         else
  686. fprintf(sql_file, "  %s %s", quote_name(row[SHOW_FIELDNAME],name_buff),
  687. row[SHOW_TYPE]);
  688.         if (row[SHOW_DEFAULT])
  689.         {
  690. fputs(" DEFAULT ", sql_file);
  691. unescape(sql_file,row[SHOW_DEFAULT],lengths[SHOW_DEFAULT]);
  692.         }
  693.         if (!row[SHOW_NULL][0])
  694. fputs(" NOT NULL", sql_file);
  695.         if (row[SHOW_EXTRA][0])
  696. fprintf(sql_file, " %s",row[SHOW_EXTRA]);
  697.       }
  698.     }
  699.     numFields = (uint) mysql_num_rows(tableRes);
  700.     mysql_free_result(tableRes);
  701.     if (!tFlag)
  702.     {
  703.       /* Make an sql-file, if path was given iow. option -T was given */
  704.       char buff[20+FN_REFLEN];
  705.       uint keynr,primary_key;
  706.       sprintf(buff,"show keys from %s",table_name);
  707.       if (mysql_query(sock, buff))
  708.       {
  709.         fprintf(stderr, "%s: Can't get keys for table '%s' (%s)n",
  710.       my_progname, table, mysql_error(sock));
  711.         if (sql_file != stdout)
  712. my_fclose(sql_file, MYF(MY_WME));
  713.         safe_exit(EX_MYSQLERR);
  714.         DBUG_RETURN(0);
  715.       }
  716.       tableRes=mysql_store_result(sock);
  717.       /* Find first which key is primary key */
  718.       keynr=0;
  719.       primary_key=INT_MAX;
  720.       while ((row=mysql_fetch_row(tableRes)))
  721.       {
  722.         if (atoi(row[3]) == 1)
  723.         {
  724. keynr++;
  725.     #ifdef FORCE_PRIMARY_KEY
  726. if (atoi(row[1]) == 0 && primary_key == INT_MAX)
  727.   primary_key=keynr;
  728.     #endif
  729. if (!strcmp(row[2],"PRIMARY"))
  730. {
  731.   primary_key=keynr;
  732.   break;
  733. }
  734.         }
  735.       }
  736.       mysql_data_seek(tableRes,0);
  737.       keynr=0;
  738.       while ((row=mysql_fetch_row(tableRes)))
  739.       {
  740.         if (atoi(row[3]) == 1)
  741.         {
  742. if (keynr++)
  743.   putc(')', sql_file);
  744. if (atoi(row[1]))       /* Test if duplicate key */
  745.   /* Duplicate allowed */
  746.   fprintf(sql_file, ",n  KEY %s (",quote_name(row[2],name_buff));
  747. else if (keynr == primary_key)
  748.   fputs(",n  PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
  749. else
  750.   fprintf(sql_file, ",n  UNIQUE %s (",quote_name(row[2],name_buff));
  751.         }
  752.         else
  753. putc(',', sql_file);
  754.         fputs(quote_name(row[4],name_buff), sql_file);
  755.         if (row[7])
  756. fprintf(sql_file, " (%s)",row[7]);      /* Sub key */
  757.       }
  758.       if (keynr)
  759.         putc(')', sql_file);
  760.       fputs("n)",sql_file);
  761.       /* Get MySQL specific create options */
  762.       if (create_options)
  763.       {
  764.         sprintf(buff,"show table status like '%s'",table);
  765.         if (mysql_query(sock, buff))
  766.         {
  767. if (mysql_errno(sock) != ER_PARSE_ERROR)
  768. { /* If old MySQL version */
  769.   if (verbose)
  770.     fprintf(stderr,
  771.     "# Warning: Couldn't get status information for table '%s' (%s)n",
  772.     table,mysql_error(sock));
  773. }
  774.         }
  775.         else if (!(tableRes=mysql_store_result(sock)) ||
  776.        !(row=mysql_fetch_row(tableRes)))
  777.         {
  778. fprintf(stderr,
  779. "Error: Couldn't read status information for table '%s' (%s)n",
  780. table,mysql_error(sock));
  781.         }
  782.         else
  783.         {
  784. fputs("/*!",sql_file);
  785. print_value(sql_file,tableRes,row,"type=","Type",0);
  786. print_value(sql_file,tableRes,row,"","Create_options",0);
  787. print_value(sql_file,tableRes,row,"comment=","Comment",1);
  788. fputs(" */",sql_file);
  789.         }
  790.         mysql_free_result(tableRes); /* Is always safe to free */
  791.       }
  792.       fputs(";n", sql_file);
  793.     }
  794.   }
  795.   if (cFlag)
  796.   {
  797.     strpos=strmov(strpos,") VALUES ");
  798.     if (!extended_insert)
  799.       strpos=strmov(strpos,"(");
  800.   }
  801.   DBUG_RETURN(numFields);
  802. } /* getTableStructure */
  803. static char *add_load_option(char *ptr,const char *object,
  804.      const char *statement)
  805. {
  806.   if (object)
  807.   {
  808.     /* Don't escape hex constants */
  809.     if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
  810.       ptr= strxmov(ptr," ",statement," ",object,NullS);
  811.     else
  812.     {
  813.       /* char constant; escape */
  814.       ptr= strxmov(ptr," ",statement," '",NullS);
  815.       ptr= field_escape(ptr,object,(uint) strlen(object));
  816.       *ptr++= ''';
  817.     }
  818.   }
  819.   return ptr;
  820. } /* add_load_option */
  821. /*
  822. ** Allow the user to specify field terminator strings like:
  823. ** "'", "", "\" (escaped backslash), "t" (tab), "n" (newline)
  824. ** This is done by doubleing ' and add a end - if needed to avoid
  825. ** syntax errors from the SQL parser.
  826. */
  827. static char *field_escape(char *to,const char *from,uint length)
  828. {
  829.   const char *end;
  830.   uint end_backslashes=0;
  831.   for (end= from+length; from != end; from++)
  832.   {
  833.     *to++= *from;
  834.     if (*from == '\')
  835.       end_backslashes^=1;    /* find odd number of backslashes */
  836.     else
  837.     {
  838.       if (*from == ''' && !end_backslashes)
  839. *to++= *from;      /* We want a duplicate of "'" for MySQL */
  840.       end_backslashes=0;
  841.     }
  842.   }
  843.   /* Add missing backslashes if user has specified odd number of backs.*/
  844.   if (end_backslashes)
  845.     *to++= '\';
  846.   return to;
  847. } /* field_escape */
  848. /*
  849. ** dumpTable saves database contents as a series of INSERT statements.
  850. */
  851. static void dumpTable(uint numFields, char *table)
  852. {
  853.   char query[1024], *end, buff[256],table_buff[NAME_LEN+3];
  854.   MYSQL_RES *res;
  855.   MYSQL_FIELD  *field;
  856.   MYSQL_ROW    row;
  857.   ulong rownr, row_break, total_length, init_length;
  858.   if (verbose)
  859.     fprintf(stderr, "# Sending SELECT query...n");
  860.   if (path)
  861.   {
  862.     char filename[FN_REFLEN], tmp_path[FN_REFLEN];
  863.     strmov(tmp_path, path);
  864.     convert_dirname(tmp_path);
  865.     my_load_path(tmp_path, tmp_path, NULL);
  866.     fn_format(filename, table, tmp_path, ".txt", 4);
  867.     my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if
  868.     filename wasn't deleted */
  869.     to_unix_path(filename);
  870.     sprintf(query, "SELECT * INTO OUTFILE '%s'", filename);
  871.     end= strend(query);
  872.     if (replace)
  873.       end= strmov(end, " REPLACE");
  874.     if (ignore)
  875.       end= strmov(end, " IGNORE");
  876.     if (fields_terminated || enclosed || opt_enclosed || escaped)
  877.       end= strmov(end, " FIELDS");
  878.     end= add_load_option(end, fields_terminated, " TERMINATED BY");
  879.     end= add_load_option(end, enclosed, " ENCLOSED BY");
  880.     end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY");
  881.     end= add_load_option(end, escaped, " ESCAPED BY");
  882.     end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
  883.     *end= '';
  884.     sprintf(buff," FROM %s",table);
  885.     end= strmov(end,buff);
  886.     if (where)
  887.       end= strxmov(end, " WHERE ",where,NullS);
  888.     if (mysql_query(sock, query))
  889.     {
  890.       DBerror(sock, "when executing 'SELECT INTO OUTFILE'");
  891.       return;
  892.     }
  893.   }
  894.   else
  895.   {
  896.     printf("n#n# Dumping data for table '%s'n", table);
  897.     sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff));
  898.     if (where)
  899.     {
  900.       printf("# WHERE:  %sn",where);
  901.       strxmov(strend(query), " WHERE ",where,NullS);
  902.     }
  903.     puts("#n");
  904.     if (mysql_query(sock, query))
  905.     {
  906.       DBerror(sock, "when retrieving data from server");
  907.       return;
  908.     }
  909.     if (quick)
  910.       res=mysql_use_result(sock);
  911.     else
  912.       res=mysql_store_result(sock);
  913.     if (!res)
  914.     {
  915.       DBerror(sock, "when retrieving data from server");
  916.       return;
  917.     }
  918.     if (verbose)
  919.       fprintf(stderr, "# Retrieving rows...n");
  920.     if (mysql_num_fields(res) != numFields)
  921.     {
  922.       fprintf(stderr,"%s: Error in field count for table: '%s' !  Aborting.n",
  923.       my_progname,table);
  924.       safe_exit(EX_CONSCHECK);
  925.       return;
  926.     }
  927.     if (opt_lock)
  928.       printf("LOCK TABLES %s WRITE;n", quote_name(table,table_buff));
  929.     total_length=net_buffer_length; /* Force row break */
  930.     row_break=0;
  931.     rownr=0;
  932.     init_length=(uint) strlen(insert_pat)+4;
  933.     while ((row=mysql_fetch_row(res)))
  934.     {
  935.       uint i;
  936.       ulong *lengths=mysql_fetch_lengths(res);
  937.       rownr++;
  938.       if (!extended_insert)
  939. fputs(insert_pat,stdout);
  940.       mysql_field_seek(res,0);
  941.       for (i = 0; i < mysql_num_fields(res); i++)
  942.       {
  943. if (!(field = mysql_fetch_field(res)))
  944. {
  945.   sprintf(query,"%s: Not enough fields from table '%s'! Aborting.n",
  946.   my_progname,table);
  947.   fputs(query,stderr);
  948.   safe_exit(EX_CONSCHECK);
  949.   return;
  950. }
  951. if (extended_insert)
  952. {
  953.   ulong length = lengths[i];
  954.   if (i == 0)
  955.     dynstr_set(&extended_row,"(");
  956.   else
  957.     dynstr_append(&extended_row,",");
  958.   if (row[i])
  959.   {
  960.     if (length)
  961.     {
  962.       if (!IS_NUM_FIELD(field))
  963.       {
  964. if (dynstr_realloc(&extended_row,length * 2+2))
  965. {
  966.   fputs("Aborting dump (out of memory)",stderr);
  967.   safe_exit(EX_EOM);
  968. }
  969. dynstr_append(&extended_row,"'");
  970. extended_row.length +=
  971.   mysql_real_escape_string(&mysql_connection,
  972.    &extended_row.str[extended_row.length],row[i],length);
  973. extended_row.str[extended_row.length]='';
  974. dynstr_append(&extended_row,"'");
  975.       }
  976.       else
  977. dynstr_append(&extended_row,row[i]);
  978.     }
  979.     else
  980.       dynstr_append(&extended_row,"''");
  981.   }
  982.   else if (dynstr_append(&extended_row,"NULL"))
  983.   {
  984.     fputs("Aborting dump (out of memory)",stderr);
  985.     safe_exit(EX_EOM);
  986.   }
  987. }
  988. else
  989. {
  990.   if (i)
  991.     putchar(',');
  992.   if (row[i])
  993.   {
  994.     if (!IS_NUM_FIELD(field))
  995.       unescape(stdout, row[i], lengths[i]);
  996.     else
  997.       fputs(row[i],stdout);
  998.   }
  999.   else
  1000.   {
  1001.     fputs("NULL",stdout);
  1002.   }
  1003. }
  1004.       }
  1005.       if (extended_insert)
  1006.       {
  1007. ulong row_length;
  1008. dynstr_append(&extended_row,")");
  1009.         row_length = 2 + extended_row.length;
  1010.         if (total_length + row_length < net_buffer_length)
  1011.         {
  1012.   total_length += row_length;
  1013.   putchar(','); /* Always row break */
  1014.   fputs(extended_row.str,stdout);
  1015. }
  1016.         else
  1017.         {
  1018.   if (row_break)
  1019.     puts(";");
  1020.   row_break=1; /* This is first row */
  1021.   fputs(insert_pat,stdout);
  1022.   fputs(extended_row.str,stdout);
  1023.   total_length = row_length+init_length;
  1024.         }
  1025.       }
  1026.       else
  1027.       {
  1028. puts(");");
  1029.       }
  1030.     }
  1031.     if (extended_insert && row_break)
  1032.       puts(";"); /* If not empty table */
  1033.     fflush(stdout);
  1034.     if (mysql_errno(sock))
  1035.     {
  1036.       sprintf(query,"%s: Error %d: %s when dumping table '%s' at row: %ldn",
  1037.       my_progname,
  1038.       mysql_errno(sock),
  1039.       mysql_error(sock),
  1040.       table,
  1041.       rownr);
  1042.       fputs(query,stderr);
  1043.       safe_exit(EX_CONSCHECK);
  1044.       return;
  1045.     }
  1046.     if (opt_lock)
  1047.       puts("UNLOCK TABLES;");
  1048.     mysql_free_result(res);
  1049.   }
  1050. } /* dumpTable */
  1051. static char *getTableName(int reset)
  1052. {
  1053.   static MYSQL_RES *res = NULL;
  1054.   MYSQL_ROW    row;
  1055.   if (!res)
  1056.   {
  1057.     if (!(res = mysql_list_tables(sock,NullS)))
  1058.       return(NULL);
  1059.   }
  1060.   if ((row = mysql_fetch_row(res)))
  1061.     return((char*) row[0]);
  1062.   if (reset)
  1063.     mysql_data_seek(res,0);      /* We want to read again */
  1064.   else
  1065.   {
  1066.     mysql_free_result(res);
  1067.     res = NULL;
  1068.   }
  1069.   return(NULL);
  1070. } /* getTableName */
  1071. static int dump_all_databases()
  1072. {
  1073.   MYSQL_ROW row;
  1074.   MYSQL_RES *tableres;
  1075.   int result=0;
  1076.   if (mysql_query(sock, "SHOW DATABASES") ||
  1077.       !(tableres = mysql_store_result(sock)))
  1078.   {
  1079.     my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
  1080.     MYF(0), mysql_error(sock));
  1081.     return 1;
  1082.   }
  1083.   while ((row = mysql_fetch_row(tableres)))
  1084.   {
  1085.     if (dump_all_tables_in_db(row[0]))
  1086.       result=1;
  1087.   }
  1088.   return result;
  1089. }
  1090. /* dump_all_databases */
  1091. static int dump_databases(char **db_names)
  1092. {
  1093.   int result=0;
  1094.   for ( ; *db_names ; db_names++)
  1095.   {
  1096.     if (dump_all_tables_in_db(*db_names))
  1097.       result=1;
  1098.   }
  1099.   return result;
  1100. } /* dump_databases */
  1101. static int init_dumping(char *database)
  1102. {
  1103.   if (mysql_select_db(sock, database))
  1104.   {
  1105.     DBerror(sock, "when selecting the database");
  1106.     return 1; /* If --force */
  1107.   }
  1108.   if (!path)
  1109.   {
  1110.     if (opt_databases || opt_alldbs)
  1111.     {
  1112.       printf("n#n# Current Database: %sn#n", database);
  1113.       if (!opt_create_db)
  1114. printf("nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;n", database);
  1115.       printf("nUSE %s;n", database);
  1116.     }
  1117.   }
  1118.   if (extended_insert)
  1119.     if (init_dynamic_string(&extended_row, "", 1024, 1024))
  1120.       exit(EX_EOM);
  1121.   return 0;
  1122. } /* init_dumping */
  1123. static int dump_all_tables_in_db(char *database)
  1124. {
  1125.   char *table;
  1126.   uint numrows;
  1127.   if (init_dumping(database))
  1128.     return 1;
  1129.   if (lock_tables)
  1130.   {
  1131.     DYNAMIC_STRING query;
  1132.     init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
  1133.     for (numrows=0 ; (table = getTableName(1)) ; numrows++)
  1134.     {
  1135.       dynstr_append(&query, table);
  1136.       dynstr_append(&query, " READ /*!32311 LOCAL */,");
  1137.     }
  1138.     if (numrows && mysql_real_query(sock, query.str, query.length-1))
  1139.       DBerror(sock, "when using LOCK TABLES");
  1140.             /* We shall continue here, if --force was given */
  1141.     dynstr_free(&query);
  1142.   }
  1143.   if (flush_logs)
  1144.   {
  1145.     if (mysql_refresh(sock, REFRESH_LOG))
  1146.       DBerror(sock, "when doing refresh");
  1147.            /* We shall continue here, if --force was given */
  1148.   }
  1149.   while ((table = getTableName(0)))
  1150.   {
  1151.     numrows = getTableStructure(table, database);
  1152.     if (!dFlag && numrows > 0)
  1153.       dumpTable(numrows,table);
  1154.   }
  1155.   if (lock_tables)
  1156.     mysql_query(sock,"UNLOCK_TABLES");
  1157.   return 0;
  1158. } /* dump_all_tables_in_db */
  1159. static int dump_selected_tables(char *db, char **table_names, int tables)
  1160. {
  1161.   uint numrows;
  1162.   if (init_dumping(db))
  1163.     return 1;
  1164.   if (lock_tables)
  1165.   {
  1166.     DYNAMIC_STRING query;
  1167.     int i;
  1168.     init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
  1169.     for (i=0 ; i < tables ; i++)
  1170.     {
  1171.       dynstr_append(&query, table_names[i]);
  1172.       dynstr_append(&query, " READ /*!32311 LOCAL */,");
  1173.     }
  1174.     if (mysql_real_query(sock, query.str, query.length-1))
  1175.       DBerror(sock, "when doing LOCK TABLES");
  1176.        /* We shall countinue here, if --force was given */
  1177.     dynstr_free(&query);
  1178.   }
  1179.   if (flush_logs)
  1180.   {
  1181.     if (mysql_refresh(sock, REFRESH_LOG))
  1182.       DBerror(sock, "when doing refresh");
  1183.      /* We shall countinue here, if --force was given */
  1184.   }
  1185.   for (; tables > 0 ; tables-- , table_names++)
  1186.   {
  1187.     numrows = getTableStructure(*table_names, db);
  1188.     if (!dFlag && numrows > 0)
  1189.       dumpTable(numrows, *table_names);
  1190.   }
  1191.   if (lock_tables)
  1192.     mysql_query(sock,"UNLOCK_TABLES");
  1193.   return 0;
  1194. } /* dump_selected_tables */
  1195. /* Print a value with a prefix on file */
  1196. static void print_value(FILE *file, MYSQL_RES  *result, MYSQL_ROW row,
  1197. const char *prefix, const char *name,
  1198. int string_value)
  1199. {
  1200.   MYSQL_FIELD *field;
  1201.   mysql_field_seek(result, 0);
  1202.   for ( ; (field = mysql_fetch_field(result)) ; row++)
  1203.   {
  1204.     if (!strcmp(field->name,name))
  1205.     {
  1206.       if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
  1207.       {
  1208. fputc(' ',file);
  1209. fputs(prefix, file);
  1210. if (string_value)
  1211.   unescape(file,row[0],(uint) strlen(row[0]));
  1212. else
  1213.   fputs(row[0], file);
  1214. return;
  1215.       }
  1216.     }
  1217.   }
  1218.   return; /* This shouldn't happen */
  1219. } /* print_value */
  1220. int main(int argc, char **argv)
  1221. {
  1222.   MY_INIT(argv[0]);
  1223.   /*
  1224.   ** Check out the args
  1225.   */
  1226.   if (get_options(&argc, &argv))
  1227.   {
  1228.     my_end(0);
  1229.     exit(EX_USAGE);
  1230.   }
  1231.   if (dbConnect(current_host, current_user, opt_password))
  1232.     exit(EX_MYSQLERR);
  1233.   if (!path)
  1234.     write_heder(stdout, *argv);
  1235.    if (opt_first_slave)
  1236.    {
  1237.      lock_tables=0; /* No other locks needed */
  1238.      if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK"))
  1239.      {
  1240.        my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s",
  1241.        MYF(0), mysql_error(sock));
  1242.        my_end(0);
  1243.        return(first_error);
  1244.      }
  1245.    }
  1246.   if (opt_alldbs)
  1247.     dump_all_databases();
  1248.   /* Only one database and selected table(s) */
  1249.   else if (argc > 1 && !opt_databases)
  1250.     dump_selected_tables(*argv, (argv + 1), (argc - 1));
  1251.   /* One or more databases, all tables */
  1252.   else
  1253.     dump_databases(argv);
  1254.   if (opt_first_slave)
  1255.   {
  1256.     if (mysql_query(sock, "FLUSH MASTER"))
  1257.     {
  1258.       my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s",
  1259.       MYF(0), mysql_error(sock));
  1260.     }
  1261.     if (mysql_query(sock, "UNLOCK TABLES"))
  1262.     {
  1263.       my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s",
  1264.       MYF(0), mysql_error(sock));
  1265.    }
  1266.   }
  1267.   dbDisconnect(current_host);
  1268.   puts("");
  1269.   my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
  1270.   if (extended_insert)
  1271.     dynstr_free(&extended_row);
  1272.   my_end(0);
  1273.   return(first_error);
  1274. } /* main */