xref: /illumos-gate/usr/src/lib/libresolv2/common/irs/lcl_ng.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 1997-2002 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*
7*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1996-1999 by Internet Software Consortium.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
10*7c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
11*7c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
12*7c478bd9Sstevel@tonic-gate  *
13*7c478bd9Sstevel@tonic-gate  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
14*7c478bd9Sstevel@tonic-gate  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15*7c478bd9Sstevel@tonic-gate  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
16*7c478bd9Sstevel@tonic-gate  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
17*7c478bd9Sstevel@tonic-gate  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18*7c478bd9Sstevel@tonic-gate  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19*7c478bd9Sstevel@tonic-gate  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20*7c478bd9Sstevel@tonic-gate  * SOFTWARE.
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER)
26*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "$Id: lcl_ng.c,v 1.17 2001/05/29 05:49:05 marka Exp $";
27*7c478bd9Sstevel@tonic-gate #endif
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /* Imports */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #include "port_before.h"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
34*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
35*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
36*7c478bd9Sstevel@tonic-gate #include <resolv.h>
37*7c478bd9Sstevel@tonic-gate #include <errno.h>
38*7c478bd9Sstevel@tonic-gate #include <stdio.h>
39*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
40*7c478bd9Sstevel@tonic-gate #include <string.h>
41*7c478bd9Sstevel@tonic-gate #include <unistd.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #include <irs.h>
44*7c478bd9Sstevel@tonic-gate #include <isc/memcluster.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #include "port_after.h"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #include "irs_p.h"
49*7c478bd9Sstevel@tonic-gate #include "lcl_p.h"
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /* Definitions */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #define NG_HOST         0       /* Host name */
54*7c478bd9Sstevel@tonic-gate #define NG_USER         1       /* User name */
55*7c478bd9Sstevel@tonic-gate #define NG_DOM          2       /* and Domain name */
56*7c478bd9Sstevel@tonic-gate #define LINSIZ		1024    /* Length of netgroup file line */
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate  * XXX Warning XXX
60*7c478bd9Sstevel@tonic-gate  * This code is a hack-and-slash special.  It realy needs to be
61*7c478bd9Sstevel@tonic-gate  * rewritten with things like strdup, and realloc in mind.
62*7c478bd9Sstevel@tonic-gate  * More reasonable data structures would not be a bad thing.
63*7c478bd9Sstevel@tonic-gate  */
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate /*
66*7c478bd9Sstevel@tonic-gate  * Static Variables and functions used by setnetgrent(), getnetgrent() and
67*7c478bd9Sstevel@tonic-gate  * endnetgrent().
68*7c478bd9Sstevel@tonic-gate  * There are two linked lists:
69*7c478bd9Sstevel@tonic-gate  * - linelist is just used by setnetgrent() to parse the net group file via.
70*7c478bd9Sstevel@tonic-gate  *   parse_netgrp()
71*7c478bd9Sstevel@tonic-gate  * - netgrp is the list of entries for the current netgroup
72*7c478bd9Sstevel@tonic-gate  */
73*7c478bd9Sstevel@tonic-gate struct linelist {
74*7c478bd9Sstevel@tonic-gate 	struct linelist *l_next;	/* Chain ptr. */
75*7c478bd9Sstevel@tonic-gate 	int		l_parsed;	/* Flag for cycles */
76*7c478bd9Sstevel@tonic-gate 	char *		l_groupname;	/* Name of netgroup */
77*7c478bd9Sstevel@tonic-gate 	char *		l_line;		/* Netgroup entrie(s) to be parsed */
78*7c478bd9Sstevel@tonic-gate };
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate struct ng_old_struct {
81*7c478bd9Sstevel@tonic-gate 	struct ng_old_struct *ng_next;	/* Chain ptr */
82*7c478bd9Sstevel@tonic-gate 	char *		ng_str[3];	/* Field pointers, see below */
83*7c478bd9Sstevel@tonic-gate };
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate struct pvt {
86*7c478bd9Sstevel@tonic-gate 	FILE			*fp;
87*7c478bd9Sstevel@tonic-gate 	struct linelist		*linehead;
88*7c478bd9Sstevel@tonic-gate 	struct ng_old_struct    *nextgrp;
89*7c478bd9Sstevel@tonic-gate 	struct {
90*7c478bd9Sstevel@tonic-gate 		struct ng_old_struct	*gr;
91*7c478bd9Sstevel@tonic-gate 		char			*grname;
92*7c478bd9Sstevel@tonic-gate 	} grouphead;
93*7c478bd9Sstevel@tonic-gate };
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate /* Forward */
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate static void 		ng_rewind(struct irs_ng *, const char*);
98*7c478bd9Sstevel@tonic-gate static void 		ng_close(struct irs_ng *);
99*7c478bd9Sstevel@tonic-gate static int		ng_next(struct irs_ng *, const char **,
100*7c478bd9Sstevel@tonic-gate 				const char **, const char **);
101*7c478bd9Sstevel@tonic-gate static int 		ng_test(struct irs_ng *, const char *,
102*7c478bd9Sstevel@tonic-gate 				const char *, const char *,
103*7c478bd9Sstevel@tonic-gate 				const char *);
104*7c478bd9Sstevel@tonic-gate static void		ng_minimize(struct irs_ng *);
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate static int 		parse_netgrp(struct irs_ng *, const char*);
107*7c478bd9Sstevel@tonic-gate static struct linelist *read_for_group(struct irs_ng *, const char *);
108*7c478bd9Sstevel@tonic-gate static void		freelists(struct irs_ng *);
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate /* Public */
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate struct irs_ng *
113*7c478bd9Sstevel@tonic-gate irs_lcl_ng(struct irs_acc *this) {
114*7c478bd9Sstevel@tonic-gate 	struct irs_ng *ng;
115*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt;
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 	UNUSED(this);
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 	if (!(ng = memget(sizeof *ng))) {
120*7c478bd9Sstevel@tonic-gate 		errno = ENOMEM;
121*7c478bd9Sstevel@tonic-gate 		return (NULL);
122*7c478bd9Sstevel@tonic-gate 	}
123*7c478bd9Sstevel@tonic-gate 	memset(ng, 0x5e, sizeof *ng);
124*7c478bd9Sstevel@tonic-gate 	if (!(pvt = memget(sizeof *pvt))) {
125*7c478bd9Sstevel@tonic-gate 		memput(ng, sizeof *ng);
126*7c478bd9Sstevel@tonic-gate 		errno = ENOMEM;
127*7c478bd9Sstevel@tonic-gate 		return (NULL);
128*7c478bd9Sstevel@tonic-gate 	}
129*7c478bd9Sstevel@tonic-gate 	memset(pvt, 0, sizeof *pvt);
130*7c478bd9Sstevel@tonic-gate 	ng->private = pvt;
131*7c478bd9Sstevel@tonic-gate 	ng->close = ng_close;
132*7c478bd9Sstevel@tonic-gate 	ng->next = ng_next;
133*7c478bd9Sstevel@tonic-gate 	ng->test = ng_test;
134*7c478bd9Sstevel@tonic-gate 	ng->rewind = ng_rewind;
135*7c478bd9Sstevel@tonic-gate 	ng->minimize = ng_minimize;
136*7c478bd9Sstevel@tonic-gate 	return (ng);
137*7c478bd9Sstevel@tonic-gate }
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate /* Methods */
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate static void
142*7c478bd9Sstevel@tonic-gate ng_close(struct irs_ng *this) {
143*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	if (pvt->fp != NULL)
146*7c478bd9Sstevel@tonic-gate 		fclose(pvt->fp);
147*7c478bd9Sstevel@tonic-gate 	freelists(this);
148*7c478bd9Sstevel@tonic-gate 	memput(pvt, sizeof *pvt);
149*7c478bd9Sstevel@tonic-gate 	memput(this, sizeof *this);
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate /*
153*7c478bd9Sstevel@tonic-gate  * Parse the netgroup file looking for the netgroup and build the list
154*7c478bd9Sstevel@tonic-gate  * of netgrp structures. Let parse_netgrp() and read_for_group() do
155*7c478bd9Sstevel@tonic-gate  * most of the work.
156*7c478bd9Sstevel@tonic-gate  */
157*7c478bd9Sstevel@tonic-gate static void
158*7c478bd9Sstevel@tonic-gate ng_rewind(struct irs_ng *this, const char *group) {
159*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 	if (pvt->fp != NULL && fseek(pvt->fp, SEEK_CUR, 0L) == -1) {
162*7c478bd9Sstevel@tonic-gate 		fclose(pvt->fp);
163*7c478bd9Sstevel@tonic-gate 		pvt->fp = NULL;
164*7c478bd9Sstevel@tonic-gate 	}
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate 	if (pvt->fp == NULL || pvt->grouphead.gr == NULL ||
167*7c478bd9Sstevel@tonic-gate 	    strcmp(group, pvt->grouphead.grname)) {
168*7c478bd9Sstevel@tonic-gate 		freelists(this);
169*7c478bd9Sstevel@tonic-gate 		if (pvt->fp != NULL)
170*7c478bd9Sstevel@tonic-gate 			fclose(pvt->fp);
171*7c478bd9Sstevel@tonic-gate 		pvt->fp = fopen(_PATH_NETGROUP, "r");
172*7c478bd9Sstevel@tonic-gate 		if (pvt->fp != NULL) {
173*7c478bd9Sstevel@tonic-gate 			if (parse_netgrp(this, group))
174*7c478bd9Sstevel@tonic-gate 				freelists(this);
175*7c478bd9Sstevel@tonic-gate 			if (!(pvt->grouphead.grname = strdup(group)))
176*7c478bd9Sstevel@tonic-gate 				freelists(this);
177*7c478bd9Sstevel@tonic-gate 			fclose(pvt->fp);
178*7c478bd9Sstevel@tonic-gate 			pvt->fp = NULL;
179*7c478bd9Sstevel@tonic-gate 		}
180*7c478bd9Sstevel@tonic-gate 	}
181*7c478bd9Sstevel@tonic-gate 	pvt->nextgrp = pvt->grouphead.gr;
182*7c478bd9Sstevel@tonic-gate }
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate /*
185*7c478bd9Sstevel@tonic-gate  * Get the next netgroup off the list.
186*7c478bd9Sstevel@tonic-gate  */
187*7c478bd9Sstevel@tonic-gate static int
188*7c478bd9Sstevel@tonic-gate ng_next(struct irs_ng *this, const char **host, const char **user,
189*7c478bd9Sstevel@tonic-gate 	const char **domain)
190*7c478bd9Sstevel@tonic-gate {
191*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 	if (pvt->nextgrp) {
194*7c478bd9Sstevel@tonic-gate 		*host = pvt->nextgrp->ng_str[NG_HOST];
195*7c478bd9Sstevel@tonic-gate 		*user = pvt->nextgrp->ng_str[NG_USER];
196*7c478bd9Sstevel@tonic-gate 		*domain = pvt->nextgrp->ng_str[NG_DOM];
197*7c478bd9Sstevel@tonic-gate 		pvt->nextgrp = pvt->nextgrp->ng_next;
198*7c478bd9Sstevel@tonic-gate 		return (1);
199*7c478bd9Sstevel@tonic-gate 	}
200*7c478bd9Sstevel@tonic-gate 	return (0);
201*7c478bd9Sstevel@tonic-gate }
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate /*
204*7c478bd9Sstevel@tonic-gate  * Search for a match in a netgroup.
205*7c478bd9Sstevel@tonic-gate  */
206*7c478bd9Sstevel@tonic-gate static int
207*7c478bd9Sstevel@tonic-gate ng_test(struct irs_ng *this, const char *name,
208*7c478bd9Sstevel@tonic-gate 	const char *host, const char *user, const char *domain)
209*7c478bd9Sstevel@tonic-gate {
210*7c478bd9Sstevel@tonic-gate 	const char *ng_host, *ng_user, *ng_domain;
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate 	ng_rewind(this, name);
213*7c478bd9Sstevel@tonic-gate 	while (ng_next(this, &ng_host, &ng_user, &ng_domain))
214*7c478bd9Sstevel@tonic-gate 		if ((host == NULL || ng_host == NULL ||
215*7c478bd9Sstevel@tonic-gate 		     !strcmp(host, ng_host)) &&
216*7c478bd9Sstevel@tonic-gate 		    (user ==  NULL || ng_user == NULL ||
217*7c478bd9Sstevel@tonic-gate 		     !strcmp(user, ng_user)) &&
218*7c478bd9Sstevel@tonic-gate 		    (domain == NULL || ng_domain == NULL ||
219*7c478bd9Sstevel@tonic-gate 		     !strcmp(domain, ng_domain))) {
220*7c478bd9Sstevel@tonic-gate 			freelists(this);
221*7c478bd9Sstevel@tonic-gate 			return (1);
222*7c478bd9Sstevel@tonic-gate 		}
223*7c478bd9Sstevel@tonic-gate 	freelists(this);
224*7c478bd9Sstevel@tonic-gate 	return (0);
225*7c478bd9Sstevel@tonic-gate }
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate static void
228*7c478bd9Sstevel@tonic-gate ng_minimize(struct irs_ng *this) {
229*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate 	if (pvt->fp != NULL) {
232*7c478bd9Sstevel@tonic-gate 		(void)fclose(pvt->fp);
233*7c478bd9Sstevel@tonic-gate 		pvt->fp = NULL;
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate }
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate /* Private */
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate /*
240*7c478bd9Sstevel@tonic-gate  * endnetgrent() - cleanup
241*7c478bd9Sstevel@tonic-gate  */
242*7c478bd9Sstevel@tonic-gate static void
243*7c478bd9Sstevel@tonic-gate freelists(struct irs_ng *this) {
244*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
245*7c478bd9Sstevel@tonic-gate 	struct linelist *lp, *olp;
246*7c478bd9Sstevel@tonic-gate 	struct ng_old_struct *gp, *ogp;
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	lp = pvt->linehead;
249*7c478bd9Sstevel@tonic-gate 	while (lp) {
250*7c478bd9Sstevel@tonic-gate 		olp = lp;
251*7c478bd9Sstevel@tonic-gate 		lp = lp->l_next;
252*7c478bd9Sstevel@tonic-gate 		free(olp->l_groupname);
253*7c478bd9Sstevel@tonic-gate 		free(olp->l_line);
254*7c478bd9Sstevel@tonic-gate 		free((char *)olp);
255*7c478bd9Sstevel@tonic-gate 	}
256*7c478bd9Sstevel@tonic-gate 	pvt->linehead = NULL;
257*7c478bd9Sstevel@tonic-gate 	if (pvt->grouphead.grname) {
258*7c478bd9Sstevel@tonic-gate 		free(pvt->grouphead.grname);
259*7c478bd9Sstevel@tonic-gate 		pvt->grouphead.grname = NULL;
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 	gp = pvt->grouphead.gr;
262*7c478bd9Sstevel@tonic-gate 	while (gp) {
263*7c478bd9Sstevel@tonic-gate 		ogp = gp;
264*7c478bd9Sstevel@tonic-gate 		gp = gp->ng_next;
265*7c478bd9Sstevel@tonic-gate 		if (ogp->ng_str[NG_HOST])
266*7c478bd9Sstevel@tonic-gate 			free(ogp->ng_str[NG_HOST]);
267*7c478bd9Sstevel@tonic-gate 		if (ogp->ng_str[NG_USER])
268*7c478bd9Sstevel@tonic-gate 			free(ogp->ng_str[NG_USER]);
269*7c478bd9Sstevel@tonic-gate 		if (ogp->ng_str[NG_DOM])
270*7c478bd9Sstevel@tonic-gate 			free(ogp->ng_str[NG_DOM]);
271*7c478bd9Sstevel@tonic-gate 		free((char *)ogp);
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 	pvt->grouphead.gr = NULL;
274*7c478bd9Sstevel@tonic-gate }
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate /*
277*7c478bd9Sstevel@tonic-gate  * Parse the netgroup file setting up the linked lists.
278*7c478bd9Sstevel@tonic-gate  */
279*7c478bd9Sstevel@tonic-gate static int
280*7c478bd9Sstevel@tonic-gate parse_netgrp(struct irs_ng *this, const char *group) {
281*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
282*7c478bd9Sstevel@tonic-gate 	char *spos, *epos;
283*7c478bd9Sstevel@tonic-gate 	int len, strpos;
284*7c478bd9Sstevel@tonic-gate 	char *pos, *gpos;
285*7c478bd9Sstevel@tonic-gate 	struct ng_old_struct *grp;
286*7c478bd9Sstevel@tonic-gate 	struct linelist *lp = pvt->linehead;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate         /*
289*7c478bd9Sstevel@tonic-gate          * First, see if the line has already been read in.
290*7c478bd9Sstevel@tonic-gate          */
291*7c478bd9Sstevel@tonic-gate 	while (lp) {
292*7c478bd9Sstevel@tonic-gate 		if (!strcmp(group, lp->l_groupname))
293*7c478bd9Sstevel@tonic-gate 			break;
294*7c478bd9Sstevel@tonic-gate 		lp = lp->l_next;
295*7c478bd9Sstevel@tonic-gate 	}
296*7c478bd9Sstevel@tonic-gate 	if (lp == NULL &&
297*7c478bd9Sstevel@tonic-gate 	    (lp = read_for_group(this, group)) == NULL)
298*7c478bd9Sstevel@tonic-gate 		return (1);
299*7c478bd9Sstevel@tonic-gate 	if (lp->l_parsed) {
300*7c478bd9Sstevel@tonic-gate 		/*fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);*/
301*7c478bd9Sstevel@tonic-gate 		return (1);
302*7c478bd9Sstevel@tonic-gate 	} else
303*7c478bd9Sstevel@tonic-gate 		lp->l_parsed = 1;
304*7c478bd9Sstevel@tonic-gate 	pos = lp->l_line;
305*7c478bd9Sstevel@tonic-gate 	while (*pos != '\0') {
306*7c478bd9Sstevel@tonic-gate 		if (*pos == '(') {
307*7c478bd9Sstevel@tonic-gate 			if (!(grp = malloc(sizeof (struct ng_old_struct)))) {
308*7c478bd9Sstevel@tonic-gate 				freelists(this);
309*7c478bd9Sstevel@tonic-gate 				errno = ENOMEM;
310*7c478bd9Sstevel@tonic-gate 				return (1);
311*7c478bd9Sstevel@tonic-gate 			}
312*7c478bd9Sstevel@tonic-gate 			memset(grp, 0, sizeof (struct ng_old_struct));
313*7c478bd9Sstevel@tonic-gate 			grp->ng_next = pvt->grouphead.gr;
314*7c478bd9Sstevel@tonic-gate 			pvt->grouphead.gr = grp;
315*7c478bd9Sstevel@tonic-gate 			pos++;
316*7c478bd9Sstevel@tonic-gate 			gpos = strsep(&pos, ")");
317*7c478bd9Sstevel@tonic-gate 			for (strpos = 0; strpos < 3; strpos++) {
318*7c478bd9Sstevel@tonic-gate 				if ((spos = strsep(&gpos, ","))) {
319*7c478bd9Sstevel@tonic-gate 					while (*spos == ' ' || *spos == '\t')
320*7c478bd9Sstevel@tonic-gate 						spos++;
321*7c478bd9Sstevel@tonic-gate 					if ((epos = strpbrk(spos, " \t"))) {
322*7c478bd9Sstevel@tonic-gate 						*epos = '\0';
323*7c478bd9Sstevel@tonic-gate 						len = epos - spos;
324*7c478bd9Sstevel@tonic-gate 					} else
325*7c478bd9Sstevel@tonic-gate 						len = strlen(spos);
326*7c478bd9Sstevel@tonic-gate 					if (len > 0) {
327*7c478bd9Sstevel@tonic-gate 						if(!(grp->ng_str[strpos]
328*7c478bd9Sstevel@tonic-gate 						   =  (char *)
329*7c478bd9Sstevel@tonic-gate 						   malloc(len + 1))) {
330*7c478bd9Sstevel@tonic-gate 							freelists(this);
331*7c478bd9Sstevel@tonic-gate 							return (1);
332*7c478bd9Sstevel@tonic-gate 						}
333*7c478bd9Sstevel@tonic-gate 						memcpy(grp->ng_str[strpos],
334*7c478bd9Sstevel@tonic-gate 						       spos,
335*7c478bd9Sstevel@tonic-gate 						       len + 1);
336*7c478bd9Sstevel@tonic-gate 					}
337*7c478bd9Sstevel@tonic-gate 				} else
338*7c478bd9Sstevel@tonic-gate 					goto errout;
339*7c478bd9Sstevel@tonic-gate 			}
340*7c478bd9Sstevel@tonic-gate 		} else {
341*7c478bd9Sstevel@tonic-gate 			spos = strsep(&pos, ", \t");
342*7c478bd9Sstevel@tonic-gate 			if (spos != NULL && parse_netgrp(this, spos)) {
343*7c478bd9Sstevel@tonic-gate 				freelists(this);
344*7c478bd9Sstevel@tonic-gate 				return (1);
345*7c478bd9Sstevel@tonic-gate 			}
346*7c478bd9Sstevel@tonic-gate 		}
347*7c478bd9Sstevel@tonic-gate 		if (pos == NULL)
348*7c478bd9Sstevel@tonic-gate 			break;
349*7c478bd9Sstevel@tonic-gate 		while (*pos == ' ' || *pos == ',' || *pos == '\t')
350*7c478bd9Sstevel@tonic-gate 			pos++;
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate 	return (0);
353*7c478bd9Sstevel@tonic-gate  errout:
354*7c478bd9Sstevel@tonic-gate 	/*fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname,
355*7c478bd9Sstevel@tonic-gate 		  spos);*/
356*7c478bd9Sstevel@tonic-gate 	return (1);
357*7c478bd9Sstevel@tonic-gate }
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate /*
360*7c478bd9Sstevel@tonic-gate  * Read the netgroup file and save lines until the line for the netgroup
361*7c478bd9Sstevel@tonic-gate  * is found. Return 1 if eof is encountered.
362*7c478bd9Sstevel@tonic-gate  */
363*7c478bd9Sstevel@tonic-gate static struct linelist *
364*7c478bd9Sstevel@tonic-gate read_for_group(struct irs_ng *this, const char *group) {
365*7c478bd9Sstevel@tonic-gate 	struct pvt *pvt = (struct pvt *)this->private;
366*7c478bd9Sstevel@tonic-gate 	char *pos, *spos, *linep = NULL, *olinep;
367*7c478bd9Sstevel@tonic-gate 	int len, olen, cont;
368*7c478bd9Sstevel@tonic-gate 	struct linelist *lp;
369*7c478bd9Sstevel@tonic-gate 	char line[LINSIZ + 1];
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	while (fgets(line, LINSIZ, pvt->fp) != NULL) {
372*7c478bd9Sstevel@tonic-gate 		pos = line;
373*7c478bd9Sstevel@tonic-gate 		if (*pos == '#')
374*7c478bd9Sstevel@tonic-gate 			continue;
375*7c478bd9Sstevel@tonic-gate 		while (*pos == ' ' || *pos == '\t')
376*7c478bd9Sstevel@tonic-gate 			pos++;
377*7c478bd9Sstevel@tonic-gate 		spos = pos;
378*7c478bd9Sstevel@tonic-gate 		while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
379*7c478bd9Sstevel@tonic-gate 			*pos != '\0')
380*7c478bd9Sstevel@tonic-gate 			pos++;
381*7c478bd9Sstevel@tonic-gate 		len = pos - spos;
382*7c478bd9Sstevel@tonic-gate 		while (*pos == ' ' || *pos == '\t')
383*7c478bd9Sstevel@tonic-gate 			pos++;
384*7c478bd9Sstevel@tonic-gate 		if (*pos != '\n' && *pos != '\0') {
385*7c478bd9Sstevel@tonic-gate 			if (!(lp = malloc(sizeof (*lp)))) {
386*7c478bd9Sstevel@tonic-gate 				freelists(this);
387*7c478bd9Sstevel@tonic-gate 				return (NULL);
388*7c478bd9Sstevel@tonic-gate 			}
389*7c478bd9Sstevel@tonic-gate 			lp->l_parsed = 0;
390*7c478bd9Sstevel@tonic-gate 			if (!(lp->l_groupname = malloc(len + 1))) {
391*7c478bd9Sstevel@tonic-gate 				free(lp);
392*7c478bd9Sstevel@tonic-gate 				freelists(this);
393*7c478bd9Sstevel@tonic-gate 				return (NULL);
394*7c478bd9Sstevel@tonic-gate 			}
395*7c478bd9Sstevel@tonic-gate 			memcpy(lp->l_groupname, spos,  len);
396*7c478bd9Sstevel@tonic-gate 			*(lp->l_groupname + len) = '\0';
397*7c478bd9Sstevel@tonic-gate 			len = strlen(pos);
398*7c478bd9Sstevel@tonic-gate 			olen = 0;
399*7c478bd9Sstevel@tonic-gate 			olinep = NULL;
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 			/*
402*7c478bd9Sstevel@tonic-gate 			 * Loop around handling line continuations.
403*7c478bd9Sstevel@tonic-gate 			 */
404*7c478bd9Sstevel@tonic-gate 			do {
405*7c478bd9Sstevel@tonic-gate 				if (*(pos + len - 1) == '\n')
406*7c478bd9Sstevel@tonic-gate 					len--;
407*7c478bd9Sstevel@tonic-gate 				if (*(pos + len - 1) == '\\') {
408*7c478bd9Sstevel@tonic-gate 					len--;
409*7c478bd9Sstevel@tonic-gate 					cont = 1;
410*7c478bd9Sstevel@tonic-gate 				} else
411*7c478bd9Sstevel@tonic-gate 					cont = 0;
412*7c478bd9Sstevel@tonic-gate 				if (len > 0) {
413*7c478bd9Sstevel@tonic-gate 					if (!(linep = malloc(olen + len + 1))){
414*7c478bd9Sstevel@tonic-gate 						if (olen > 0)
415*7c478bd9Sstevel@tonic-gate 							free(olinep);
416*7c478bd9Sstevel@tonic-gate 						free(lp->l_groupname);
417*7c478bd9Sstevel@tonic-gate 						free(lp);
418*7c478bd9Sstevel@tonic-gate 						freelists(this);
419*7c478bd9Sstevel@tonic-gate 						errno = ENOMEM;
420*7c478bd9Sstevel@tonic-gate 						return (NULL);
421*7c478bd9Sstevel@tonic-gate 					}
422*7c478bd9Sstevel@tonic-gate 					if (olen > 0) {
423*7c478bd9Sstevel@tonic-gate 						memcpy(linep, olinep, olen);
424*7c478bd9Sstevel@tonic-gate 						free(olinep);
425*7c478bd9Sstevel@tonic-gate 					}
426*7c478bd9Sstevel@tonic-gate 					memcpy(linep + olen, pos, len);
427*7c478bd9Sstevel@tonic-gate 					olen += len;
428*7c478bd9Sstevel@tonic-gate 					*(linep + olen) = '\0';
429*7c478bd9Sstevel@tonic-gate 					olinep = linep;
430*7c478bd9Sstevel@tonic-gate 				}
431*7c478bd9Sstevel@tonic-gate 				if (cont) {
432*7c478bd9Sstevel@tonic-gate 					if (fgets(line, LINSIZ, pvt->fp)) {
433*7c478bd9Sstevel@tonic-gate 						pos = line;
434*7c478bd9Sstevel@tonic-gate 						len = strlen(pos);
435*7c478bd9Sstevel@tonic-gate 					} else
436*7c478bd9Sstevel@tonic-gate 						cont = 0;
437*7c478bd9Sstevel@tonic-gate 				}
438*7c478bd9Sstevel@tonic-gate 			} while (cont);
439*7c478bd9Sstevel@tonic-gate 			lp->l_line = linep;
440*7c478bd9Sstevel@tonic-gate 			lp->l_next = pvt->linehead;
441*7c478bd9Sstevel@tonic-gate 			pvt->linehead = lp;
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate 			/*
444*7c478bd9Sstevel@tonic-gate 			 * If this is the one we wanted, we are done.
445*7c478bd9Sstevel@tonic-gate 			 */
446*7c478bd9Sstevel@tonic-gate 			if (!strcmp(lp->l_groupname, group))
447*7c478bd9Sstevel@tonic-gate 				return (lp);
448*7c478bd9Sstevel@tonic-gate 		}
449*7c478bd9Sstevel@tonic-gate 	}
450*7c478bd9Sstevel@tonic-gate 	return (NULL);
451*7c478bd9Sstevel@tonic-gate }
452