4.3BSD-UWisc/src/lib/libc/net/getnetgrent.c
#if defined(LIBC_RCS) && !defined(lint)
static char rcs_id[] =
"$Header: getnetgrent.c,v 1.2 86/09/08 14:46:48 tadl Exp $";
#endif
/*
* RCS info
* $Locker: $
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getnetgrent.c 1.1 86/02/03 Copyr 1985 Sun Micro";
/* @(#)getnetgrent.c 2.1 86/04/11 NFSSRC */
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <ctype.h>
#include <rpcsvc/ypclnt.h>
#define MAXGROUPLEN 1024
/*
* access members of a netgroup
*/
struct grouplist { /* also used by pwlib */
char *gl_machine;
char *gl_name;
char *gl_domain;
struct grouplist *gl_nxt;
};
extern char *malloc(),*alloca();
extern char *strcpy(),*strncpy();
static char *any(), *index();
static struct list { /* list of names to check for loops */
char *name;
struct list *nxt;
};
static struct grouplist *grouplist, *grlist;
static void getgroup();
static void doit();
static char *fill();
static char *match();
static char domain[256];
setnetgrent(grp)
char *grp;
{
static char oldgrp[256];
if (strcmp(oldgrp, grp) == 0)
grlist = grouplist;
else {
if (grouplist != NULL)
endnetgrent();
getgroup(grp);
grlist = grouplist;
(void) strcpy(oldgrp, grp);
}
}
endnetgrent() {
struct grouplist *gl;
for (gl = grouplist; gl != NULL; gl = gl->gl_nxt) {
if (gl->gl_name)
free(gl->gl_name);
if (gl->gl_domain)
free(gl->gl_domain);
if (gl->gl_machine)
free(gl->gl_machine);
free((char *) gl);
}
grouplist = NULL;
grlist = NULL;
}
getnetgrent(machinep, namep, domainp)
char **machinep, **namep, **domainp;
{
if (grlist) {
*machinep = grlist->gl_machine;
*namep = grlist->gl_name;
*domainp = grlist->gl_domain;
grlist = grlist->gl_nxt;
return (1);
}
else
return (0);
}
static void
getgroup(grp)
char *grp;
{
if (getdomainname(domain, sizeof(domain)) < 0) {
(void) fprintf(stderr,
"getnetgrent: getdomainname system call missing\n");
exit(1);
}
doit(grp,(struct list *) NULL);
}
/*
* recursive function to find the members of netgroup "group". "list" is
* the path followed through the netgroups so far, to check for cycles.
*/
static void
doit(group,list)
char *group;
struct list *list;
{
register char *p, *q;
register struct list *ls;
char *val;
struct grouplist *gpls;
/*
* check for non-existing groups
*/
if ((val = match(group)) == NULL) {
return;
}
/*
* check for cycles
*/
for (ls = list; ls != NULL; ls = ls->nxt) {
if (strcmp(ls->name, group) == 0) {
(void) fprintf(stderr,
"Cycle detected in /etc/netgroup: %s.\n",group);
return;
}
}
ls = (struct list *) alloca(sizeof(struct list));
ls->name = group;
ls->nxt = list;
list = ls;
p = val;
while (p != NULL) {
while (*p == ' ' || *p == '\t')
p++;
if (*p == 0 || *p =='#')
break;
if (*p == '(') {
gpls = (struct grouplist *) malloc(sizeof(struct grouplist));
p++;
if (!(p = fill(p,&gpls->gl_machine,','))) {
goto syntax_error;
}
if (!(p = fill(p,&gpls->gl_name,','))) {
goto syntax_error;
}
if (!(p = fill(p,&gpls->gl_domain,')'))) {
goto syntax_error;
}
gpls->gl_nxt = grouplist;
grouplist = gpls;
} else {
q = any(p, " \t\n#");
if (q && *q == '#')
break;
*q = 0;
doit(p,list);
*q = ' ';
}
p = any(p, " \t");
}
return;
syntax_error:
(void) fprintf(stderr,"syntax error in /etc/netgroup\n");
(void) fprintf(stderr,"--- %s\n",val);
return;
}
/*
* Fill a buffer "target" selectively from buffer "start".
* "termchar" terminates the information in start, and preceding
* or trailing white space is ignored. The location just after the
* terminating character is returned.
*/
static char *
fill(start,target,termchar)
char *start;
char **target;
char termchar;
{
register char *p;
register char *q;
char *r;
unsigned size;
for (p = start; *p == ' ' || *p == '\t'; p++)
;
r = index(p, termchar);
if (r == NULL) {
return(NULL);
}
if (p == r) {
*target = NULL;
} else {
for (q = r-1; *q == ' ' || *q == '\t'; q--)
;
size = q - p + 1;
*target = malloc(size+1);
(void) strncpy(*target,p,(int) size);
(*target)[size] = 0;
}
return(r+1);
}
static char *
match(group)
char *group;
{
char *val;
int vallen;
int err;
err = yp_match(domain,"netgroup",group,strlen(group),&val,&vallen);
if (err) {
#ifdef DEBUG
(void) fprintf(stderr,"yp_match(netgroup,%s) failed: %s\n",group
,yperr_string(err));
#endif
return(NULL);
}
return(val);
}
/*
* scans cp, looking for a match with any character
* in match. Returns pointer to place in cp that matched
* (or NULL if no match)
*/
static char *
any(cp, match)
register char *cp;
char *match;
{
register char *mp, c;
while (c = *cp) {
for (mp = match; *mp; mp++)
if (*mp == c)
return (cp);
cp++;
}
return ((char *)0);
}