getgrent.c revision 1.4
1/*	$NetBSD: getgrent.c,v 1.4 2001/06/15 17:26:51 tsutsui Exp $	*/
2
3/*
4 * Copyright (c) 1989, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37/*
38 * Copied from:  lib/libc/gen/getgrent.c
39 * and then gutted, leaving only /etc/group support.
40 */
41
42#include <sys/cdefs.h>
43
44#ifdef __weak_alias
45#define endgrent		_endgrent
46#define getgrent		_getgrent
47#define getgrgid		_getgrgid
48#define getgrnam		_getgrnam
49#define setgrent		_setgrent
50#define setgroupent		_setgroupent
51#endif
52
53#include <sys/types.h>
54#include <stdio.h>
55#include <stdlib.h>
56#include <string.h>
57#include <grp.h>
58
59#ifdef __weak_alias
60__weak_alias(endgrent,_endgrent)
61__weak_alias(getgrent,_getgrent)
62__weak_alias(getgrgid,_getgrgid)
63__weak_alias(getgrnam,_getgrnam)
64__weak_alias(setgrent,_setgrent)
65__weak_alias(setgroupent,_setgroupent)
66#endif
67
68static FILE *_gr_fp;
69static struct group _gr_group;
70static int _gr_stayopen;
71static int grscan __P((int, int, const char *));
72static int start_gr __P((void));
73
74#define	MAXGRP		200
75static char *members[MAXGRP];
76#define	MAXLINELENGTH	1024
77static char line[MAXLINELENGTH];
78
79struct group *
80getgrent()
81{
82	if ((!_gr_fp && !start_gr()) || !grscan(0, 0, NULL))
83		return(NULL);
84	return(&_gr_group);
85}
86
87struct group *
88getgrnam(name)
89	const char *name;
90{
91	int rval;
92
93	if (!start_gr())
94		return(NULL);
95	rval = grscan(1, 0, name);
96	if (!_gr_stayopen)
97		endgrent();
98	return(rval ? &_gr_group : NULL);
99}
100
101struct group *
102#ifdef __STDC__
103getgrgid(gid_t gid)
104#else
105getgrgid(gid)
106	gid_t gid;
107#endif
108{
109	int rval;
110
111	if (!start_gr())
112		return(NULL);
113	rval = grscan(1, gid, NULL);
114	if (!_gr_stayopen)
115		endgrent();
116	return(rval ? &_gr_group : NULL);
117}
118
119static int
120start_gr()
121{
122	if (_gr_fp) {
123		rewind(_gr_fp);
124		return(1);
125	}
126	return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
127}
128
129void
130setgrent()
131{
132	(void) setgroupent(0);
133}
134
135int
136setgroupent(stayopen)
137	int stayopen;
138{
139	if (!start_gr())
140		return(0);
141	_gr_stayopen = stayopen;
142	return(1);
143}
144
145void
146endgrent()
147{
148	if (_gr_fp) {
149		(void)fclose(_gr_fp);
150		_gr_fp = NULL;
151	}
152}
153
154static int
155grscan(search, gid, name)
156	register int search, gid;
157	register const char *name;
158{
159	register char *cp, **m;
160	char *bp;
161
162	for (;;) {
163		if (!fgets(line, sizeof(line), _gr_fp))
164			return(0);
165		bp = line;
166		/* skip lines that are too big */
167		if (!strchr(line, '\n')) {
168			int ch;
169
170			while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
171				;
172			continue;
173		}
174		_gr_group.gr_name = strsep(&bp, ":\n");
175		if (search && name && strcmp(_gr_group.gr_name, name))
176			continue;
177		_gr_group.gr_passwd = strsep(&bp, ":\n");
178		if (!(cp = strsep(&bp, ":\n")))
179			continue;
180		_gr_group.gr_gid = atoi(cp);
181		if (search && name == NULL && _gr_group.gr_gid != gid)
182			continue;
183		cp = NULL;
184		if (bp == NULL)
185			continue;
186		for (m = _gr_group.gr_mem = members;; bp++) {
187			if (m == &members[MAXGRP - 1])
188				break;
189			if (*bp == ',') {
190				if (cp) {
191					*bp = '\0';
192					*m++ = cp;
193					cp = NULL;
194				}
195			} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
196				if (cp) {
197					*bp = '\0';
198					*m++ = cp;
199				}
200				break;
201			} else if (cp == NULL)
202				cp = bp;
203		}
204		*m = NULL;
205		return(1);
206	}
207	/* NOTREACHED */
208}
209