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