1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1989, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#ifndef lint
33#if 0
34static const char sccsid[] = "@(#)getgrent.c	8.2 (Berkeley) 3/21/94";
35#endif
36static const char rcsid[] =
37  "$FreeBSD$";
38#endif /* not lint */
39
40/*
41 * This is a slightly modified chunk of getgrent(3). All the YP support
42 * and unneeded functions have been stripped out.
43 */
44
45#include <sys/types.h>
46#include <grp.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50
51FILE *_gr_fp;
52static struct group _gr_group;
53static int _gr_stayopen;
54static int grscan(int, int);
55static int start_gr(void);
56
57#define	MAXGRP		200
58static char *members[MAXGRP];
59#define	MAXLINELENGTH	1024
60static char line[MAXLINELENGTH];
61
62struct group *
63_getgrent(void)
64{
65	if (!_gr_fp && !start_gr()) {
66		return NULL;
67	}
68
69
70	if (!grscan(0, 0))
71		return(NULL);
72	return(&_gr_group);
73}
74
75static int
76start_gr(void)
77{
78	return 1;
79}
80
81int
82_setgroupent(int stayopen)
83{
84	if (!start_gr())
85		return(0);
86	_gr_stayopen = stayopen;
87	return(1);
88}
89
90int
91_setgrent(void)
92{
93	return(_setgroupent(0));
94}
95
96void
97_endgrent(void)
98{
99	if (_gr_fp) {
100		(void)fclose(_gr_fp);
101		_gr_fp = NULL;
102	}
103}
104
105static int
106grscan(int search, int gid)
107{
108	char *cp, **m;
109	char *bp;
110	for (;;) {
111		if (!fgets(line, sizeof(line), _gr_fp))
112			return(0);
113		bp = line;
114		/* skip lines that are too big */
115		if (!strchr(line, '\n')) {
116			int ch;
117
118			while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
119				;
120			continue;
121		}
122		if ((_gr_group.gr_name = strsep(&bp, ":\n")) == NULL)
123			break;
124		if (_gr_group.gr_name[0] == '+')
125			continue;
126		if ((_gr_group.gr_passwd = strsep(&bp, ":\n")) == NULL)
127			break;
128		if (!(cp = strsep(&bp, ":\n")))
129			continue;
130		_gr_group.gr_gid = atoi(cp);
131		if (search && _gr_group.gr_gid != gid)
132			continue;
133		cp = NULL;
134		if (bp == NULL) /* !! Must check for this! */
135			break;
136		for (m = _gr_group.gr_mem = members;; bp++) {
137			if (m == &members[MAXGRP - 1])
138				break;
139			if (*bp == ',') {
140				if (cp) {
141					*bp = '\0';
142					*m++ = cp;
143					cp = NULL;
144				}
145			} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
146				if (cp) {
147					*bp = '\0';
148					*m++ = cp;
149			}
150				break;
151			} else if (cp == NULL)
152				cp = bp;
153		}
154		*m = NULL;
155		return(1);
156	}
157	/* NOTREACHED */
158	return (0);
159}
160