1 /* 2 * Copyright (c) 2009, Sun Microsystems, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * - Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * - Redistributions in binary form must reproduce the above copyright notice, 10 * this list of conditions and the following disclaimer in the documentation 11 * and/or other materials provided with the distribution. 12 * - Neither the name of Sun Microsystems, Inc. nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Copyright (c) 1984 by Sun Microsystems, Inc. 31 */ 32 33 #include <wintirpc.h> 34 #include <sys/types.h> 35 36 //#include <netinet/in.h> 37 //#include <arpa/inet.h> 38 39 #include <assert.h> 40 //#include <netdb.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 45 #include <rpc/rpc.h> 46 #ifdef YP 47 #include <rpcsvc/yp_prot.h> 48 #include <rpcsvc/ypclnt.h> 49 #endif 50 #include <libc_private.h> 51 52 /* 53 * Internet version. 54 */ 55 static struct rpcdata { 56 FILE *rpcf; 57 int stayopen; 58 #define MAXALIASES 35 59 char *rpc_aliases[MAXALIASES]; 60 struct rpcent rpc; 61 char line[BUFSIZ+1]; 62 #ifdef YP 63 char *domain; 64 char *current; 65 int currentlen; 66 #endif 67 } *rpcdata; 68 69 static struct rpcent *interpret(char *val, size_t len); 70 71 #ifdef YP 72 static int __yp_nomap = 0; 73 #endif /* YP */ 74 75 #define RPCDB "/etc/rpc" 76 77 static struct rpcdata *_rpcdata(void); 78 79 static struct rpcdata * 80 _rpcdata() 81 { 82 struct rpcdata *d = rpcdata; 83 84 if (d == 0) { 85 d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); 86 rpcdata = d; 87 } 88 return (d); 89 } 90 91 #ifdef GQ 92 struct rpcent * 93 getrpcbynumber(number) 94 int number; 95 { 96 #ifdef YP 97 int reason; 98 char adrstr[16]; 99 #endif 100 struct rpcent *p; 101 struct rpcdata *d = _rpcdata(); 102 103 if (d == 0) 104 return (0); 105 #ifdef YP 106 if (!__yp_nomap && _yp_check(&d->domain)) { 107 sprintf(adrstr, "%d", number); 108 reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr), 109 &d->current, &d->currentlen); 110 switch(reason) { 111 case 0: 112 break; 113 case YPERR_MAP: 114 __yp_nomap = 1; 115 goto no_yp; 116 break; 117 default: 118 return(0); 119 break; 120 } 121 d->current[d->currentlen] = '\0'; 122 p = interpret(d->current, d->currentlen); 123 (void) free(d->current); 124 return p; 125 } 126 no_yp: 127 #endif /* YP */ 128 129 setrpcent(0); 130 while ((p = getrpcent()) != NULL) { 131 if (p->r_number == number) 132 break; 133 } 134 endrpcent(); 135 return (p); 136 } 137 138 struct rpcent * 139 getrpcbyname(name) 140 char *name; 141 { 142 struct rpcent *rpc = NULL; 143 char **rp; 144 145 assert(name != NULL); 146 147 setrpcent(0); 148 while ((rpc = getrpcent()) != NULL) { 149 if (strcmp(rpc->r_name, name) == 0) 150 goto done; 151 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 152 if (strcmp(*rp, name) == 0) 153 goto done; 154 } 155 } 156 done: 157 endrpcent(); 158 return (rpc); 159 } 160 #endif /* GQ */ 161 162 void 163 setrpcent(f) 164 int f; 165 { 166 struct rpcdata *d = _rpcdata(); 167 168 if (d == 0) 169 return; 170 #ifdef YP 171 if (!__yp_nomap && _yp_check(NULL)) { 172 if (d->current) 173 free(d->current); 174 d->current = NULL; 175 d->currentlen = 0; 176 return; 177 } 178 __yp_nomap = 0; 179 #endif /* YP */ 180 if (d->rpcf == NULL) 181 d->rpcf = fopen(RPCDB, "r"); 182 else 183 rewind(d->rpcf); 184 d->stayopen |= f; 185 } 186 187 void 188 endrpcent() 189 { 190 struct rpcdata *d = _rpcdata(); 191 192 if (d == 0) 193 return; 194 #ifdef YP 195 if (!__yp_nomap && _yp_check(NULL)) { 196 if (d->current && !d->stayopen) 197 free(d->current); 198 d->current = NULL; 199 d->currentlen = 0; 200 return; 201 } 202 __yp_nomap = 0; 203 #endif /* YP */ 204 if (d->rpcf && !d->stayopen) { 205 fclose(d->rpcf); 206 d->rpcf = NULL; 207 } 208 } 209 210 struct rpcent * 211 getrpcent() 212 { 213 struct rpcdata *d = _rpcdata(); 214 #ifdef YP 215 struct rpcent *hp; 216 int reason; 217 char *val = NULL; 218 int vallen; 219 #endif 220 221 if (d == 0) 222 return(NULL); 223 #ifdef YP 224 if (!__yp_nomap && _yp_check(&d->domain)) { 225 if (d->current == NULL && d->currentlen == 0) { 226 reason = yp_first(d->domain, "rpc.bynumber", 227 &d->current, &d->currentlen, 228 &val, &vallen); 229 } else { 230 reason = yp_next(d->domain, "rpc.bynumber", 231 d->current, d->currentlen, 232 &d->current, &d->currentlen, 233 &val, &vallen); 234 } 235 switch(reason) { 236 case 0: 237 break; 238 case YPERR_MAP: 239 __yp_nomap = 1; 240 goto no_yp; 241 break; 242 default: 243 return(0); 244 break; 245 } 246 val[vallen] = '\0'; 247 hp = interpret(val, vallen); 248 (void) free(val); 249 return hp; 250 } 251 no_yp: 252 #endif /* YP */ 253 if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) 254 return (NULL); 255 /* -1 so there is room to append a \n below */ 256 if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL) 257 return (NULL); 258 return (interpret(d->line, strlen(d->line))); 259 } 260 261 static struct rpcent * 262 interpret(val, len) 263 char *val; 264 size_t len; 265 { 266 struct rpcdata *d = _rpcdata(); 267 char *p; 268 char *cp, **q; 269 270 assert(val != NULL); 271 272 if (d == 0) 273 return (0); 274 (void) strncpy(d->line, val, BUFSIZ); 275 d->line[BUFSIZ] = '\0'; 276 p = d->line; 277 p[len] = '\n'; 278 if (*p == '#') 279 return (getrpcent()); 280 cp = strpbrk(p, "#\n"); 281 if (cp == NULL) 282 return (getrpcent()); 283 *cp = '\0'; 284 cp = strpbrk(p, " \t"); 285 if (cp == NULL) 286 return (getrpcent()); 287 *cp++ = '\0'; 288 /* THIS STUFF IS INTERNET SPECIFIC */ 289 d->rpc.r_name = d->line; 290 while (*cp == ' ' || *cp == '\t') 291 cp++; 292 d->rpc.r_number = atoi(cp); 293 q = d->rpc.r_aliases = d->rpc_aliases; 294 cp = strpbrk(cp, " \t"); 295 if (cp != NULL) 296 *cp++ = '\0'; 297 while (cp && *cp) { 298 if (*cp == ' ' || *cp == '\t') { 299 cp++; 300 continue; 301 } 302 if (q < &(d->rpc_aliases[MAXALIASES - 1])) 303 *q++ = cp; 304 cp = strpbrk(cp, " \t"); 305 if (cp != NULL) 306 *cp++ = '\0'; 307 } 308 *q = NULL; 309 return (&d->rpc); 310 } 311 312