1 /* $NetBSD: getnetgrent_r.c,v 1.1.1.1 2009/04/12 15:33:42 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1998, 1999, 2001, 2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #if defined(LIBC_SCCS) && !defined(lint) 21 static const char rcsid[] = "Id: getnetgrent_r.c,v 1.14 2008/11/14 02:36:51 marka Exp"; 22 #endif /* LIBC_SCCS and not lint */ 23 24 #include <port_before.h> 25 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 26 static int getnetgrent_r_not_required = 0; 27 #else 28 #include <errno.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <sys/types.h> 32 #include <netinet/in.h> 33 #include <netdb.h> 34 #include <stdlib.h> 35 #include <port_after.h> 36 37 #ifdef NGR_R_RETURN 38 #ifndef NGR_R_PRIVATE 39 #define NGR_R_PRIVATE 0 40 #endif 41 42 static NGR_R_RETURN 43 copy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **, 44 const char *, const char *, const char *, NGR_R_COPY_ARGS); 45 46 NGR_R_RETURN 47 innetgr_r(const char *netgroup, const char *host, const char *user, 48 const char *domain) { 49 char *ng, *ho, *us, *dom; 50 51 DE_CONST(netgroup, ng); 52 DE_CONST(host, ho); 53 DE_CONST(user, us); 54 DE_CONST(domain, dom); 55 56 return (innetgr(ng, ho, us, dom)); 57 } 58 59 /*% 60 * These assume a single context is in operation per thread. 61 * If this is not the case we will need to call irs directly 62 * rather than through the base functions. 63 */ 64 65 NGR_R_RETURN 66 getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp, 67 NGR_R_CONST char **domainp, NGR_R_ARGS) 68 { 69 NGR_R_CONST char *mp, *up, *dp; 70 int res = getnetgrent(&mp, &up, &dp); 71 72 if (res != 1) 73 return (res); 74 75 return (copy_protoent(machinep, userp, domainp, 76 mp, up, dp, NGR_R_COPY)); 77 } 78 79 #if NGR_R_PRIVATE == 2 80 struct private { 81 char *buf; 82 }; 83 84 #endif 85 NGR_R_SET_RETURN 86 #ifdef NGR_R_SET_ARGS 87 setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS) 88 #else 89 setnetgrent_r(NGR_R_SET_CONST char *netgroup) 90 #endif 91 { 92 #if NGR_R_PRIVATE == 2 93 struct private *p; 94 #endif 95 char *tmp; 96 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0 97 UNUSED(buf); 98 UNUSED(buflen); 99 #endif 100 101 DE_CONST(netgroup, tmp); 102 setnetgrent(tmp); 103 104 #if NGR_R_PRIVATE == 1 105 *buf = NULL; 106 #elif NGR_R_PRIVATE == 2 107 *buf = p = malloc(sizeof(struct private)); 108 if (p == NULL) 109 #ifdef NGR_R_SET_RESULT 110 return (NGR_R_BAD); 111 #else 112 return; 113 #endif 114 p->buf = NULL; 115 #endif 116 #ifdef NGR_R_SET_RESULT 117 return (NGR_R_SET_RESULT); 118 #endif 119 } 120 121 NGR_R_END_RETURN 122 #ifdef NGR_R_END_ARGS 123 endnetgrent_r(NGR_R_END_ARGS) 124 #else 125 endnetgrent_r(void) 126 #endif 127 { 128 #if NGR_R_PRIVATE == 2 129 struct private *p = buf; 130 #endif 131 #if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0 132 UNUSED(buf); 133 UNUSED(buflen); 134 #endif 135 136 endnetgrent(); 137 #if NGR_R_PRIVATE == 1 138 if (*buf != NULL) 139 free(*buf); 140 *buf = NULL; 141 #elif NGR_R_PRIVATE == 2 142 if (p->buf != NULL) 143 free(p->buf); 144 free(p); 145 #endif 146 NGR_R_END_RESULT(NGR_R_OK); 147 } 148 149 /* Private */ 150 151 static int 152 copy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp, 153 NGR_R_CONST char **domainp, const char *mp, const char *up, 154 const char *dp, NGR_R_COPY_ARGS) 155 { 156 #if NGR_R_PRIVATE == 2 157 struct private *p = buf; 158 #endif 159 char *cp; 160 int n; 161 int len; 162 163 /* Find out the amount of space required to store the answer. */ 164 len = 0; 165 if (mp != NULL) len += strlen(mp) + 1; 166 if (up != NULL) len += strlen(up) + 1; 167 if (dp != NULL) len += strlen(dp) + 1; 168 169 #if NGR_R_PRIVATE == 1 170 if (*buf != NULL) 171 free(*buf); 172 *buf = malloc(len); 173 if (*buf == NULL) 174 return(NGR_R_BAD); 175 cp = *buf; 176 #elif NGR_R_PRIVATE == 2 177 if (p->buf) 178 free(p->buf); 179 p->buf = malloc(len); 180 if (p->buf == NULL) 181 return(NGR_R_BAD); 182 cp = p->buf; 183 #else 184 if (len > (int)buflen) { 185 errno = ERANGE; 186 return (NGR_R_BAD); 187 } 188 cp = buf; 189 #endif 190 191 if (mp != NULL) { 192 n = strlen(mp) + 1; 193 strcpy(cp, mp); 194 *machinep = cp; 195 cp += n; 196 } else 197 *machinep = NULL; 198 199 if (up != NULL) { 200 n = strlen(up) + 1; 201 strcpy(cp, up); 202 *userp = cp; 203 cp += n; 204 } else 205 *userp = NULL; 206 207 if (dp != NULL) { 208 n = strlen(dp) + 1; 209 strcpy(cp, dp); 210 *domainp = cp; 211 cp += n; 212 } else 213 *domainp = NULL; 214 215 return (NGR_R_OK); 216 } 217 #else /* NGR_R_RETURN */ 218 static int getnetgrent_r_unknown_system = 0; 219 #endif /* NGR_R_RETURN */ 220 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 221 /*! \file */ 222