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