1 /* $OpenBSD: getrpcent.c,v 1.22 2020/10/13 04:42:28 guenther 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 <stdio.h> 35 #include <stdlib.h> 36 #include <sys/types.h> 37 #include <string.h> 38 #include <limits.h> 39 #include <rpc/rpc.h> 40 41 /* 42 * Internet version. 43 */ 44 static struct rpcdata { 45 FILE *rpcf; 46 int stayopen; 47 #define MAXALIASES 35 48 char *rpc_aliases[MAXALIASES]; 49 struct rpcent rpc; 50 char line[BUFSIZ+1]; 51 } *rpcdata; 52 53 static struct rpcent *interpret(char *val, int len); 54 55 static const char RPCDB[] = "/etc/rpc"; 56 57 static struct rpcdata * 58 _rpcdata(void) 59 { 60 struct rpcdata *d = rpcdata; 61 62 if (d == NULL) { 63 d = calloc(1, sizeof (struct rpcdata)); 64 rpcdata = d; 65 } 66 return (d); 67 } 68 69 struct rpcent * 70 getrpcbynumber(int number) 71 { 72 struct rpcdata *d = _rpcdata(); 73 struct rpcent *p; 74 75 if (d == NULL) 76 return (0); 77 setrpcent(0); 78 while ((p = getrpcent())) { 79 if (p->r_number == number) 80 break; 81 } 82 endrpcent(); 83 return (p); 84 } 85 86 struct rpcent * 87 getrpcbyname(char *name) 88 { 89 struct rpcent *rpc; 90 char **rp; 91 92 setrpcent(0); 93 while ((rpc = getrpcent())) { 94 if (strcmp(rpc->r_name, name) == 0) 95 goto done; 96 for (rp = rpc->r_aliases; *rp != NULL; rp++) { 97 if (strcmp(*rp, name) == 0) 98 goto done; 99 } 100 } 101 done: 102 endrpcent(); 103 return (rpc); 104 } 105 106 void 107 setrpcent(int f) 108 { 109 struct rpcdata *d = _rpcdata(); 110 111 if (d == NULL) 112 return; 113 if (d->rpcf == NULL) 114 d->rpcf = fopen(RPCDB, "re"); 115 else 116 rewind(d->rpcf); 117 d->stayopen |= f; 118 } 119 DEF_WEAK(setrpcent); 120 121 void 122 endrpcent(void) 123 { 124 struct rpcdata *d = _rpcdata(); 125 126 if (d == NULL) 127 return; 128 if (d->rpcf && !d->stayopen) { 129 fclose(d->rpcf); 130 d->rpcf = NULL; 131 } 132 } 133 DEF_WEAK(endrpcent); 134 135 struct rpcent * 136 getrpcent(void) 137 { 138 struct rpcdata *d = _rpcdata(); 139 140 if (d == NULL) 141 return(NULL); 142 if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "re")) == NULL) 143 return (NULL); 144 /* -1 so there is room to append a \n below */ 145 if (fgets(d->line, sizeof(d->line) - 1, d->rpcf) == NULL) 146 return (NULL); 147 return (interpret(d->line, strlen(d->line))); 148 } 149 DEF_WEAK(getrpcent); 150 151 static struct rpcent * 152 interpret(char *val, int len) 153 { 154 const char *errstr; 155 struct rpcdata *d = _rpcdata(); 156 char *p; 157 char *cp, *num, **q; 158 159 if (d == NULL) 160 return (0); 161 strlcpy(d->line, val, sizeof(d->line)); 162 p = d->line; 163 p[len] = '\n'; 164 if (*p == '#') 165 return (getrpcent()); 166 cp = strpbrk(p, "#\n"); 167 if (cp == NULL) 168 return (getrpcent()); 169 *cp = '\0'; 170 cp = strpbrk(p, " \t"); 171 if (cp == NULL) 172 return (getrpcent()); 173 *cp++ = '\0'; 174 /* THIS STUFF IS INTERNET SPECIFIC */ 175 d->rpc.r_name = d->line; 176 while (*cp == ' ' || *cp == '\t') 177 cp++; 178 num = cp; 179 cp = strpbrk(cp, " \t"); 180 if (cp != NULL) 181 *cp++ = '\0'; 182 d->rpc.r_number = strtonum(num, 0, INT_MAX, &errstr); 183 if (errstr) 184 return (0); 185 q = d->rpc.r_aliases = d->rpc_aliases; 186 while (cp && *cp) { 187 if (*cp == ' ' || *cp == '\t') { 188 cp++; 189 continue; 190 } 191 if (q < &(d->rpc_aliases[MAXALIASES - 1])) 192 *q++ = cp; 193 cp = strpbrk(cp, " \t"); 194 if (cp != NULL) 195 *cp++ = '\0'; 196 } 197 *q = NULL; 198 return (&d->rpc); 199 } 200 201