Home | History | Annotate | Line # | Download | only in gen
getgrent.c revision 1.11
      1 /*	$NetBSD: getgrent.c,v 1.11 1995/02/27 04:12:39 cgd Exp $	*/
      2 
      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. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #if defined(LIBC_SCCS) && !defined(lint)
     37 #if 0
     38 static char sccsid[] = "@(#)getgrent.c	8.2 (Berkeley) 3/21/94";
     39 #else
     40 static char rcsid[] = "$NetBSD: getgrent.c,v 1.11 1995/02/27 04:12:39 cgd Exp $";
     41 #endif
     42 #endif /* LIBC_SCCS and not lint */
     43 
     44 #include <sys/types.h>
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <grp.h>
     49 #ifdef YP
     50 #include <rpc/rpc.h>
     51 #include <rpcsvc/yp_prot.h>
     52 #include <rpcsvc/ypclnt.h>
     53 #endif
     54 
     55 static FILE *_gr_fp;
     56 static struct group _gr_group;
     57 static int _gr_stayopen;
     58 static int grscan(), start_gr();
     59 
     60 #define	MAXGRP		200
     61 static char *members[MAXGRP];
     62 #define	MAXLINELENGTH	1024
     63 static char line[MAXLINELENGTH];
     64 
     65 #ifdef YP
     66 static char	*__ypcurrent, *__ypdomain;
     67 static int	__ypcurrentlen, __ypmode=0;
     68 #endif
     69 
     70 struct group *
     71 getgrent()
     72 {
     73 	if (!_gr_fp && !start_gr() || !grscan(0, 0, NULL))
     74 		return(NULL);
     75 	return(&_gr_group);
     76 }
     77 
     78 struct group *
     79 getgrnam(name)
     80 	const char *name;
     81 {
     82 	int rval;
     83 
     84 	if (!start_gr())
     85 		return(NULL);
     86 	rval = grscan(1, 0, name);
     87 	if (!_gr_stayopen)
     88 		endgrent();
     89 	return(rval ? &_gr_group : NULL);
     90 }
     91 
     92 struct group *
     93 #ifdef __STDC__
     94 getgrgid(gid_t gid)
     95 #else
     96 getgrgid(gid)
     97 	gid_t gid;
     98 #endif
     99 {
    100 	int rval;
    101 
    102 	if (!start_gr())
    103 		return(NULL);
    104 	rval = grscan(1, gid, NULL);
    105 	if (!_gr_stayopen)
    106 		endgrent();
    107 	return(rval ? &_gr_group : NULL);
    108 }
    109 
    110 static int
    111 start_gr()
    112 {
    113 	if (_gr_fp) {
    114 		rewind(_gr_fp);
    115 #ifdef YP
    116 		__ypmode = 0;
    117 		if(__ypcurrent)
    118 			free(__ypcurrent);
    119 		__ypcurrent = NULL;
    120 #endif
    121 		return(1);
    122 	}
    123 	return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
    124 }
    125 
    126 void
    127 setgrent()
    128 {
    129 	(void) setgroupent(0);
    130 }
    131 
    132 int
    133 setgroupent(stayopen)
    134 	int stayopen;
    135 {
    136 	if (!start_gr())
    137 		return(0);
    138 	_gr_stayopen = stayopen;
    139 	return(1);
    140 }
    141 
    142 void
    143 endgrent()
    144 {
    145 	if (_gr_fp) {
    146 		(void)fclose(_gr_fp);
    147 		_gr_fp = NULL;
    148 #ifdef YP
    149 		__ypmode = 0;
    150 		if(__ypcurrent)
    151 			free(__ypcurrent);
    152 		__ypcurrent = NULL;
    153 #endif
    154 	}
    155 }
    156 
    157 static int
    158 grscan(search, gid, name)
    159 	register int search, gid;
    160 	register char *name;
    161 {
    162 	register char *cp, **m;
    163 	char *bp;
    164 
    165 	for (;;) {
    166 #ifdef YP
    167 		if(__ypmode) {
    168 			char *key, *data;
    169 			int keylen, datalen;
    170 			int r;
    171 
    172 			if(!__ypdomain) {
    173 				if(yp_get_default_domain(&__ypdomain)) {
    174 					__ypmode = 0;
    175 					continue;
    176 				}
    177 			}
    178 			if(__ypcurrent) {
    179 				r = yp_next(__ypdomain, "group.byname",
    180 					__ypcurrent, __ypcurrentlen,
    181 					&key, &keylen, &data, &datalen);
    182 				free(__ypcurrent);
    183 				/*printf("yp_next %d\n", r);*/
    184 				switch(r) {
    185 				case 0:
    186 					break;
    187 				default:
    188 					__ypcurrent = NULL;
    189 					__ypmode = 0;
    190 					free(data);
    191 					continue;
    192 				}
    193 				__ypcurrent = key;
    194 				__ypcurrentlen = keylen;
    195 				bcopy(data, line, datalen);
    196 				free(data);
    197 			} else {
    198 				r = yp_first(__ypdomain, "group.byname",
    199 					&__ypcurrent, &__ypcurrentlen,
    200 					&data, &datalen);
    201 				/*printf("yp_first %d\n", r);*/
    202 				switch(r) {
    203 				case 0:
    204 					break;
    205 				default:
    206 					__ypmode = 0;
    207 					free(data);
    208 					continue;
    209 				}
    210 				bcopy(data, line, datalen);
    211 				free(data);
    212 			}
    213 			line[datalen] = '\0';
    214 			/*printf("line = %s\n", line);*/
    215 			bp = line;
    216 			goto parse;
    217 		}
    218 #endif
    219 		if (!fgets(line, sizeof(line), _gr_fp))
    220 			return(0);
    221 		bp = line;
    222 		/* skip lines that are too big */
    223 		if (!strchr(line, '\n')) {
    224 			int ch;
    225 
    226 			while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
    227 				;
    228 			continue;
    229 		}
    230 #ifdef YP
    231 		if ((strcmp("+\n", line) == 0) || (strncmp("+:", line, 2) == 0)) {
    232 			if(_yp_check(NULL)) {
    233 				__ypmode = 1;
    234 				continue;
    235 			}
    236 		}
    237 parse:
    238 #endif
    239 		_gr_group.gr_name = strsep(&bp, ":\n");
    240 		if (search && name && strcmp(_gr_group.gr_name, name))
    241 			continue;
    242 		_gr_group.gr_passwd = strsep(&bp, ":\n");
    243 		if (!(cp = strsep(&bp, ":\n")))
    244 			continue;
    245 		_gr_group.gr_gid = atoi(cp);
    246 		if (search && name == NULL && _gr_group.gr_gid != gid)
    247 			continue;
    248 		cp = NULL;
    249 		if (bp == NULL)
    250 			continue;
    251 		for (m = _gr_group.gr_mem = members;; bp++) {
    252 			if (m == &members[MAXGRP - 1])
    253 				break;
    254 			if (*bp == ',') {
    255 				if (cp) {
    256 					*bp = '\0';
    257 					*m++ = cp;
    258 					cp = NULL;
    259 				}
    260 			} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
    261 				if (cp) {
    262 					*bp = '\0';
    263 					*m++ = cp;
    264 				}
    265 				break;
    266 			} else if (cp == NULL)
    267 				cp = bp;
    268 		}
    269 		*m = NULL;
    270 		return(1);
    271 	}
    272 	/* NOTREACHED */
    273 }
    274