diff options
author | unknown <Damien@damiendev.> | 2007-03-22 15:55:18 -0400 |
---|---|---|
committer | unknown <Damien@damiendev.> | 2007-03-22 15:55:18 -0400 |
commit | 55e8db7e702136bf0cf1dd601a47b5c1fa45491a (patch) | |
tree | d9ba7917bc3aa3a57c2ced249b2cc036acb3b73e /client | |
parent | bdb9b4483e270fc9d095109ad47615b6b4be62f3 (diff) | |
parent | 1a52767fcad94766e13322fc552c508c89dcb91a (diff) | |
download | mariadb-git-55e8db7e702136bf0cf1dd601a47b5c1fa45491a.tar.gz |
Merge damiendev.:C:/build/mysql-5.0
into damiendev.:C:/build/dev50
Diffstat (limited to 'client')
-rw-r--r-- | client/mysqldump.c | 554 |
1 files changed, 324 insertions, 230 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 94ab9dac5ac..333bfbff1e6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -76,13 +76,13 @@ #define IGNORE_DATA 0x01 /* don't dump data for this table */ #define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */ -static char *add_load_option(char *ptr, const char *object, - const char *statement); +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value); static ulong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, uint *err_len); static char *alloc_query_str(ulong size); -static char *field_escape(char *to,const char *from,uint length); +static void field_escape(DYNAMIC_STRING* in, const char *from); static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0, @@ -121,6 +121,19 @@ FILE *md_result_file= 0; static char *shared_memory_base_name=0; #endif static uint opt_protocol= 0; + +/* +Dynamic_string wrapper functions. In this file use these +wrappers, they will terminate the process if there is +an allocation failure. +*/ +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment); +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src); +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str); +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length); +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size); /* Constant for detection of default value of default_charset. If default_charset is equal to mysql_universal_client_charset, then @@ -419,7 +432,9 @@ static struct my_option my_long_options[] = static const char *load_default_groups[]= { "mysqldump","client",0 }; -static void safe_exit(int error); +static void maybe_exit(int error); +static void die(int error, const char* reason, ...); +static void maybe_die(int error, const char* reason, ...); static void write_header(FILE *sql_file, char *db_name); static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix,const char *name, @@ -474,11 +489,7 @@ static void verbose_msg(const char *fmt, ...) void check_io(FILE *file) { if (ferror(file)) - { - fprintf(stderr, "%s: Got errno %d on write\n", my_progname, errno); - ignore_errors= 0; /* We can't ignore this error */ - safe_exit(EX_EOF); - } + die(EX_EOF, "Got errno %d on write", errno); } static void print_version(void) @@ -864,12 +875,74 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); - fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, + maybe_die(EX_MYSQLERR, "Got error: %d: %s %s", mysql_errno(mysql_arg), mysql_error(mysql_arg), when); - fflush(stderr); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; -} /* DB_error */ +} + + + +/* + Prints out an error message and kills the process. + + SYNOPSIS + die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process. +*/ +static void die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + ignore_errors= 0; /* force the exit */ + maybe_exit(error_num); +} + + +/* + Prints out an error message and maybe kills the process. + + SYNOPSIS + maybe_die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process, unless the --force command line option is used. + + This call should be used for non-fatal errors (such as database + errors) that the code may still be able to continue to the next unit + of work. + +*/ +static void maybe_die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + maybe_exit(error_num); +} + /* @@ -894,10 +967,8 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, if (mysql_query(mysql_con, query) || (res && !((*res)= mysql_store_result(mysql_con)))) { - fprintf(stderr, "%s: Couldn't execute '%s': %s (%d)\n", - my_progname, query, - mysql_error(mysql_con), mysql_errno(mysql_con)); - safe_exit(EX_MYSQLERR); + maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)", + query, mysql_error(mysql_con), mysql_errno(mysql_con)); return 1; } return 0; @@ -942,7 +1013,7 @@ static void free_resources() } -static void safe_exit(int error) +static void maybe_exit(int error) { if (!first_error) first_error= error; @@ -1002,10 +1073,7 @@ static int connect_to_db(char *host, char *user,char *passwd) my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } /* set time_zone to UTC to allow dumping date types between servers with different time zone settings @@ -1014,10 +1082,7 @@ static int connect_to_db(char *host, char *user,char *passwd) { my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } } DBUG_RETURN(0); } /* connect_to_db */ @@ -1038,10 +1103,8 @@ static void unescape(FILE *file,char *pos,uint length) char *tmp; DBUG_ENTER("unescape"); if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME)))) - { - ignore_errors=0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate memory"); + mysql_real_escape_string(&mysql_connection, tmp, pos, length); fputc('\'', file); fputs(tmp, file); @@ -1350,7 +1413,7 @@ static void print_blob_as_hex(FILE *output_file, const char *str, ulong len) /* dump_routines_for_db - -- retrievs list of routines for a given db, and prints out + -- retrieves list of routines for a given db, and prints out the CREATE PROCEDURE definition into the output (the dump). This function has logic to print the appropriate syntax depending on whether @@ -1545,11 +1608,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (!insert_pat_inited) { insert_pat_inited= 1; - if (init_dynamic_string(&insert_pat, "", 1024, 1024)) - safe_exit(EX_MYSQLERR); + init_dynamic_string_checked(&insert_pat, "", 1024, 1024); } else - dynstr_set(&insert_pat, ""); + dynstr_set_checked(&insert_pat, ""); } insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : @@ -1581,18 +1643,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(buff, sizeof(buff), "show create table %s", result_table); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } + write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1656,7 +1713,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } else @@ -1719,7 +1775,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1731,19 +1786,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, */ if (write_data) { - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, opt_quoted_table); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, opt_quoted_table); if (complete_insert) { - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, " ("); } else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1753,10 +1808,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (init) { - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; - dynstr_append(&insert_pat, + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); } } @@ -1771,10 +1826,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); if (mysql_query_with_error_report(mysql, &result, query_buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } /* Make an sql-file, if path was given iow. option -T was given */ if (!opt_no_create_info) @@ -1782,10 +1834,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1803,17 +1852,17 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (write_data) { - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, result_table); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, result_table); if (opt_complete_insert) - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, " ("); else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1828,11 +1877,11 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } if (complete_insert) - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; if (opt_complete_insert) - dynstr_append(&insert_pat, + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); if (!opt_no_create_info) { @@ -1882,7 +1931,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_progname, result_table, mysql_error(mysql)); if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1992,9 +2040,9 @@ continue_xml: } if (opt_complete_insert) { - dynstr_append_mem(&insert_pat, ") VALUES ", 9); + dynstr_append_checked(&insert_pat, ") VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } if (sql_file != md_result_file) { @@ -2041,7 +2089,6 @@ static void dump_triggers_for_table(char *table, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; } if (mysql_num_rows(result)) @@ -2100,24 +2147,28 @@ DELIMITER ;;\n"); DBUG_VOID_RETURN; } -static char *add_load_option(char *ptr,const char *object, - const char *statement) +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value) { - if (object) + if (!option_value) { - /* Don't escape hex constants */ - if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X')) - ptr= strxmov(ptr," ",statement," ",object,NullS); - else - { - /* char constant; escape */ - ptr= strxmov(ptr," ",statement," '",NullS); - ptr= field_escape(ptr,object,(uint) strlen(object)); - *ptr++= '\''; - } + /* Null value means we don't add this option. */ + return; + } + + dynstr_append_checked(str, option); + + if (strncmp(option_value, "0x", sizeof("0x")-1) == 0) + { + /* It's a hex constant, don't escape */ + dynstr_append_checked(str, option_value); } - return ptr; -} /* add_load_option */ + else + { + /* char constant; escape */ + field_escape(str, option_value); + } +} /* @@ -2127,28 +2178,36 @@ static char *add_load_option(char *ptr,const char *object, syntax errors from the SQL parser. */ -static char *field_escape(char *to,const char *from,uint length) +static void field_escape(DYNAMIC_STRING* in, const char *from) { - const char *end; - uint end_backslashes=0; + uint end_backslashes= 0; - for (end= from+length; from != end; from++) + dynstr_append_checked(in, "'"); + + while (*from) { - *to++= *from; + dynstr_append_mem_checked(in, from, 1); + if (*from == '\\') end_backslashes^=1; /* find odd number of backslashes */ else { if (*from == '\'' && !end_backslashes) - *to++= *from; /* We want a duplicate of "'" for MySQL */ + { + /* We want a duplicate of "'" for MySQL */ + dynstr_append_checked(in, "\'"); + } end_backslashes=0; } + from++; } /* Add missing backslashes if user has specified odd number of backs.*/ if (end_backslashes) - *to++= '\\'; - return to; -} /* field_escape */ + dynstr_append_checked(in, "\\"); + + dynstr_append_checked(in, "'"); +} + static char *alloc_query_str(ulong size) @@ -2156,10 +2215,8 @@ static char *alloc_query_str(ulong size) char *query; if (!(query= (char*) my_malloc(size, MYF(MY_WME)))) - { - ignore_errors= 0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate a query string."); + return query; } @@ -2179,13 +2236,14 @@ static char *alloc_query_str(ulong size) void */ + static void dump_table(char *table, char *db) { char ignore_flag; - char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char buf[200], table_buff[NAME_LEN+3]; + DYNAMIC_STRING query_string; char table_type[NAME_LEN]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; - char *query= query_buf; int error= 0; ulong rownr, row_break, total_length, init_length; uint num_fields; @@ -2239,44 +2297,69 @@ static void dump_table(char *table, char *db) opt_quoted_table= quote_name(table, table_buff2, 0); verbose_msg("-- Sending SELECT query...\n"); + + init_dynamic_string_checked(&query_string, "", 1024, 1024); + if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - convert_dirname(tmp_path,path,NullS); + + if (strlen(path) >= FN_REFLEN) + { + /* + This check is made because the some the file functions below + have FN_REFLEN sized stack allocated buffers and will cause + a crash even if the input destination buffer is large enough + to hold the output. + */ + die(EX_USAGE, "Input filename or options too long: %s", path); + } + + /* + Convert the path to native os format + and resolve to the full filepath. + */ + convert_dirname(tmp_path,path,NullS); my_load_path(tmp_path, tmp_path, NULL); - fn_format(filename, table, tmp_path, ".txt", 4); - my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if - filename wasn't deleted */ + fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME)); + + /* Must delete the file that 'INTO OUTFILE' will write to */ + my_delete(filename, MYF(0)); + + /* convert to a unix path name to stick into the query */ to_unix_path(filename); - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'", - filename); - end= strend(query); + + /* now build the query string */ + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); + dynstr_append_checked(&query_string, filename); + dynstr_append_checked(&query_string, "'"); if (fields_terminated || enclosed || opt_enclosed || escaped) - end= strmov(end, " FIELDS"); - end= add_load_option(end, fields_terminated, " TERMINATED BY"); - end= add_load_option(end, enclosed, " ENCLOSED BY"); - end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY"); - end= add_load_option(end, escaped, " ESCAPED BY"); - end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); - *end= '\0'; - - my_snprintf(buff, sizeof(buff), " FROM %s", result_table); - end= strmov(end,buff); - if (where || order_by) - { - query= alloc_query_str((ulong) ((end - query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); - - if (where) - end= strxmov(end, " WHERE ", where, NullS); - if (order_by) - end= strxmov(end, " ORDER BY ", order_by, NullS); - } - if (mysql_real_query(mysql, query, (uint) (end - query))) + dynstr_append_checked(&query_string, " FIELDS"); + + add_load_option(&query_string, " TERMINATED BY ", fields_terminated); + add_load_option(&query_string, " ENCLOSED BY ", enclosed); + add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed); + add_load_option(&query_string, " ESCAPED BY ", escaped); + add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated); + + dynstr_append_checked(&query_string, " FROM "); + dynstr_append_checked(&query_string, result_table); + + if (where) + { + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); + } + + if (order_by) + { + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); + } + + if (mysql_real_query(mysql, query_string.str, query_string.length)) { DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); DBUG_VOID_RETURN; @@ -2290,41 +2373,38 @@ static void dump_table(char *table, char *db) result_table); check_io(md_result_file); } - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s", - result_table); - if (where || order_by) - { - query= alloc_query_str((ulong) (strlen(query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); + dynstr_append_checked(&query_string, result_table); - if (where) + if (where) + { + if (!opt_xml && opt_comments) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- WHERE: %s\n", where); - check_io(md_result_file); - } - end= strxmov(end, " WHERE ", where, NullS); + fprintf(md_result_file, "-- WHERE: %s\n", where); + check_io(md_result_file); } - if (order_by) + + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); + } + if (order_by) + { + if (!opt_xml && opt_comments) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); - check_io(md_result_file); - } - end= strxmov(end, " ORDER BY ", order_by, NullS); + fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); + check_io(md_result_file); } + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); } + if (!opt_xml && !opt_compact) { fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query_with_error_report(mysql, 0, query)) + if (mysql_query_with_error_report(mysql, 0, query_string.str)) { DB_error(mysql, "when retrieving data from server"); goto err; @@ -2398,14 +2478,9 @@ static void dump_table(char *table, char *db) ulong length= lengths[i]; if (!(field= mysql_fetch_field(res))) - { - my_snprintf(query, QUERY_LENGTH, - "%s: Not enough fields from table %s! Aborting.\n", - my_progname, result_table); - fputs(query,stderr); - error= EX_CONSCHECK; - goto err; - } + die(EX_CONSCHECK, + "Not enough fields from table %s! Aborting.\n", + result_table); /* 63 is my_charset_bin. If charsetnr is not 63, @@ -2424,9 +2499,9 @@ static void dump_table(char *table, char *db) if (extended_insert && !opt_xml) { if (i == 0) - dynstr_set(&extended_row,"("); + dynstr_set_checked(&extended_row,"("); else - dynstr_append(&extended_row,","); + dynstr_append_checked(&extended_row,","); if (row[i]) { @@ -2441,15 +2516,10 @@ static void dump_table(char *table, char *db) - In non-HEX mode we need up to 2 bytes per character, plus 2 bytes for leading and trailing '\'' characters. */ - if (dynstr_realloc(&extended_row,length * 2+2)) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; - } + dynstr_realloc_checked(&extended_row,length * 2+2); if (opt_hex_blob && is_blob) { - dynstr_append(&extended_row, "0x"); + dynstr_append_checked(&extended_row, "0x"); extended_row.length+= mysql_hex_string(extended_row.str + extended_row.length, row[i], length); @@ -2457,13 +2527,13 @@ static void dump_table(char *table, char *db) } else { - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); extended_row.length += mysql_real_escape_string(&mysql_connection, &extended_row.str[extended_row.length], row[i],length); extended_row.str[extended_row.length]='\0'; - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); } } else @@ -2472,30 +2542,26 @@ static void dump_table(char *table, char *db) char *ptr= row[i]; if (my_isalpha(charset_info, *ptr) || (*ptr == '-' && my_isalpha(charset_info, ptr[1]))) - dynstr_append(&extended_row, "NULL"); + dynstr_append_checked(&extended_row, "NULL"); else { if (field->type == FIELD_TYPE_DECIMAL) { /* add " signs around */ - dynstr_append(&extended_row, "'"); - dynstr_append(&extended_row, ptr); - dynstr_append(&extended_row, "'"); + dynstr_append_checked(&extended_row, "'"); + dynstr_append_checked(&extended_row, ptr); + dynstr_append_checked(&extended_row, "'"); } else - dynstr_append(&extended_row, ptr); + dynstr_append_checked(&extended_row, ptr); } } } else - dynstr_append(&extended_row,"''"); - } - else if (dynstr_append(&extended_row,"NULL")) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; + dynstr_append_checked(&extended_row,"''"); } + else + dynstr_append_checked(&extended_row,"NULL"); } else { @@ -2512,16 +2578,16 @@ static void dump_table(char *table, char *db) { if (opt_hex_blob && is_blob && length) { - /* Define xsi:type="xs:hexBinary" for hex encoded data */ - print_xml_tag(md_result_file, "\t\t", "", "field", "name=", - field->name, "xsi:type=", "xs:hexBinary", NullS); - print_blob_as_hex(md_result_file, row[i], length); + /* Define xsi:type="xs:hexBinary" for hex encoded data */ + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, "xsi:type=", "xs:hexBinary", NullS); + print_blob_as_hex(md_result_file, row[i], length); } else { - print_xml_tag(md_result_file, "\t\t", "", "field", "name=", - field->name, NullS); - print_quoted_xml(md_result_file, row[i], length); + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, NullS); + print_quoted_xml(md_result_file, row[i], length); } fputs("</field>\n", md_result_file); } @@ -2581,7 +2647,7 @@ static void dump_table(char *table, char *db) if (extended_insert) { ulong row_length; - dynstr_append(&extended_row,")"); + dynstr_append_checked(&extended_row,")"); row_length= 2 + extended_row.length; if (total_length + row_length < opt_net_buffer_length) { @@ -2617,14 +2683,14 @@ static void dump_table(char *table, char *db) check_io(md_result_file); if (mysql_errno(mysql)) { - my_snprintf(query, QUERY_LENGTH, + my_snprintf(buf, sizeof(buf), "%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, mysql_errno(mysql), mysql_error(mysql), result_table, rownr); - fputs(query,stderr); + fputs(buf,stderr); error= EX_CONSCHECK; goto err; } @@ -2647,15 +2713,13 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } mysql_free_result(res); - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + dynstr_free(&query_string); } DBUG_VOID_RETURN; err: - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(error); + dynstr_free(&query_string); + maybe_exit(error); DBUG_VOID_RETURN; } /* dump_table */ @@ -2842,8 +2906,8 @@ static int init_dumping(char *database, int init_func(char*)) check_io(md_result_file); } } - if (extended_insert && init_dynamic_string(&extended_row, "", 1024, 1024)) - exit(EX_EOM); + if (extended_insert) + init_dynamic_string_checked(&extended_row, "", 1024, 1024); return 0; } /* init_dumping */ @@ -2876,11 +2940,11 @@ static int dump_all_tables_in_db(char *database) if (lock_tables) { DYNAMIC_STRING query; - init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024); for (numrows= 0 ; (table= getTableName(1)) ; numrows++) { - dynstr_append(&query, quote_name(table, table_buff, 1)); - dynstr_append(&query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&query, quote_name(table, table_buff, 1)); + dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(mysql, query.str, query.length-1)) DB_error(mysql, "when using LOCK TABLES"); @@ -2953,11 +3017,11 @@ static my_bool dump_all_views_in_db(char *database) if (lock_tables) { DYNAMIC_STRING query; - init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024); for (numrows= 0 ; (table= getTableName(1)); numrows++) { - dynstr_append(&query, quote_name(table, table_buff, 1)); - dynstr_append(&query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&query, quote_name(table, table_buff, 1)); + dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(mysql, query.str, query.length-1)) DB_error(mysql, "when using LOCK TABLES"); @@ -3009,9 +3073,7 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) quote_for_like(old_table_name, show_name_buff)); if (mysql_query_with_error_report(mysql, 0, query)) - { - safe_exit(EX_MYSQLERR); - } + return NullS; if ((table_res= mysql_store_result(mysql))) { @@ -3047,9 +3109,9 @@ static int dump_selected_tables(char *db, char **table_names, int tables) init_alloc_root(&root, 8192, 0); if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *)))) - exit(EX_EOM); + die(EX_EOM, "alloc_root failure."); - init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024); for (; tables > 0 ; tables-- , table_names++) { /* the table name passed on commandline may be wrong case */ @@ -3058,16 +3120,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) /* Add found table name to lock_tables_query */ if (lock_tables) { - dynstr_append(&lock_tables_query, quote_name(*pos, table_buff, 1)); - dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1)); + dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,"); } pos++; } else { - my_printf_error(0,"Couldn't find table: \"%s\"\n", MYF(0), - *table_names); - safe_exit(EX_ILLEGAL_TABLE); + maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); /* We shall countinue here, if --force was given */ } } @@ -3482,12 +3542,12 @@ static int replace(DYNAMIC_STRING *ds_str, const char *start= strstr(ds_str->str, search_str); if (!start) return 1; - init_dynamic_string(&ds_tmp, "", + init_dynamic_string_checked(&ds_tmp, "", ds_str->length + replace_len, 256); - dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str); - dynstr_append_mem(&ds_tmp, replace_str, replace_len); - dynstr_append(&ds_tmp, start + search_len); - dynstr_set(ds_str, ds_tmp.str); + dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str); + dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len); + dynstr_append_checked(&ds_tmp, start + search_len); + dynstr_set_checked(ds_str, ds_tmp.str); dynstr_free(&ds_tmp); return 0; } @@ -3533,10 +3593,7 @@ static my_bool get_view_structure(char *table, char* db) my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table); if (mysql_query_with_error_report(mysql, &table_res, query)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } /* Check if this is a view */ field= mysql_fetch_field_direct(table_res, 0); @@ -3550,10 +3607,8 @@ static my_bool get_view_structure(char *table, char* db) if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } + write_header(sql_file, db); } @@ -3599,14 +3654,14 @@ static my_bool get_view_structure(char *table, char* db) /* Save the result of SHOW CREATE TABLE in ds_view */ row= mysql_fetch_row(table_res); lengths= mysql_fetch_lengths(table_res); - init_dynamic_string(&ds_view, row[1], lengths[1] + 1, 1024); + init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024); mysql_free_result(table_res); /* Get the result from "select ... information_schema" */ if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { - safe_exit(EX_MYSQLERR); + DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view."); DBUG_RETURN(1); } @@ -3678,6 +3733,45 @@ static my_bool get_view_structure(char *table, char* db) DBUG_RETURN(0); } +/* + The following functions are wrappers for the dynamic string functions + and if they fail, the wrappers will terminate the current process. +*/ + +#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation" + +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment) +{ + if (init_dynamic_string(str, init_str, init_alloc, alloc_increment)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src) +{ + if (dynstr_append(dest, src)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str) +{ + if (dynstr_set(str, init_str)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length) +{ + if (dynstr_append_mem(str, append, length)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size) +{ + if (dynstr_realloc(str, additional_size)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + int main(int argc, char **argv) { |