From 31537b75b74ece069617b255f05d229a00943b28 Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <gnu@gisladisker.se>
Date: Sat, 1 Aug 2015 20:38:55 +0200
Subject: [PATCH 08/60] ifconfig: Apply interface flags correctly.

Changes of interface flags could be suppressed when
an address assignment was requested at the same time.
Suppress also printout when properties are changed.
Reported by Hans-Peter Budek.
---
 ChangeLog          | 29 +++++++++++++++++++++++++++++
 ifconfig/options.c | 27 ++++++++++++++++++++++++---
 ifconfig/options.h |  6 ++----
 3 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2f664b8d..557b7a9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2015-08-01  Mats Erik Andersson  <gnu@gisladisker.se>
+
+	ifconfig: Apply flags correctly.
+	When finalizing actions, some flags could be forgotten.
+	In particular, the flag 'up' was ignored whenever an
+	address was assigned at the same time.  This is related
+	to the fact that an invocation only effecting interface
+	flags, still resulted in a full printout if interface
+	status.  This latter behaviour differs from all other
+	implementations and is rather annoying.  The issue was
+	detected and reported by Hans-Peter Budek in
+	http://lists.gnu.org/archive/html/bug-inetutils/2015-07/msg00000.html
+
+	* ifconfig/options.c (pending_setflags, pending_clrflags):
+	Define as static variables.
+	(pending_valid): New variable.
+	(argp_options) <message 'up'>: Delete the claim that 'up' be
+	a default action together with address.
+	(parse_opt_set_flag): When `ifp' exists, update `ifp->valid'
+	with IF_VALID_FLAGS.  Otherwise, update `pending_valid'.
+	(parse_opt_finalize): If `ifp' exists and `pending_valid` is
+	set, then update `ifp->valid'.  The update of `ifp->setflags'
+	and `ifp->clrflags' is performed independently of assigning
+	an output format, as the latter would cause a printout also
+	when only some flag is being altered.
+	* ifconfig/options.h (IF_VALID_FLAGS): New macro.
+	(IF_VALID_HWADDR): Updated value.
+	(pending_setflags. pending_clrflags): Removed declaration.
+
 2015-07-30  Mats Erik Andersson  <gnu@gisladisker.se>
 
 	ifconfig: A work-around specific to GNU/Hurd.
diff --git a/ifconfig/options.c b/ifconfig/options.c
index 30320622..484f2522 100644
--- a/ifconfig/options.c
+++ b/ifconfig/options.c
@@ -49,8 +49,9 @@ int list_mode;
 int verbose;
 
 /* Flags asked for, possibly still pending application.  */
-int pending_setflags;
-int pending_clrflags;
+static int pending_setflags = 0;
+static int pending_clrflags = 0;
+static int pending_valid = 0;
 
 /* Array of all interfaces on the command line.  */
 struct ifconfig *ifs;
@@ -270,7 +271,7 @@ static struct argp_option argp_options[] = {
   { "format", FORMAT_OPTION, "FORMAT", 0,
     "select output format; set to `help' for info", GRP },
   { "up", UP_OPTION, NULL, 0,
-    "activate the interface (default if address is given)", GRP },
+    "activate the interface", GRP },
   { "down", DOWN_OPTION, NULL, 0,
     "shut the interface down", GRP },
   { "flags", 'F', "FLAG[,FLAG...]", 0,
@@ -381,6 +382,11 @@ void
 parse_opt_set_flag (struct ifconfig *ifp _GL_UNUSED_PARAMETER,
 		    int flag, int rev)
 {
+  if (ifp)
+    ifp->valid |= IF_VALID_FLAGS;
+  else
+    pending_valid |= IF_VALID_FLAGS;
+
   if (rev)
     {
       pending_clrflags |= flag;
@@ -496,12 +502,27 @@ parse_opt_set_default_format_from_file (const char *file)
 void
 parse_opt_finalize (struct ifconfig *ifp)
 {
+  /* The flags `--up' and `--down' are allowed early.  */
+  if (ifp && pending_valid)
+    {
+      ifp->valid |= pending_valid;
+      pending_valid = 0;
+    }
+
+  /* Only the empty set of actions, i.e., only the interface name
+   * is present on the command line, merits printout of status.
+   */
   if (ifp && !ifp->valid)
     {
       ifp->valid = IF_VALID_FORMAT;
       ifp->format = default_format;
+    }
+
+  if (ifp && (pending_setflags | pending_clrflags))
+    {
       ifp->setflags |= pending_setflags;
       ifp->clrflags |= pending_clrflags;
+      pending_setflags = pending_clrflags = 0;
     }
 }
 
diff --git a/ifconfig/options.h b/ifconfig/options.h
index 10528386..b3bfae43 100644
--- a/ifconfig/options.h
+++ b/ifconfig/options.h
@@ -50,9 +50,10 @@ struct ifconfig
   int mtu;
 # define IF_VALID_METRIC	0x100
   int metric;
+# define IF_VALID_FLAGS		0x200
   int setflags;
   int clrflags;
-# define IF_VALID_HWADDR	0x200
+# define IF_VALID_HWADDR	0x400
   char *hwaddr;
 };
 
@@ -67,9 +68,6 @@ extern struct format formats[];
 extern int all_option;
 extern int ifs_cmdline;
 
-extern int pending_setflags;
-extern int pending_clrflags;
-
 /* Array of interfaces mentioned on the command line.  */
 extern struct ifconfig *ifs;
 extern int nifs;
-- 
2.26.0.292.g33ef6b2f38

