diff mbox

[22/22] mkfs: prevent multiple specifications of a single option

Message ID 1481117249-21273-23-git-send-email-jtulak@redhat.com (mailing list archive)
State Superseded
Headers show

Commit Message

Jan Tulak Dec. 7, 2016, 1:27 p.m. UTC
Because things like -l size=40M,size=50M are clearly wrong and should
not pass. However, in two cases, we do not know if the option is a
string or number - thus the few more lines with can_respec flag.

Signed-off-by: Jan Tulak <jtulak@redhat.com>
---
 mkfs/xfs_mkfs.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Bill O'Donnell Jan. 16, 2017, 2:18 p.m. UTC | #1
On Wed, Dec 07, 2016 at 02:27:29PM +0100, Jan Tulak wrote:
> Because things like -l size=40M,size=50M are clearly wrong and should
> not pass. However, in two cases, we do not know if the option is a
> string or number - thus the few more lines with can_respec flag.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>

Reviewed-by: Bill O'Donnell <billodo@redhat.com>

> ---
>  mkfs/xfs_mkfs.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index cd0eb20..7fe743a 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -432,6 +432,10 @@ test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
>   *     Set to true if, when user specifies the option, she has to specify
>   *     a value too. That is, if needs_val is true, then it is not possible to
>   *     use the subopt as a flag.
> + *
> + *   can_respec OPTIONAL
> + *     If true, then there can come one getnum() after a getstr() call for this
> + *     option.
>   */
>  struct opt_params {
>  	int		index;
> @@ -458,6 +462,7 @@ struct opt_params {
>  		union u_value value;
>  		enum e_type 	type;
>  		bool		needs_val;
> +		bool		can_respec;
>  	}		subopt_params[MAX_SUBOPTS];
>  } opts[MAX_OPTS] = {
>  	{
> @@ -877,6 +882,7 @@ struct opt_params {
>  			  .maxval.i = 2,
>  			  .needs_val = true,
>  			  .type = INT,
> +			  .can_respec = true,
>  			},
>  			{ .index = L_SUNIT,
>  			  .conflicts = { {.opt = OPT_L,
> @@ -1009,6 +1015,7 @@ struct opt_params {
>  			  .maxval.i = 2,
>  			  .needs_val = true,
>  			  .type = INT,
> +			  .can_respec = true,
>  			},
>  			{ .index = N_FTYPE,
>  			  .conflicts = {  {.opt = OPT_M,
> @@ -2017,6 +2024,22 @@ getnum(
>  	struct subopt_param	*sp = &opts->subopt_params[index];
>  	long long		c;
>  
> +	if (sp->seen){
> +		/* If the option has respec flag, it is possible to do ONE
> +		 * getnum call even with sp->seen == 1. Do this by disabling
> +		 * the respec flag - this time we can continue, but if getnum
> +		 * gets called once more, we will fail.
> +		 */
> +		if (sp->can_respec){
> +			sp->can_respec = false;
> +		} else {
> +			fprintf(stderr,
> +			_("You can't use an option multiple times: -%c %s\n"),
> +			  opts->name, opts->subopts[index]);
> +			usage();
> +		}
> +	}
> +
>  	/* empty strings might just return a default value */
>  	if (!str || *str == '\0') {
>  		if (sp->needs_val)
> @@ -2123,6 +2146,12 @@ getstr(
>  	/* empty strings for string options are not valid */
>  	if (!str || *str == '\0')
>  		reqval(opts->name, (char **)opts->subopts, index);
> +	if (opts->subopt_params[index].seen){
> +		fprintf(stderr,
> +		_("You can't use an option multiple times: -%c %s\n"),
> +		  opts->name, opts->subopts[index]);
> +		usage();
> +	}
>  	opts->subopt_params[index].seen = true;
>  	return str;
>  }
> -- 
> 2.8.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index cd0eb20..7fe743a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -432,6 +432,10 @@  test_uvalue_num(enum e_type a_type, union u_value a, long long b) {
  *     Set to true if, when user specifies the option, she has to specify
  *     a value too. That is, if needs_val is true, then it is not possible to
  *     use the subopt as a flag.
+ *
+ *   can_respec OPTIONAL
+ *     If true, then there can come one getnum() after a getstr() call for this
+ *     option.
  */
 struct opt_params {
 	int		index;
@@ -458,6 +462,7 @@  struct opt_params {
 		union u_value value;
 		enum e_type 	type;
 		bool		needs_val;
+		bool		can_respec;
 	}		subopt_params[MAX_SUBOPTS];
 } opts[MAX_OPTS] = {
 	{
@@ -877,6 +882,7 @@  struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = L_SUNIT,
 			  .conflicts = { {.opt = OPT_L,
@@ -1009,6 +1015,7 @@  struct opt_params {
 			  .maxval.i = 2,
 			  .needs_val = true,
 			  .type = INT,
+			  .can_respec = true,
 			},
 			{ .index = N_FTYPE,
 			  .conflicts = {  {.opt = OPT_M,
@@ -2017,6 +2024,22 @@  getnum(
 	struct subopt_param	*sp = &opts->subopt_params[index];
 	long long		c;
 
+	if (sp->seen){
+		/* If the option has respec flag, it is possible to do ONE
+		 * getnum call even with sp->seen == 1. Do this by disabling
+		 * the respec flag - this time we can continue, but if getnum
+		 * gets called once more, we will fail.
+		 */
+		if (sp->can_respec){
+			sp->can_respec = false;
+		} else {
+			fprintf(stderr,
+			_("You can't use an option multiple times: -%c %s\n"),
+			  opts->name, opts->subopts[index]);
+			usage();
+		}
+	}
+
 	/* empty strings might just return a default value */
 	if (!str || *str == '\0') {
 		if (sp->needs_val)
@@ -2123,6 +2146,12 @@  getstr(
 	/* empty strings for string options are not valid */
 	if (!str || *str == '\0')
 		reqval(opts->name, (char **)opts->subopts, index);
+	if (opts->subopt_params[index].seen){
+		fprintf(stderr,
+		_("You can't use an option multiple times: -%c %s\n"),
+		  opts->name, opts->subopts[index]);
+		usage();
+	}
 	opts->subopt_params[index].seen = true;
 	return str;
 }