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 *
_rpcdata(void)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 *
getrpcbynumber(int number)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 *
getrpcbyname(char * name)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
setrpcent(int f)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
endrpcent(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 *
getrpcent(void)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 *
interpret(char * val,int len)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