1 /* $OpenBSD: getrpcent.c,v 1.18 2015/04/25 21:38:22 miod 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 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 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 = (struct rpcdata *)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 120 void 121 endrpcent(void) 122 { 123 struct rpcdata *d = _rpcdata(); 124 125 if (d == NULL) 126 return; 127 if (d->rpcf && !d->stayopen) { 128 fclose(d->rpcf); 129 d->rpcf = NULL; 130 } 131 } 132 133 struct rpcent * 134 getrpcent(void) 135 { 136 struct rpcdata *d = _rpcdata(); 137 138 if (d == NULL) 139 return(NULL); 140 if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "re")) == NULL) 141 return (NULL); 142 /* -1 so there is room to append a \n below */ 143 if (fgets(d->line, sizeof(d->line) - 1, d->rpcf) == NULL) 144 return (NULL); 145 return (interpret(d->line, strlen(d->line))); 146 } 147 148 static struct rpcent * 149 interpret(char *val, int len) 150 { 151 const char *errstr; 152 struct rpcdata *d = _rpcdata(); 153 char *p; 154 char *cp, *num, **q; 155 156 if (d == NULL) 157 return (0); 158 strlcpy(d->line, val, sizeof(d->line)); 159 p = d->line; 160 p[len] = '\n'; 161 if (*p == '#') 162 return (getrpcent()); 163 cp = strpbrk(p, "#\n"); 164 if (cp == NULL) 165 return (getrpcent()); 166 *cp = '\0'; 167 cp = strpbrk(p, " \t"); 168 if (cp == NULL) 169 return (getrpcent()); 170 *cp++ = '\0'; 171 /* THIS STUFF IS INTERNET SPECIFIC */ 172 d->rpc.r_name = d->line; 173 while (*cp == ' ' || *cp == '\t') 174 cp++; 175 num = cp; 176 cp = strpbrk(cp, " \t"); 177 if (cp != NULL) 178 *cp++ = '\0'; 179 d->rpc.r_number = strtonum(num, 0, INT_MAX, &errstr); 180 if (errstr) 181 return (0); 182 q = d->rpc.r_aliases = d->rpc_aliases; 183 while (cp && *cp) { 184 if (*cp == ' ' || *cp == '\t') { 185 cp++; 186 continue; 187 } 188 if (q < &(d->rpc_aliases[MAXALIASES - 1])) 189 *q++ = cp; 190 cp = strpbrk(cp, " \t"); 191 if (cp != NULL) 192 *cp++ = '\0'; 193 } 194 *q = NULL; 195 return (&d->rpc); 196 } 197 198