Libinfo-173.tar.gz
[apple/libinfo.git] / nis.subproj / getnetgrent.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 #if !defined(lint) && defined(SCCSIDS)
26 static char sccsid[] = "@(#)getnetgrent.c 1.2 90/07/20 4.1NFSSRC; from 1.22 88/02/08 Copyr 1985 Sun Micro";
27 #endif
28
29 /*
30 * Copyright (c) 1985 by Sun Microsystems, Inc.
31 */
32
33 #include <stdio.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <rpcsvc/ypclnt.h>
38
39 #define MAXGROUPLEN 1024
40
41 /*
42 * access members of a netgroup
43 */
44
45 static struct grouplist { /* also used by pwlib */
46 char *gl_machine;
47 char *gl_name;
48 char *gl_domain;
49 struct grouplist *gl_nxt;
50 } *grouplist, *grlist;
51
52
53 struct list { /* list of names to check for loops */
54 char *name;
55 struct list *nxt;
56 };
57
58 static void doit();
59 static char *fill();
60 static char *match();
61
62 static char *domain;
63 static char *oldgrp;
64
65 char *NETGROUP = "netgroup";
66
67 void _old_endnetgrent(void);
68 void _old_setnetgrent(char *);
69
70 void _old_setnetgrent(grp)
71 char *grp;
72 {
73
74 if (oldgrp == NULL)
75 oldgrp = (char *)calloc(1,256);
76 if (strcmp(oldgrp, grp) == 0)
77 grlist = grouplist;
78 else {
79 if (grouplist != NULL)
80 _old_endnetgrent();
81 doit(grp, (struct list *) NULL);
82 grlist = grouplist;
83 (void) strcpy(oldgrp, grp);
84 }
85 }
86
87 void _old_endnetgrent()
88 {
89 register struct grouplist *gl;
90
91 for (gl = grouplist; gl != NULL; gl = gl->gl_nxt) {
92 if (gl->gl_name)
93 free(gl->gl_name);
94 if (gl->gl_domain)
95 free(gl->gl_domain);
96 if (gl->gl_machine)
97 free(gl->gl_machine);
98 free((char *) gl);
99 }
100 grouplist = NULL;
101 grlist = NULL;
102 if (oldgrp) {
103 free(oldgrp);
104 oldgrp = 0;
105 }
106 }
107
108 int _old_getnetgrent(machinep, namep, domainp)
109 char **machinep, **namep, **domainp;
110 {
111
112 if (grlist == 0)
113 return (0);
114 *machinep = grlist->gl_machine;
115 *namep = grlist->gl_name;
116 *domainp = grlist->gl_domain;
117 grlist = grlist->gl_nxt;
118 return (1);
119 }
120
121 /*
122 * recursive function to find the members of netgroup "group". "list" is
123 * the path followed through the netgroups so far, to check for cycles.
124 */
125 static void
126 doit(group,list)
127 char *group;
128 struct list *list;
129 {
130 register char *p, *q;
131 register struct list *ls;
132 struct list this_group;
133 char *val;
134 struct grouplist *gpls;
135
136 /*
137 * check for non-existing groups
138 */
139 if ((val = match(group)) == NULL)
140 return;
141
142 /*
143 * check for cycles
144 */
145 for (ls = list; ls != NULL; ls = ls->nxt)
146 if (strcmp(ls->name, group) == 0) {
147 (void) fprintf(stderr,
148 "Cycle detected in /etc/netgroup: %s.\n", group);
149 return;
150 }
151
152 ls = &this_group;
153 ls->name = group;
154 ls->nxt = list;
155 list = ls;
156
157 p = val;
158 while (p != NULL) {
159 while (*p == ' ' || *p == '\t')
160 p++;
161 if (*p == 0 || *p =='#')
162 break;
163 if (*p == '(') {
164 gpls = (struct grouplist *)
165 malloc(sizeof(struct grouplist));
166 p++;
167 if (!(p = fill(p,&gpls->gl_machine,',')))
168 goto syntax_error;
169 if (!(p = fill(p,&gpls->gl_name,',')))
170 goto syntax_error;
171 if (!(p = fill(p,&gpls->gl_domain,')')))
172 goto syntax_error;
173 gpls->gl_nxt = grouplist;
174 grouplist = gpls;
175 } else {
176 q = strpbrk(p, " \t\n#");
177 if (q && *q == '#')
178 break;
179 *q = 0;
180 doit(p,list);
181 *q = ' ';
182 }
183 p = strpbrk(p, " \t");
184 }
185 return;
186
187 syntax_error:
188 (void) fprintf(stderr,"syntax error in /etc/netgroup\n");
189 (void) fprintf(stderr,"--- %s\n",val);
190 return;
191 }
192
193 /*
194 * Fill a buffer "target" selectively from buffer "start".
195 * "termchar" terminates the information in start, and preceding
196 * or trailing white space is ignored. The location just after the
197 * terminating character is returned.
198 */
199 static char *
200 fill(start,target,termchar)
201 char *start, **target, termchar;
202 {
203 register char *p, *q;
204 char *r;
205 unsigned size;
206
207 for (p = start; *p == ' ' || *p == '\t'; p++)
208 ;
209 r = index(p, termchar);
210 if (r == NULL)
211 return (NULL);
212 if (p == r)
213 *target = NULL;
214 else {
215 for (q = r-1; *q == ' ' || *q == '\t'; q--)
216 ;
217 size = q - p + 1;
218 *target = malloc(size+1);
219 (void) strncpy(*target,p,(int) size);
220 (*target)[size] = 0;
221 }
222 return (r+1);
223 }
224
225 static char *
226 match(group)
227 char *group;
228 {
229 char *val;
230 int vallen;
231
232 if (domain == NULL)
233 (void) yp_get_default_domain(&domain );
234 if (yp_match(domain, NETGROUP, group, strlen(group), &val, &vallen))
235 return (NULL);
236 return (val);
237 }