* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
* %sccs.include.redist.c%
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid
[] = "@(#)getnetgrent.c 5.2 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#define _PATH_NETGROUP "/etc/netgroup"
* Static Variables and functions used by setnetgrent(), getnetgrent() and
* There are two linked lists:
* - linelist is just used by setnetgrent() to parse the net group file via.
* - netgrp is the list of entries for the current netgroup
struct linelist
*l_next
; /* Chain ptr. */
int l_parsed
; /* Flag for cycles */
char *l_groupname
; /* Name of netgroup */
char *l_line
; /* Netgroup entrie(s) to be parsed */
struct netgrp
*ng_next
; /* Chain ptr */
char *ng_str
[3]; /* Field pointers, see below */
#define NG_HOST 0 /* Host name */
#define NG_USER 1 /* User name */
#define NG_DOM 2 /* and Domain name */
static struct linelist
*linehead
= (struct linelist
*)0;
static struct netgrp
*nextgrp
= (struct netgrp
*)0;
static FILE *netf
= (FILE *)0;
static int parse_netgrp();
static struct linelist
*read_for_group();
void setnetgrent(), endnetgrent();
int getnetgrent(), innetgr();
#define LINSIZ 1024 /* Length of netgroup file line */
* Parse the netgroup file looking for the netgroup and build the list
* of netgrp structures. Let parse_netgrp() and read_for_group() do
if (grouphead
.gr
== (struct netgrp
*)0 ||
strcmp(group
, grouphead
.grname
)) {
if (netf
= fopen(_PATH_NETGROUP
, "r")) {
grouphead
.grname
= (char *)
malloc(strlen(group
) + 1);
strcpy(grouphead
.grname
, group
);
* Get the next netgroup off the list.
getnetgrent(hostp
, userp
, domp
)
char **hostp
, **userp
, **domp
;
*hostp
= nextgrp
->ng_str
[NG_HOST
];
*userp
= nextgrp
->ng_str
[NG_USER
];
*domp
= nextgrp
->ng_str
[NG_DOM
];
nextgrp
= nextgrp
->ng_next
;
* endnetgrent() - cleanup
register struct linelist
*lp
, *olp
;
register struct netgrp
*gp
, *ogp
;
linehead
= (struct linelist
*)0;
grouphead
.grname
= (char *)0;
if (ogp
->ng_str
[NG_HOST
])
free(ogp
->ng_str
[NG_HOST
]);
if (ogp
->ng_str
[NG_USER
])
free(ogp
->ng_str
[NG_USER
]);
free(ogp
->ng_str
[NG_DOM
]);
grouphead
.gr
= (struct netgrp
*)0;
* Search for a match in a netgroup.
innetgr(group
, host
, user
, dom
)
char *group
, *host
, *user
, *dom
;
while (getnetgrent(&hst
, &usr
, &dm
))
if ((host
== (char *)0 || !strcmp(host
, hst
)) &&
(user
== (char *)0 || !strcmp(user
, usr
)) &&
(dom
== (char *)0 || !strcmp(dom
, dm
))) {
* Parse the netgroup file setting up the linked lists.
register char *spos
, *epos
;
register int len
, strpos
;
struct linelist
*lp
= linehead
;
* First, see if the line has already been read in.
if (!strcmp(group
, lp
->l_groupname
))
if (lp
== (struct linelist
*)0 &&
(lp
= read_for_group(group
)) == (struct linelist
*)0)
fprintf(stderr
, "Cycle in netgroup %s\n", lp
->l_groupname
);
grp
= (struct netgrp
*)malloc(sizeof (struct netgrp
));
bzero((char *)grp
, sizeof (struct netgrp
));
grp
->ng_next
= grouphead
.gr
;
gpos
= strsep(&pos
, ")");
for (strpos
= 0; strpos
< 3; strpos
++) {
if (spos
= strsep(&gpos
, ",")) {
while (*spos
== ' ' || *spos
== '\t')
if (epos
= strpbrk(spos
, " \t")) {
grp
->ng_str
[strpos
] = (char *)
bcopy(spos
, grp
->ng_str
[strpos
],
spos
= strsep(&pos
, ", \t");
while (*pos
== ' ' || *pos
== ',' || *pos
== '\t')
fprintf(stderr
, "Bad netgroup %s at ..%s\n", lp
->l_groupname
,
* Read the netgroup file and save lines until the line for the netgroup
* is found. Return 1 if eof is encountered.
register char *pos
, *spos
, *linep
, *olinep
;
while (fgets(line
, LINSIZ
, netf
) != NULL
) {
while (*pos
== ' ' || *pos
== '\t')
while (*pos
!= ' ' && *pos
!= '\t' && *pos
!= '\n' &&
while (*pos
== ' ' || *pos
== '\t')
if (*pos
!= '\n' && *pos
!= '\0') {
lp
= (struct linelist
*)malloc(sizeof (*lp
));
lp
->l_groupname
= (char *)malloc(len
+ 1);
bcopy(spos
, lp
->l_groupname
, len
);
*(lp
->l_groupname
+ len
) = '\0';
* Loop around handling line continuations.
if (*(pos
+ len
- 1) == '\n')
if (*(pos
+ len
- 1) == '\\') {
linep
= (char *)malloc(olen
+ len
+ 1);
bcopy(olinep
, linep
, olen
);
bcopy(pos
, linep
+ olen
, len
);
if (fgets(line
, LINSIZ
, netf
)) {
* If this is the one we wanted, we are done.
if (!strcmp(lp
->l_groupname
, group
))
return ((struct linelist
*)0);