diff options
author | Sergei Golubchik <sergii@pisem.net> | 2014-02-01 00:54:03 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2014-02-01 00:54:03 +0100 |
commit | 59d9d08e2b6f6f35e781d24c47d33d26fb4ba2a5 (patch) | |
tree | 3e4a302ccf3912d4d8a40aa271414003bfe7c9b6 /sql/tztime.cc | |
parent | ce02738d7f2f2688eeec7004dd6a30293d36044f (diff) | |
parent | 6b6d40fa6ca1fe36f2a51c2723c58dfb3fc025bb (diff) | |
download | mariadb-git-59d9d08e2b6f6f35e781d24c47d33d26fb4ba2a5.tar.gz |
5.5 merge
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 192 |
1 files changed, 154 insertions, 38 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 0a574fb7688..3e79f1bc39e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -41,6 +41,8 @@ #include <my_time.h> #include "tztime.h" #include <my_sys.h> +#include <mysql_version.h> +#include <my_getopt.h> #endif #include "tzfile.h" @@ -63,6 +65,8 @@ #endif /* !defined(DBUG_OFF) */ #endif /* defined(TZINFO2SQL) || defined(TESTTIME) */ +#define PROGRAM_VERSION "1.1" + /* Structure describing local time type (e.g. Moscow summer time (MSD)) */ typedef struct ttinfo { @@ -2386,7 +2390,6 @@ void Time_zone::adjust_leap_second(MYSQL_TIME *t) tables. */ - /* Print info about time zone described by TIME_ZONE_INFO struct as SQL statements populating mysql.time_zone* tables. @@ -2471,6 +2474,15 @@ MEM_ROOT tz_storage; char fullname[FN_REFLEN + 1]; char *root_name_end; +/* + known file types that exist in the zoneinfo directory that are safe to + silently skip +*/ +const char *known_extensions[]= { + ".tab", + NullS +}; + /* Recursively scan zoneinfo directory and print all found time zone @@ -2479,6 +2491,8 @@ char *root_name_end; SYNOPSIS scan_tz_dir() name_end - pointer to end of path to directory to be searched. + symlink_recursion_level How many symlink directory levels are used + verbose >0 if we should print warnings DESCRIPTION This auxiliary recursive function also uses several global @@ -2494,7 +2508,7 @@ char *root_name_end; */ my_bool -scan_tz_dir(char * name_end, uint symlink_recursion_level) +scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose) { MY_DIR *cur_dir; char *name_end_tmp; @@ -2535,12 +2549,21 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level) following such symlinks infinitely: /usr/share/zoneinfo/posix/posix/posix/.../posix/ */ - fflush(stdout); - fprintf(stderr, "Warning: Skipping directory '%s': " - "to avoid infinite symlink recursion.\n", fullname); + + /* + This is a normal case and not critical. only print warning if + verbose mode is choosen. + */ + if (verbose > 0) + { + fflush(stdout); + fprintf(stderr, "Warning: Skipping directory '%s': " + "to avoid infinite symlink recursion.\n", fullname); + } continue; } - if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink)) + if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink, + verbose)) { my_dirend(cur_dir); return 1; @@ -2553,10 +2576,28 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level) print_tz_as_sql(root_name_end + 1, &tz_info); else { - fflush(stdout); - fprintf(stderr, - "Warning: Unable to load '%s' as time zone. Skipping it.\n", - fullname); + /* + Some systems (like debian, opensuse etc) have description + files (.tab). We skip these silently if verbose is > 0 + */ + const char *current_ext= fn_ext(fullname); + my_bool known_ext= 0; + + for (const char **ext= known_extensions ; *ext ; ext++) + { + if (!strcmp(*ext, current_ext)) + { + known_ext= 1; + break; + } + } + if (verbose > 0 || !known_ext) + { + fflush(stdout); + fprintf(stderr, + "Warning: Unable to load '%s' as time zone. Skipping it.\n", + fullname); + } } free_root(&tz_storage, MYF(0)); } @@ -2575,34 +2616,114 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level) } +my_bool opt_leap, opt_verbose; + +static const char *load_default_groups[]= +{ "mysql_tzinfo_to_sql", 0}; + +static struct my_option my_long_options[] = +{ + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, +#ifdef DBUG_OFF + {"debug", '#', "This is a non-debug version. Catch this and exit", + 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#else + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"leap", 'l', "Print the leap second information from the given time zone file. By convention, when --leap is used the next argument is the timezonefile", + &opt_leap, &opt_leap, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Write non critical warnings", + &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + +C_MODE_START +static my_bool get_one_option(int optid, const struct my_option *, + char *argument); +C_MODE_END + +static void print_version(void) +{ + printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname, PROGRAM_VERSION, + MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); +} + +static void print_usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s [options] timezonedir\n", my_progname); + fprintf(stderr, " %s [options] timezonefile timezonename\n", my_progname); + print_defaults("my",load_default_groups); + puts(""); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} + + +static my_bool +get_one_option(int optid, const struct my_option *opt, char *argument) +{ + switch(optid) { + case '#': +#ifndef DBUG_OFF + DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysq_tzinfo_to_sql.trace"); +#endif + break; + case '?': + print_version(); + puts(""); + print_usage(); + exit(0); + case 'V': + print_version(); + exit(0); + } + return 0; +} + + int main(int argc, char **argv) { + char **default_argv; MY_INIT(argv[0]); - if (argc != 2 && argc != 3) + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); + + default_argv= argv; + + if ((handle_options(&argc, &argv, my_long_options, get_one_option))) + exit(1); + + if ((argc != 1 && argc != 2) || (opt_leap && argc != 1)) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s timezonedir\n", argv[0]); - fprintf(stderr, " %s timezonefile timezonename\n", argv[0]); - fprintf(stderr, " %s --leap timezonefile\n", argv[0]); + print_usage(); + free_defaults(default_argv); return 1; } - - if (argc == 2) + if (argc == 1 && !opt_leap) { - root_name_end= strmake_buf(fullname, argv[1]); + /* Argument is timezonedir */ + + root_name_end= strmake_buf(fullname, argv[0]); printf("TRUNCATE TABLE time_zone;\n"); printf("TRUNCATE TABLE time_zone_name;\n"); printf("TRUNCATE TABLE time_zone_transition;\n"); printf("TRUNCATE TABLE time_zone_transition_type;\n"); - if (scan_tz_dir(root_name_end, 0)) + if (scan_tz_dir(root_name_end, 0, opt_verbose)) { fflush(stdout); - fprintf(stderr, "There were fatal errors during processing " - "of zoneinfo directory\n"); + fprintf(stderr, + "There were fatal errors during processing " + "of zoneinfo directory '%s'\n", fullname); return 1; } @@ -2613,32 +2734,27 @@ main(int argc, char **argv) } else { + /* + First argument is timezonefile. + The second is timezonename if opt_leap is not given + */ init_alloc_root(&tz_storage, 32768, 0, MYF(0)); - if (strcmp(argv[1], "--leap") == 0) + if (tz_load(argv[0], &tz_info, &tz_storage)) { - if (tz_load(argv[2], &tz_info, &tz_storage)) - { - fflush(stdout); - fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]); - return 1; - } - print_tz_leaps_as_sql(&tz_info); + fflush(stdout); + fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[0]); + return 1; } + if (opt_leap) + print_tz_leaps_as_sql(&tz_info); else - { - if (tz_load(argv[1], &tz_info, &tz_storage)) - { - fflush(stdout); - fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]); - return 1; - } - print_tz_as_sql(argv[2], &tz_info); - } + print_tz_as_sql(argv[1], &tz_info); free_root(&tz_storage, MYF(0)); } + free_defaults(default_argv); my_end(0); return 0; } |