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