Libinfo-89.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 #ifdef NOTDEF
239 /* NOTDEF because OOL buffers are counted in bytes with untyped IPC */
240 p_datalen *= BYTES_PER_XDR_UNIT;
241 #endif
242 xdrmem_create(&p_xdr, p_data, p_datalen,
243 XDR_DECODE);
244 if (!xdr_int(&p_xdr, &p_nentries))
245 {
246 xdr_destroy(&p_xdr);
247 lu_endprotoent();
248 return (NULL);
249 }
250 }
251
252 if (p_nentries == 0)
253 {
254 xdr_destroy(&p_xdr);
255 lu_endprotoent();
256 return (NULL);
257 }
258
259 bzero(&lu_p, sizeof(lu_p));
260 if (!xdr__lu_protoent(&p_xdr, &lu_p))
261 {
262 xdr_destroy(&p_xdr);
263 lu_endprotoent();
264 return (NULL);
265 }
266
267 p_nentries--;
268 convert_p(&lu_p);
269 xdr_free(xdr__lu_protoent, &lu_p);
270 return (&global_p);
271 }
272
273 struct protoent *
274 getprotobynumber(int number)
275 {
276 LOOKUP1(lu_getprotobynumber, _old_getprotobynumber, number,
277 struct protoent);
278 }
279
280 struct protoent *
281 getprotobyname(const char *name)
282 {
283 LOOKUP1(lu_getprotobyname, _old_getprotobyname, name, struct protoent);
284 }
285
286 struct protoent *
287 getprotoent(void)
288 {
289 GETENT(lu_getprotoent, _old_getprotoent, &p_state, struct protoent);
290 }
291
292 void
293 setprotoent(int stayopen)
294 {
295 SETSTATE(lu_setprotoent, _old_setprotoent, &p_state, stayopen);
296 }
297
298 void
299 endprotoent(void)
300 {
301 UNSETSTATE(lu_endprotoent, _old_endprotoent, &p_state);
302 }