getgrent.c revision 1.5
1/* $NetBSD: getgrent.c,v 1.5 2002/02/02 15:31:58 lukem 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 * NetBSD: getgrent.c,v 1.42 2002/02/02 15:21:29 lukem Exp 40 * and then gutted, leaving only /etc/group support. 41 */ 42 43#include <sys/cdefs.h> 44 45#ifdef __weak_alias 46#define endgrent _endgrent 47#define getgrent _getgrent 48#define getgrgid _getgrgid 49#define getgrnam _getgrnam 50#define setgrent _setgrent 51#define setgroupent _setgroupent 52 53__weak_alias(endgrent,_endgrent) 54__weak_alias(getgrent,_getgrent) 55__weak_alias(getgrgid,_getgrgid) 56__weak_alias(getgrnam,_getgrnam) 57__weak_alias(setgrent,_setgrent) 58__weak_alias(setgroupent,_setgroupent) 59#endif 60 61#include <sys/types.h> 62 63#include <grp.h> 64#include <limits.h> 65#include <stdio.h> 66#include <stdlib.h> 67#include <string.h> 68 69static FILE *_gr_fp; 70static struct group _gr_group; 71static int _gr_filesdone; 72static int _gr_stayopen; 73 74static int grscan(int, gid_t, const char *); 75static int grstart(void); 76static int grmatchline(int, gid_t, const char *); 77 78#define MAXGRP 200 79#define MAXLINELENGTH 1024 80static char *members[MAXGRP]; 81static char grline[MAXLINELENGTH]; 82 83struct group * 84getgrent(void) 85{ 86 if ((!_gr_fp && !grstart()) || !grscan(0, 0, NULL)) 87 return (NULL); 88 return (&_gr_group); 89} 90 91struct group * 92getgrnam(const char *name) 93{ 94 int rval; 95 96 if (!grstart()) 97 return(NULL); 98 rval = grscan(1, 0, name); 99 if (!_gr_stayopen) 100 endgrent(); 101 return(rval ? &_gr_group : NULL); 102} 103 104struct group * 105getgrgid(gid_t gid) 106{ 107 int rval; 108 109 if (!grstart()) 110 return(NULL); 111 rval = grscan(1, gid, NULL); 112 if (!_gr_stayopen) 113 endgrent(); 114 return(rval ? &_gr_group : NULL); 115} 116 117static int 118grstart(void) 119{ 120 _gr_filesdone = 0; 121 if (_gr_fp) { 122 rewind(_gr_fp); 123 return(1); 124 } 125 return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0); 126} 127 128void 129setgrent(void) 130{ 131 (void) setgroupent(0); 132} 133 134int 135setgroupent(int stayopen) 136{ 137 if (!grstart()) 138 return(0); 139 _gr_stayopen = stayopen; 140 return(1); 141} 142 143void 144endgrent(void) 145{ 146 _gr_filesdone = 0; 147 if (_gr_fp) { 148 (void)fclose(_gr_fp); 149 _gr_fp = NULL; 150 } 151} 152 153static int 154grscan(int search, gid_t gid, const char *name) 155{ 156 if (_gr_filesdone) 157 return 0; 158 for (;;) { 159 if (!fgets(grline, sizeof(grline), _gr_fp)) { 160 if (!search) 161 _gr_filesdone = 1; 162 return 0; 163 } 164 /* skip lines that are too big */ 165 if (!strchr(grline, '\n')) { 166 int ch; 167 168 while ((ch = getc(_gr_fp)) != '\n' && ch != EOF) 169 ; 170 continue; 171 } 172 if (grmatchline(search, gid, name)) 173 return 1; 174 } 175 /* NOTREACHED */ 176} 177 178static int 179grmatchline(int search, gid_t gid, const char *name) 180{ 181 unsigned long id; 182 char **m; 183 char *cp, *bp, *ep; 184 185 /* name may be NULL if search is nonzero */ 186 187 bp = grline; 188 memset(&_gr_group, 0, sizeof(_gr_group)); 189 _gr_group.gr_name = strsep(&bp, ":\n"); 190 if (search && name && strcmp(_gr_group.gr_name, name)) 191 return 0; 192 _gr_group.gr_passwd = strsep(&bp, ":\n"); 193 if (!(cp = strsep(&bp, ":\n"))) 194 return 0; 195 id = strtoul(cp, &ep, 10); 196 if (id > GID_MAX || *ep != '\0') 197 return 0; 198 _gr_group.gr_gid = (gid_t)id; 199 if (search && name == NULL && _gr_group.gr_gid != gid) 200 return 0; 201 cp = NULL; 202 if (bp == NULL) 203 return 0; 204 for (_gr_group.gr_mem = m = members;; bp++) { 205 if (m == &members[MAXGRP - 1]) 206 break; 207 if (*bp == ',') { 208 if (cp) { 209 *bp = '\0'; 210 *m++ = cp; 211 cp = NULL; 212 } 213 } else if (*bp == '\0' || *bp == '\n' || *bp == ' ') { 214 if (cp) { 215 *bp = '\0'; 216 *m++ = cp; 217 } 218 break; 219 } else if (cp == NULL) 220 cp = bp; 221 } 222 *m = NULL; 223 return 1; 224} 225