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