2N/A/*
2N/A * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
2N/A * Copyright (C) 1998, 1999, 2001, 2003 Internet Software Consortium.
2N/A *
2N/A * Permission to use, copy, modify, and/or distribute this software for any
2N/A * purpose with or without fee is hereby granted, provided that the above
2N/A * copyright notice and this permission notice appear in all copies.
2N/A *
2N/A * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
2N/A * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2N/A * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
2N/A * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2N/A * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2N/A * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2N/A * PERFORMANCE OF THIS SOFTWARE.
2N/A */
2N/A
2N/A#if defined(LIBC_SCCS) && !defined(lint)
2N/Astatic const char rcsid[] = "$Id: getnetgrent_r.c,v 1.14 2008/11/14 02:36:51 marka Exp $";
2N/A#endif /* LIBC_SCCS and not lint */
2N/A
2N/A#include <port_before.h>
2N/A#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
2N/A static int getnetgrent_r_not_required = 0;
2N/A#else
2N/A#include <errno.h>
2N/A#include <string.h>
2N/A#include <stdio.h>
2N/A#include <sys/types.h>
2N/A#include <netinet/in.h>
2N/A#include <netdb.h>
2N/A#include <stdlib.h>
2N/A#include <port_after.h>
2N/A
2N/A#ifdef NGR_R_RETURN
2N/A#ifndef NGR_R_PRIVATE
2N/A#define NGR_R_PRIVATE 0
2N/A#endif
2N/A
2N/Astatic NGR_R_RETURN
2N/Acopy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **,
2N/A const char *, const char *, const char *, NGR_R_COPY_ARGS);
2N/A
2N/ANGR_R_RETURN
2N/Ainnetgr_r(const char *netgroup, const char *host, const char *user,
2N/A const char *domain) {
2N/A char *ng, *ho, *us, *dom;
2N/A
2N/A DE_CONST(netgroup, ng);
2N/A DE_CONST(host, ho);
2N/A DE_CONST(user, us);
2N/A DE_CONST(domain, dom);
2N/A
2N/A return (innetgr(ng, ho, us, dom));
2N/A}
2N/A
2N/A/*%
2N/A * These assume a single context is in operation per thread.
2N/A * If this is not the case we will need to call irs directly
2N/A * rather than through the base functions.
2N/A */
2N/A
2N/ANGR_R_RETURN
2N/Agetnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
2N/A NGR_R_CONST char **domainp, NGR_R_ARGS)
2N/A{
2N/A NGR_R_CONST char *mp, *up, *dp;
2N/A int res = getnetgrent(&mp, &up, &dp);
2N/A
2N/A if (res != 1)
2N/A return (res);
2N/A
2N/A return (copy_protoent(machinep, userp, domainp,
2N/A mp, up, dp, NGR_R_COPY));
2N/A}
2N/A
2N/A#if NGR_R_PRIVATE == 2
2N/Astruct private {
2N/A char *buf;
2N/A};
2N/A
2N/A#endif
2N/ANGR_R_SET_RETURN
2N/A#ifdef NGR_R_SET_ARGS
2N/Asetnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS)
2N/A#else
2N/Asetnetgrent_r(NGR_R_SET_CONST char *netgroup)
2N/A#endif
2N/A{
2N/A#if NGR_R_PRIVATE == 2
2N/A struct private *p;
2N/A#endif
2N/A char *tmp;
2N/A#if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
2N/A UNUSED(buf);
2N/A UNUSED(buflen);
2N/A#endif
2N/A
2N/A DE_CONST(netgroup, tmp);
2N/A setnetgrent(tmp);
2N/A
2N/A#if NGR_R_PRIVATE == 1
2N/A *buf = NULL;
2N/A#elif NGR_R_PRIVATE == 2
2N/A *buf = p = malloc(sizeof(struct private));
2N/A if (p == NULL)
2N/A#ifdef NGR_R_SET_RESULT
2N/A return (NGR_R_BAD);
2N/A#else
2N/A return;
2N/A#endif
2N/A p->buf = NULL;
2N/A#endif
2N/A#ifdef NGR_R_SET_RESULT
2N/A return (NGR_R_SET_RESULT);
2N/A#endif
2N/A}
2N/A
2N/ANGR_R_END_RETURN
2N/A#ifdef NGR_R_END_ARGS
2N/Aendnetgrent_r(NGR_R_END_ARGS)
2N/A#else
2N/Aendnetgrent_r(void)
2N/A#endif
2N/A{
2N/A#if NGR_R_PRIVATE == 2
2N/A struct private *p = buf;
2N/A#endif
2N/A#if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
2N/A UNUSED(buf);
2N/A UNUSED(buflen);
2N/A#endif
2N/A
2N/A endnetgrent();
2N/A#if NGR_R_PRIVATE == 1
2N/A if (*buf != NULL)
2N/A free(*buf);
2N/A *buf = NULL;
2N/A#elif NGR_R_PRIVATE == 2
2N/A if (p->buf != NULL)
2N/A free(p->buf);
2N/A free(p);
2N/A#endif
2N/A NGR_R_END_RESULT(NGR_R_OK);
2N/A}
2N/A
2N/A/* Private */
2N/A
2N/Astatic int
2N/Acopy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
2N/A NGR_R_CONST char **domainp, const char *mp, const char *up,
2N/A const char *dp, NGR_R_COPY_ARGS)
2N/A{
2N/A#if NGR_R_PRIVATE == 2
2N/A struct private *p = buf;
2N/A#endif
2N/A char *cp;
2N/A int n;
2N/A int len;
2N/A
2N/A /* Find out the amount of space required to store the answer. */
2N/A len = 0;
2N/A if (mp != NULL) len += strlen(mp) + 1;
2N/A if (up != NULL) len += strlen(up) + 1;
2N/A if (dp != NULL) len += strlen(dp) + 1;
2N/A
2N/A#if NGR_R_PRIVATE == 1
2N/A if (*buf != NULL)
2N/A free(*buf);
2N/A *buf = malloc(len);
2N/A if (*buf == NULL)
2N/A return(NGR_R_BAD);
2N/A cp = *buf;
2N/A#elif NGR_R_PRIVATE == 2
2N/A if (p->buf)
2N/A free(p->buf);
2N/A p->buf = malloc(len);
2N/A if (p->buf == NULL)
2N/A return(NGR_R_BAD);
2N/A cp = p->buf;
2N/A#else
2N/A if (len > (int)buflen) {
2N/A errno = ERANGE;
2N/A return (NGR_R_BAD);
2N/A }
2N/A cp = buf;
2N/A#endif
2N/A
2N/A if (mp != NULL) {
2N/A n = strlen(mp) + 1;
2N/A strcpy(cp, mp);
2N/A *machinep = cp;
2N/A cp += n;
2N/A } else
2N/A *machinep = NULL;
2N/A
2N/A if (up != NULL) {
2N/A n = strlen(up) + 1;
2N/A strcpy(cp, up);
2N/A *userp = cp;
2N/A cp += n;
2N/A } else
2N/A *userp = NULL;
2N/A
2N/A if (dp != NULL) {
2N/A n = strlen(dp) + 1;
2N/A strcpy(cp, dp);
2N/A *domainp = cp;
2N/A cp += n;
2N/A } else
2N/A *domainp = NULL;
2N/A
2N/A return (NGR_R_OK);
2N/A}
2N/A#else /* NGR_R_RETURN */
2N/A static int getnetgrent_r_unknown_system = 0;
2N/A#endif /* NGR_R_RETURN */
2N/A#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
2N/A/*! \file */