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