.
[gnulib.git] / lib / userspec.c
index f00308d..67bde65 100644 (file)
@@ -40,6 +40,14 @@ char *alloca ();
 #include <pwd.h>
 #include <grp.h>
 
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
 #if HAVE_STRING_H
 # include <string.h>
 #else
@@ -57,6 +65,9 @@ char *alloca ();
 # include <unistd.h>
 #endif
 
+#include "xalloc.h"
+#include "xstrtol.h"
+
 #if ENABLE_NLS
 # include <libintl.h>
 # define _(Text) gettext (Text)
@@ -79,6 +90,34 @@ struct group *getgrgid ();
 # define endpwent() ((void) 0)
 #endif
 
+#ifndef CHAR_BIT
+# define CHAR_BIT 8
+#endif
+
+/* The extra casts work around common compiler bugs.  */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
+   It is necessary at least when t == time_t.  */
+#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
+                             ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
+#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
+
+#ifndef UID_T_MAX
+# define UID_T_MAX TYPE_MAXIMUM (uid_t)
+#endif
+
+#ifndef GID_T_MAX
+# define GID_T_MAX TYPE_MAXIMUM (gid_t)
+#endif
+
+/* MAXUID may come from limits.h or sys/params.h.  */
+#ifndef MAXUID
+# define MAXUID UID_T_MAX
+#endif
+#ifndef MAXGID
+# define MAXGID GID_T_MAX
+#endif
+
 /* Perform the equivalent of the statement `dest = strdup (src);',
    but obtaining storage via alloca instead of from the heap.  */
 
@@ -137,7 +176,6 @@ const char *
 parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
                 char **username_arg, char **groupname_arg)
 {
-  static const char *E_no_memory = N_("virtual memory exhausted");
   static const char *E_invalid_user = N_("invalid user");
   static const char *E_invalid_group = N_("invalid group");
   static const char *E_bad_spec =
@@ -210,17 +248,21 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
        {
 
          if (!is_number (u))
-           error_msg = _(E_invalid_user);
+           error_msg = E_invalid_user;
          else
            {
              int use_login_group;
              use_login_group = (separator != NULL && g == NULL);
              if (use_login_group)
-               error_msg = _(E_bad_spec);
+               error_msg = E_bad_spec;
              else
                {
-                 /* FIXME: don't use atoi!  */
-                 *uid = atoi (u);
+                 unsigned long int tmp_long;
+                 if (xstrtoul (u, NULL, 0, &tmp_long, NULL) != LONGINT_OK
+                     || tmp_long > MAXUID)
+                   return _(E_invalid_user);
+                 printf ("MAXUID: %u\n", (uid_t) MAXUID);
+                 *uid = tmp_long;
                }
            }
        }
@@ -259,11 +301,14 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
       if (grp == NULL)
        {
          if (!is_number (g))
-           error_msg = _(E_invalid_group);
+           error_msg = E_invalid_group;
          else
            {
-             /* FIXME: don't use atoi!  */
-             *gid = atoi (g);
+             unsigned long int tmp_long;
+             if (xstrtoul (u, NULL, 0, &tmp_long, NULL) != LONGINT_OK
+                 || tmp_long > MAXGID)
+               return _(E_invalid_group);
+             *gid = tmp_long;
            }
        }
       else
@@ -280,7 +325,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
        {
          *username_arg = strdup (u);
          if (*username_arg == NULL)
-           error_msg = _(E_no_memory);
+           error_msg = xalloc_msg_memory_exhausted;
        }
 
       if (groupname != NULL && error_msg == NULL)
@@ -293,7 +338,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
                  free (*username_arg);
                  *username_arg = NULL;
                }
-             error_msg = _(E_no_memory);
+             error_msg = xalloc_msg_memory_exhausted;
            }
        }
     }
@@ -306,7 +351,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
       goto retry;
     }
 
-  return error_msg;
+  return _(error_msg);
 }
 
 #ifdef TEST