From a146e7be893446521362d60d302d50dfe1001f13 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Tue, 17 Apr 2012 18:37:42 -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 018cfdc1506..09d505f2f78 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2644,8 +2644,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 f4c317ae149..624886e5c9e 100644 --- a/src/bin/scripts/clusterdb.c +++ b/src/bin/scripts/clusterdb.c @@ -106,18 +106,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 c2153db630e..a98fad5918e 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 7fadee0d513..22237dff4a1 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 53fff01a74b..f9272fecc39 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -116,17 +116,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 7457e6d3046..a93541e06ff 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -129,18 +129,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) -- 2.39.5