Mercurial > hg > octave-lojdl > gnulib-hg
annotate lib/userspec.c @ 52:d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
* userspec.c [index]: Ditto.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Mon, 05 Apr 1993 00:53:40 +0000 |
parents | 41c9d08b09d7 |
children | 12f81400139d |
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 | |
20 #include <stdio.h> | |
21 #include <sys/types.h> | |
22 #include <pwd.h> | |
23 #include <grp.h> | |
24 | |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
25 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H) |
5 | 26 #include <string.h> |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
27 #ifndef index |
5 | 28 #define index strchr |
52
d9ca5dc520bf
* system.h [rindex, incl, bcopy, bzero]: Ditto.
Jim Meyering <jim@meyering.net>
parents:
5
diff
changeset
|
29 #endif |
5 | 30 #else |
31 #include <strings.h> | |
32 #endif | |
33 | |
34 #ifdef STDC_HEADERS | |
35 #include <stdlib.h> | |
36 #else | |
37 char *malloc (); | |
38 #endif | |
39 | |
40 #ifdef HAVE_UNISTD_H | |
41 #include <unistd.h> | |
42 #endif | |
43 | |
44 #ifndef _POSIX_VERSION | |
45 struct passwd *getpwnam (); | |
46 struct group *getgrnam (); | |
47 struct group *getgrgid (); | |
48 #endif | |
49 | |
50 #ifdef _POSIX_SOURCE | |
51 #define endpwent() | |
52 #define endgrent() | |
53 #endif | |
54 | |
55 #define isdigit(c) ((c) >= '0' && (c) <= '9') | |
56 | |
57 char *strdup (); | |
58 static int isnumber (); | |
59 | |
60 /* Extract from NAME, which has the form "[user][:.][group]", | |
61 a USERNAME, UID U, GROUPNAME, and GID G. | |
62 Either user or group, or both, must be present. | |
63 If the group is omitted but the ":" or "." separator is given, | |
64 use the given user's login group. | |
65 | |
66 USERNAME and GROUPNAME will be in newly malloc'd memory. | |
67 Either one might be NULL instead, indicating that it was not | |
68 given and the corresponding numeric ID was left unchanged. | |
69 Might write NULs into NAME. | |
70 | |
71 Return NULL if successful, a static error message string if not. */ | |
72 | |
73 char * | |
74 parse_user_spec (name, uid, gid, username, groupname) | |
75 char *name; | |
76 uid_t *uid; | |
77 gid_t *gid; | |
78 char **username, **groupname; | |
79 { | |
80 static char *tired = "virtual memory exhausted"; | |
81 struct passwd *pwd; | |
82 struct group *grp; | |
83 char *cp; | |
84 int use_login_group = 0; | |
85 | |
86 *username = *groupname = NULL; | |
87 | |
88 /* Check whether a group is given. */ | |
89 cp = index (name, ':'); | |
90 if (cp == NULL) | |
91 cp = index (name, '.'); | |
92 if (cp != NULL) | |
93 { | |
94 *cp++ = '\0'; | |
95 if (*cp == '\0') | |
96 { | |
97 if (cp == name + 1) | |
98 /* Neither user nor group given, just "." or ":". */ | |
99 return "can not omit both user and group"; | |
100 else | |
101 /* "user.". */ | |
102 use_login_group = 1; | |
103 } | |
104 else | |
105 { | |
106 /* Explicit group. */ | |
107 *groupname = strdup (cp); | |
108 if (*groupname == NULL) | |
109 return tired; | |
110 grp = getgrnam (cp); | |
111 if (grp == NULL) | |
112 { | |
113 if (!isnumber (cp)) | |
114 return "invalid group"; | |
115 *gid = atoi (cp); | |
116 } | |
117 else | |
118 *gid = grp->gr_gid; | |
119 endgrent (); /* Save a file descriptor. */ | |
120 } | |
121 } | |
122 | |
123 /* Parse the user name, now that any group has been removed. */ | |
124 | |
125 if (name[0] == '\0') | |
126 /* No user name was given, just a group. */ | |
127 return NULL; | |
128 | |
129 *username = strdup (name); | |
130 if (*username == NULL) | |
131 return tired; | |
132 | |
133 pwd = getpwnam (name); | |
134 if (pwd == NULL) | |
135 { | |
136 if (!isnumber (name)) | |
137 return "invalid user"; | |
138 if (use_login_group) | |
139 return "cannot get the login group of a numeric UID"; | |
140 *uid = atoi (name); | |
141 } | |
142 else | |
143 { | |
144 *uid = pwd->pw_uid; | |
145 if (use_login_group) | |
146 { | |
147 *gid = pwd->pw_gid; | |
148 grp = getgrgid (pwd->pw_gid); | |
149 if (grp == NULL) | |
150 { | |
151 *groupname = malloc (15); | |
152 if (*groupname == NULL) | |
153 return tired; | |
154 sprintf (*groupname, "%u", pwd->pw_gid); | |
155 } | |
156 else | |
157 { | |
158 *groupname = strdup (grp->gr_name); | |
159 if (*groupname == NULL) | |
160 return tired; | |
161 } | |
162 endgrent (); | |
163 } | |
164 } | |
165 endpwent (); | |
166 return NULL; | |
167 } | |
168 | |
169 /* Return nonzero if STR represents an unsigned decimal integer, | |
170 otherwise return 0. */ | |
171 | |
172 static int | |
173 isnumber (str) | |
174 char *str; | |
175 { | |
176 for (; *str; str++) | |
177 if (!isdigit (*str)) | |
178 return 0; | |
179 return 1; | |
180 } |