Libinfo-78.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_protocol.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Protocol lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28 #include <stdlib.h>
29 #include <mach/mach.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "lookup.h"
33 #include <rpc/types.h>
34 #include <rpc/xdr.h>
35 #include "_lu_types.h"
36 #include <netdb.h>
37 #include "lu_utils.h"
38 #import <netinet/in.h>
39
40 extern struct protoent *_old_getprotobynumber();
41 extern struct protoent *_old_getprotobyname();
42 extern struct protoent *_old_getprotoent();
43 extern void _old_setprotoent();
44 extern void _old_endprotoent();
45
46 static lookup_state p_state = LOOKUP_CACHE;
47 static struct protoent global_p;
48 static int global_free = 1;
49 static char *p_data = NULL;
50 static unsigned p_datalen;
51 static int p_nentries;
52 static int p_start;
53 static XDR p_xdr;
54
55 static void
56 freeold(void)
57 {
58 char **aliases;
59
60 if (global_free == 1) return;
61
62 free(global_p.p_name);
63 aliases = global_p.p_aliases;
64 if (aliases != NULL)
65 {
66 while (*aliases != NULL) free(*aliases++);
67 free(global_p.p_aliases);
68 }
69
70 global_free = 1;
71 }
72
73 static void
74 convert_p(_lu_protoent *lu_p)
75 {
76 int i, len;
77
78 freeold();
79
80 global_p.p_name = strdup(lu_p->p_names.p_names_val[0]);
81
82 len = lu_p->p_names.p_names_len - 1;
83 global_p.p_aliases = (char **)malloc((len + 1) * sizeof(char *));
84
85 for (i = 0; i < len; i++)
86 {
87 global_p.p_aliases[i] = strdup(lu_p->p_names.p_names_val[i+1]);
88 }
89
90 global_p.p_aliases[len] = NULL;
91
92 global_p.p_proto = lu_p->p_proto;
93
94 global_free = 0;
95 }
96
97 static struct protoent *
98 lu_getprotobynumber(long number)
99 {
100 unsigned datalen;
101 _lu_protoent_ptr lu_p;
102 XDR xdr;
103 static int proc = -1;
104 unit lookup_buf[MAX_INLINE_UNITS];
105
106 if (proc < 0)
107 {
108 if (_lookup_link(_lu_port, "getprotobynumber", &proc) != KERN_SUCCESS)
109 {
110 return (NULL);
111 }
112 }
113
114 number = htonl(number);
115 datalen = MAX_INLINE_UNITS;
116 if (_lookup_one(_lu_port, proc, (unit *)&number, 1, lookup_buf, &datalen)
117 != KERN_SUCCESS)
118 {
119 return (NULL);
120 }
121
122 datalen *= BYTES_PER_XDR_UNIT;
123 xdrmem_create(&xdr, lookup_buf, datalen,
124 XDR_DECODE);
125 lu_p = NULL;
126 if (!xdr__lu_protoent_ptr(&xdr, &lu_p) || (lu_p == NULL))
127 {
128 xdr_destroy(&xdr);
129 return (NULL);
130 }
131
132 xdr_destroy(&xdr);
133
134 convert_p(lu_p);
135 xdr_free(xdr__lu_protoent_ptr, &lu_p);
136 return (&global_p);
137 }
138
139 static struct protoent *
140 lu_getprotobyname(const char *name)
141 {
142 unsigned datalen;
143 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
144 XDR outxdr;
145 XDR inxdr;
146 _lu_protoent_ptr lu_p;
147 static int proc = -1;
148 unit lookup_buf[MAX_INLINE_UNITS];
149
150 if (proc < 0)
151 {
152 if (_lookup_link(_lu_port, "getprotobyname", &proc) != KERN_SUCCESS)
153 {
154 return (NULL);
155 }
156 }
157
158 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
159 if (!xdr__lu_string(&outxdr, &name))
160 {
161 xdr_destroy(&outxdr);
162 return (NULL);
163 }
164
165 datalen = MAX_INLINE_UNITS;
166 if (_lookup_one(_lu_port, proc, (unit *)namebuf,
167 xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen)
168 != KERN_SUCCESS)
169 {
170 xdr_destroy(&outxdr);
171 return (NULL);
172 }
173
174 xdr_destroy(&outxdr);
175
176 datalen *= BYTES_PER_XDR_UNIT;
177 xdrmem_create(&inxdr, lookup_buf, datalen,
178 XDR_DECODE);
179 lu_p = NULL;
180 if (!xdr__lu_protoent_ptr(&inxdr, &lu_p) || (lu_p == NULL))
181 {
182 xdr_destroy(&inxdr);
183 return (NULL);
184 }
185
186 xdr_destroy(&inxdr);
187
188 convert_p(lu_p);
189 xdr_free(xdr__lu_protoent_ptr, &lu_p);
190 return (&global_p);
191 }
192
193 static void
194 lu_endprotoent()
195 {
196 p_nentries = 0;
197 if (p_data != NULL)
198 {
199 freeold();
200 vm_deallocate(mach_task_self(), (vm_address_t)p_data, p_datalen);
201 p_data = NULL;
202 }
203 }
204
205 static void
206 lu_setprotoent()
207 {
208 lu_endprotoent();
209 p_start = 1;
210 }
211
212 static struct protoent *
213 lu_getprotoent()
214 {
215 static int proc = -1;
216 _lu_protoent lu_p;
217
218 if (p_start == 1)
219 {
220 p_start = 0;
221
222 if (proc < 0)
223 {
224 if (_lookup_link(_lu_port, "getprotoent", &proc) != KERN_SUCCESS)
225 {
226 lu_endprotoent();
227 return (NULL);
228 }
229 }
230
231 if (_lookup_all(_lu_port, proc, NULL, 0, &p_data, &p_datalen)
232 != KERN_SUCCESS)
233 {
234 lu_endprotoent();
235 return (NULL);
236 }
237
238 p_datalen *= BYTES_PER_XDR_UNIT;
239 xdrmem_create(&p_xdr, p_data, p_datalen,
240 XDR_DECODE);
241 if (!xdr_int(&p_xdr, &p_nentries))
242 {
243 xdr_destroy(&p_xdr);
244 lu_endprotoent();
245 return (NULL);
246 }
247 }
248
249 if (p_nentries == 0)
250 {
251 xdr_destroy(&p_xdr);
252 lu_endprotoent();
253 return (NULL);
254 }
255
256 bzero(&lu_p, sizeof(lu_p));
257 if (!xdr__lu_protoent(&p_xdr, &lu_p))
258 {
259 xdr_destroy(&p_xdr);
260 lu_endprotoent();
261 return (NULL);
262 }
263
264 p_nentries--;
265 convert_p(&lu_p);
266 xdr_free(xdr__lu_protoent, &lu_p);
267 return (&global_p);
268 }
269
270 struct protoent *
271 getprotobynumber(int number)
272 {
273 LOOKUP1(lu_getprotobynumber, _old_getprotobynumber, number,
274 struct protoent);
275 }
276
277 struct protoent *
278 getprotobyname(const char *name)
279 {
280 LOOKUP1(lu_getprotobyname, _old_getprotobyname, name, struct protoent);
281 }
282
283 struct protoent *
284 getprotoent(void)
285 {
286 GETENT(lu_getprotoent, _old_getprotoent, &p_state, struct protoent);
287 }
288
289 void
290 setprotoent(int stayopen)
291 {
292 SETSTATE(lu_setprotoent, _old_setprotoent, &p_state, stayopen);
293 }
294
295 void
296 endprotoent(void)
297 {
298 UNSETSTATE(lu_endprotoent, _old_endprotoent, &p_state);
299 }