Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/userspec.c @ 105:12f81400139d
merge with 3.8.3b
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Wed, 06 Oct 1993 16:44:42 +0000 |
parents | d9ca5dc520bf |
children | c74e20573782 |
rev | line source |
---|---|
5 | 1 /* userspec.c -- Parse a user and group string. |
2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; if not, write to the Free Software | |
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
17 | |
18 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ | |
19 | |
105 | 20 #ifdef HAVE_CONFIG_H |
21 #if defined (CONFIG_BROKETS) | |
22 /* We use <config.h> instead of "config.h" so that a compilation | |
23 using -I. -I will use ./config.h rather than /config.h | |
24 (which it would do because it found this file in ). */ | |
25 #include <config.h> | |
26 #else | |
27 #include "config.h" | |
28 #endif | |
29 #endif | |
30 | |
5 | 31 #include <stdio.h> |
32 #include <sys/types.h> | |
33 #include <pwd.h> | |
34 #include <grp.h> | |
35 | |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
36 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H) |
5 | 37 #include <string.h> |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
38 #ifndef index |
5 | 39 #define index strchr |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
40 #endif |
5 | 41 #else |
42 #include <strings.h> | |
43 #endif | |
44 | |
45 #ifdef STDC_HEADERS | |
46 #include <stdlib.h> | |
47 #else | |
48 char *malloc (); | |
49 #endif | |
50 | |
51 #ifdef HAVE_UNISTD_H | |
52 #include <unistd.h> | |
53 #endif | |
54 | |
55 #ifndef _POSIX_VERSION | |
56 struct passwd *getpwnam (); | |
57 struct group *getgrnam (); | |
58 struct group *getgrgid (); | |
59 #endif | |
60 | |
61 #ifdef _POSIX_SOURCE | |
62 #define endpwent() | |
63 #define endgrent() | |
64 #endif | |
65 | |
66 #define isdigit(c) ((c) >= '0' && (c) <= '9') | |
67 | |
68 char *strdup (); | |
69 static int isnumber (); | |
70 | |
71 /* Extract from NAME, which has the form "[user][:.][group]", | |
72 a USERNAME, UID U, GROUPNAME, and GID G. | |
73 Either user or group, or both, must be present. | |
74 If the group is omitted but the ":" or "." separator is given, | |
75 use the given user's login group. | |
76 | |
77 USERNAME and GROUPNAME will be in newly malloc'd memory. | |
78 Either one might be NULL instead, indicating that it was not | |
79 given and the corresponding numeric ID was left unchanged. | |
80 Might write NULs into NAME. | |
81 | |
82 Return NULL if successful, a static error message string if not. */ | |
83 | |
84 char * | |
85 parse_user_spec (name, uid, gid, username, groupname) | |
86 char *name; | |
87 uid_t *uid; | |
88 gid_t *gid; | |
89 char **username, **groupname; | |
90 { | |
91 static char *tired = "virtual memory exhausted"; | |
92 struct passwd *pwd; | |
93 struct group *grp; | |
94 char *cp; | |
95 int use_login_group = 0; | |
96 | |
97 *username = *groupname = NULL; | |
98 | |
99 /* Check whether a group is given. */ | |
100 cp = index (name, ':'); | |
101 if (cp == NULL) | |
102 cp = index (name, '.'); | |
103 if (cp != NULL) | |
104 { | |
105 *cp++ = '\0'; | |
106 if (*cp == '\0') | |
107 { | |
108 if (cp == name + 1) | |
109 /* Neither user nor group given, just "." or ":". */ | |
110 return "can not omit both user and group"; | |
111 else | |
112 /* "user.". */ | |
113 use_login_group = 1; | |
114 } | |
115 else | |
116 { | |
117 /* Explicit group. */ | |
118 *groupname = strdup (cp); | |
119 if (*groupname == NULL) | |
120 return tired; | |
121 grp = getgrnam (cp); | |
122 if (grp == NULL) | |
123 { | |
124 if (!isnumber (cp)) | |
125 return "invalid group"; | |
126 *gid = atoi (cp); | |
127 } | |
128 else | |
129 *gid = grp->gr_gid; | |
130 endgrent (); /* Save a file descriptor. */ | |
131 } | |
132 } | |
133 | |
134 /* Parse the user name, now that any group has been removed. */ | |
135 | |
136 if (name[0] == '\0') | |
137 /* No user name was given, just a group. */ | |
138 return NULL; | |
139 | |
140 *username = strdup (name); | |
141 if (*username == NULL) | |
142 return tired; | |
143 | |
144 pwd = getpwnam (name); | |
145 if (pwd == NULL) | |
146 { | |
147 if (!isnumber (name)) | |
148 return "invalid user"; | |
149 if (use_login_group) | |
150 return "cannot get the login group of a numeric UID"; | |
151 *uid = atoi (name); | |
152 } | |
153 else | |
154 { | |
155 *uid = pwd->pw_uid; | |
156 if (use_login_group) | |
157 { | |
158 *gid = pwd->pw_gid; | |
159 grp = getgrgid (pwd->pw_gid); | |
160 if (grp == NULL) | |
161 { | |
162 *groupname = malloc (15); | |
163 if (*groupname == NULL) | |
164 return tired; | |
165 sprintf (*groupname, "%u", pwd->pw_gid); | |
166 } | |
167 else | |
168 { | |
169 *groupname = strdup (grp->gr_name); | |
170 if (*groupname == NULL) | |
171 return tired; | |
172 } | |
173 endgrent (); | |
174 } | |
175 } | |
176 endpwent (); | |
177 return NULL; | |
178 } | |
179 | |
180 /* Return nonzero if STR represents an unsigned decimal integer, | |
181 otherwise return 0. */ | |
182 | |
183 static int | |
184 isnumber (str) | |
185 char *str; | |
186 { | |
187 for (; *str; str++) | |
188 if (!isdigit (*str)) | |
189 return 0; | |
190 return 1; | |
191 } |