Merge from coreutils.
[gnulib.git] / lib / userspec.c
index 27b687d..8cf6239 100644 (file)
@@ -1,5 +1,6 @@
 /* userspec.c -- Parse a user and group string.
-   Copyright (C) 1989-1992, 1997, 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1989-1992, 1997-1998, 2000, 2002-2004 Free Software
+   Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 # include <config.h>
 #endif
 
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-#  include <alloca.h>
-# else
-#  ifdef _AIX
- #  pragma alloca
-#  else
-char *alloca ();
-#  endif
-# endif
-#endif
+#include <alloca.h>
+
+/* Specification.  */
+#include "userspec.h"
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -44,37 +36,22 @@ char *alloca ();
 # include <sys/param.h>
 #endif
 
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#if HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-# ifndef strchr
-#  define strchr index
-# endif
-#endif
-
-#if STDC_HEADERS
-# include <stdlib.h>
-#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
 
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif
 
+#include "strdup.h"
+#include "posixver.h"
 #include "xalloc.h"
 #include "xstrtol.h"
 
-#if ENABLE_NLS
-# include <libintl.h>
-# define _(Text) gettext (Text)
-#else
-# define _(Text) Text
-#endif
-#define N_(Text) Text
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
 
 #ifndef _POSIX_VERSION
 struct passwd *getpwnam ();
@@ -90,10 +67,6 @@ 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.
@@ -134,16 +107,11 @@ struct group *getgrgid ();
    - Its arg may be any int or unsigned int; it need not be an unsigned char.
    - It's guaranteed to evaluate its argument exactly once.
    - It's typically faster.
-   Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
-   only '0' through '9' are digits.  Prefer ISDIGIT to isdigit unless
-   it's important to use the locale's definition of `digit' even when the
-   host does not conform to Posix.  */
+   POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to
+   ISDIGIT_LOCALE unless it's important to use the locale's definition
+   of `digit' even when the host does not conform to POSIX.  */
 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
 
-#ifndef strdup
-char *strdup ();
-#endif
-
 /* Return nonzero if STR represents an unsigned decimal integer,
    otherwise return 0. */
 
@@ -163,8 +131,8 @@ is_number (const char *str)
    use the given user's login group.
    If SPEC_ARG contains a `:', then use that as the separator, ignoring
    any `.'s.  If there is no `:', but there is a `.', then first look
-   up SPEC_ARG as a login name.  If that look-up fails, then try again
-   interpreting the `.'  as a separator.
+   up the entire SPEC_ARG as a login name.  If that look-up fails, then
+   try again interpreting the `.'  as a separator.
 
    USERNAME and GROUPNAME will be in newly malloc'd memory.
    Either one might be NULL instead, indicating that it was not
@@ -202,7 +170,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
   separator = strchr (spec, ':');
 
   /* If there is no colon, then see if there's a `.'.  */
-  if (separator == NULL)
+  if (separator == NULL && posix2_version () < 200112)
     {
       dot = strchr (spec, '.');
       /* If there's no colon but there is a `.', then first look up the
@@ -304,7 +272,7 @@ parse_user_spec (const char *spec_arg, uid_t *uid, gid_t *gid,
          else
            {
              unsigned long int tmp_long;
-             if (xstrtoul (u, NULL, 0, &tmp_long, NULL) != LONGINT_OK
+             if (xstrtoul (g, NULL, 0, &tmp_long, NULL) != LONGINT_OK
                  || tmp_long > MAXGID)
                return _(E_invalid_group);
              *gid = tmp_long;