From cb748f195f3f56a2e5c7db950d7abf633308c071 Mon Sep 17 00:00:00 2001
From: Shreenidhi Shedi <sshedi@vmware.com>
Date: Wed, 1 Sep 2021 23:31:36 +0530
Subject: [PATCH 08/12] Reformat & refactor userspec.c

Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
---
 src/userspec.c | 347 ++++++++++++++++++++++++++-----------------------
 1 file changed, 184 insertions(+), 163 deletions(-)

diff --git a/src/userspec.c b/src/userspec.c
index c1d1ae3..f2526f3 100644
--- a/src/userspec.c
+++ b/src/userspec.c
@@ -1,4 +1,5 @@
-/* userspec.c -- Parse a user and group string.
+/*
+ * userspec.c -- Parse a user and group string.
    Copyright (C) 1989-1992, 2001, 2004-2005, 2007, 2010, 2014-2015,
    2017, 2020-2021 Free Software Foundation, Inc.
 
@@ -15,12 +16,12 @@
    You should have received a copy of the GNU General Public
    License along with this program; if not, write to the Free
    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301 USA.  */
+   Boston, MA 02110-1301 USA.
+ */
 
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
 
 #include <system.h>
-#include <alloca.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <sys/types.h>
@@ -32,17 +33,14 @@
 # define endgrent()
 #endif
 
-/* Perform the equivalent of the statement `dest = strdup (src);',
-   but obtaining storage via alloca instead of from the heap.  */
-
-#define V_STRDUP(dest, src)						\
-  do									\
-    {									\
-      int _len = strlen ((src));					\
-      (dest) = (char *) alloca (_len + 1);				\
-      strcpy (dest, src);						\
-    }									\
-  while (0)
+#define FREE(ptr) \
+    do { \
+        if (ptr) \
+        { \
+            free (ptr); \
+            ptr = NULL; \
+        } \
+    } while (0)
 
 /* Return nonzero if STR represents an unsigned decimal integer,
    otherwise return 0. */
@@ -50,10 +48,10 @@
 static int
 isnumber_p (const char *str)
 {
-  for (; *str; str++)
-    if (!isdigit (*str))
-      return 0;
-  return 1;
+    for (; *str; str++)
+        if (!isdigit (*str))
+            return 0;
+    return 1;
 }
 
 /* Extract from NAME, which has the form "[user][:.][group]",
@@ -66,149 +64,172 @@ isnumber_p (const char *str)
    Either one might be NULL instead, indicating that it was not
    given and the corresponding numeric ID was left unchanged.
 
-   Return NULL if successful, a static error message string if not.  */
+   Return NULL if successful, a static error message string if not. */
 
 const char *
 parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
-		 char **username_arg, char **groupname_arg)
+        char **username_arg, char **groupname_arg)
 {
-  static const char *tired = "virtual memory exhausted";
-  const char *error_msg;
-  char *spec;			/* A copy we can write on.  */
-  struct passwd *pwd;
-  struct group *grp;
-  char *g, *u, *separator;
-  char *groupname;
-
-  error_msg = NULL;
-  *username_arg = *groupname_arg = NULL;
-  groupname = NULL;
-
-  V_STRDUP (spec, spec_arg);
-
-  /* Find the separator if there is one.  */
-  separator = strchr (spec, ':');
-  if (separator == NULL)
-    separator = strchr (spec, '.');
+    char *g = NULL;
+    char *u = NULL;
+    char *spec = NULL;    /* A copy we can write on.  */
+    char *separator = NULL;
+    char *groupname = NULL;
+    struct group *grp = NULL;
+    struct passwd *pwd = NULL;
+    const char *error_msg = NULL;
+    static const char *tired = "virtual memory exhausted";
+
+    *username_arg = NULL;
+    *groupname_arg = NULL;
+
+    spec = strdup (spec_arg);
+    if (spec == NULL)
+    {
+        error_msg = tired;
+        goto finish;
+    }
 
-  /* Replace separator with a NUL.  */
-  if (separator != NULL)
-    *separator = '\0';
+    /* Find the separator if there is one.  */
+    separator = strchr (spec, ':');
+    if (separator == NULL)
+        separator = strchr (spec, '.');
 
-  /* Set U and G to non-zero length strings corresponding to user and
-     group specifiers or to NULL.  */
-  u = (*spec == '\0' ? NULL : spec);
+    /* Replace separator with a NUL.  */
+    if (separator != NULL)
+        *separator = '\0';
 
-  g = (separator == NULL || *(separator + 1) == '\0'
-       ? NULL
-       : separator + 1);
+    /* Set U and G to non-zero length strings corresponding to user and
+       group specifiers or to NULL.  */
+    u = (*spec == '\0' ? NULL : spec);
 
-  if (u == NULL && g == NULL)
-    return "can not omit both user and group";
+    g = (separator == NULL || *(separator + 1) == '\0' ? NULL : separator + 1);
+    if (u == NULL && g == NULL)
+    {
+        error_msg = _("can not omit both user and group");
+        goto finish;
+    }
 
-  if (u != NULL)
+    if (u != NULL)
     {
-      if (*u == '+')
-	{
-	  pwd = NULL;
-	  ++u;
-	}
-      else
-	pwd = getpwnam (u);
-
-      if (pwd == NULL)
-	{
-	  if (!isnumber_p (u))
-	    error_msg = _("invalid user");
-	  else
-	    {
-	      int use_login_group;
-	      use_login_group = (separator != NULL && g == NULL);
-	      if (use_login_group)
-		error_msg = _("cannot get the login group of a numeric UID");
-	      else
-		*uid = atoi (u);
-	    }
-	}
-      else
-	{
-	  *uid = pwd->pw_uid;
-	  if (g == NULL && separator != NULL)
-	    {
-	      /* A separator was given, but a group was not specified,
-	         so get the login group.  */
-	      *gid = pwd->pw_gid;
-	      grp = getgrgid (pwd->pw_gid);
-	      if (grp == NULL)
-		{
-		  /* This is enough room to hold the unsigned decimal
-		     representation of any 32-bit quantity and the trailing
-		     zero byte.  */
-		  char uint_buf[21] = {0};
-		  snprintf (uint_buf, sizeof (uint_buf), "%u", (unsigned int) (pwd->pw_gid));
-		  V_STRDUP (groupname, uint_buf);
-		}
-	      else
-		{
-		  V_STRDUP (groupname, grp->gr_name);
-		}
-	      endgrent ();
-	    }
-	}
-      endpwent ();
+        if (*u == '+')
+        {
+            pwd = NULL;
+            ++u;
+        }
+        else
+        {
+            pwd = getpwnam (u);
+        }
+
+        if (pwd == NULL)
+        {
+            if (!isnumber_p (u))
+            {
+                error_msg = _("invalid user");
+                goto finish;
+            }
+            if (separator != NULL && g == NULL)
+            {
+                error_msg = _("cannot get the login group of a numeric UID");
+                goto finish;
+            }
+            *uid = atoi (u);
+        }
+        else
+        {
+            *uid = pwd->pw_uid;
+            if (g == NULL && separator != NULL)
+            {
+                /* A separator was given, but a group was not specified,
+                   so get the login group.  */
+                *gid = pwd->pw_gid;
+                grp = getgrgid (pwd->pw_gid);
+                if (grp == NULL)
+                {
+                    /* This is enough room to hold the unsigned decimal
+                       representation of any 32-bit quantity and the trailing
+                       zero byte.  */
+                    char uint_buf[21] = {0};
+                    snprintf (uint_buf, sizeof (uint_buf), "%u", (unsigned int) (pwd->pw_gid));
+                    groupname = strdup (uint_buf);
+                    if (groupname == NULL)
+                    {
+                        error_msg = tired;
+                        goto finish;
+                    }
+                }
+                else
+                {
+                    groupname = strdup (grp->gr_name);
+                    if (groupname == NULL)
+                    {
+                        error_msg = tired;
+                        goto finish;
+                    }
+                }
+                endgrent ();
+            }
+        }
+        endpwent ();
     }
 
-  if (g != NULL && error_msg == NULL)
+    if (g != NULL)
     {
-      /* Explicit group.  */
-      if (*g == '+')
-	{
-	  grp = NULL;
-	  ++g;
-	}
-      else
-	grp = getgrnam (g);
-
-      if (grp == NULL)
-	{
-	  if (!isnumber_p (g))
-	    error_msg = _("invalid group");
-	  else
-	    *gid = atoi (g);
-	}
-      else
-	*gid = grp->gr_gid;
-      endgrent ();		/* Save a file descriptor.  */
-
-      if (error_msg == NULL)
-	V_STRDUP (groupname, g);
+        /* Explicit group */
+        if (*g == '+')
+        {
+            grp = NULL;
+            ++g;
+        }
+        else
+        {
+            grp = getgrnam (g);
+        }
+
+        if (grp == NULL)
+        {
+            if (!isnumber_p (g))
+            {
+                error_msg = _("invalid group");
+                goto finish;
+            }
+            *gid = atoi (g);
+        }
+        else
+        {
+            *gid = grp->gr_gid;
+        }
+        endgrent ();    /* Save a file descriptor. */
+
+        groupname = strdup (g);
+        if (groupname == NULL)
+        {
+            error_msg = tired;
+            goto finish;
+        }
     }
 
-  if (error_msg == NULL)
+    if (u != NULL)
     {
-      if (u != NULL)
-	{
-	  *username_arg = strdup (u);
-	  if (*username_arg == NULL)
-	    error_msg = tired;
-	}
-
-      if (groupname != NULL && error_msg == NULL)
-	{
-	  *groupname_arg = strdup (groupname);
-	  if (*groupname_arg == NULL)
-	    {
-	      if (*username_arg != NULL)
-		{
-		  free (*username_arg);
-		  *username_arg = NULL;
-		}
-	      error_msg = tired;
-	    }
-	}
+        *username_arg = strdup (u);
+        if (*username_arg == NULL)
+        {
+            error_msg = tired;
+            goto finish;
+        }
     }
 
-  return error_msg;
+    *groupname_arg = groupname;
+
+finish:
+    if (spec != NULL)
+        FREE (spec);
+
+    if (error_msg != NULL)
+        FREE (groupname);
+
+    return error_msg;
 }
 
 #ifdef TEST
@@ -218,29 +239,29 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
 int
 main (int argc, char **argv)
 {
-  int i;
+    int i;
 
-  for (i = 1; i < argc; i++)
+    for (i = 1; i < argc; i++)
     {
-      const char *e;
-      char *username, *groupname;
-      uid_t uid;
-      gid_t gid;
-      char *tmp;
-
-      tmp = strdup (argv[i]);
-      e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
-      free (tmp);
-      printf ("%s: %u %u %s %s %s\n",
-	      argv[i],
-	      (unsigned int) uid,
-	      (unsigned int) gid,
-	      NULL_CHECK (username),
-	      NULL_CHECK (groupname),
-	      NULL_CHECK (e));
+        const char *e;
+        char *username, *groupname;
+        uid_t uid;
+        gid_t gid;
+        char *tmp;
+
+        tmp = strdup (argv[i]);
+        e = parse_user_spec (tmp, &uid, &gid, &username, &groupname);
+        FREE (tmp);
+        printf ("%s: %u %u %s %s %s\n",
+                argv[i],
+                (unsigned int) uid,
+                (unsigned int) gid,
+                NULL_CHECK (username),
+                NULL_CHECK (groupname),
+                NULL_CHECK (e));
     }
 
-  exit (0);
+    return 0;
 }
 
 #endif
-- 
2.17.1

