1/* $NetBSD: getrpcent.c,v 1.22 2011/10/15 23:00:02 christos Exp $ */ 2 3/* 4 * Copyright (c) 2010, Oracle America, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials 15 * provided with the distribution. 16 * * Neither the name of the "Oracle America, Inc." nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> 35#if defined(LIBC_SCCS) && !defined(lint) 36#if 0 37static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro"; 38#else 39__RCSID("$NetBSD: getrpcent.c,v 1.22 2011/10/15 23:00:02 christos Exp $"); 40#endif 41#endif 42 43/* 44 * Copyright (c) 1984 by Sun Microsystems, Inc. 45 */ 46 47#include "namespace.h" 48 49#include <sys/types.h> 50 51#include <netinet/in.h> 52#include <arpa/inet.h> 53 54#include <assert.h> 55#include <netdb.h> 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59 60#include <rpc/rpc.h> 61 62#ifdef __weak_alias 63__weak_alias(endrpcent,_endrpcent) 64__weak_alias(getrpcbyname,_getrpcbyname) 65__weak_alias(getrpcbynumber,_getrpcbynumber) 66__weak_alias(getrpcent,_getrpcent) 67__weak_alias(setrpcent,_setrpcent) 68#endif 69 70/* 71 * Internet version. 72 */ 73static struct rpcdata { 74 FILE *rpcf; 75 int stayopen; 76#define MAXALIASES 35 77 char *rpc_aliases[MAXALIASES]; 78 struct rpcent rpc; 79 char line[BUFSIZ+1]; 80} *rpcdata; 81 82static struct rpcent *interpret(char *val, size_t len); 83 84#define RPCDB "/etc/rpc" 85 86static struct rpcdata *_rpcdata(void); 87 88static struct rpcdata * 89_rpcdata(void) 90{ 91 struct rpcdata *d = rpcdata; 92 93 if (d == 0) { 94 d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); 95 rpcdata = d; 96 } 97 return (d); 98} 99 100struct rpcent * 101getrpcbynumber(int number) 102{ 103 struct rpcent *rpc; 104 105 setrpcent(0); 106 while ((rpc = getrpcent()) != NULL) { 107 if (rpc->r_number == number) 108 break; 109 } 110 endrpcent(); 111 return (rpc); 112} 113 114struct rpcent * 115getrpcbyname(const char *name) 116{ 117 struct rpcent *rpc; 118 char **rp; 119 120 _DIAGASSERT(name != NULL); 121 122 setrpcent(0); 123 while ((rpc = getrpcent()) != NULL) { 124 if (strcmp(rpc->r_name, name) == 0) 125 break; 126 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 127 if (strcmp(*rp, name) == 0) 128 goto found; 129 } 130 } 131found: 132 endrpcent(); 133 return (rpc); 134} 135 136void 137setrpcent(int f) 138{ 139 struct rpcdata *d = _rpcdata(); 140 141 if (d == 0) 142 return; 143 if (d->rpcf == NULL) 144 d->rpcf = fopen(RPCDB, "re"); 145 else 146 rewind(d->rpcf); 147 d->stayopen |= f; 148} 149 150void 151endrpcent(void) 152{ 153 struct rpcdata *d = _rpcdata(); 154 155 if (d == 0) 156 return; 157 if (d->rpcf && !d->stayopen) { 158 fclose(d->rpcf); 159 d->rpcf = NULL; 160 } 161} 162 163struct rpcent * 164getrpcent(void) 165{ 166 struct rpcdata *d = _rpcdata(); 167 168 if (d == 0) 169 return(NULL); 170 if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "re")) == NULL) 171 return (NULL); 172 if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) 173 return (NULL); 174 return (interpret(d->line, strlen(d->line))); 175} 176 177static struct rpcent * 178interpret(char *val, size_t len) 179{ 180 struct rpcdata *d = _rpcdata(); 181 char *p; 182 char *cp, **q; 183 184 _DIAGASSERT(val != NULL); 185 186 if (d == 0) 187 return (0); 188 (void) strncpy(d->line, val, len); 189 p = d->line; 190 d->line[len] = '\n'; 191 if (*p == '#') 192 return (getrpcent()); 193 cp = strpbrk(p, "#\n"); 194 if (cp == NULL) 195 return (getrpcent()); 196 *cp = '\0'; 197 cp = strpbrk(p, " \t"); 198 if (cp == NULL) 199 return (getrpcent()); 200 *cp++ = '\0'; 201 /* THIS STUFF IS INTERNET SPECIFIC */ 202 d->rpc.r_name = d->line; 203 while (*cp == ' ' || *cp == '\t') 204 cp++; 205 d->rpc.r_number = atoi(cp); 206 q = d->rpc.r_aliases = d->rpc_aliases; 207 cp = strpbrk(cp, " \t"); 208 if (cp != NULL) 209 *cp++ = '\0'; 210 while (cp && *cp) { 211 if (*cp == ' ' || *cp == '\t') { 212 cp++; 213 continue; 214 } 215 if (q < &(d->rpc_aliases[MAXALIASES - 1])) 216 *q++ = cp; 217 cp = strpbrk(cp, " \t"); 218 if (cp != NULL) 219 *cp++ = '\0'; 220 } 221 *q = NULL; 222 return (&d->rpc); 223} 224