2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * Copyright (C) 1989 by NeXT, Inc.
30 #include <mach/mach.h>
33 #include <rpc/types.h>
36 #include <netinet/in.h>
38 #include "_lu_types.h"
42 extern struct protoent
*_old_getprotobynumber();
43 extern struct protoent
*_old_getprotobyname();
44 extern struct protoent
*_old_getprotoent();
45 extern void _old_setprotoent();
46 extern void _old_endprotoent();
48 #define PROTO_GET_NAME 1
49 #define PROTO_GET_NUM 2
50 #define PROTO_GET_ENT 3
53 free_protocol_data(struct protoent
*p
)
57 if (p
== NULL
) return;
59 if (p
->p_name
!= NULL
) free(p
->p_name
);
60 aliases
= p
->p_aliases
;
63 while (*aliases
!= NULL
) free(*aliases
++);
69 free_protocol(struct protoent
*p
)
71 if (p
== NULL
) return;
72 free_protocol_data(p
);
77 free_lu_thread_info_protocol(void *x
)
79 struct lu_thread_info
*tdata
;
81 if (x
== NULL
) return;
83 tdata
= (struct lu_thread_info
*)x
;
85 if (tdata
->lu_entry
!= NULL
)
87 free_protocol((struct protoent
*)tdata
->lu_entry
);
88 tdata
->lu_entry
= NULL
;
91 _lu_data_free_vm_xdr(tdata
);
96 static struct protoent
*
97 extract_protocol(XDR
*xdr
)
100 int i
, j
, nvals
, nkeys
, status
;
103 if (xdr
== NULL
) return NULL
;
105 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
107 p
= (struct protoent
*)calloc(1, sizeof(struct protoent
));
109 for (i
= 0; i
< nkeys
; i
++)
115 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
130 if ((p
->p_name
== NULL
) && (!strcmp("name", key
)))
135 p
->p_aliases
= (char **)calloc(nvals
, sizeof(char *));
136 for (j
= 1; j
< nvals
; j
++) p
->p_aliases
[j
-1] = vals
[j
];
140 else if (!strcmp("number", key
))
142 p
->p_proto
= atoi(vals
[0]);
148 for (; j
< nvals
; j
++) free(vals
[j
]);
153 if (p
->p_name
== NULL
) p
->p_name
= strdup("");
154 if (p
->p_aliases
== NULL
) p
->p_aliases
= (char **)calloc(1, sizeof(char *));
159 static struct protoent
*
160 copy_protocol(struct protoent
*in
)
165 if (in
== NULL
) return NULL
;
167 p
= (struct protoent
*)calloc(1, sizeof(struct protoent
));
169 p
->p_proto
= in
->p_proto
;
170 p
->p_name
= LU_COPY_STRING(in
->p_name
);
173 if (in
->p_aliases
!= NULL
)
175 for (len
= 0; in
->p_aliases
[len
] != NULL
; len
++);
178 p
->p_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
179 for (i
= 0; i
< len
; i
++)
181 p
->p_aliases
[i
] = strdup(in
->p_aliases
[i
]);
188 recycle_protocol(struct lu_thread_info
*tdata
, struct protoent
*in
)
192 if (tdata
== NULL
) return;
193 p
= (struct protoent
*)tdata
->lu_entry
;
198 tdata
->lu_entry
= NULL
;
201 if (tdata
->lu_entry
== NULL
)
203 tdata
->lu_entry
= in
;
207 free_protocol_data(p
);
209 p
->p_proto
= in
->p_proto
;
210 p
->p_name
= in
->p_name
;
211 p
->p_aliases
= in
->p_aliases
;
216 static struct protoent
*
217 lu_getprotobynumber(long number
)
220 unsigned int datalen
;
222 static int proc
= -1;
228 if (_lookup_link(_lu_port
, "getprotobynumber", &proc
) != KERN_SUCCESS
)
234 number
= htonl(number
);
238 if (_lookup_all(_lu_port
, proc
, (unit
*)&number
, 1, &lookup_buf
, &datalen
)
244 datalen
*= BYTES_PER_XDR_UNIT
;
245 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
247 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
250 if (!xdr_int(&inxdr
, &count
))
253 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
260 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
264 p
= extract_protocol(&inxdr
);
266 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
271 static struct protoent
*
272 lu_getprotobyname(const char *name
)
275 unsigned int datalen
;
276 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
279 static int proc
= -1;
285 if (_lookup_link(_lu_port
, "getprotobyname", &proc
) != KERN_SUCCESS
)
291 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
292 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
294 xdr_destroy(&outxdr
);
301 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
,
302 xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
)
305 xdr_destroy(&outxdr
);
309 xdr_destroy(&outxdr
);
311 datalen
*= BYTES_PER_XDR_UNIT
;
312 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
314 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
317 if (!xdr_int(&inxdr
, &count
))
320 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
327 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
331 p
= extract_protocol(&inxdr
);
333 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
341 struct lu_thread_info
*tdata
;
343 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
344 _lu_data_free_vm_xdr(tdata
);
354 static struct protoent
*
358 static int proc
= -1;
359 struct lu_thread_info
*tdata
;
361 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
364 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
365 _lu_data_set_key(_lu_data_key_protocol
, tdata
);
368 if (tdata
->lu_vm
== NULL
)
372 if (_lookup_link(_lu_port
, "getprotoent", &proc
) != KERN_SUCCESS
)
379 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
385 /* mig stubs measure size in words (4 bytes) */
386 tdata
->lu_vm_length
*= 4;
388 if (tdata
->lu_xdr
!= NULL
)
390 xdr_destroy(tdata
->lu_xdr
);
393 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
395 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
396 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
403 if (tdata
->lu_vm_cursor
== 0)
409 p
= extract_protocol(tdata
->lu_xdr
);
416 tdata
->lu_vm_cursor
--;
421 static struct protoent
*
422 getproto(const char *name
, int number
, int source
)
424 struct protoent
*res
= NULL
;
425 struct lu_thread_info
*tdata
;
427 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
430 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
431 _lu_data_set_key(_lu_data_key_protocol
, tdata
);
439 res
= lu_getprotobyname(name
);
442 res
= lu_getprotobynumber(number
);
445 res
= lu_getprotoent();
455 res
= copy_protocol(_old_getprotobyname(name
));
458 res
= copy_protocol(_old_getprotobynumber(number
));
461 res
= copy_protocol(_old_getprotoent());
467 recycle_protocol(tdata
, res
);
468 return (struct protoent
*)tdata
->lu_entry
;
472 getprotobyname(const char *name
)
474 return getproto(name
, -2, PROTO_GET_NAME
);
478 getprotobynumber(int number
)
480 return getproto(NULL
, number
, PROTO_GET_NUM
);
486 return getproto(NULL
, -2, PROTO_GET_ENT
);
490 setprotoent(int stayopen
)
492 if (_lu_running()) lu_setprotoent();
493 else _old_setprotoent(stayopen
);
499 if (_lu_running()) lu_endprotoent();
500 else _old_endprotoent();