From 1b37a8c3cc4f0615f80d6007e2bbd47c6bd7e1e3 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Tue, 17 Apr 2012 18:30:34 -0400 Subject: [PATCH] Don't override arguments set via options with positional arguments. A number of utility programs were rather careless about paremeters that can be set via both an option argument and a positional argument. This leads to results which can violate the Principal Of Least Astonishment. These changes refuse to use positional arguments to override settings that have been made via positional arguments. The changes are backpatched to all live branches. --- src/bin/initdb/initdb.c | 7 +++++-- src/bin/scripts/clusterdb.c | 26 +++++++++++++++----------- src/bin/scripts/createlang.c | 14 ++++++++++++-- src/bin/scripts/droplang.c | 14 ++++++++++++-- src/bin/scripts/reindexdb.c | 25 +++++++++++++++---------- src/bin/scripts/vacuumdb.c | 27 ++++++++++++++++----------- 6 files changed, 75 insertions(+), 38 deletions(-) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 87a9c95430..303b0cf756 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2760,8 +2760,11 @@ main(int argc, char *argv[]) } - /* Non-option argument specifies data directory */ - if (optind < argc) + /* + * Non-option argument specifies data directory + * as long as it wasn't already specified with -D / --pgdata + */ + if (optind < argc && strlen(pg_data) == 0) { pg_data = xstrdup(argv[optind]); optind++; diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c index b01f91c1d6..0f711e870b 100644 --- a/src/bin/scripts/clusterdb.c +++ b/src/bin/scripts/clusterdb.c @@ -112,18 +112,22 @@ main(int argc, char *argv[]) } } - switch (argc - optind) + /* + * Non-option argument specifies database name + * as long as it wasn't already specified with -d / --dbname + */ + if (optind < argc && dbname == NULL) { - case 0: - break; - case 1: - dbname = argv[optind]; - break; - default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 1]); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + dbname = argv[optind]; + optind++; + } + + if (optind < argc) + { + fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), + progname, argv[optind + 1]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); } setup_cancel_handler(); diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c index c8b927c675..cc671a4976 100644 --- a/src/bin/scripts/createlang.c +++ b/src/bin/scripts/createlang.c @@ -91,14 +91,24 @@ main(int argc, char *argv[]) } } + /* + * We set dbname from positional arguments if it is not + * already set by option arguments -d. If not doing + * listlangs, positional dbname must follow positional + * langname. + */ + if (argc - optind > 0) { if (listlangs) - dbname = argv[optind++]; + { + if (dbname == NULL) + dbname = argv[optind++]; + } else { langname = argv[optind++]; - if (argc - optind > 0) + if (argc - optind > 0 && dbname == NULL) dbname = argv[optind++]; } } diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c index 66bc9664a5..47ec37f5e9 100644 --- a/src/bin/scripts/droplang.c +++ b/src/bin/scripts/droplang.c @@ -90,14 +90,24 @@ main(int argc, char *argv[]) } } + /* + * We set dbname from positional arguments if it is not + * already set by option arguments -d. If not doing + * listlangs, positional dbname must follow positional + * langname. + */ + if (argc - optind > 0) { if (listlangs) - dbname = argv[optind++]; + { + if (dbname == NULL) + dbname = argv[optind++]; + } else { langname = argv[optind++]; - if (argc - optind > 0) + if (argc - optind > 0 && dbname == NULL) dbname = argv[optind++]; } } diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c index 54b478db60..614a6885a0 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -122,17 +122,22 @@ main(int argc, char *argv[]) } } - switch (argc - optind) + /* + * Non-option argument specifies database name + * as long as it wasn't already specified with -d / --dbname + */ + if (optind < argc && dbname == NULL) { - case 0: - break; - case 1: - dbname = argv[optind]; - break; - default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind + 1]); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + dbname = argv[optind]; + optind++; + } + + if (optind < argc) + { + fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), + progname, argv[optind + 1]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); } setup_cancel_handler(); diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 1698c5f630..fe303ad885 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -135,18 +135,23 @@ main(int argc, char *argv[]) } } - switch (argc - optind) + + /* + * Non-option argument specifies database name + * as long as it wasn't already specified with -d / --dbname + */ + if (optind < argc && dbname == NULL) { - case 0: - break; - case 1: - dbname = argv[optind]; - break; - default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 1]); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); + dbname = argv[optind]; + optind++; + } + + if (optind < argc) + { + fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), + progname, argv[optind + 1]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); } if (analyze_only)